diff --git a/.gitattributes b/.gitattributes index 0a998a5369fff9..4a487c3c2a14e5 100644 --- a/.gitattributes +++ b/.gitattributes @@ -37,3 +37,20 @@ Lib/test/test_importlib/data01/* -text *.proj text eol=crlf PCbuild/readme.txt text eol=crlf PC/readme.txt text eol=crlf + +# Generated files +# https://github.com/github/linguist#generated-code +Include/graminit.h linguist-generated=true +Python/graminit.h linguist-generated=true +Modules/clinic/*.h linguist-generated=true +Objects/clinic/*.h linguist-generated=true +PC/clinic/*.h linguist-generated=true +Python/clinic/*.h linguist-generated=true +Python/importlib.h linguist-generated=true +Python/importlib_external.h linguist-generated=true +Include/Python-ast.h linguist-generated=true +Python/Python-ast.c linguist-generated=true +Include/opcode.h linguist-generated=true +Python/opcode_targets.h linguist-generated=true +Objects/typeslots.inc linguist-generated=true +Modules/unicodedata_db.h linguist-generated=true diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 55e4168747e10d..2731c0e8e5503b 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,12 +1,30 @@ -!!! If this is a backport PR (PR made against branches other than `master`), + diff --git a/.github/appveyor.yml b/.github/appveyor.yml index 6662732326a3b8..638540d46bb9cb 100644 --- a/.github/appveyor.yml +++ b/.github/appveyor.yml @@ -1,4 +1,4 @@ -version: 3.7build{build} +version: 3.8build{build} clone_depth: 5 branches: only: @@ -6,7 +6,7 @@ branches: - /\d\.\d/ - buildbot-custom cache: - - externals -> PCbuild\* + - externals -> PCbuild before_build: - ps: |+ if ($env:APPVEYOR_RE_BUILD) { diff --git a/.gitignore b/.gitignore index 6539cc2daeed7a..3035a2ab3060e4 100644 --- a/.gitignore +++ b/.gitignore @@ -115,3 +115,4 @@ Tools/ssl/win32 .vs/ .vscode/ gmon.out +.mypy_cache/ diff --git a/.travis.yml b/.travis.yml index 3a5d203f8cb88c..beecff2e6abf4a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -49,16 +49,30 @@ matrix: - cd Doc # Sphinx is pinned so that new versions that introduce new warnings won't suddenly cause build failures. # (Updating the version is fine as long as no warnings are raised by doing so.) - - python -m pip install sphinx~=1.6.1 blurb + # The theme used by the docs is stored seperately, so we need to install that as well. + - python -m pip install sphinx~=1.6.1 blurb python-docs-theme script: - make check suspicious html SPHINXOPTS="-q -W -j4" + - os: osx + language: c + compiler: clang + # Testing under macOS is optional until testing stability has been demonstrated. + env: OPTIONAL=true + before_install: + # Python 3 is needed for Argument Clinic and multissl + - HOMEBREW_NO_AUTO_UPDATE=1 brew install xz python3 + - export PATH=$(brew --prefix)/bin:$(brew --prefix)/sbin:$PATH - os: linux language: c compiler: gcc env: OPTIONAL=true + addons: + apt: + packages: + - lcov before_script: - ./configure - - make -s -j4 + - make coverage -s -j4 # Need a venv that can parse covered code. - ./python -m venv venv - ./venv/bin/python -m pip install -U coverage @@ -69,6 +83,7 @@ matrix: after_script: # Probably should be after_success once test suite updated to run under coverage.py. # Make the `coverage` command available to Codecov w/ a version of Python that can parse all source files. - source ./venv/bin/activate + - make coverage-lcov - bash <(curl -s https://codecov.io/bash) @@ -76,9 +91,9 @@ before_install: - set -e - | # Check short-circuit conditions - if [ "${TESTING}" != "docs" ] + if [[ "${TESTING}" != "docs" ]] then - if [ "$TRAVIS_PULL_REQUEST" = "false" ] + if [[ "$TRAVIS_PULL_REQUEST" == "false" ]] then echo "Not a PR, doing full build." else @@ -101,7 +116,7 @@ before_install: install: - | # Install OpenSSL as necessary - if [ "${TESTING}" != "docs" ] + if [[ "${TESTING}" != "docs" ]] then # clang complains about unused-parameter a lot, redirect stderr python3 Tools/ssl/multissltests.py --steps=library \ @@ -139,6 +154,11 @@ script: notifications: email: false + webhooks: + urls: + - https://python.zulipchat.com/api/v1/external/travis?api_key=QTP4LAknlFml0NuPQmAetvH4KQaokiQE&stream=core%2Ftest+runs + on_success: change + on_failure: always irc: channels: # This is set to a secure variable to prevent forks from notifying the diff --git a/.vsts/linux-buildbot.yml b/.vsts/linux-buildbot.yml index d75d7f57650e27..fc2c8ca2486e1b 100644 --- a/.vsts/linux-buildbot.yml +++ b/.vsts/linux-buildbot.yml @@ -54,6 +54,7 @@ steps: liblzma-dev libffi-dev uuid-dev + xvfb displayName: 'Install dependencies' - script: python3 Tools/ssl/multissltests.py --steps=library --base-directory $(build.sourcesDirectory)/multissl --openssl $(OPENSSL) --system Linux displayName: 'python multissltests.py' @@ -67,5 +68,5 @@ steps: - script: make pythoninfo displayName: 'Display build info' -- script: make buildbottest TESTOPTS="-j4 -uall,-cpu" +- script: xvfb-run make buildbottest TESTOPTS="-j4 -uall,-cpu" displayName: 'Tests' diff --git a/.vsts/linux-coverage.yml b/.vsts/linux-coverage.yml index 3657b1720ee2cc..14e42fb6b6105e 100644 --- a/.vsts/linux-coverage.yml +++ b/.vsts/linux-coverage.yml @@ -53,6 +53,7 @@ steps: liblzma-dev libffi-dev uuid-dev + xvfb displayName: 'Install dependencies' - script: python3 Tools/ssl/multissltests.py --steps=library --base-directory $(build.sourcesDirectory)/multissl --openssl $(OPENSSL) --system Linux displayName: 'python multissltests.py' @@ -70,7 +71,7 @@ steps: - script: ./venv/bin/python -m test.pythoninfo displayName: 'Display build info' -- script: ./venv/bin/python -m coverage run --pylib -m test --fail-env-changed -uall,-cpu -x test_multiprocessing_fork -x test_multiprocessing_forkserver -x test_multiprocessing_spawn -x test_concurrent_futures +- script: xvfb-run ./venv/bin/python -m coverage run --pylib -m test --fail-env-changed -uall,-cpu -x test_multiprocessing_fork -x test_multiprocessing_forkserver -x test_multiprocessing_spawn -x test_concurrent_futures displayName: 'Tests with coverage' - script: source ./venv/bin/activate && bash <(curl -s https://codecov.io/bash) diff --git a/.vsts/linux-deps.yml b/.vsts/linux-deps.yml index b6c8a3690ea13b..83b0b5961721d0 100644 --- a/.vsts/linux-deps.yml +++ b/.vsts/linux-deps.yml @@ -31,6 +31,7 @@ steps: liblzma-dev libffi-dev uuid-dev + xvfb displayName: 'Install dependencies' - script: python3 Tools/ssl/multissltests.py --steps=library --base-directory $(build.sourcesDirectory)/multissl --openssl $(OPENSSL) --system Linux displayName: 'python multissltests.py' diff --git a/.vsts/linux-pr.yml b/.vsts/linux-pr.yml index 7f4d458f5a7cfa..80e42844a1a0cb 100644 --- a/.vsts/linux-pr.yml +++ b/.vsts/linux-pr.yml @@ -53,6 +53,7 @@ steps: liblzma-dev libffi-dev uuid-dev + xvfb displayName: 'Install dependencies' - script: python3 Tools/ssl/multissltests.py --steps=library --base-directory $(build.sourcesDirectory)/multissl --openssl $(OPENSSL) --system Linux displayName: 'python multissltests.py' @@ -71,5 +72,5 @@ steps: - script: ./python Tools/scripts/patchcheck.py --travis true displayName: 'Run patchcheck.py' -- script: make buildbottest TESTOPTS="-j4 -uall,-cpu" +- script: xvfb-run make buildbottest TESTOPTS="-j4 -uall,-cpu" displayName: 'Tests' diff --git a/Doc/Makefile b/Doc/Makefile index 307d1e0e7de10b..042f960b93e7ff 100644 --- a/Doc/Makefile +++ b/Doc/Makefile @@ -123,7 +123,7 @@ clean: venv: $(PYTHON) -m venv $(VENVDIR) - $(VENVDIR)/bin/python3 -m pip install -U Sphinx blurb + $(VENVDIR)/bin/python3 -m pip install -U Sphinx blurb python-docs-theme @echo "The venv has been created in the $(VENVDIR) directory" dist: diff --git a/Doc/README.rst b/Doc/README.rst index a29d1f3a708a43..b34916040eb93f 100644 --- a/Doc/README.rst +++ b/Doc/README.rst @@ -20,11 +20,11 @@ tree but are maintained separately and are available from * `Sphinx `_ * `blurb `_ +* `python-docs-theme `_ The easiest way to install these tools is to create a virtual environment and install the tools into there. - Using make ---------- diff --git a/Doc/c-api/memory.rst b/Doc/c-api/memory.rst index 73ae6db498cf2c..9f7b13c1472953 100644 --- a/Doc/c-api/memory.rst +++ b/Doc/c-api/memory.rst @@ -35,7 +35,7 @@ operate within the bounds of the private heap. It is important to understand that the management of the Python heap is performed by the interpreter itself and that the user has no control over it, -even if she regularly manipulates object pointers to memory blocks inside that +even if they regularly manipulate object pointers to memory blocks inside that heap. The allocation of heap space for Python objects and other internal buffers is performed on demand by the Python memory manager through the Python/C API functions listed in this document. diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index 6cbcc273c1f153..5615f59514b9de 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -20,18 +20,472 @@ functionality. The fields of the type object are examined in detail in this section. The fields will be described in the order in which they occur in the structure. -Typedefs: unaryfunc, binaryfunc, ternaryfunc, inquiry, intargfunc, -intintargfunc, intobjargproc, intintobjargproc, objobjargproc, destructor, -freefunc, printfunc, getattrfunc, getattrofunc, setattrfunc, setattrofunc, -reprfunc, hashfunc +In addition to the following quick reference, the :ref:`examples` +section provides at-a-glance insight into the meaning and use of +:c:type:`PyTypeObject`. + + +Quick Reference +--------------- + +.. _tp-slots-table: + +"tp slots" +^^^^^^^^^^ + +.. table:: + :widths: 18,18,18,1,1,1,1 + + +---------------------------------------------+-----------------------------------+-------------------+---------------+ + | PyTypeObject Slot [#slots]_ | :ref:`Type ` | special | Info [#cols]_ | + | | | methods/attrs +---+---+---+---+ + | | | | O | T | D | I | + +=============================================+===================================+===================+===+===+===+===+ + | :c:member:`~PyTypeObject.tp_name` | const char * | __name__ | X | X | | | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_basicsize` | Py_ssize_t | | X | X | | X | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_itemsize` | Py_ssize_t | | | X | | X | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_dealloc` | :c:type:`destructor` | | X | X | | X | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | (:c:member:`~PyTypeObject.tp_print`) | | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | (:c:member:`~PyTypeObject.tp_getattr`) | :c:type:`getattrfunc` | __getattribute__, | | | | G | + | | | __getattr__ | | | | | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | (:c:member:`~PyTypeObject.tp_setattr`) | :c:type:`setattrfunc` | __setattr__, | | | | G | + | | | __delattr__ | | | | | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_as_async` | :c:type:`PyAsyncMethods` * | :ref:`sub-slots` | | | | % | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_repr` | :c:type:`reprfunc` | __repr__ | X | X | | X | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_as_number` | :c:type:`PyNumberMethods` * | :ref:`sub-slots` | | | | % | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_as_sequence` | :c:type:`PySequenceMethods` * | :ref:`sub-slots` | | | | % | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_as_mapping` | :c:type:`PyMappingMethods` * | :ref:`sub-slots` | | | | % | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_hash` | :c:type:`hashfunc` | __hash__ | X | | | G | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_call` | :c:type:`ternaryfunc` | __call__ | | X | | X | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_str` | :c:type:`reprfunc` | __str__ | X | | | X | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_getattro` | :c:type:`getattrofunc` | __getattribute__, | X | X | | G | + | | | __getattr__ | | | | | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_setattro` | :c:type:`setattrofunc` | __setattr__, | X | X | | G | + | | | __delattr__ | | | | | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_as_buffer` | :c:type:`PyBufferProcs` * | | | | | % | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_flags` | unsigned long | | X | X | | ? | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_doc` | const char * | __doc__ | X | X | | | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_traverse` | :c:type:`traverseproc` | | | X | | G | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_clear` | :c:type:`inquiry` | | | X | | G | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_richcompare` | :c:type:`richcmpfunc` | __lt__, | X | | | G | + | | | __le__, | | | | | + | | | __eq__, | | | | | + | | | __ne__, | | | | | + | | | __gt__, | | | | | + | | | __ge__ | | | | | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_weaklistoffset` | Py_ssize_t | | | X | | ? | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_iter` | :c:type:`getiterfunc` | __iter__ | | | | X | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_iternext` | :c:type:`iternextfunc` | __next__ | | | | X | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_methods` | :c:type:`PyMethodDef` [] | | X | X | | | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_members` | :c:type:`PyMemberDef` [] | | | X | | | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_getset` | :c:type:`PyGetSetDef` [] | | X | X | | | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_base` | :c:type:`PyTypeObject` * | __base__ | | | X | | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_dict` | :c:type:`PyObject` * | __dict__ | | | ? | | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_descr_get` | :c:type:`descrgetfunc` | __get__ | | | | X | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_descr_set` | :c:type:`descrsetfunc` | __set__, | | | | X | + | | | __delete__ | | | | | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_dictoffset` | Py_ssize_t | | | X | | ? | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_init` | :c:type:`initproc` | __init__ | X | X | | X | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_alloc` | :c:type:`allocfunc` | | X | | ? | ? | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_new` | :c:type:`newfunc` | __new__ | X | X | ? | ? | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_free` | :c:type:`freefunc` | | X | X | ? | ? | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_is_gc` | :c:type:`inquiry` | | | X | | X | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | <:c:member:`~PyTypeObject.tp_bases`> | :c:type:`PyObject` * | __bases__ | | | ~ | | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | <:c:member:`~PyTypeObject.tp_mro`> | :c:type:`PyObject` * | __mro__ | | | ~ | | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | [:c:member:`~PyTypeObject.tp_cache`] | :c:type:`PyObject` * | | | | | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | [:c:member:`~PyTypeObject.tp_subclasses`] | :c:type:`PyObject` * | __subclasses__ | | | | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | [:c:member:`~PyTypeObject.tp_weaklist`] | :c:type:`PyObject` * | | | | | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | (:c:member:`~PyTypeObject.tp_del`) | :c:type:`destructor` | | | | | | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | [:c:member:`~PyTypeObject.tp_version_tag`] | unsigned int | | | | | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_finalize` | :c:type:`destructor` | __del__ | | | | X | + +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + +If :const:`COUNT_ALLOCS` is defined then the following (internal-only) +fields exist as well: + +* :c:member:`~PyTypeObject.tp_allocs` +* :c:member:`~PyTypeObject.tp_frees` +* :c:member:`~PyTypeObject.tp_maxalloc` +* :c:member:`~PyTypeObject.tp_prev` +* :c:member:`~PyTypeObject.tp_next` + +.. [#slots] + A slot name in parentheses indicates it is (effectively) deprecated. + Names in angle brackets should be treated as read-only. + Names in square brackets are for internal use only. + "" (as a prefix) means the field is required (must be non-*NULL*). +.. [#cols] Columns: + + **"O"**: set on :c:type:`PyBaseObject_Type` + + **"T"**: set on :c:type:`PyType_Type` + + **"D"**: default (if slot is set to *NULL*) + + .. code-block:: none + + X - *PyType_Ready* sets this value if it is *NULL* + ~ - *PyType_Ready* always sets this value (it should be *NULL*) + ? - *PyType_Ready* may set this value depending on other slots + + Also see the inheritance column ("I"). + + **"I"**: inheritance + + .. code-block:: none + + X - type slot is inherited via *PyType_Ready* if defined with a *NULL* value + % - the slots of the sub-struct are inherited individually + G - inherited, but only in combination with other slots; see the slot's description + ? - it's complicated; see the slot's description + + Note that some slots are effectively inherited through the normal + attribute lookup chain. + +.. _sub-slots: + +sub-slots +^^^^^^^^^ + +.. table:: + :widths: 26,17,12 + + +---------------------------------------------------------+-----------------------------------+--------------+ + | Slot | :ref:`Type ` | special | + | | | methods | + +=========================================================+===================================+==============+ + | :c:member:`~PyAsyncMethods.am_await` | :c:type:`unaryfunc` | __await__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyAsyncMethods.am_aiter` | :c:type:`unaryfunc` | __aiter__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyAsyncMethods.am_anext` | :c:type:`unaryfunc` | __anext__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyNumberMethods.nb_add` | :c:type:`binaryfunc` | __add__ | + | | | __radd__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyNumberMethods.nb_inplace_add` | :c:type:`binaryfunc` | __iadd__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyNumberMethods.nb_subtract` | :c:type:`binaryfunc` | __sub__ | + | | | __rsub__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyNumberMethods.nb_inplace_subtract` | :c:type:`binaryfunc` | __sub__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyNumberMethods.nb_multiply` | :c:type:`binaryfunc` | __mul__ | + | | | __rmul__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyNumberMethods.nb_inplace_multiply` | :c:type:`binaryfunc` | __mul__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyNumberMethods.nb_remainder` | :c:type:`binaryfunc` | __mod__ | + | | | __rmod__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyNumberMethods.nb_inplace_remainder` | :c:type:`binaryfunc` | __mod__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyNumberMethods.nb_divmod` | :c:type:`binaryfunc` | __divmod__ | + | | | __rdivmod__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyNumberMethods.nb_power` | :c:type:`ternaryfunc` | __pow__ | + | | | __rpow__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyNumberMethods.nb_inplace_power` | :c:type:`ternaryfunc` | __pow__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyNumberMethods.nb_negative` | :c:type:`unaryfunc` | __neg__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyNumberMethods.nb_positive` | :c:type:`unaryfunc` | __pos__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyNumberMethods.nb_absolute` | :c:type:`unaryfunc` | __abs__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyNumberMethods.nb_bool` | :c:type:`inquiry` | __bool__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyNumberMethods.nb_invert` | :c:type:`unaryfunc` | __invert__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyNumberMethods.nb_lshift` | :c:type:`binaryfunc` | __lshift__ | + | | | __rlshift__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyNumberMethods.nb_inplace_lshift` | :c:type:`binaryfunc` | __lshift__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyNumberMethods.nb_rshift` | :c:type:`binaryfunc` | __rshift__ | + | | | __rrshift__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyNumberMethods.nb_inplace_rshift` | :c:type:`binaryfunc` | __rshift__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyNumberMethods.nb_and` | :c:type:`binaryfunc` | __and__ | + | | | __rand__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyNumberMethods.nb_inplace_and` | :c:type:`binaryfunc` | __and__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyNumberMethods.nb_xor` | :c:type:`binaryfunc` | __xor__ | + | | | __rxor__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyNumberMethods.nb_inplace_xor` | :c:type:`binaryfunc` | __xor__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyNumberMethods.nb_or` | :c:type:`binaryfunc` | __or__ | + | | | __ror__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyNumberMethods.nb_inplace_or` | :c:type:`binaryfunc` | __or__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyNumberMethods.nb_int` | :c:type:`unaryfunc` | __int__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyNumberMethods.nb_reserved` | void * | | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyNumberMethods.nb_float` | :c:type:`unaryfunc` | __float__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyNumberMethods.nb_floor_divide` | :c:type:`binaryfunc` | __floordiv__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyNumberMethods.nb_inplace_floor_divide` | :c:type:`binaryfunc` | __floordiv__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyNumberMethods.nb_true_divide` | :c:type:`binaryfunc` | __truediv__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyNumberMethods.nb_inplace_true_divide` | :c:type:`binaryfunc` | __truediv__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyNumberMethods.nb_index` | :c:type:`binaryfunc` | __index__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyNumberMethods.nb_matrix_multiply` | :c:type:`binaryfunc` | __matmul__ | + | | | __rmatmul__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyNumberMethods.nb_inplace_matrix_multiply` | :c:type:`binaryfunc` | __matmul__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyMappingMethods.mp_length` | :c:type:`lenfunc` | __len__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyMappingMethods.mp_subscript` | :c:type:`binaryfunc` | __getitem__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyMappingMethods.mp_ass_subscript` | :c:type:`objobjargproc` | __setitem__, | + | | | __delitem__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PySequenceMethods.sq_length` | :c:type:`lenfunc` | __len__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PySequenceMethods.sq_concat` | :c:type:`binaryfunc` | __add__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PySequenceMethods.sq_repeat` | :c:type:`ssizeargfunc` | __mul__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PySequenceMethods.sq_item` | :c:type:`ssizeargfunc` | __getitem__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PySequenceMethods.sq_ass_item` | :c:type:`ssizeobjargproc` | __setitem__ | + | | | __delitem__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PySequenceMethods.sq_contains` | :c:type:`objobjproc` | __contains__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PySequenceMethods.sq_inplace_concat` | :c:type:`binaryfunc` | __iadd__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PySequenceMethods.sq_inplace_repeat` | :c:type:`ssizeargfunc` | __imul__ | + +---------------------------------------------------------+-----------------------------------+--------------+ + | | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyBufferProcs.bf_getbuffer` | :c:func:`getbufferproc` | | + +---------------------------------------------------------+-----------------------------------+--------------+ + | :c:member:`~PyBufferProcs.bf_releasebuffer` | :c:func:`releasebufferproc` | | + +---------------------------------------------------------+-----------------------------------+--------------+ + +.. _slot-typedefs-table: + +slot typedefs +^^^^^^^^^^^^^ + ++-----------------------------+-----------------------------+----------------------+ +| typedef | Parameter Types | Return Type | ++=============================+=============================+======================+ +| :c:type:`allocfunc` | .. line-block:: | :c:type:`PyObject` * | +| | | | +| | :c:type:`PyTypeObject` * | | +| | Py_ssize_t | | ++-----------------------------+-----------------------------+----------------------+ +| :c:type:`destructor` | void * | void | ++-----------------------------+-----------------------------+----------------------+ +| :c:type:`freefunc` | void * | void | ++-----------------------------+-----------------------------+----------------------+ +| :c:type:`traverseproc` | .. line-block:: | int | +| | | | +| | void * | | +| | :c:type:`visitproc` | | +| | void * | | ++-----------------------------+-----------------------------+----------------------+ +| :c:type:`newfunc` | .. line-block:: | :c:type:`PyObject` * | +| | | | +| | :c:type:`PyObject` * | | +| | :c:type:`PyObject` * | | +| | :c:type:`PyObject` * | | ++-----------------------------+-----------------------------+----------------------+ +| :c:type:`initproc` | .. line-block:: | int | +| | | | +| | :c:type:`PyObject` * | | +| | :c:type:`PyObject` * | | +| | :c:type:`PyObject` * | | ++-----------------------------+-----------------------------+----------------------+ +| :c:type:`reprfunc` | :c:type:`PyObject` * | :c:type:`PyObject` * | ++-----------------------------+-----------------------------+----------------------+ +| :c:type:`printfunc` | .. line-block:: | int | +| | | | +| | :c:type:`PyObject` * | | +| | FILE * | | +| | int | | ++-----------------------------+-----------------------------+----------------------+ +| :c:type:`getattrfunc` | .. line-block:: | :c:type:`PyObject` * | +| | | | +| | :c:type:`PyObject` * | | +| | const char * | | ++-----------------------------+-----------------------------+----------------------+ +| :c:type:`setattrfunc` | .. line-block:: | int | +| | | | +| | :c:type:`PyObject` * | | +| | const char * | | +| | :c:type:`PyObject` * | | ++-----------------------------+-----------------------------+----------------------+ +| :c:type:`getattrofunc` | .. line-block:: | :c:type:`PyObject` * | +| | | | +| | :c:type:`PyObject` * | | +| | :c:type:`PyObject` * | | ++-----------------------------+-----------------------------+----------------------+ +| :c:type:`setattrofunc` | .. line-block:: | int | +| | | | +| | :c:type:`PyObject` * | | +| | :c:type:`PyObject` * | | +| | :c:type:`PyObject` * | | ++-----------------------------+-----------------------------+----------------------+ +| :c:type:`descrgetfunc` | .. line-block:: | :c:type:`PyObject` * | +| | | | +| | :c:type:`PyObject` * | | +| | :c:type:`PyObject` * | | +| | :c:type:`PyObject` * | | ++-----------------------------+-----------------------------+----------------------+ +| :c:type:`descrsetfunc` | .. line-block:: | int | +| | | | +| | :c:type:`PyObject` * | | +| | :c:type:`PyObject` * | | +| | :c:type:`PyObject` * | | ++-----------------------------+-----------------------------+----------------------+ +| :c:type:`hashfunc` | :c:type:`PyObject` * | Py_hash_t | ++-----------------------------+-----------------------------+----------------------+ +| :c:type:`richcmpfunc` | .. line-block:: | :c:type:`PyObject` * | +| | | | +| | :c:type:`PyObject` * | | +| | :c:type:`PyObject` * | | +| | int | | ++-----------------------------+-----------------------------+----------------------+ +| :c:type:`getiterfunc` | :c:type:`PyObject` * | :c:type:`PyObject` * | ++-----------------------------+-----------------------------+----------------------+ +| :c:type:`iternextfunc` | :c:type:`PyObject` * | :c:type:`PyObject` * | ++-----------------------------+-----------------------------+----------------------+ +| :c:type:`lenfunc` | :c:type:`PyObject` * | Py_ssize_t | ++-----------------------------+-----------------------------+----------------------+ +| :c:type:`getbufferproc` | .. line-block:: | int | +| | | | +| | :c:type:`PyObject` * | | +| | :c:type:`Py_buffer` * | | +| | int | | ++-----------------------------+-----------------------------+----------------------+ +| :c:type:`releasebufferproc` | .. line-block:: | void | +| | | | +| | :c:type:`PyObject` * | | +| | :c:type:`Py_buffer` * | | ++-----------------------------+-----------------------------+----------------------+ +| :c:type:`inquiry` | void * | int | ++-----------------------------+-----------------------------+----------------------+ +| :c:type:`unaryfunc` | .. line-block:: | :c:type:`PyObject` * | +| | | | +| | :c:type:`PyObject` * | | ++-----------------------------+-----------------------------+----------------------+ +| :c:type:`binaryfunc` | .. line-block:: | :c:type:`PyObject` * | +| | | | +| | :c:type:`PyObject` * | | +| | :c:type:`PyObject` * | | ++-----------------------------+-----------------------------+----------------------+ +| :c:type:`ternaryfunc` | .. line-block:: | :c:type:`PyObject` * | +| | | | +| | :c:type:`PyObject` * | | +| | :c:type:`PyObject` * | | +| | :c:type:`PyObject` * | | ++-----------------------------+-----------------------------+----------------------+ +| :c:type:`ssizeargfunc` | .. line-block:: | :c:type:`PyObject` * | +| | | | +| | :c:type:`PyObject` * | | +| | Py_ssize_t | | ++-----------------------------+-----------------------------+----------------------+ +| :c:type:`ssizeobjargproc` | .. line-block:: | int | +| | | | +| | :c:type:`PyObject` * | | +| | Py_ssize_t | | ++-----------------------------+-----------------------------+----------------------+ +| :c:type:`objobjproc` | .. line-block:: | int | +| | | | +| | :c:type:`PyObject` * | | +| | :c:type:`PyObject` * | | ++-----------------------------+-----------------------------+----------------------+ +| :c:type:`objobjargproc` | .. line-block:: | int | +| | | | +| | :c:type:`PyObject` * | | +| | :c:type:`PyObject` * | | +| | :c:type:`PyObject` * | | ++-----------------------------+-----------------------------+----------------------+ + +See :ref:`slot-typedefs` below for more detail. + + +PyTypeObject Definition +----------------------- The structure definition for :c:type:`PyTypeObject` can be found in :file:`Include/object.h`. For convenience of reference, this repeats the definition found there: +.. XXX Drop this? + .. literalinclude:: ../includes/typestruct.h +PyObject Slots +-------------- + The type object structure extends the :c:type:`PyVarObject` structure. The :attr:`ob_size` field is used for dynamic types (created by :func:`type_new`, usually called from a class statement). Note that :c:data:`PyType_Type` (the @@ -51,6 +505,8 @@ type objects) *must* have the :attr:`ob_size` field. that are still alive at the end of a run when the environment variable :envvar:`PYTHONDUMPREFS` is set. + **Inheritance:** + These fields are not inherited by subtypes. @@ -62,6 +518,8 @@ type objects) *must* have the :attr:`ob_size` field. *not* count as references. But for dynamically allocated type objects, the instances *do* count as references. + **Inheritance:** + This field is not inherited by subtypes. @@ -83,17 +541,32 @@ type objects) *must* have the :attr:`ob_size` field. initializes it to the :attr:`ob_type` field of the base class. :c:func:`PyType_Ready` will not change this field if it is non-zero. + **Inheritance:** + This field is inherited by subtypes. +PyVarObject Slots +----------------- + .. c:member:: Py_ssize_t PyVarObject.ob_size For statically allocated type objects, this should be initialized to zero. For dynamically allocated type objects, this field has a special internal meaning. + **Inheritance:** + This field is not inherited by subtypes. +PyTypeObject Slots +------------------ + +Each slot has a section describing inheritance. If :c:func:`PyType_Ready` +may set a value when the field is set to *NULL* then there will also be +a "Default" section. (Note that many fields set on :c:type:`PyBaseObject_Type` +and :c:type:`PyType_Type` effectively act as defaults.) + .. c:member:: const char* PyTypeObject.tp_name Pointer to a NUL-terminated string containing the name of the type. For types @@ -119,6 +592,12 @@ type objects) *must* have the :attr:`ob_size` field. type will be impossible to pickle. Additionally, it will not be listed in module documentations created with pydoc. + This field must not be *NULL*. It is the only required field + in :c:func:`PyTypeObject` (other than potentially + :c:member:`~PyTypeObject.tp_itemsize`). + + **Inheritance:** + This field is not inherited by subtypes. @@ -151,11 +630,6 @@ type objects) *must* have the :attr:`ob_size` field. ``sizeof`` operator on the struct used to declare the instance layout. The basic size does not include the GC header size. - These fields are inherited separately by subtypes. If the base type has a - non-zero :c:member:`~PyTypeObject.tp_itemsize`, it is generally not safe to set - :c:member:`~PyTypeObject.tp_itemsize` to a different non-zero value in a subtype (though this - depends on the implementation of the base type). - A note about alignment: if the variable items require a particular alignment, this should be taken care of by the value of :c:member:`~PyTypeObject.tp_basicsize`. Example: suppose a type implements an array of ``double``. :c:member:`~PyTypeObject.tp_itemsize` is @@ -163,12 +637,23 @@ type objects) *must* have the :attr:`ob_size` field. :c:member:`~PyTypeObject.tp_basicsize` is a multiple of ``sizeof(double)`` (assuming this is the alignment requirement for ``double``). + For any type with variable-length instances, this field must not be *NULL*. + + **Inheritance:** + + These fields are inherited separately by subtypes. If the base type has a + non-zero :c:member:`~PyTypeObject.tp_itemsize`, it is generally not safe to set + :c:member:`~PyTypeObject.tp_itemsize` to a different non-zero value in a subtype (though this + depends on the implementation of the base type). + .. c:member:: destructor PyTypeObject.tp_dealloc A pointer to the instance destructor function. This function must be defined unless the type guarantees that its instances will never be deallocated (as is - the case for the singletons ``None`` and ``Ellipsis``). + the case for the singletons ``None`` and ``Ellipsis``). The function signature is:: + + void tp_dealloc(PyObject *self); The destructor function is called by the :c:func:`Py_DECREF` and :c:func:`Py_XDECREF` macros when the new reference count is zero. At this point, @@ -185,6 +670,8 @@ type objects) *must* have the :attr:`ob_size` field. :c:func:`PyObject_GC_Del` if the instance was allocated using :c:func:`PyObject_GC_New` or :c:func:`PyObject_GC_NewVar`. + **Inheritance:** + This field is inherited by subtypes. @@ -199,9 +686,11 @@ type objects) *must* have the :attr:`ob_size` field. This field is deprecated. When it is defined, it should point to a function that acts the same as the :c:member:`~PyTypeObject.tp_getattro` function, but taking a C string - instead of a Python string object to give the attribute name. The signature is :: + instead of a Python string object to give the attribute name. + + **Inheritance:** - PyObject * tp_getattr(PyObject *o, char *attr_name); + Group: :attr:`tp_getattr`, :attr:`tp_getattro` This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_getattro`: a subtype inherits both :c:member:`~PyTypeObject.tp_getattr` and :c:member:`~PyTypeObject.tp_getattro` from its base type when @@ -214,17 +703,18 @@ type objects) *must* have the :attr:`ob_size` field. This field is deprecated. When it is defined, it should point to a function that acts the same as the :c:member:`~PyTypeObject.tp_setattro` function, but taking a C string - instead of a Python string object to give the attribute name. The signature is :: + instead of a Python string object to give the attribute name. - PyObject * tp_setattr(PyObject *o, char *attr_name, PyObject *v); + **Inheritance:** + + Group: :attr:`tp_setattr`, :attr:`tp_setattro` - The *v* argument is set to *NULL* to delete the attribute. This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_setattro`: a subtype inherits both :c:member:`~PyTypeObject.tp_setattr` and :c:member:`~PyTypeObject.tp_setattro` from its base type when the subtype's :c:member:`~PyTypeObject.tp_setattr` and :c:member:`~PyTypeObject.tp_setattro` are both *NULL*. -.. c:member:: PyAsyncMethods* tp_as_async +.. c:member:: PyAsyncMethods* PyTypeObject.tp_as_async Pointer to an additional structure that contains fields relevant only to objects which implement :term:`awaitable` and :term:`asynchronous iterator` @@ -233,6 +723,11 @@ type objects) *must* have the :attr:`ob_size` field. .. versionadded:: 3.5 Formerly known as ``tp_compare`` and ``tp_reserved``. + **Inheritance:** + + The :c:member:`~PyTypeObject.tp_as_async` field is not inherited, + but the contained fields are inherited individually. + .. c:member:: reprfunc PyTypeObject.tp_repr @@ -241,45 +736,60 @@ type objects) *must* have the :attr:`ob_size` field. An optional pointer to a function that implements the built-in function :func:`repr`. - The signature is the same as for :c:func:`PyObject_Repr`; it must return a string - or a Unicode object. Ideally, this function should return a string that, when - passed to :func:`eval`, given a suitable environment, returns an object with the + The signature is the same as for :c:func:`PyObject_Repr`:: + + PyObject *tp_repr(PyObject *self); + + The function must return a string or a Unicode object. Ideally, + this function should return a string that, when passed to + :func:`eval`, given a suitable environment, returns an object with the same value. If this is not feasible, it should return a string starting with ``'<'`` and ending with ``'>'`` from which both the type and the value of the object can be deduced. + **Inheritance:** + + This field is inherited by subtypes. + + **Default:** + When this field is not set, a string of the form ``<%s object at %p>`` is returned, where ``%s`` is replaced by the type name, and ``%p`` by the object's memory address. - This field is inherited by subtypes. -.. c:member:: PyNumberMethods* tp_as_number +.. c:member:: PyNumberMethods* PyTypeObject.tp_as_number Pointer to an additional structure that contains fields relevant only to objects which implement the number protocol. These fields are documented in :ref:`number-structs`. + **Inheritance:** + The :c:member:`~PyTypeObject.tp_as_number` field is not inherited, but the contained fields are inherited individually. -.. c:member:: PySequenceMethods* tp_as_sequence +.. c:member:: PySequenceMethods* PyTypeObject.tp_as_sequence Pointer to an additional structure that contains fields relevant only to objects which implement the sequence protocol. These fields are documented in :ref:`sequence-structs`. + **Inheritance:** + The :c:member:`~PyTypeObject.tp_as_sequence` field is not inherited, but the contained fields are inherited individually. -.. c:member:: PyMappingMethods* tp_as_mapping +.. c:member:: PyMappingMethods* PyTypeObject.tp_as_mapping Pointer to an additional structure that contains fields relevant only to objects which implement the mapping protocol. These fields are documented in :ref:`mapping-structs`. + **Inheritance:** + The :c:member:`~PyTypeObject.tp_as_mapping` field is not inherited, but the contained fields are inherited individually. @@ -291,11 +801,18 @@ type objects) *must* have the :attr:`ob_size` field. An optional pointer to a function that implements the built-in function :func:`hash`. - The signature is the same as for :c:func:`PyObject_Hash`; it must return a - value of the type Py_hash_t. The value ``-1`` should not be returned as a + The signature is the same as for :c:func:`PyObject_Hash`:: + + Py_hash_t tp_hash(PyObject *); + + The value ``-1`` should not be returned as a normal return value; when an error occurs during the computation of the hash value, the function should set an exception and return ``-1``. + When this field is not set (*and* :attr:`tp_richcompare` is not set), + an attempt to take the hash of the object raises :exc:`TypeError`. + This is the same as setting it to :c:func:`PyObject_HashNotImplemented`. + This field can be set explicitly to :c:func:`PyObject_HashNotImplemented` to block inheritance of the hash method from a parent type. This is interpreted as the equivalent of ``__hash__ = None`` at the Python level, causing @@ -304,8 +821,9 @@ type objects) *must* have the :attr:`ob_size` field. the Python level will result in the ``tp_hash`` slot being set to :c:func:`PyObject_HashNotImplemented`. - When this field is not set, an attempt to take the hash of the - object raises :exc:`TypeError`. + **Inheritance:** + + Group: :attr:`tp_hash`, :attr:`tp_richcompare` This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_richcompare`: a subtype inherits both of @@ -317,7 +835,11 @@ type objects) *must* have the :attr:`ob_size` field. An optional pointer to a function that implements calling the object. This should be *NULL* if the object is not callable. The signature is the same as - for :c:func:`PyObject_Call`. + for :c:func:`PyObject_Call`:: + + PyObject *tp_call(PyObject *self, PyObject *args, PyObject *kwargs); + + **Inheritance:** This field is inherited by subtypes. @@ -329,43 +851,73 @@ type objects) *must* have the :attr:`ob_size` field. constructor for that type. This constructor calls :c:func:`PyObject_Str` to do the actual work, and :c:func:`PyObject_Str` will call this handler.) - The signature is the same as for :c:func:`PyObject_Str`; it must return a string - or a Unicode object. This function should return a "friendly" string + The signature is the same as for :c:func:`PyObject_Str`:: + + PyObject *tp_str(PyObject *self); + + The function must return a string or a Unicode object. It should be a "friendly" string representation of the object, as this is the representation that will be used, among other things, by the :func:`print` function. - When this field is not set, :c:func:`PyObject_Repr` is called to return a string - representation. + **Inheritance:** This field is inherited by subtypes. + **Default:** + + When this field is not set, :c:func:`PyObject_Repr` is called to return a string + representation. + .. c:member:: getattrofunc PyTypeObject.tp_getattro An optional pointer to the get-attribute function. - The signature is the same as for :c:func:`PyObject_GetAttr`. It is usually - convenient to set this field to :c:func:`PyObject_GenericGetAttr`, which - implements the normal way of looking for object attributes. + The signature is the same as for :c:func:`PyObject_GetAttr`:: + + PyObject *tp_getattro(PyObject *self, PyObject *attr); + + It is usually convenient to set this field to :c:func:`PyObject_GenericGetAttr`, + which implements the normal way of looking for object attributes. + + **Inheritance:** + + Group: :attr:`tp_getattr`, :attr:`tp_getattro` This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_getattr`: a subtype inherits both :c:member:`~PyTypeObject.tp_getattr` and :c:member:`~PyTypeObject.tp_getattro` from its base type when the subtype's :c:member:`~PyTypeObject.tp_getattr` and :c:member:`~PyTypeObject.tp_getattro` are both *NULL*. + **Default:** + + :c:type:`PyBaseObject_Type` uses :c:func:`PyObject_GenericGetAttr`. + .. c:member:: setattrofunc PyTypeObject.tp_setattro An optional pointer to the function for setting and deleting attributes. - The signature is the same as for :c:func:`PyObject_SetAttr`, but setting - *v* to *NULL* to delete an attribute must be supported. It is usually - convenient to set this field to :c:func:`PyObject_GenericSetAttr`, which - implements the normal way of setting object attributes. + The signature is the same as for :c:func:`PyObject_SetAttr`:: + + PyObject *tp_setattro(PyObject *self, PyObject *attr, PyObject *value); + + In addition, setting *value* to *NULL* to delete an attribute must be + supported. It is usually convenient to set this field to + :c:func:`PyObject_GenericSetAttr`, which implements the normal + way of setting object attributes. + + **Inheritance:** + + Group: :attr:`tp_setattr`, :attr:`tp_setattro` This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_setattr`: a subtype inherits both :c:member:`~PyTypeObject.tp_setattr` and :c:member:`~PyTypeObject.tp_setattro` from its base type when the subtype's :c:member:`~PyTypeObject.tp_setattr` and :c:member:`~PyTypeObject.tp_setattro` are both *NULL*. + **Default:** + + :c:type:`PyBaseObject_Type` uses :c:func:`PyObject_GenericSetAttr`. + .. c:member:: PyBufferProcs* PyTypeObject.tp_as_buffer @@ -373,8 +925,10 @@ type objects) *must* have the :attr:`ob_size` field. which implement the buffer interface. These fields are documented in :ref:`buffer-structs`. - The :c:member:`~PyTypeObject.tp_as_buffer` field is not inherited, but the contained fields are - inherited individually. + **Inheritance:** + + The :c:member:`~PyTypeObject.tp_as_buffer` field is not inherited, + but the contained fields are inherited individually. .. c:member:: unsigned long PyTypeObject.tp_flags @@ -387,6 +941,8 @@ type objects) *must* have the :attr:`ob_size` field. such a flag bit is clear, the type fields it guards must not be accessed and must be considered to have a zero or *NULL* value instead. + **Inheritance:** + Inheritance of this field is complicated. Most flag bits are inherited individually, i.e. if the base type has a flag bit set, the subtype inherits this flag bit. The flag bits that pertain to extension structures are strictly @@ -398,12 +954,20 @@ type objects) *must* have the :attr:`ob_size` field. :c:member:`~PyTypeObject.tp_traverse` and :c:member:`~PyTypeObject.tp_clear` fields in the subtype exist and have *NULL* values. + .. XXX are most flag bits *really* inherited individually? + + **Default:** + + :c:type:`PyBaseObject_Type` uses + ``Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE``. + + **Bit Masks:** + The following bit masks are currently defined; these can be ORed together using the ``|`` operator to form the value of the :c:member:`~PyTypeObject.tp_flags` field. The macro :c:func:`PyType_HasFeature` takes a type and a flags value, *tp* and *f*, and checks whether ``tp->tp_flags & f`` is non-zero. - .. data:: Py_TPFLAGS_HEAPTYPE This bit is set when the type object itself is allocated on the heap. In this @@ -413,6 +977,10 @@ type objects) *must* have the :attr:`ob_size` field. subtypes; only the type referenced by the instance's ob_type gets INCREF'ed or DECREF'ed). + **Inheritance:** + + ??? + .. data:: Py_TPFLAGS_BASETYPE @@ -420,18 +988,30 @@ type objects) *must* have the :attr:`ob_size` field. this bit is clear, the type cannot be subtyped (similar to a "final" class in Java). + **Inheritance:** + + ??? + .. data:: Py_TPFLAGS_READY This bit is set when the type object has been fully initialized by :c:func:`PyType_Ready`. + **Inheritance:** + + ??? + .. data:: Py_TPFLAGS_READYING This bit is set while :c:func:`PyType_Ready` is in the process of initializing the type object. + **Inheritance:** + + ??? + .. data:: Py_TPFLAGS_HAVE_GC @@ -442,6 +1022,17 @@ type objects) *must* have the :attr:`ob_size` field. GC-related fields :c:member:`~PyTypeObject.tp_traverse` and :c:member:`~PyTypeObject.tp_clear` are present in the type object. + **Inheritance:** + + Group: :const:`Py_TPFLAGS_HAVE_GC`, :attr:`tp_traverse`, :attr:`tp_clear` + + The :const:`Py_TPFLAGS_HAVE_GC` flag bit is inherited + together with the :attr:`tp_traverse` and :attr:`tp_clear` + fields, i.e. if the :const:`Py_TPFLAGS_HAVE_GC` flag bit is + clear in the subtype and the :attr:`tp_traverse` and + :attr:`tp_clear` fields in the subtype exist and have *NULL* + values. + .. data:: Py_TPFLAGS_DEFAULT @@ -450,6 +1041,12 @@ type objects) *must* have the :attr:`ob_size` field. the following bits: :const:`Py_TPFLAGS_HAVE_STACKLESS_EXTENSION`, :const:`Py_TPFLAGS_HAVE_VERSION_TAG`. + **Inheritance:** + + ??? + + .. XXX Document more flags here? + .. data:: Py_TPFLAGS_LONG_SUBCLASS .. data:: Py_TPFLAGS_LIST_SUBCLASS @@ -483,15 +1080,20 @@ type objects) *must* have the :attr:`ob_size` field. type object. This is exposed as the :attr:`__doc__` attribute on the type and instances of the type. + **Inheritance:** + This field is *not* inherited by subtypes. .. c:member:: traverseproc PyTypeObject.tp_traverse An optional pointer to a traversal function for the garbage collector. This is - only used if the :const:`Py_TPFLAGS_HAVE_GC` flag bit is set. More information - about Python's garbage collection scheme can be found in section - :ref:`supporting-cycle-detection`. + only used if the :const:`Py_TPFLAGS_HAVE_GC` flag bit is set. The signature is:: + + int tp_traverse(PyObject *self, visitproc visit, void *arg); + + More information about Python's garbage collection scheme can be found + in section :ref:`supporting-cycle-detection`. The :c:member:`~PyTypeObject.tp_traverse` pointer is used by the garbage collector to detect reference cycles. A typical implementation of a :c:member:`~PyTypeObject.tp_traverse` function @@ -520,6 +1122,10 @@ type objects) *must* have the :attr:`ob_size` field. :c:func:`local_traverse` to have these specific names; don't name them just anything. + **Inheritance:** + + Group: :const:`Py_TPFLAGS_HAVE_GC`, :attr:`tp_traverse`, :attr:`tp_clear` + This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_clear` and the :const:`Py_TPFLAGS_HAVE_GC` flag bit: the flag bit, :c:member:`~PyTypeObject.tp_traverse`, and :c:member:`~PyTypeObject.tp_clear` are all inherited from the base type if they are all zero in @@ -529,7 +1135,9 @@ type objects) *must* have the :attr:`ob_size` field. .. c:member:: inquiry PyTypeObject.tp_clear An optional pointer to a clear function for the garbage collector. This is only - used if the :const:`Py_TPFLAGS_HAVE_GC` flag bit is set. + used if the :const:`Py_TPFLAGS_HAVE_GC` flag bit is set. The signature is:: + + int tp_clear(PyObject *); The :c:member:`~PyTypeObject.tp_clear` member function is used to break reference cycles in cyclic garbage detected by the garbage collector. Taken together, all :c:member:`~PyTypeObject.tp_clear` @@ -575,6 +1183,10 @@ type objects) *must* have the :attr:`ob_size` field. More information about Python's garbage collection scheme can be found in section :ref:`supporting-cycle-detection`. + **Inheritance:** + + Group: :const:`Py_TPFLAGS_HAVE_GC`, :attr:`tp_traverse`, :attr:`tp_clear` + This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_traverse` and the :const:`Py_TPFLAGS_HAVE_GC` flag bit: the flag bit, :c:member:`~PyTypeObject.tp_traverse`, and :c:member:`~PyTypeObject.tp_clear` are all inherited from the base type if they are all zero in @@ -583,14 +1195,16 @@ 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)``. The first - parameter is guaranteed to be an instance of the type that is defined - by :c:type:`PyTypeObject`. + An optional pointer to the rich comparison function, whose signature is:: + + PyObject *tp_richcompare(PyObject *self, PyObject *other, 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 - ``Py_NotImplemented``, if another error occurred it must return ``NULL`` and + ``Py_NotImplemented``, if another error occurred it must return *NULL* and set an exception condition. .. note:: @@ -599,11 +1213,6 @@ type objects) *must* have the :attr:`ob_size` field. comparisons makes sense (e.g. ``==`` and ``!=``, but not ``<`` and friends), directly raise :exc:`TypeError` in the rich comparison function. - This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_hash`: - a subtype inherits :c:member:`~PyTypeObject.tp_richcompare` and :c:member:`~PyTypeObject.tp_hash` when - the subtype's :c:member:`~PyTypeObject.tp_richcompare` and :c:member:`~PyTypeObject.tp_hash` are both - *NULL*. - The following constants are defined to be used as the third argument for :c:member:`~PyTypeObject.tp_richcompare` and for :c:func:`PyObject_RichCompare`: @@ -625,7 +1234,7 @@ type objects) *must* have the :attr:`ob_size` field. The following macro is defined to ease writing rich comparison functions: - .. c:function:: PyObject *Py_RETURN_RICHCOMPARE(VAL_A, VAL_B, int op) + .. c:function:: PyObject \*Py_RETURN_RICHCOMPARE(VAL_A, VAL_B, int op) Return ``Py_True`` or ``Py_False`` from the function, depending on the result of a comparison. @@ -635,10 +1244,27 @@ type objects) *must* have the :attr:`ob_size` field. The return value's reference count is properly incremented. - On error, sets an exception and returns NULL from the function. + On error, sets an exception and returns *NULL* from the function. .. versionadded:: 3.7 + **Inheritance:** + + Group: :attr:`tp_hash`, :attr:`tp_richcompare` + + This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_hash`: + a subtype inherits :c:member:`~PyTypeObject.tp_richcompare` and :c:member:`~PyTypeObject.tp_hash` when + the subtype's :c:member:`~PyTypeObject.tp_richcompare` and :c:member:`~PyTypeObject.tp_hash` are both + *NULL*. + + **Default:** + + :c:type:`PyBaseObject_Type` provides a :attr:`tp_richcompare` + implementation, which may be inherited. However, if only + :attr:`tp_hash` is defined, not even the inherited function is used + and instances of the type will not be able to participate in any + comparisons. + .. c:member:: Py_ssize_t PyTypeObject.tp_weaklistoffset @@ -652,6 +1278,8 @@ type objects) *must* have the :attr:`ob_size` field. Do not confuse this field with :c:member:`~PyTypeObject.tp_weaklist`; that is the list head for weak references to the type object itself. + **Inheritance:** + This field is inherited by subtypes, but see the rules listed below. A subtype may override this offset; this means that the subtype uses a different weak reference list head than the base type. Since the list head is always found via @@ -671,13 +1299,18 @@ type objects) *must* have the :attr:`ob_size` field. :attr:`__weakref__`, the type inherits its :c:member:`~PyTypeObject.tp_weaklistoffset` from its base type. + .. c:member:: getiterfunc PyTypeObject.tp_iter An optional pointer to a function that returns an iterator for the object. Its presence normally signals that the instances of this type are iterable (although sequences may be iterable without this function). - This function has the same signature as :c:func:`PyObject_GetIter`. + This function has the same signature as :c:func:`PyObject_GetIter`:: + + PyObject *tp_iter(PyObject *self); + + **Inheritance:** This field is inherited by subtypes. @@ -685,6 +1318,10 @@ type objects) *must* have the :attr:`ob_size` field. .. c:member:: iternextfunc PyTypeObject.tp_iternext An optional pointer to a function that returns the next item in an iterator. + The signature is:: + + PyObject *tp_iternext(PyObject *self); + When the iterator is exhausted, it must return *NULL*; a :exc:`StopIteration` exception may or may not be set. When another error occurs, it must return *NULL* too. Its presence signals that the instances of this type are @@ -696,6 +1333,8 @@ type objects) *must* have the :attr:`ob_size` field. This function has the same signature as :c:func:`PyIter_Next`. + **Inheritance:** + This field is inherited by subtypes. @@ -707,6 +1346,8 @@ type objects) *must* have the :attr:`ob_size` field. For each entry in the array, an entry is added to the type's dictionary (see :c:member:`~PyTypeObject.tp_dict` below) containing a method descriptor. + **Inheritance:** + This field is not inherited by subtypes (methods are inherited through a different mechanism). @@ -720,6 +1361,8 @@ type objects) *must* have the :attr:`ob_size` field. For each entry in the array, an entry is added to the type's dictionary (see :c:member:`~PyTypeObject.tp_dict` below) containing a member descriptor. + **Inheritance:** + This field is not inherited by subtypes (members are inherited through a different mechanism). @@ -732,6 +1375,8 @@ type objects) *must* have the :attr:`ob_size` field. For each entry in the array, an entry is added to the type's dictionary (see :c:member:`~PyTypeObject.tp_dict` below) containing a getset descriptor. + **Inheritance:** + This field is not inherited by subtypes (computed attributes are inherited through a different mechanism). @@ -742,9 +1387,32 @@ type objects) *must* have the :attr:`ob_size` field. this level, only single inheritance is supported; multiple inheritance require dynamically creating a type object by calling the metatype. - This field is not inherited by subtypes (obviously), but it defaults to - ``&PyBaseObject_Type`` (which to Python programmers is known as the type - :class:`object`). + .. note:: + + .. from Modules/xxmodule.c + + Slot initialization is subject to the rules of initializing globals. + C99 requires the initializers to be "address constants". Function + designators like :c:func:`PyType_GenericNew`, with implicit conversion + to a pointer, are valid C99 address constants. + + However, the unary '&' operator applied to a non-static variable + like :c:func:`PyBaseObject_Type` is not required to produce an address + constant. Compilers may support this (gcc does), MSVC does not. + Both compilers are strictly standard conforming in this particular + behavior. + + Consequently, :c:member:`~PyTypeObject.tp_base` should be set in + the extension module's init function. + + **Inheritance:** + + This field is not inherited by subtypes (obviously). + + **Default:** + + This field defaults to ``&PyBaseObject_Type`` (which to Python + programmers is known as the type :class:`object`). .. c:member:: PyObject* PyTypeObject.tp_dict @@ -757,9 +1425,16 @@ type objects) *must* have the :attr:`ob_size` field. attributes for the type may be added to this dictionary only if they don't correspond to overloaded operations (like :meth:`__add__`). + **Inheritance:** + This field is not inherited by subtypes (though the attributes defined in here are inherited through a different mechanism). + **Default:** + + If this field is *NULL*, :c:func:`PyType_Ready` will assign a new + dictionary to it. + .. warning:: It is not safe to use :c:func:`PyDict_SetItem` on or otherwise modify @@ -770,11 +1445,13 @@ type objects) *must* have the :attr:`ob_size` field. An optional pointer to a "descriptor get" function. - The function signature is :: + The function signature is:: PyObject * tp_descr_get(PyObject *self, PyObject *obj, PyObject *type); - .. XXX explain. + .. XXX explain more? + + **Inheritance:** This field is inherited by subtypes. @@ -784,14 +1461,17 @@ type objects) *must* have the :attr:`ob_size` field. An optional pointer to a function for setting and deleting a descriptor's value. - The function signature is :: + The function signature is:: int tp_descr_set(PyObject *self, PyObject *obj, PyObject *value); The *value* argument is set to *NULL* to delete the value. - This field is inherited by subtypes. - .. XXX explain. + .. XXX explain more? + + **Inheritance:** + + This field is inherited by subtypes. .. c:member:: Py_ssize_t PyTypeObject.tp_dictoffset @@ -829,6 +1509,8 @@ type objects) *must* have the :attr:`ob_size` field. store the sign of the number. (There's never a need to do this calculation yourself; it is done for you by :c:func:`_PyObject_GetDictPtr`.) + **Inheritance:** + This field is inherited by subtypes, but see the rules listed below. A subtype may override this offset; this means that the subtype instances store the dictionary at a difference offset than the base type. Since the dictionary is @@ -846,6 +1528,11 @@ type objects) *must* have the :attr:`ob_size` field. not have the expected effect, it just causes confusion. Maybe this should be added as a feature just like :attr:`__weakref__` though.) + **Default:** + + This slot has no default. For static types, if the field is + *NULL* then no :attr:`__dict__` gets created for instances. + .. c:member:: initproc PyTypeObject.tp_init @@ -856,9 +1543,9 @@ type objects) *must* have the :attr:`ob_size` field. :meth:`__init__`, and it is possible to reinitialize an instance by calling its :meth:`__init__` method again. - The function signature is :: + The function signature is:: - int tp_init(PyObject *self, PyObject *args, PyObject *kwds) + int tp_init(PyObject *self, PyObject *args, PyObject *kwds); The self argument is the instance to be initialized; the *args* and *kwds* arguments represent positional and keyword arguments of the call to @@ -871,47 +1558,46 @@ type objects) *must* have the :attr:`ob_size` field. :c:member:`~PyTypeObject.tp_init` function is called; if :c:member:`~PyTypeObject.tp_new` returns an instance of a subtype of the original type, the subtype's :c:member:`~PyTypeObject.tp_init` is called. + **Inheritance:** + This field is inherited by subtypes. + **Default:** + + For static types this field does not have a default. + .. c:member:: allocfunc PyTypeObject.tp_alloc An optional pointer to an instance allocation function. - The function signature is :: + The function signature is:: - PyObject *tp_alloc(PyTypeObject *self, Py_ssize_t nitems) + PyObject *tp_alloc(PyTypeObject *self, Py_ssize_t nitems); - The purpose of this function is to separate memory allocation from memory - initialization. It should return a pointer to a block of memory of adequate - length for the instance, suitably aligned, and initialized to zeros, but with - :attr:`ob_refcnt` set to ``1`` and :attr:`ob_type` set to the type argument. If - the type's :c:member:`~PyTypeObject.tp_itemsize` is non-zero, the object's :attr:`ob_size` field - should be initialized to *nitems* and the length of the allocated memory block - should be ``tp_basicsize + nitems*tp_itemsize``, rounded up to a multiple of - ``sizeof(void*)``; otherwise, *nitems* is not used and the length of the block - should be :c:member:`~PyTypeObject.tp_basicsize`. + **Inheritance:** - Do not use this function to do any other instance initialization, not even to - allocate additional memory; that should be done by :c:member:`~PyTypeObject.tp_new`. + This field is inherited by static subtypes, but not by dynamic + subtypes (subtypes created by a class statement). + + **Default:** + + For dynamic subtypes, this field is always set to + :c:func:`PyType_GenericAlloc`, to force a standard heap + allocation strategy. - This field is inherited by static subtypes, but not by dynamic subtypes - (subtypes created by a class statement); in the latter, this field is always set - to :c:func:`PyType_GenericAlloc`, to force a standard heap allocation strategy. - That is also the recommended value for statically defined types. + For static subtypes, :c:type:`PyBaseObject_Type` uses + :c:func:`PyType_GenericAlloc`. That is the recommended value + for all statically defined types. .. c:member:: newfunc PyTypeObject.tp_new An optional pointer to an instance creation function. - If this function is *NULL* for a particular type, that type cannot be called to - create new instances; presumably there is some other way to create instances, - like a factory function. + The function signature is:: - The function signature is :: - - PyObject *tp_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) + PyObject *tp_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds); The subtype argument is the type of the object being created; the *args* and *kwds* arguments represent positional and keyword arguments of the call to the @@ -927,24 +1613,40 @@ type objects) *must* have the :attr:`ob_size` field. in :c:member:`~PyTypeObject.tp_new`, while for mutable types, most initialization should be deferred to :c:member:`~PyTypeObject.tp_init`. + **Inheritance:** + This field is inherited by subtypes, except it is not inherited by static types whose :c:member:`~PyTypeObject.tp_base` is *NULL* or ``&PyBaseObject_Type``. + **Default:** -.. c:member:: destructor PyTypeObject.tp_free + For static types this field has no default. This means if the + slot is defined as *NULL*, the type cannot be called to create new + instances; presumably there is some other way to create + instances, like a factory function. - An optional pointer to an instance deallocation function. Its signature is - :c:type:`freefunc`:: - void tp_free(void *) +.. c:member:: freefunc PyTypeObject.tp_free + + An optional pointer to an instance deallocation function. Its signature is:: + + void tp_free(void *self); An initializer that is compatible with this signature is :c:func:`PyObject_Free`. - This field is inherited by static subtypes, but not by dynamic subtypes - (subtypes created by a class statement); in the latter, this field is set to a - deallocator suitable to match :c:func:`PyType_GenericAlloc` and the value of the + **Inheritance:** + + This field is inherited by static subtypes, but not by dynamic + subtypes (subtypes created by a class statement) + + **Default:** + + In dynamic subtypes, this field is set to a deallocator suitable to + match :c:func:`PyType_GenericAlloc` and the value of the :const:`Py_TPFLAGS_HAVE_GC` flag bit. + For static subtypes, :c:type:`PyBaseObject_Type` uses PyObject_Del. + .. c:member:: inquiry PyTypeObject.tp_is_gc @@ -956,16 +1658,23 @@ type objects) *must* have the :attr:`ob_size` field. some types have a mixture of statically and dynamically allocated instances, and the statically allocated instances are not collectible. Such types should define this function; it should return ``1`` for a collectible instance, and - ``0`` for a non-collectible instance. The signature is :: + ``0`` for a non-collectible instance. The signature is:: - int tp_is_gc(PyObject *self) + int tp_is_gc(PyObject *self); (The only example of this are types themselves. The metatype, :c:data:`PyType_Type`, defines this function to distinguish between statically and dynamically allocated types.) + **Inheritance:** + This field is inherited by subtypes. + **Default:** + + This slot has no default. If this field is *NULL*, + :const:`Py_TPFLAGS_HAVE_GC` is used as the functional equivalent. + .. c:member:: PyObject* PyTypeObject.tp_bases @@ -974,6 +1683,8 @@ type objects) *must* have the :attr:`ob_size` field. This is set for types created by a class statement. It should be *NULL* for statically defined types. + **Inheritance:** + This field is not inherited. @@ -982,15 +1693,60 @@ type objects) *must* have the :attr:`ob_size` field. Tuple containing the expanded set of base types, starting with the type itself and ending with :class:`object`, in Method Resolution Order. - This field is not inherited; it is calculated fresh by :c:func:`PyType_Ready`. + + **Inheritance:** + + This field is not inherited; it is calculated fresh by + :c:func:`PyType_Ready`. + + +.. c:member:: PyObject* PyTypeObject.tp_cache + + Unused. Internal use only. + + **Inheritance:** + + This field is not inherited. + + +.. c:member:: PyObject* PyTypeObject.tp_subclasses + + List of weak references to subclasses. Internal use only. + + **Inheritance:** + + This field is not inherited. + + +.. c:member:: PyObject* PyTypeObject.tp_weaklist + + Weak reference list head, for weak references to this type object. Not + inherited. Internal use only. + + **Inheritance:** + + This field is not inherited. + + +.. c:member:: destructor PyTypeObject.tp_del + + This field is deprecated. Use :c:member:`~PyTypeObject.tp_finalize` instead. + + +.. c:member:: unsigned int PyTypeObject.tp_version_tag + + Used to index into the method cache. Internal use only. + + **Inheritance:** + + This field is not inherited. .. c:member:: destructor PyTypeObject.tp_finalize - An optional pointer to an instance finalization function. Its signature is - :c:type:`destructor`:: + An optional pointer to an instance finalization function. Its signature is:: - void tp_finalize(PyObject *) + void tp_finalize(PyObject *self); If :c:member:`~PyTypeObject.tp_finalize` is set, the interpreter calls it once when finalizing an instance. It is called either from the garbage @@ -1019,6 +1775,8 @@ type objects) *must* have the :attr:`ob_size` field. For this field to be taken into account (even through inheritance), you must also set the :const:`Py_TPFLAGS_HAVE_FINALIZE` flags bit. + **Inheritance:** + This field is inherited by subtypes. .. versionadded:: 3.4 @@ -1026,47 +1784,32 @@ type objects) *must* have the :attr:`ob_size` field. .. seealso:: "Safe object finalization" (:pep:`442`) -.. c:member:: PyObject* PyTypeObject.tp_cache - - Unused. Not inherited. Internal use only. - - -.. c:member:: PyObject* PyTypeObject.tp_subclasses - - List of weak references to subclasses. Not inherited. Internal use only. - - -.. c:member:: PyObject* PyTypeObject.tp_weaklist - - Weak reference list head, for weak references to this type object. Not - inherited. Internal use only. - The remaining fields are only defined if the feature test macro :const:`COUNT_ALLOCS` is defined, and are for internal use only. They are documented here for completeness. None of these fields are inherited by subtypes. - .. c:member:: Py_ssize_t PyTypeObject.tp_allocs Number of allocations. - .. c:member:: Py_ssize_t PyTypeObject.tp_frees Number of frees. - .. c:member:: Py_ssize_t PyTypeObject.tp_maxalloc Maximum simultaneously allocated objects. +.. c:member:: PyTypeObject* PyTypeObject.tp_prev + + Pointer to the previous type object with a non-zero :c:member:`~PyTypeObject.tp_allocs` field. .. c:member:: PyTypeObject* PyTypeObject.tp_next Pointer to the next type object with a non-zero :c:member:`~PyTypeObject.tp_allocs` field. -Also, note that, in a garbage collected Python, tp_dealloc may be called from +Also, note that, in a garbage collected Python, :c:member:`~PyTypeObject.tp_dealloc` may be called from any Python thread, not just the thread which created the object (if the object becomes part of a refcount cycle, that cycle might be collected by a garbage collection on any thread). This is not a problem for Python API calls, since @@ -1077,6 +1820,18 @@ objects on the thread which called tp_dealloc will not violate any assumptions of the library. +Heap Types +---------- + +In addition to defining Python types statically, you can define them +dynamically (i.e. to the heap) using :c:func:`PyType_FromSpec` and +:c:func:`PyType_FromSpecWithBases`. + +.. XXX Explain how to use PyType_FromSpec(). + +.. XXX Document PyType_Spec. + + .. _number-structs: Number Object Structures @@ -1091,6 +1846,8 @@ Number Object Structures implement the number protocol. Each function is used by the function of similar name documented in the :ref:`number` section. + .. XXX Drop the definition? + Here is the structure definition:: typedef struct { @@ -1142,15 +1899,52 @@ Number Object Structures and implement the necessary conversions (at least one of the operands is an instance of the defined type). If the operation is not defined for the given operands, binary and ternary functions must return - ``Py_NotImplemented``, if another error occurred they must return ``NULL`` + ``Py_NotImplemented``, if another error occurred they must return *NULL* and set an exception. .. note:: - The :c:data:`nb_reserved` field should always be ``NULL``. It + The :c:data:`nb_reserved` field should always be *NULL*. It was previously called :c:data:`nb_long`, and was renamed in Python 3.0.1. +.. c:member:: binaryfunc PyNumberMethods.nb_add +.. c:member:: binaryfunc PyNumberMethods.nb_subtract +.. c:member:: binaryfunc PyNumberMethods.nb_multiply +.. c:member:: binaryfunc PyNumberMethods.nb_remainder +.. c:member:: binaryfunc PyNumberMethods.nb_divmod +.. c:member:: ternaryfunc PyNumberMethods.nb_power +.. c:member:: unaryfunc PyNumberMethods.nb_negative +.. c:member:: unaryfunc PyNumberMethods.nb_positive +.. c:member:: unaryfunc PyNumberMethods.nb_absolute +.. c:member:: inquiry PyNumberMethods.nb_bool +.. c:member:: unaryfunc PyNumberMethods.nb_invert +.. c:member:: binaryfunc PyNumberMethods.nb_lshift +.. c:member:: binaryfunc PyNumberMethods.nb_rshift +.. c:member:: binaryfunc PyNumberMethods.nb_and +.. c:member:: binaryfunc PyNumberMethods.nb_xor +.. c:member:: binaryfunc PyNumberMethods.nb_or +.. c:member:: unaryfunc PyNumberMethods.nb_int +.. c:member:: void *PyNumberMethods.nb_reserved +.. c:member:: unaryfunc PyNumberMethods.nb_float +.. c:member:: binaryfunc PyNumberMethods.nb_inplace_add +.. c:member:: binaryfunc PyNumberMethods.nb_inplace_subtract +.. c:member:: binaryfunc PyNumberMethods.nb_inplace_multiply +.. c:member:: binaryfunc PyNumberMethods.nb_inplace_remainder +.. c:member:: ternaryfunc PyNumberMethods.nb_inplace_power +.. c:member:: binaryfunc PyNumberMethods.nb_inplace_lshift +.. c:member:: binaryfunc PyNumberMethods.nb_inplace_rshift +.. c:member:: binaryfunc PyNumberMethods.nb_inplace_and +.. c:member:: binaryfunc PyNumberMethods.nb_inplace_xor +.. c:member:: binaryfunc PyNumberMethods.nb_inplace_or +.. c:member:: binaryfunc PyNumberMethods.nb_floor_divide +.. c:member:: binaryfunc PyNumberMethods.nb_true_divide +.. c:member:: binaryfunc PyNumberMethods.nb_inplace_floor_divide +.. c:member:: binaryfunc PyNumberMethods.nb_inplace_true_divide +.. c:member:: unaryfunc PyNumberMethods.nb_index +.. c:member:: binaryfunc PyNumberMethods.nb_matrix_multiply +.. c:member:: binaryfunc PyNumberMethods.nb_inplace_matrix_multiply + .. _mapping-structs: @@ -1390,7 +2184,7 @@ Async Object Structures The signature of this function is:: - PyObject *am_await(PyObject *self) + PyObject *am_await(PyObject *self); The returned object must be an iterator, i.e. :c:func:`PyIter_Check` must return ``1`` for it. @@ -1401,7 +2195,7 @@ Async Object Structures The signature of this function is:: - PyObject *am_aiter(PyObject *self) + PyObject *am_aiter(PyObject *self); Must return an :term:`awaitable` object. See :meth:`__anext__` for details. @@ -1412,7 +2206,259 @@ Async Object Structures The signature of this function is:: - PyObject *am_anext(PyObject *self) + PyObject *am_anext(PyObject *self); Must return an :term:`awaitable` object. See :meth:`__anext__` for details. This slot may be set to *NULL*. + + +.. _slot-typedefs: + +Slot Type typedefs +================== + +.. c:type:: PyObject *(*allocfunc)(PyTypeObject *cls, Py_ssize_t nitems) + + The purpose of this function is to separate memory allocation from memory + initialization. It should return a pointer to a block of memory of adequate + length for the instance, suitably aligned, and initialized to zeros, but with + :attr:`ob_refcnt` set to ``1`` and :attr:`ob_type` set to the type argument. If + the type's :c:member:`~PyTypeObject.tp_itemsize` is non-zero, the object's :attr:`ob_size` field + should be initialized to *nitems* and the length of the allocated memory block + should be ``tp_basicsize + nitems*tp_itemsize``, rounded up to a multiple of + ``sizeof(void*)``; otherwise, *nitems* is not used and the length of the block + should be :c:member:`~PyTypeObject.tp_basicsize`. + + This function should not do any other instance initialization, not even to + allocate additional memory; that should be done by :c:member:`~PyTypeObject.tp_new`. + +.. c:type:: void (*destructor)(PyObject *) + +.. c:type:: void (*freefunc)(void *) + + See :c:member:`~PyTypeObject.tp_free`. + +.. c:type:: PyObject *(*newfunc)(PyObject *, PyObject *, PyObject *) + + See :c:member:`~PyTypeObject.tp_new`. + +.. c:type:: int (*initproc)(PyObject *, PyObject *, PyObject *) + + See :c:member:`~PyTypeObject.tp_init`. + +.. c:type:: PyObject *(*reprfunc)(PyObject *) + + See :c:member:`~PyTypeObject.tp_repr`. + +.. c:type:: int (*printfunc)(PyObject *, FILE *, int) + + This is hidden if :const:`PY_LIMITED_API` is set. + +.. c:type:: PyObject *(*getattrfunc)(PyObject *self, char *attr) + + Return the value of the named attribute for the object. + +.. c:type:: int (*setattrfunc)(PyObject *self, char *attr, PyObject *value) + + Set the value of the named attribute for the object. + The value argument is set to *NULL* to delete the attribute. + +.. c:type:: PyObject *(*getattrofunc)(PyObject *self, PyObject *attr) + + Return the value of the named attribute for the object. + + See :c:member:`~PyTypeObject.tp_getattro`. + +.. c:type:: int (*setattrofunc)(PyObject *self, PyObject *attr, PyObject *value) + + Set the value of the named attribute for the object. + The value argument is set to *NULL* to delete the attribute. + + See :c:member:`~PyTypeObject.tp_setattro`. + +.. c:type:: PyObject *(*descrgetfunc)(PyObject *, PyObject *, PyObject *) + + See :c:member:`~PyTypeObject.tp_descrget`. + +.. c:type:: int (*descrsetfunc)(PyObject *, PyObject *, PyObject *) + + See :c:member:`~PyTypeObject.tp_descrset`. + +.. c:type:: Py_hash_t (*hashfunc)(PyObject *) + + See :c:member:`~PyTypeObject.tp_hash`. + +.. c:type:: PyObject *(*richcmpfunc)(PyObject *, PyObject *, int) + + See :c:member:`~PyTypeObject.tp_richcompare`. + +.. c:type:: PyObject *(*getiterfunc)(PyObject *) + + See :c:member:`~PyTypeObject.tp_iter`. + +.. c:type:: PyObject *(*iternextfunc)(PyObject *) + + See :c:member:`~PyTypeObject.tp_iternext`. + +.. c:type:: Py_ssize_t (*lenfunc)(PyObject *) + +.. c:type:: int (*getbufferproc)(PyObject *, Py_buffer *, int) + +.. c:type:: void (*releasebufferproc)(PyObject *, Py_buffer *) + +.. c:type:: PyObject *(*unaryfunc)(PyObject *) + +.. c:type:: PyObject *(*binaryfunc)(PyObject *, PyObject *) + +.. c:type:: PyObject *(*ternaryfunc)(PyObject *, PyObject *, PyObject *) + +.. c:type:: PyObject *(*ssizeargfunc)(PyObject *, Py_ssize_t) + +.. c:type:: int (*ssizeobjargproc)(PyObject *, Py_ssize_t) + +.. c:type:: int (*objobjproc)(PyObject *, PyObject *) + +.. c:type:: int (*objobjargproc)(PyObject *, PyObject *, PyObject *) + + +.. _examples: + +Examples +======== + +The following are simple examples of Python type definitions. They +include common usage you may encounter. Some demonstrate tricky corner +cases. For more examples, practical info, and a tutorial, see +:ref:`defining-new-types` and :ref:`new-types-topics`. + +A basic static type:: + + typedef struct { + PyObject_HEAD + const char *data; + } MyObject; + + static PyTypeObject MyObject_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "mymod.MyObject", + .tp_basicsize = sizeof(MyObject), + .tp_doc = "My objects", + .tp_new = myobj_new, + .tp_dealloc = (destructor)myobj_dealloc, + .tp_repr = (reprfunc)myobj_repr, + }; + +You may also find older code (especially in the CPython code base) +with a more verbose initializer:: + + static PyTypeObject MyObject_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "mymod.MyObject", /* tp_name */ + sizeof(MyObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)myobj_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)myobj_repr, /* 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 */ + 0, /* tp_flags */ + "My objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + myobj_new, /* tp_new */ + }; + +A type that supports weakrefs, instance dicts, and hashing:: + + typedef struct { + PyObject_HEAD + const char *data; + PyObject *inst_dict; + PyObject *weakreflist; + } MyObject; + + static PyTypeObject MyObject_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "mymod.MyObject", + .tp_basicsize = sizeof(MyObject), + .tp_doc = "My objects", + .tp_weaklistoffset = offsetof(MyObject, weakreflist), + .tp_dictoffset = offsetof(MyObject, inst_dict), + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + .tp_new = myobj_new, + .tp_traverse = (traverseproc)myobj_traverse, + .tp_clear = (inquiry)myobj_clear, + .tp_alloc = PyType_GenericNew, + .tp_dealloc = (destructor)myobj_dealloc, + .tp_repr = (reprfunc)myobj_repr, + .tp_hash = (hashfunc)myobj_hash, + .tp_richcompare = PyBaseObject_Type.tp_richcompare, + }; + +A str subclass that cannot be subclassed and cannot be called +to create instances (e.g. uses a separate factory func):: + + typedef struct { + PyUnicodeObject raw; + char *extra; + } MyStr; + + static PyTypeObject MyStr_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "mymod.MyStr", + .tp_basicsize = sizeof(MyStr), + .tp_base = NULL, // set to &PyUnicode_Type in module init + .tp_doc = "my custom str", + .tp_flags = Py_TPFLAGS_DEFAULT, + .tp_new = NULL, + .tp_repr = (reprfunc)myobj_repr, + }; + +The simplest static type (with fixed-length instances):: + + typedef struct { + PyObject_HEAD + } MyObject; + + static PyTypeObject MyObject_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "mymod.MyObject", + }; + +The simplest static type (with variable-length instances):: + + typedef struct { + PyObject_VAR_HEAD + const char *data[1]; + } MyObject; + + static PyTypeObject MyObject_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "mymod.MyObject", + .tp_basicsize = sizeof(MyObject) - sizeof(char *), + .tp_itemsize = sizeof(char *), + }; diff --git a/Doc/conf.py b/Doc/conf.py index 19a2f7d67ff831..d8efce035c9ce3 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -46,9 +46,13 @@ # ----------------------- # Use our custom theme. -html_theme = 'pydoctheme' +html_theme = 'python_docs_theme' html_theme_path = ['tools'] -html_theme_options = {'collapsiblesidebar': True} +html_theme_options = { + 'collapsiblesidebar': True, + 'issues_url': 'https://docs.python.org/3/bugs.html', + 'root_include_title': False # We use the version switcher instead. +} # Short title used e.g. for HTML tags. html_short_title = '%s Documentation' % release diff --git a/Doc/distutils/builtdist.rst b/Doc/distutils/builtdist.rst index f523a672340876..758bd141ac956b 100644 --- a/Doc/distutils/builtdist.rst +++ b/Doc/distutils/builtdist.rst @@ -21,7 +21,7 @@ specialty---writing code and creating source distributions---while an intermediary species called *packagers* springs up to turn source distributions into built distributions for as many platforms as there are packagers. -Of course, the module developer could be his own packager; or the packager could +Of course, the module developer could be their own packager; or the packager could be a volunteer "out there" somewhere who has access to a platform which the original developer does not; or it could be software periodically grabbing new source distributions and turning them into built distributions for as many diff --git a/Doc/distutils/introduction.rst b/Doc/distutils/introduction.rst index a38555910361b8..7721484fe73717 100644 --- a/Doc/distutils/introduction.rst +++ b/Doc/distutils/introduction.rst @@ -94,7 +94,7 @@ containing your setup script :file:`setup.py`, and your module :file:`foo.py`. The archive file will be named :file:`foo-1.0.tar.gz` (or :file:`.zip`), and will unpack into a directory :file:`foo-1.0`. -If an end-user wishes to install your :mod:`foo` module, all she has to do is +If an end-user wishes to install your :mod:`foo` module, all they have to do is download :file:`foo-1.0.tar.gz` (or :file:`.zip`), unpack it, and---from the :file:`foo-1.0` directory---run :: diff --git a/Doc/extending/newtypes.rst b/Doc/extending/newtypes.rst index d0d2ec1f88207c..8b9549d7e39e2e 100644 --- a/Doc/extending/newtypes.rst +++ b/Doc/extending/newtypes.rst @@ -1,5 +1,7 @@ .. highlightlang:: c +.. _new-types-topics: + ***************************************** Defining Extension Types: Assorted Topics ***************************************** diff --git a/Doc/extending/newtypes_tutorial.rst b/Doc/extending/newtypes_tutorial.rst index ac48637bbee9be..bb8a40d0fb06f5 100644 --- a/Doc/extending/newtypes_tutorial.rst +++ b/Doc/extending/newtypes_tutorial.rst @@ -457,7 +457,7 @@ We define a single method, :meth:`Custom.name()`, that outputs the objects name concatenation of the first and last names. :: static PyObject * - Custom_name(CustomObject *self) + Custom_name(CustomObject *self, PyObject *Py_UNUSED(ignored)) { if (self->first == NULL) { PyErr_SetString(PyExc_AttributeError, "first"); diff --git a/Doc/faq/design.rst b/Doc/faq/design.rst index 5d8f3a56c01488..10fa490931c558 100644 --- a/Doc/faq/design.rst +++ b/Doc/faq/design.rst @@ -2,6 +2,11 @@ Design and History FAQ ====================== +.. only:: html + + .. contents:: + + Why does Python use indentation for grouping of statements? ----------------------------------------------------------- @@ -343,7 +348,7 @@ each Python stack frame. Also, extensions can call back into Python at almost random moments. Therefore, a complete threads implementation requires thread support for C. -Answer 2: Fortunately, there is `Stackless Python <https://bitbucket.org/stackless-dev/stackless/wiki/Home>`_, +Answer 2: Fortunately, there is `Stackless Python <https://github.com/stackless-dev/stackless/wiki>`_, which has a completely redesigned interpreter loop that avoids the C stack. @@ -465,10 +470,10 @@ you can always change a list's elements. Only immutable elements can be used as dictionary keys, and hence only tuples and not lists can be used as keys. -How are lists implemented? --------------------------- +How are lists implemented in CPython? +------------------------------------- -Python's lists are really variable-length arrays, not Lisp-style linked lists. +CPython's lists are really variable-length arrays, not Lisp-style linked lists. The implementation uses a contiguous array of references to other objects, and keeps a pointer to this array and the array's length in a list head structure. @@ -481,10 +486,10 @@ when the array must be grown, some extra space is allocated so the next few times don't require an actual resize. -How are dictionaries implemented? ---------------------------------- +How are dictionaries implemented in CPython? +-------------------------------------------- -Python's dictionaries are implemented as resizable hash tables. Compared to +CPython's dictionaries are implemented as resizable hash tables. Compared to B-trees, this gives better performance for lookup (the most common operation by far) under most circumstances, and the implementation is simpler. @@ -495,7 +500,7 @@ on the key and a per-process seed; for example, "Python" could hash to to 1142331976. The hash code is then used to calculate a location in an internal array where the value will be stored. Assuming that you're storing keys that all have different hash values, this means that dictionaries take -constant time -- O(1), in computer science notation -- to retrieve a key. +constant time -- O(1), in Big-O notation -- to retrieve a key. Why must dictionary keys be immutable? diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index d986ab642bfb32..53f3b7f528c065 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -371,8 +371,8 @@ 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={}): + # Callers can only provide two parameters and optionally pass _cache by keyword + def expensive(arg1, arg2, *, _cache={}): if (arg1, arg2) in _cache: return _cache[(arg1, arg2)] diff --git a/Doc/faq/python-video-icon.png b/Doc/faq/python-video-icon.png index 4de54b403d7c0f..265da50c7b38fc 100644 Binary files a/Doc/faq/python-video-icon.png and b/Doc/faq/python-video-icon.png differ diff --git a/Doc/glossary.rst b/Doc/glossary.rst index 988842aefc0d67..668dbb2a7ce921 100644 --- a/Doc/glossary.rst +++ b/Doc/glossary.rst @@ -14,8 +14,9 @@ Glossary ``...`` The default Python prompt of the interactive shell when entering code for - an indented code block or within a pair of matching left and right - delimiters (parentheses, square brackets or curly braces). + an indented code block, when within a pair of matching left and right + delimiters (parentheses, square brackets, curly braces or triple quotes), + or after specifying a decorator. 2to3 A tool that tries to convert Python 2.x code to Python 3.x code by @@ -642,7 +643,7 @@ Glossary list A built-in Python :term:`sequence`. Despite its name it is more akin to an array in other languages than to a linked list since access to - elements are O(1). + elements is O(1). list comprehension A compact way to process all or part of the elements in a sequence and diff --git a/Doc/howto/descriptor.rst b/Doc/howto/descriptor.rst index 5e85a9aa6594e4..6e4aa3e975f6f4 100644 --- a/Doc/howto/descriptor.rst +++ b/Doc/howto/descriptor.rst @@ -58,7 +58,7 @@ That is all there is to it. Define any of these methods and an object is considered a descriptor and can override default behavior upon being looked up as an attribute. -If an object defines both :meth:`__get__` and :meth:`__set__`, it is considered +If an object defines :meth:`__set__` or :meth:`__delete__`, it is considered a data descriptor. Descriptors that only define :meth:`__get__` are called non-data descriptors (they are typically used for methods but other uses are possible). diff --git a/Doc/howto/logging_flow.png b/Doc/howto/logging_flow.png old mode 100755 new mode 100644 index a88382309a18df..fac4acd7755302 Binary files a/Doc/howto/logging_flow.png and b/Doc/howto/logging_flow.png differ diff --git a/Doc/includes/run-func.c b/Doc/includes/run-func.c index ead7bdd23209a3..9caf1fdb20104a 100644 --- a/Doc/includes/run-func.c +++ b/Doc/includes/run-func.c @@ -3,7 +3,7 @@ int main(int argc, char *argv[]) { - PyObject *pName, *pModule, *pDict, *pFunc; + PyObject *pName, *pModule, *pFunc; PyObject *pArgs, *pValue; int i; diff --git a/Doc/includes/tzinfo_examples.py b/Doc/includes/tzinfo_examples.py index ae5a5092665f09..9b9e32a553e7d8 100644 --- a/Doc/includes/tzinfo_examples.py +++ b/Doc/includes/tzinfo_examples.py @@ -1,4 +1,4 @@ -from datetime import tzinfo, timedelta, datetime, timezone +from datetime import tzinfo, timedelta, datetime ZERO = timedelta(0) HOUR = timedelta(hours=1) diff --git a/Doc/installing/index.rst b/Doc/installing/index.rst index 7a69869fb50885..8f105a15161c44 100644 --- a/Doc/installing/index.rst +++ b/Doc/installing/index.rst @@ -62,11 +62,6 @@ Key terms of the mailing list used to coordinate Python packaging standards development). -.. deprecated:: 3.6 - ``pyvenv`` was the recommended tool for creating virtual environments for - Python 3.3 and 3.4, and is `deprecated in Python 3.6 - <https://docs.python.org/dev/whatsnew/3.6.html#deprecated-features>`_. - .. versionchanged:: 3.5 The use of ``venv`` is now recommended for creating virtual environments. diff --git a/Doc/library/cgi.rst b/Doc/library/cgi.rst index 0b1aead9ddf1fd..4048592e7361f7 100644 --- a/Doc/library/cgi.rst +++ b/Doc/library/cgi.rst @@ -284,18 +284,6 @@ algorithms implemented in this module in other circumstances. passed to :func:`urllib.parse.parse_qs` unchanged. -.. function:: parse_qs(qs, keep_blank_values=False, strict_parsing=False) - - This function is deprecated in this module. Use :func:`urllib.parse.parse_qs` - instead. It is maintained here only for backward compatibility. - - -.. function:: parse_qsl(qs, keep_blank_values=False, strict_parsing=False) - - This function is deprecated in this module. Use :func:`urllib.parse.parse_qsl` - instead. It is maintained here only for backward compatibility. - - .. function:: parse_multipart(fp, pdict, encoding="utf-8", errors="replace") Parse input of type :mimetype:`multipart/form-data` (for file uploads). @@ -348,20 +336,6 @@ algorithms implemented in this module in other circumstances. Print a list of useful (used by CGI) environment variables in HTML. -.. function:: escape(s, quote=False) - - Convert the characters ``'&'``, ``'<'`` and ``'>'`` in string *s* to HTML-safe - sequences. Use this if you need to display text that might contain such - characters in HTML. If the optional flag *quote* is true, the quotation mark - character (``"``) is also translated; this helps for inclusion in an HTML - attribute value delimited by double quotes, as in ``<a href="...">``. Note - that single quotes are never translated. - - .. deprecated:: 3.2 - This function is unsafe because *quote* is false by default, and therefore - deprecated. Use :func:`html.escape` instead. - - .. _cgi-security: Caring about security diff --git a/Doc/library/compileall.rst b/Doc/library/compileall.rst index 7b3963da894fba..22d1c6bfa41680 100644 --- a/Doc/library/compileall.rst +++ b/Doc/library/compileall.rst @@ -109,6 +109,11 @@ 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`. +Similarly, the :func:`compile` function respects the :attr:`sys.pycache_prefix` +setting. The generated bytecode cache will only be useful if :func:`compile` is +run with the same :attr:`sys.pycache_prefix` (if any) that will be used at +runtime. + Public functions ---------------- diff --git a/Doc/library/concurrent.futures.rst b/Doc/library/concurrent.futures.rst index 707d24dc2529cc..6934acc7f88e27 100644 --- a/Doc/library/concurrent.futures.rst +++ b/Doc/library/concurrent.futures.rst @@ -380,6 +380,11 @@ The :class:`Future` class encapsulates the asynchronous execution of a callable. This method should only be used by :class:`Executor` implementations and unit tests. + .. versionchanged:: 3.8 + This method raises + :exc:`concurrent.futures.InvalidStateError` if the :class:`Future` is + already done. + .. method:: set_exception(exception) Sets the result of the work associated with the :class:`Future` to the @@ -388,6 +393,10 @@ The :class:`Future` class encapsulates the asynchronous execution of a callable. This method should only be used by :class:`Executor` implementations and unit tests. + .. versionchanged:: 3.8 + This method raises + :exc:`concurrent.futures.InvalidStateError` if the :class:`Future` is + already done. Module Functions ---------------- @@ -466,6 +475,13 @@ Exception classes .. versionadded:: 3.7 +.. exception:: InvalidStateError + + Raised when an operation is performed on a future that is not allowed + in the current state. + + .. versionadded:: 3.8 + .. currentmodule:: concurrent.futures.thread .. exception:: BrokenThreadPool diff --git a/Doc/library/configparser.rst b/Doc/library/configparser.rst index 4e55623f5360d4..1e5f25f3691919 100644 --- a/Doc/library/configparser.rst +++ b/Doc/library/configparser.rst @@ -445,20 +445,19 @@ the :meth:`__init__` options: Hint: if you want to specify default values for a specific section, use :meth:`read_dict` before you read the actual file. -* *dict_type*, default value: :class:`collections.OrderedDict` +* *dict_type*, default value: :class:`dict` This option has a major impact on how the mapping protocol will behave and how - the written configuration files look. With the default ordered - dictionary, every section is stored in the order they were added to the - parser. Same goes for options within sections. + the written configuration files look. With the standard dictionary, every + section is stored in the order they were added to the parser. Same goes for + options within sections. An alternative dictionary type can be used for example to sort sections and - options on write-back. You can also use a regular dictionary for performance - reasons. + options on write-back. Please note: there are ways to add a set of key-value pairs in a single operation. When you use a regular dictionary in those operations, the order - of the keys may be random. For example: + of the keys will be ordered. For example: .. doctest:: @@ -474,40 +473,9 @@ the :meth:`__init__` options: ... 'baz': 'z'} ... }) >>> parser.sections() # doctest: +SKIP - ['section3', 'section2', 'section1'] - >>> [option for option in parser['section3']] # doctest: +SKIP - ['baz', 'foo', 'bar'] - - In these operations you need to use an ordered dictionary as well: - - .. doctest:: - - >>> from collections import OrderedDict - >>> parser = configparser.ConfigParser() - >>> parser.read_dict( - ... OrderedDict(( - ... ('s1', - ... OrderedDict(( - ... ('1', '2'), - ... ('3', '4'), - ... ('5', '6'), - ... )) - ... ), - ... ('s2', - ... OrderedDict(( - ... ('a', 'b'), - ... ('c', 'd'), - ... ('e', 'f'), - ... )) - ... ), - ... )) - ... ) - >>> parser.sections() # doctest: +SKIP - ['s1', 's2'] - >>> [option for option in parser['s1']] # doctest: +SKIP - ['1', '3', '5'] - >>> [option for option in parser['s2'].values()] # doctest: +SKIP - ['b', 'd', 'f'] + ['section1', 'section2', 'section3'] + >>> [option for option in parser['section3']] # doctest: +SKIP + ['foo', 'bar', 'baz'] * *allow_no_value*, default value: ``False`` @@ -1123,6 +1091,11 @@ ConfigParser Objects given *section*. Optional arguments have the same meaning as for the :meth:`get` method. + .. versionchanged:: 3.8 + Items present in *vars* no longer appear in the result. The previous + behaviour mixed actual parser options with variables provided for + interpolation. + .. method:: set(section, option, value) diff --git a/Doc/library/contextvars.rst b/Doc/library/contextvars.rst index 9c7ea2bdb7b68b..8805661c456edb 100644 --- a/Doc/library/contextvars.rst +++ b/Doc/library/contextvars.rst @@ -48,6 +48,8 @@ Context Variables The name of the variable. This is a read-only property. + .. versionadded:: 3.7.1 + .. method:: get([default]) Return a value for the context variable for the current context. diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst index 1ac2570eae5ac0..53c181c4014a9c 100644 --- a/Doc/library/datetime.rst +++ b/Doc/library/datetime.rst @@ -241,7 +241,7 @@ Supported operations: +--------------------------------+-----------------------------------------------+ | ``t1 = t2 - t3`` | Difference of *t2* and *t3*. Afterwards *t1* | | | == *t2* - *t3* and *t2* == *t1* + *t3* are | -| | true. (1) | +| | true. (1)(6) | +--------------------------------+-----------------------------------------------+ | ``t1 = t2 * i or t1 = i * t2`` | Delta multiplied by an integer. | | | Afterwards *t1* // i == *t2* is true, | @@ -317,6 +317,11 @@ Notes: >>> print(_) -1 day, 19:00:00 +(6) + The expression ``t2 - t3`` will always be equal to the expression ``t2 + (-t3)`` except + when t3 is equal to ``timedelta.max``; in that case the former will produce a result + while the latter will overflow. + In addition to the operations listed above :class:`timedelta` objects support certain additions and subtractions with :class:`date` and :class:`.datetime` objects (see below). @@ -513,8 +518,6 @@ Notes: :const:`MINYEAR` or larger than :const:`MAXYEAR`. (2) - This isn't quite equivalent to date1 + (-timedelta), because -timedelta in - isolation can overflow in cases where date1 - timedelta does not. ``timedelta.seconds`` and ``timedelta.microseconds`` are ignored. (3) @@ -961,8 +964,6 @@ Supported operations: Computes the datetime2 such that datetime2 + timedelta == datetime1. As for addition, the result has the same :attr:`~.datetime.tzinfo` attribute as the input datetime, and no time zone adjustments are done even if the input is aware. - This isn't quite equivalent to datetime1 + (-timedelta), because -timedelta - in isolation can overflow in cases where datetime1 - timedelta does not. (3) Subtraction of a :class:`.datetime` from a :class:`.datetime` is defined only if diff --git a/Doc/library/dbm.rst b/Doc/library/dbm.rst index 0150f5d5c6e8c3..ab45cac830e24d 100644 --- a/Doc/library/dbm.rst +++ b/Doc/library/dbm.rst @@ -339,9 +339,23 @@ The module defines the following: dumbdbm database is created, files with :file:`.dat` and :file:`.dir` extensions are created. - 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 *flag* argument can be: + + +---------+-------------------------------------------+ + | Value | Meaning | + +=========+===========================================+ + | ``'r'`` | Open existing database for reading only | + | | (default) | + +---------+-------------------------------------------+ + | ``'w'`` | Open existing database for reading and | + | | writing | + +---------+-------------------------------------------+ + | ``'c'`` | Open database for reading and writing, | + | | creating it if it doesn't exist | + +---------+-------------------------------------------+ + | ``'n'`` | Always create a new, empty database, open | + | | for reading and writing | + +---------+-------------------------------------------+ 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 @@ -356,9 +370,10 @@ The module defines the following: :func:`.open` always creates a new database when the flag has the value ``'n'``. - .. deprecated-removed:: 3.6 3.8 - Creating database in ``'r'`` and ``'w'`` modes. Modifying database in - ``'r'`` mode. + .. versionchanged:: 3.8 + A database opened with flags ``'r'`` is now read-only. Opening with + flags ``'r'`` and ``'w'`` no longer creates a database if it does not + exist. In addition to the methods provided by the :class:`collections.abc.MutableMapping` class, :class:`dumbdbm` objects diff --git a/Doc/library/depgraph-output.png b/Doc/library/depgraph-output.png deleted file mode 100644 index 960bb1b5639e7f..00000000000000 Binary files a/Doc/library/depgraph-output.png and /dev/null differ diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index 535b36efbf2ec8..8f505e65bd51e5 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -335,6 +335,14 @@ The Python compiler currently generates the following bytecode instructions. three. +.. opcode:: ROT_FOUR + + Lifts second, third and forth stack items one position up, moves top down + to position four. + + .. versionadded:: 3.8 + + .. opcode:: DUP_TOP Duplicates the reference on top of the stack. @@ -580,6 +588,17 @@ the original TOS1. .. versionadded:: 3.5 +.. opcode:: END_ASYNC_FOR + + Terminates an :keyword:`async for` loop. Handles an exception raised + when awaiting a next item. If TOS is :exc:`StopAsyncIteration` pop 7 + values from the stack and restore the exception state using the second + three of them. Otherwise re-raise the exception using the three values + from the stack. An exception handler block is removed from the block stack. + + .. versionadded:: 3.8 + + .. opcode:: BEFORE_ASYNC_WITH Resolves ``__aenter__`` and ``__aexit__`` from the object on top of the @@ -605,17 +624,6 @@ the original TOS1. is terminated with :opcode:`POP_TOP`. -.. opcode:: BREAK_LOOP - - Terminates a loop due to a :keyword:`break` statement. - - -.. opcode:: CONTINUE_LOOP (target) - - Continues a loop due to a :keyword:`continue` statement. *target* is the - address to jump to (which should be a :opcode:`FOR_ITER` instruction). - - .. opcode:: SET_ADD (i) Calls ``set.add(TOS1[-i], TOS)``. Used to implement set comprehensions. @@ -676,7 +684,7 @@ iterations of the loop. .. opcode:: POP_BLOCK Removes one block from the block stack. Per frame, there is a stack of - blocks, denoting nested loops, try statements, and such. + blocks, denoting :keyword:`try` statements, and such. .. opcode:: POP_EXCEPT @@ -687,11 +695,50 @@ iterations of the loop. popped values are used to restore the exception state. +.. opcode:: POP_FINALLY (preserve_tos) + + Cleans up the value stack and the block stack. If *preserve_tos* is not + ``0`` TOS first is popped from the stack and pushed on the stack after + perfoming other stack operations: + + * If TOS is ``NULL`` or an integer (pushed by :opcode:`BEGIN_FINALLY` + or :opcode:`CALL_FINALLY`) it is popped from the stack. + * If TOS is an exception type (pushed when an exception has been raised) + 6 values are popped from the stack, the last three popped values are + used to restore the exception state. An exception handler block is + removed from the block stack. + + It is similar to :opcode:`END_FINALLY`, but doesn't change the bytecode + counter nor raise an exception. Used for implementing :keyword:`break`, + :keyword:`continue` and :keyword:`return` in the :keyword:`finally` block. + + .. versionadded:: 3.8 + + +.. opcode:: BEGIN_FINALLY + + Pushes ``NULL`` onto the stack for using it in :opcode:`END_FINALLY`, + :opcode:`POP_FINALLY`, :opcode:`WITH_CLEANUP_START` and + :opcode:`WITH_CLEANUP_FINISH`. Starts the :keyword:`finally` block. + + .. versionadded:: 3.8 + + .. opcode:: END_FINALLY Terminates a :keyword:`finally` clause. The interpreter recalls whether the - exception has to be re-raised, or whether the function returns, and continues - with the outer-next block. + exception has to be re-raised or execution has to be continued depending on + the value of TOS. + + * If TOS is ``NULL`` (pushed by :opcode:`BEGIN_FINALLY`) continue from + the next instruction. TOS is popped. + * If TOS is an integer (pushed by :opcode:`CALL_FINALLY`), sets the + bytecode counter to TOS. TOS is popped. + * If TOS is an exception type (pushed when an exception has been raised) + 6 values are popped from the stack, the first three popped values are + used to re-raise the exception and the last three popped values are used + to restore the exception state. An exception handler block is removed + from the block stack. .. opcode:: LOAD_BUILD_CLASS @@ -704,9 +751,9 @@ iterations of the loop. This opcode performs several operations before a with block starts. First, it loads :meth:`~object.__exit__` from the context manager and pushes it onto - the stack for later use by :opcode:`WITH_CLEANUP`. Then, + the stack for later use by :opcode:`WITH_CLEANUP_START`. Then, :meth:`~object.__enter__` is called, and a finally block pointing to *delta* - is pushed. Finally, the result of calling the enter method is pushed onto + is pushed. Finally, the result of calling the ``__enter__()`` method is pushed onto the stack. The next opcode will either ignore it (:opcode:`POP_TOP`), or store it in (a) variable(s) (:opcode:`STORE_FAST`, :opcode:`STORE_NAME`, or :opcode:`UNPACK_SEQUENCE`). @@ -716,30 +763,31 @@ iterations of the loop. .. opcode:: WITH_CLEANUP_START - Cleans up the stack when a :keyword:`with` statement block exits. TOS is the - context manager's :meth:`__exit__` bound method. Below TOS are 1--3 values - indicating how/why the finally clause was entered: + Starts cleaning up the stack when a :keyword:`with` statement block exits. - * SECOND = ``None`` - * (SECOND, THIRD) = (``WHY_{RETURN,CONTINUE}``), retval - * SECOND = ``WHY_*``; no retval below it - * (SECOND, THIRD, FOURTH) = exc_info() + At the top of the stack are either ``NULL`` (pushed by + :opcode:`BEGIN_FINALLY`) or 6 values pushed if an exception has been + raised in the with block. Below is the context manager's + :meth:`~object.__exit__` or :meth:`~object.__aexit__` bound method. - In the last case, ``TOS(SECOND, THIRD, FOURTH)`` is called, otherwise - ``TOS(None, None, None)``. Pushes SECOND and result of the call - to the stack. + If TOS is ``NULL``, calls ``SECOND(None, None, None)``, + removes the function from the stack, leaving TOS, and pushes ``None`` + to the stack. Otherwise calls ``SEVENTH(TOP, SECOND, THIRD)``, + shifts the bottom 3 values of the stack down, replaces the empty spot + with ``NULL`` and pushes TOS. Finally pushes the result of the call. .. opcode:: WITH_CLEANUP_FINISH - Pops exception type and result of 'exit' function call from the stack. + Finishes cleaning up the stack when a :keyword:`with` statement block exits. - 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 :opcode:`END_FINALLY` from re-raising the - exception. (But non-local gotos will still be resumed.) + TOS is result of ``__exit__()`` or ``__aexit__()`` function call pushed + by :opcode:`WITH_CLEANUP_START`. SECOND is ``None`` or an exception type + (pushed when an exception has been raised). - .. XXX explain the WHY stuff! + Pops two values from the stack. If SECOND is not None and TOS is true + unwinds the EXCEPT_HANDLER block which was created when the exception + was caught and pushes ``NULL`` to the stack. All of the following opcodes use their arguments. @@ -987,22 +1035,19 @@ All of the following opcodes use their arguments. Loads the global named ``co_names[namei]`` onto the stack. -.. opcode:: SETUP_LOOP (delta) - - Pushes a block for a loop onto the block stack. The block spans from the - current instruction with a size of *delta* bytes. - +.. opcode:: SETUP_FINALLY (delta) -.. opcode:: SETUP_EXCEPT (delta) + Pushes a try block from a try-finally or try-except clause onto the block + stack. *delta* points to the finally block or the first except block. - Pushes a try block from a try-except clause onto the block stack. *delta* - points to the first except block. +.. opcode:: CALL_FINALLY (delta) -.. opcode:: SETUP_FINALLY (delta) + Pushes the address of the next instruction onto the stack and increments + bytecode counter by *delta*. Used for calling the finally block as a + "subroutine". - Pushes a try block from a try-except clause onto the block stack. *delta* - points to the finally block. + .. versionadded:: 3.8 .. opcode:: LOAD_FAST (var_num) diff --git a/Doc/library/email.errors.rst b/Doc/library/email.errors.rst index 5838767b18f742..511ad163583197 100644 --- a/Doc/library/email.errors.rst +++ b/Doc/library/email.errors.rst @@ -108,3 +108,7 @@ All defect classes are subclassed from :class:`email.errors.MessageDefect`. * :class:`InvalidBase64CharactersDefect` -- When decoding a block of base64 encoded bytes, characters outside the base64 alphabet were encountered. The characters are ignored, but the resulting decoded bytes may be invalid. + +* :class:`InvalidBase64LengthDefect` -- When decoding a block of base64 encoded + bytes, the number of non-padding base64 characters was invalid (1 more than + a multiple of 4). The encoded block was kept as-is. diff --git a/Doc/library/email.rst b/Doc/library/email.rst index c4187dd0098d1a..1033d8c130eb75 100644 --- a/Doc/library/email.rst +++ b/Doc/library/email.rst @@ -133,7 +133,7 @@ Legacy API: .. seealso:: Module :mod:`smtplib` - SMTP (Simple Mail Transport Protcol) client + SMTP (Simple Mail Transport Protocol) client Module :mod:`poplib` POP (Post Office Protocol) client diff --git a/Doc/library/enum.rst b/Doc/library/enum.rst index 787670c6ddad4e..3f17f99476415b 100644 --- a/Doc/library/enum.rst +++ b/Doc/library/enum.rst @@ -4,10 +4,10 @@ .. module:: enum :synopsis: Implementation of an enumeration class. -.. :moduleauthor:: Ethan Furman <ethan@stoneleaf.us> -.. :sectionauthor:: Barry Warsaw <barry@python.org>, -.. :sectionauthor:: Eli Bendersky <eliben@gmail.com>, -.. :sectionauthor:: Ethan Furman <ethan@stoneleaf.us> +.. moduleauthor:: Ethan Furman <ethan@stoneleaf.us> +.. sectionauthor:: Barry Warsaw <barry@python.org> +.. sectionauthor:: Eli Bendersky <eliben@gmail.com> +.. sectionauthor:: Ethan Furman <ethan@stoneleaf.us> .. versionadded:: 3.4 @@ -281,7 +281,7 @@ Iterating over the members of an enum does not provide the aliases:: >>> list(Shape) [<Shape.SQUARE: 2>, <Shape.DIAMOND: 1>, <Shape.CIRCLE: 3>] -The special attribute ``__members__`` is an ordered dictionary mapping names +The special attribute ``__members__`` is a read-only ordered mapping of names to members. It includes all names defined in the enumeration, including the aliases:: @@ -998,7 +998,7 @@ Finer Points Supported ``__dunder__`` names """""""""""""""""""""""""""""" -:attr:`__members__` is an :class:`OrderedDict` of ``member_name``:``member`` +:attr:`__members__` is a read-only ordered mapping of ``member_name``:``member`` items. It is only available on the class. :meth:`__new__`, if specified, must create and return the enum members; it is diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 457e1c34ec9a26..6476cbd65e0151 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -44,7 +44,8 @@ are always available. They are listed here in alphabetical order. Return the absolute value of a number. The argument may be an integer or a floating point number. If the argument is a complex number, its - magnitude is returned. + magnitude is returned. If *x* defines :meth:`__abs__`, + ``abs(x)`` returns ``x.__abs__()``. .. function:: all(iterable) @@ -98,7 +99,7 @@ are always available. They are listed here in alphabetical order. >>> f'{14:#b}', f'{14:b}' ('0b1110', '1110') - See also :func:`format` for more information. + See also :func:`format` for more information. .. class:: bool([x]) @@ -646,11 +647,11 @@ are always available. They are listed here in alphabetical order. dictionary lookup. Numeric values that compare equal have the same hash value (even if they are of different types, as is the case for 1 and 1.0). - .. note:: + .. note:: - For objects with custom :meth:`__hash__` methods, note that :func:`hash` - truncates the return value based on the bit width of the host machine. - See :meth:`__hash__` for details. + For objects with custom :meth:`__hash__` methods, note that :func:`hash` + truncates the return value based on the bit width of the host machine. + See :meth:`__hash__` for details. .. function:: help([object]) @@ -971,6 +972,11 @@ are always available. They are listed here in alphabetical order. encoding. (For reading and writing raw bytes use binary mode and leave *encoding* unspecified.) The available modes are: + .. _filemodes: + + .. index:: + pair: file; modes + ========= =============================================================== Character Meaning ========= =============================================================== diff --git a/Doc/library/functools.rst b/Doc/library/functools.rst index a81e819103adf3..5e278f9fe98f13 100644 --- a/Doc/library/functools.rst +++ b/Doc/library/functools.rst @@ -263,6 +263,8 @@ The :mod:`functools` module defines the following functions: value = function(value, element) return value + See :func:`itertools.accumulate` for an iterator that yields all intermediate + values. .. decorator:: singledispatch @@ -383,6 +385,52 @@ The :mod:`functools` module defines the following functions: The :func:`register` attribute supports using type annotations. +.. class:: singledispatchmethod(func) + + Transform a method into a :term:`single-dispatch <single + dispatch>` :term:`generic function`. + + To define a generic method, decorate it with the ``@singledispatchmethod`` + decorator. Note that the dispatch happens on the type of the first non-self + or non-cls argument, create your function accordingly:: + + class Negator: + @singledispatchmethod + def neg(self, arg): + raise NotImplementedError("Cannot negate a") + + @neg.register + def _(self, arg: int): + return -arg + + @neg.register + def _(self, arg: bool): + return not arg + + ``@singledispatchmethod`` supports nesting with other decorators such as + ``@classmethod``. Note that to allow for ``dispatcher.register``, + ``singledispatchmethod`` must be the *outer most* decorator. Here is the + ``Negator`` class with the ``neg`` methods being class bound:: + + class Negator: + @singledispatchmethod + @classmethod + def neg(cls, arg): + raise NotImplementedError("Cannot negate a") + + @neg.register + @classmethod + def _(cls, arg: int): + return -arg + + @neg.register + @classmethod + def _(cls, arg: bool): + return not arg + + The same pattern can be used for other similar decorators: ``staticmethod``, + ``abstractmethod``, and others. + .. function:: update_wrapper(wrapper, wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES) Update a *wrapper* function to look like the *wrapped* function. The optional diff --git a/Doc/library/hashlib-blake2-tree.png b/Doc/library/hashlib-blake2-tree.png index 010dcbafe7c61d..73e849444ed7d3 100644 Binary files a/Doc/library/hashlib-blake2-tree.png and b/Doc/library/hashlib-blake2-tree.png differ diff --git a/Doc/library/hashlib.rst b/Doc/library/hashlib.rst index 0ed0482dc54c7a..da941e5bb42b55 100644 --- a/Doc/library/hashlib.rst +++ b/Doc/library/hashlib.rst @@ -546,7 +546,7 @@ on the hash function used in digital signatures. preparer, generates all or part of a message to be signed by a second party, the message signer. If the message preparer is able to find cryptographic hash function collisions (i.e., two messages producing the - same hash value), then she might prepare meaningful versions of the message + same hash value), then they might prepare meaningful versions of the message that would produce the same hash value and digital signature, but with different results (e.g., transferring $1,000,000 to an account, rather than $10). Cryptographic hash functions have been designed with collision diff --git a/Doc/library/http.cookies.rst b/Doc/library/http.cookies.rst index fb8317ad59e6f8..f3457a0cdc7bc4 100644 --- a/Doc/library/http.cookies.rst +++ b/Doc/library/http.cookies.rst @@ -137,11 +137,16 @@ Morsel Objects * ``secure`` * ``version`` * ``httponly`` + * ``samesite`` The attribute :attr:`httponly` specifies that the cookie is only transferred in HTTP requests, and is not accessible through JavaScript. This is intended to mitigate some forms of cross-site scripting. + The attribute :attr:`samesite` specifies that the browser is not allowed to + send the cookie along with cross-site requests. This helps to mitigate CSRF + attacks. Valid values for this attribute are "Strict" and "Lax". + The keys are case-insensitive and their default value is ``''``. .. versionchanged:: 3.5 @@ -153,6 +158,9 @@ Morsel Objects :attr:`~Morsel.coded_value` are read-only. Use :meth:`~Morsel.set` for setting them. + .. versionchanged:: 3.8 + Added support for the :attr:`samesite` attribute. + .. attribute:: Morsel.value diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst index e33abae7aaca78..74a73fdbddb4cc 100644 --- a/Doc/library/importlib.rst +++ b/Doc/library/importlib.rst @@ -249,7 +249,7 @@ ABC hierarchy:: .. abstractmethod:: find_module(fullname, path=None) - An abstact method for finding a :term:`loader` for the specified + An abstract method for finding a :term:`loader` for the specified module. Originally specified in :pep:`302`, this method was meant for use in :data:`sys.meta_path` and in the path-based import subsystem. diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst index bc4316fabaee58..e33876b98c1ded 100644 --- a/Doc/library/inspect.rst +++ b/Doc/library/inspect.rst @@ -247,9 +247,10 @@ attributes: .. function:: getmembers(object[, predicate]) - Return all the members of an object in a list of (name, value) pairs sorted by - name. If the optional *predicate* argument is supplied, only members for which - the predicate returns a true value are included. + Return all the members of an object in a list of ``(name, value)`` + pairs sorted by name. If the optional *predicate* argument—which will be + called with the ``value`` object of each member—is supplied, only members + for which the predicate returns a true value are included. .. note:: @@ -751,6 +752,25 @@ function. ... print('Parameter:', param) Parameter: c + .. attribute:: Parameter.kind.description + + Describes a enum value of Parameter.kind. + + .. versionadded:: 3.8 + + Example: print all descriptions of arguments:: + + >>> def foo(a, b, *, c, d=10): + ... pass + + >>> sig = signature(foo) + >>> for param in sig.parameters.values(): + ... print(param.kind.description) + positional or keyword + positional or keyword + keyword-only + keyword-only + .. method:: Parameter.replace(*[, name][, kind][, default][, annotation]) Create a new Parameter instance based on the instance replaced was invoked diff --git a/Doc/library/io.rst b/Doc/library/io.rst index f2e0fdbc5bf3cd..98649de7310f0b 100644 --- a/Doc/library/io.rst +++ b/Doc/library/io.rst @@ -799,7 +799,7 @@ Text I/O .. versionadded:: 3.1 - .. method:: read(size) + .. method:: read(size=-1) Read and return at most *size* characters from the stream as a single :class:`str`. If *size* is negative or ``None``, reads until EOF. diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst index 2b4401ac682dd5..c63ea212e41f5a 100644 --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -160,8 +160,8 @@ 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*, *stack_info*, and *extra*. + There are four keyword arguments in *kwargs* which are inspected: + *exc_info*, *stack_info*, *stacklevel* 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 @@ -188,11 +188,19 @@ is the module's name in the Python package namespace. This mimics the ``Traceback (most recent call last):`` which is used when displaying exception frames. - The third keyword argument is *extra* which can be used to pass a - dictionary which is used to populate the __dict__ of the LogRecord created for - the logging event with user-defined attributes. These custom attributes can then - be used as you like. For example, they could be incorporated into logged - messages. For example:: + The third optional keyword argument is *stacklevel*, which defaults to ``1``. + If greater than 1, the corresponding number of stack frames are skipped + when computing the line number and function name set in the :class:`LogRecord` + created for the logging event. This can be used in logging helpers so that + the function name, filename and line number recorded are not the information + for the helper function/method, but rather its caller. The name of this + parameter mirrors the equivalent one in the :mod:`warnings` module. + + The fourth keyword argument is *extra* which can be used to pass a + dictionary which is used to populate the __dict__ of the :class:`LogRecord` + created for the logging event with user-defined attributes. These custom + attributes can then be used as you like. For example, they could be + incorporated into logged messages. For example:: FORMAT = '%(asctime)-15s %(clientip)s %(user)-8s %(message)s' logging.basicConfig(format=FORMAT) @@ -213,9 +221,9 @@ is the module's name in the Python package namespace. If you choose to use these attributes in logged messages, you need to exercise some care. In the above example, for instance, the :class:`Formatter` has been set up with a format string which expects 'clientip' and 'user' in the attribute - dictionary of the LogRecord. If these are missing, the message will not be - logged because a string formatting exception will occur. So in this case, you - always need to pass the *extra* dictionary with these keys. + dictionary of the :class:`LogRecord`. If these are missing, the message will + not be logged because a string formatting exception will occur. So in this case, + you always need to pass the *extra* dictionary with these keys. While this might be annoying, this feature is intended for use in specialized circumstances, such as multi-threaded servers where the same code executes in @@ -224,12 +232,15 @@ is the module's name in the Python package namespace. above example). In such circumstances, it is likely that specialized :class:`Formatter`\ s would be used with particular :class:`Handler`\ s. - .. versionadded:: 3.2 + .. versionchanged:: 3.2 The *stack_info* parameter was added. .. versionchanged:: 3.5 The *exc_info* parameter can now accept exception instances. + .. versionchanged:: 3.8 + The *stacklevel* parameter was added. + .. method:: Logger.info(msg, *args, **kwargs) @@ -300,12 +311,19 @@ is the module's name in the Python package namespace. Removes the specified handler *hdlr* from this logger. - .. method:: Logger.findCaller(stack_info=False) + .. method:: Logger.findCaller(stack_info=False, stacklevel=1) Finds the caller's source filename and line number. Returns the filename, line number, function name and stack information as a 4-element tuple. The stack information is returned as ``None`` unless *stack_info* is ``True``. + The *stacklevel* parameter is passed from code calling the :meth:`debug` + and other APIs. If greater than 1, the excess is used to skip stack frames + before determining the values to be returned. This will generally be useful + when calling logging APIs from helper/wrapper code, so that the information + in the event log refers not to the helper/wrapper code, but to the code that + calls it. + .. method:: Logger.handle(record) @@ -646,9 +664,9 @@ sophisticated criteria than levels, they get to see every record which is processed by the handler or logger they're attached to: this can be useful if you want to do things like counting how many records were processed by a particular logger or handler, or adding, changing or removing attributes in -the LogRecord being processed. Obviously changing the LogRecord needs to be -done with some care, but it does allow the injection of contextual information -into logs (see :ref:`filters-contextual`). +the :class:`LogRecord` being processed. Obviously changing the LogRecord needs +to be done with some care, but it does allow the injection of contextual +information into logs (see :ref:`filters-contextual`). .. _log-record: @@ -702,13 +720,13 @@ wire). be used. .. versionchanged:: 3.2 - The creation of a ``LogRecord`` has been made more configurable by + The creation of a :class:`LogRecord` has been made more configurable by providing a factory which is used to create the record. The factory can be set using :func:`getLogRecordFactory` and :func:`setLogRecordFactory` (see this for the factory's signature). This functionality can be used to inject your own values into a - LogRecord at creation time. You can use the following pattern:: + :class:`LogRecord` at creation time. You can use the following pattern:: old_factory = logging.getLogRecordFactory() @@ -989,7 +1007,7 @@ functions. above example). In such circumstances, it is likely that specialized :class:`Formatter`\ s would be used with particular :class:`Handler`\ s. - .. versionadded:: 3.2 + .. versionchanged:: 3.2 The *stack_info* parameter was added. .. function:: info(msg, *args, **kwargs) @@ -1113,7 +1131,7 @@ functions. if no handlers are defined for the root logger. This function does nothing if the root logger already has handlers - configured for it. + configured, unless the keyword argument *force* is set to ``True``. .. note:: This function should be called from the main thread before other threads are started. In versions of Python prior to @@ -1129,52 +1147,63 @@ functions. +--------------+---------------------------------------------+ | Format | Description | +==============+=============================================+ - | ``filename`` | Specifies that a FileHandler be created, | + | *filename* | Specifies that a FileHandler be created, | | | using the specified filename, rather than a | | | StreamHandler. | +--------------+---------------------------------------------+ - | ``filemode`` | Specifies the mode to open the file, if | - | | filename is specified (if filemode is | - | | unspecified, it defaults to 'a'). | + | *filemode* | If *filename* is specified, open the file | + | | in this :ref:`mode <filemodes>`. Defaults | + | | to ``'a'``. | +--------------+---------------------------------------------+ - | ``format`` | Use the specified format string for the | + | *format* | Use the specified format string for the | | | handler. | +--------------+---------------------------------------------+ - | ``datefmt`` | Use the specified date/time format. | + | *datefmt* | Use the specified date/time format, as | + | | accepted by :func:`time.strftime`. | +--------------+---------------------------------------------+ - | ``style`` | If ``format`` is specified, use this style | - | | for the format string. One of '%', '{' or | - | | '$' for %-formatting, :meth:`str.format` or | - | | :class:`string.Template` respectively, and | - | | defaulting to '%' if not specified. | + | *style* | If *format* is specified, use this style | + | | for the format string. One of ``'%'``, | + | | ``'{'`` or ``'$'`` for :ref:`printf-style | + | | <old-string-formatting>`, | + | | :meth:`str.format` or | + | | :class:`string.Template` respectively. | + | | Defaults to ``'%'``. | +--------------+---------------------------------------------+ - | ``level`` | Set the root logger level to the specified | - | | level. | + | *level* | Set the root logger level to the specified | + | | :ref:`level <levels>`. | +--------------+---------------------------------------------+ - | ``stream`` | Use the specified stream to initialize the | + | *stream* | Use the specified stream to initialize the | | | StreamHandler. Note that this argument is | - | | incompatible with 'filename' - if both are | - | | present, a ``ValueError`` is raised. | + | | incompatible with *filename* - if both | + | | are present, a ``ValueError`` is raised. | +--------------+---------------------------------------------+ - | ``handlers`` | If specified, this should be an iterable of | + | *handlers* | If specified, this should be an iterable of | | | already created handlers to add to the root | | | logger. Any handlers which don't already | | | have a formatter set will be assigned the | | | default formatter created in this function. | | | Note that this argument is incompatible | - | | with 'filename' or 'stream' - if both are | - | | present, a ``ValueError`` is raised. | + | | with *filename* or *stream* - if both | + | | are present, a ``ValueError`` is raised. | + +--------------+---------------------------------------------+ + | *force* | If this keyword argument is specified as | + | | true, any existing handlers attached to the | + | | root logger are removed and closed, before | + | | carrying out the configuration as specified | + | | by the other arguments. | +--------------+---------------------------------------------+ .. versionchanged:: 3.2 - The ``style`` argument was added. + The *style* argument was added. .. versionchanged:: 3.3 - The ``handlers`` argument was added. Additional checks were added to + The *handlers* argument was added. Additional checks were added to catch situations where incompatible arguments are specified (e.g. - ``handlers`` together with ``stream`` or ``filename``, or ``stream`` - together with ``filename``). + *handlers* together with *stream* or *filename*, or *stream* + together with *filename*). + .. versionchanged:: 3.8 + The *force* argument was added. .. function:: shutdown() diff --git a/Doc/library/operator.rst b/Doc/library/operator.rst index e4d6d05a23a7c4..250cbb6b7c0737 100644 --- a/Doc/library/operator.rst +++ b/Doc/library/operator.rst @@ -315,6 +315,8 @@ expect a function argument. method. Dictionaries accept any hashable value. Lists, tuples, and strings accept an index or a slice: + >>> itemgetter('name')({'name': 'tu', 'age': 18}) + 'tu' >>> itemgetter(1)('ABCDEFG') 'B' >>> itemgetter(1,3,5)('ABCDEFG') diff --git a/Doc/library/optparse.rst b/Doc/library/optparse.rst index 337c7c2994169b..e9b82ee2ac13c7 100644 --- a/Doc/library/optparse.rst +++ b/Doc/library/optparse.rst @@ -1677,7 +1677,7 @@ The callback function should raise :exc:`OptionValueError` if there are any problems with the option or its argument(s). :mod:`optparse` catches this and terminates the program, printing the error message you supply to stderr. Your message should be clear, concise, accurate, and mention the option at fault. -Otherwise, the user will have a hard time figuring out what he did wrong. +Otherwise, the user will have a hard time figuring out what they did wrong. .. _optparse-callback-example-1: diff --git a/Doc/library/os.rst b/Doc/library/os.rst index bb36c42f98e109..4bb27e5feb263f 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -2810,14 +2810,12 @@ features: It is an error to specify tuples for both *times* and *ns*. - Whether a directory can be given for *path* - depends on whether the operating system implements directories as files - (for example, Windows does not). Note that the exact times you set here may - not be returned by a subsequent :func:`~os.stat` call, depending on the - resolution with which your operating system records access and modification - times; see :func:`~os.stat`. The best way to preserve exact times is to - use the *st_atime_ns* and *st_mtime_ns* fields from the :func:`os.stat` - result object with the *ns* parameter to `utime`. + Note that the exact times you set here may not be returned by a subsequent + :func:`~os.stat` call, depending on the resolution with which your operating + system records access and modification times; see :func:`~os.stat`. The best + way to preserve exact times is to use the *st_atime_ns* and *st_mtime_ns* + fields from the :func:`os.stat` result object with the *ns* parameter to + `utime`. This function can support :ref:`specifying a file descriptor <path_fd>`, :ref:`paths relative to directory descriptors <dir_fd>` and :ref:`not @@ -3407,6 +3405,47 @@ written in Python, such as a mail server's external command delivery program. subprocesses. +.. function:: posix_spawn(path, argv, env, file_actions=None) + + Wraps the :c:func:`posix_spawn` C library API for use from Python. + + Most users should use :func:`subprocess.run` instead of :func:`posix_spawn`. + + The *path*, *args*, and *env* arguments are similar to :func:`execve`. + + The *file_actions* argument may be a sequence of tuples describing actions + to take on specific file descriptors in the child process between the C + library implementation's :c:func:`fork` and :c:func:`exec` steps. + The first item in each tuple must be one of the three type indicator + listed below describing the remaining tuple elements: + + .. data:: POSIX_SPAWN_OPEN + + (``os.POSIX_SPAWN_OPEN``, *fd*, *path*, *flags*, *mode*) + + Performs ``os.dup2(os.open(path, flags, mode), fd)``. + + .. data:: POSIX_SPAWN_CLOSE + + (``os.POSIX_SPAWN_CLOSE``, *fd*) + + Performs ``os.close(fd)``. + + .. data:: POSIX_SPAWN_DUP2 + + (``os.POSIX_SPAWN_DUP2``, *fd*, *new_fd*) + + Performs ``os.dup2(fd, new_fd)``. + + These tuples correspond to the C library + :c:func:`posix_spawn_file_actions_addopen`, + :c:func:`posix_spawn_file_actions_addclose`, and + :c:func:`posix_spawn_file_actions_adddup2` API calls used to prepare + for the :c:func:`posix_spawn` call itself. + + .. versionadded:: 3.7 + + .. function:: register_at_fork(*, before=None, after_in_parent=None, \ after_in_child=None) diff --git a/Doc/library/pathlib-inheritance.png b/Doc/library/pathlib-inheritance.png index b81c3deb6049d8..f0e8d021341844 100644 Binary files a/Doc/library/pathlib-inheritance.png and b/Doc/library/pathlib-inheritance.png differ diff --git a/Doc/library/pdb.rst b/Doc/library/pdb.rst index c6720cb5997436..a72876f3f5a8c0 100644 --- a/Doc/library/pdb.rst +++ b/Doc/library/pdb.rst @@ -344,7 +344,7 @@ by the local file. Specifying any command resuming execution (currently :pdbcmd:`continue`, :pdbcmd:`step`, :pdbcmd:`next`, :pdbcmd:`return`, :pdbcmd:`jump`, :pdbcmd:`quit` and their abbreviations) - terminates the command :pdbcmd:`list` (as if + terminates the command list (as if that command was immediately followed by end). This is because any time you resume execution (even with a simple next or step), you may encounter another breakpoint—which could have its own command list, leading to ambiguities about diff --git a/Doc/library/pickle.rst b/Doc/library/pickle.rst index 2b10ee2eb8ee30..4f9d3596b649db 100644 --- a/Doc/library/pickle.rst +++ b/Doc/library/pickle.rst @@ -135,14 +135,14 @@ to read the pickle produced. information about improvements brought by protocol 2. * 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 protocol, and the recommended protocol when compatibility with - other Python 3 versions is required. + :class:`bytes` objects and cannot be unpickled by Python 2.x. This was + the default protocol in Python 3.0--3.7. * 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. + optimizations. It is the default protocol starting with Python 3.8. + Refer to :pep:`3154` for information about improvements brought by + protocol 4. .. note:: Serialization is a more primitive notion than persistence; although @@ -179,8 +179,16 @@ The :mod:`pickle` module provides the following constants: 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. + default protocol is 4, first introduced in Python 3.4 and incompatible + with previous versions. + .. versionchanged:: 3.0 + + The default protocol is 3. + + .. versionchanged:: 3.8 + + The default protocol is 4. The :mod:`pickle` module provides the following functions to make the pickling process more convenient: diff --git a/Doc/library/platform.rst b/Doc/library/platform.rst index f5cb52cb4745b4..5b2ff1b497b0f0 100644 --- a/Doc/library/platform.rst +++ b/Doc/library/platform.rst @@ -243,33 +243,6 @@ Mac OS Platform Unix Platforms -------------- - -.. function:: dist(distname='', version='', id='', supported_dists=('SuSE','debian','redhat','mandrake',...)) - - This is another name for :func:`linux_distribution`. - - .. deprecated-removed:: 3.5 3.8 - See alternative like the `distro <https://pypi.org/project/distro>`_ package. - -.. function:: linux_distribution(distname='', version='', id='', supported_dists=('SuSE','debian','redhat','mandrake',...), full_distribution_name=1) - - Tries to determine the name of the Linux OS distribution name. - - ``supported_dists`` may be given to define the set of Linux distributions to - look for. It defaults to a list of currently supported Linux distributions - identified by their release file name. - - If ``full_distribution_name`` is true (default), the full distribution read - from the OS is returned. Otherwise the short name taken from - ``supported_dists`` is used. - - Returns a tuple ``(distname,version,id)`` which defaults to the args given as - parameters. ``id`` is the item in parentheses after the version number. It - is usually the version codename. - - .. deprecated-removed:: 3.5 3.8 - See alternative like the `distro <https://pypi.org/project/distro>`_ package. - .. function:: libc_ver(executable=sys.executable, lib='', version='', chunksize=2048) Tries to determine the libc version against which the file executable (defaults diff --git a/Doc/library/profile.rst b/Doc/library/profile.rst index 3f3c8a94856273..5e33efe1c16528 100644 --- a/Doc/library/profile.rst +++ b/Doc/library/profile.rst @@ -262,6 +262,19 @@ functions: ps.print_stats() print(s.getvalue()) + The :class:`Profile` class can also be used as a context manager (see + :ref:`typecontextmanager`):: + + import cProfile + + with cProfile.Profile() as pr: + # ... do something ... + + pr.print_stats() + + .. versionchanged:: 3.8 + Added context manager support. + .. method:: enable() Start collecting profiling data. diff --git a/Doc/library/re.rst b/Doc/library/re.rst index 3a051dd0dde234..75119a0a35f3e9 100644 --- a/Doc/library/re.rst +++ b/Doc/library/re.rst @@ -468,13 +468,13 @@ Most of the standard escapes supported by Python string literals are also accepted by the regular expression parser:: \a \b \f \n - \r \t \u \U - \v \x \\ + \N \r \t \u + \U \v \x \\ (Note that ``\b`` is used to represent word boundaries, and means "backspace" only inside character classes.) -``'\u'`` and ``'\U'`` escape sequences are only recognized in Unicode +``'\u'``, ``'\U'``, and ``'\N'`` escape sequences are only recognized in Unicode patterns. In bytes patterns they are errors. Octal escapes are included in a limited form. If the first digit is a 0, or if @@ -488,6 +488,9 @@ three digits in length. .. versionchanged:: 3.6 Unknown escapes consisting of ``'\'`` and an ASCII letter now are errors. +.. versionchanged:: 3.8 + The ``'\N{name}'`` escape sequence has been added. As in string literals, + it expands to the named Unicode character (e.g. ``'\N{EM DASH}'``). .. _contents-of-module-re: @@ -1447,8 +1450,8 @@ Finding all Adverbs ^^^^^^^^^^^^^^^^^^^ :func:`findall` matches *all* occurrences of a pattern, not just the first -one as :func:`search` does. For example, if one was a writer and wanted to -find all of the adverbs in some text, he or she might use :func:`findall` in +one as :func:`search` does. For example, if a writer wanted to +find all of the adverbs in some text, they might use :func:`findall` in the following manner:: >>> text = "He was carefully disguised but captured quickly by police." @@ -1462,8 +1465,8 @@ Finding all Adverbs and their Positions If one wants more information about all matches of a pattern than the matched text, :func:`finditer` is useful as it provides :ref:`match objects <match-objects>` instead of strings. Continuing with the previous example, if -one was a writer who wanted to find all of the adverbs *and their positions* in -some text, he or she would use :func:`finditer` in the following manner:: +a writer wanted to find all of the adverbs *and their positions* in +some text, they would use :func:`finditer` in the following manner:: >>> text = "He was carefully disguised but captured quickly by police." >>> for m in re.finditer(r"\w+ly", text): diff --git a/Doc/library/sched.rst b/Doc/library/sched.rst index 6094a7b871454e..ad96dbc95b0cd2 100644 --- a/Doc/library/sched.rst +++ b/Doc/library/sched.rst @@ -81,7 +81,7 @@ Scheduler Objects .. versionchanged:: 3.3 *argument* parameter is optional. - .. versionadded:: 3.3 + .. versionchanged:: 3.3 *kwargs* parameter was added. @@ -94,7 +94,7 @@ Scheduler Objects .. versionchanged:: 3.3 *argument* parameter is optional. - .. versionadded:: 3.3 + .. versionchanged:: 3.3 *kwargs* parameter was added. .. method:: scheduler.cancel(event) @@ -128,7 +128,7 @@ Scheduler Objects the calling code is responsible for canceling events which are no longer pertinent. - .. versionadded:: 3.3 + .. versionchanged:: 3.3 *blocking* parameter was added. .. attribute:: scheduler.queue diff --git a/Doc/library/secrets.rst b/Doc/library/secrets.rst index 28ce472c7e7e16..bc4766da2785b3 100644 --- a/Doc/library/secrets.rst +++ b/Doc/library/secrets.rst @@ -145,8 +145,9 @@ Generate an eight-character alphanumeric password: .. testcode:: import string + import secrets alphabet = string.ascii_letters + string.digits - password = ''.join(choice(alphabet) for i in range(8)) + password = ''.join(secrets.choice(alphabet) for i in range(8)) .. note:: @@ -164,9 +165,10 @@ three digits: .. testcode:: import string + import secrets alphabet = string.ascii_letters + string.digits while True: - password = ''.join(choice(alphabet) for i in range(10)) + password = ''.join(secrets.choice(alphabet) for i in range(10)) if (any(c.islower() for c in password) and any(c.isupper() for c in password) and sum(c.isdigit() for c in password) >= 3): @@ -177,11 +179,12 @@ Generate an `XKCD-style passphrase <https://xkcd.com/936/>`_: .. testcode:: + import secrets # On standard Linux systems, use a convenient dictionary file. # Other platforms may need to provide their own word-list. with open('/usr/share/dict/words') as f: words = [word.strip() for word in f] - password = ' '.join(choice(words) for i in range(4)) + password = ' '.join(secrets.choice(words) for i in range(4)) Generate a hard-to-guess temporary URL containing a security token @@ -189,7 +192,8 @@ suitable for password recovery applications: .. testcode:: - url = 'https://mydomain.com/reset=' + token_urlsafe() + import secrets + url = 'https://mydomain.com/reset=' + secrets.token_urlsafe() diff --git a/Doc/library/select.rst b/Doc/library/select.rst index e252e7adb9246a..8feedaa4770c6a 100644 --- a/Doc/library/select.rst +++ b/Doc/library/select.rst @@ -57,7 +57,16 @@ The module defines the following: (Only supported on Linux 2.5.44 and newer.) Return an edge polling object, which can be used as Edge or Level Triggered interface for I/O - events. *sizehint* and *flags* are deprecated and completely ignored. + events. + + *sizehint* informs epoll about the expected number of events to be + registered. It must be positive, or `-1` to use the default. It is only + used on older systems where :c:func:`epoll_create1` is not available; + otherwise it has no effect (though its value is still checked). + + *flags* is deprecated and completely ignored. However, when supplied, its + value must be ``0`` or ``select.EPOLL_CLOEXEC``, otherwise ``OSError`` is + raised. See the :ref:`epoll-objects` section below for the methods supported by epolling objects. @@ -342,7 +351,7 @@ Edge and Level Trigger Polling (epoll) Objects Remove a registered file descriptor from the epoll object. -.. method:: epoll.poll(timeout=-1, maxevents=-1) +.. method:: epoll.poll(timeout=None, maxevents=-1) Wait for events. timeout in seconds (float) diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst index 1527deb167f1e3..c692cf43b6d72b 100644 --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -51,7 +51,9 @@ Directory and files operations .. function:: copyfile(src, dst, *, follow_symlinks=True) Copy the contents (no metadata) of the file named *src* to a file named - *dst* and return *dst*. *src* and *dst* are path names given as strings. + *dst* and return *dst* in the most efficient way possible. + *src* and *dst* are path names given as strings. + *dst* must be the complete target file name; look at :func:`shutil.copy` for a copy that accepts a target directory path. If *src* and *dst* specify the same file, :exc:`SameFileError` is raised. @@ -74,6 +76,10 @@ Directory and files operations Raise :exc:`SameFileError` instead of :exc:`Error`. Since the former is a subclass of the latter, this change is backward compatible. + .. versionchanged:: 3.8 + Platform-specific fast-copy syscalls may be used internally in order to + copy the file more efficiently. See + :ref:`shutil-platform-dependent-efficient-copy-operations` section. .. exception:: SameFileError @@ -163,6 +169,11 @@ Directory and files operations Added *follow_symlinks* argument. Now returns path to the newly created file. + .. versionchanged:: 3.8 + Platform-specific fast-copy syscalls may be used internally in order to + copy the file more efficiently. See + :ref:`shutil-platform-dependent-efficient-copy-operations` section. + .. function:: copy2(src, dst, *, follow_symlinks=True) Identical to :func:`~shutil.copy` except that :func:`copy2` @@ -185,6 +196,11 @@ Directory and files operations file system attributes too (currently Linux only). Now returns path to the newly created file. + .. versionchanged:: 3.8 + Platform-specific fast-copy syscalls may be used internally in order to + copy the file more efficiently. See + :ref:`shutil-platform-dependent-efficient-copy-operations` section. + .. function:: ignore_patterns(\*patterns) This factory function creates a function that can be used as a callable for @@ -241,6 +257,10 @@ Directory and files operations Added the *ignore_dangling_symlinks* argument to silent dangling symlinks errors when *symlinks* is false. + .. versionchanged:: 3.8 + Platform-specific fast-copy syscalls may be used internally in order to + copy the file more efficiently. See + :ref:`shutil-platform-dependent-efficient-copy-operations` section. .. function:: rmtree(path, ignore_errors=False, onerror=None) @@ -314,6 +334,11 @@ Directory and files operations .. versionchanged:: 3.5 Added the *copy_function* keyword argument. + .. versionchanged:: 3.8 + Platform-specific fast-copy syscalls may be used internally in order to + copy the file more efficiently. See + :ref:`shutil-platform-dependent-efficient-copy-operations` section. + .. function:: disk_usage(path) Return disk usage statistics about the given path as a :term:`named tuple` @@ -370,6 +395,32 @@ Directory and files operations operation. For :func:`copytree`, the exception argument is a list of 3-tuples (*srcname*, *dstname*, *exception*). +.. _shutil-platform-dependent-efficient-copy-operations: + +Platform-dependent efficient copy operations +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Starting from Python 3.8 all functions involving a file copy (:func:`copyfile`, +:func:`copy`, :func:`copy2`, :func:`copytree`, and :func:`move`) may use +platform-specific "fast-copy" syscalls in order to copy the file more +efficiently (see :issue:`33671`). +"fast-copy" means that the copying operation occurs within the kernel, avoiding +the use of userspace buffers in Python as in "``outfd.write(infd.read())``". + +On macOS `fcopyfile`_ is used to copy the file content (not metadata). + +On Linux, Solaris and other POSIX platforms where :func:`os.sendfile` supports +copies between 2 regular file descriptors :func:`os.sendfile` is used. + +On Windows :func:`shutil.copyfile` uses a bigger default buffer size (1 MiB +instead of 16 KiB) and a :func:`memoryview`-based variant of +:func:`shutil.copyfileobj` is used. + +If the fast-copy operation fails and no data was written in the destination +file then shutil will silently fallback on using less efficient +:func:`copyfileobj` function internally. + +.. versionchanged:: 3.8 .. _shutil-copytree-example: @@ -654,6 +705,8 @@ Querying the size of the output terminal .. versionadded:: 3.3 +.. _`fcopyfile`: + http://www.manpagez.com/man/3/copyfile/ + .. _`Other Environment Variables`: http://pubs.opengroup.org/onlinepubs/7908799/xbd/envvar.html#tag_002_003 - diff --git a/Doc/library/signal.rst b/Doc/library/signal.rst index 67eaa2c6381376..67ee979dc0e045 100644 --- a/Doc/library/signal.rst +++ b/Doc/library/signal.rst @@ -207,6 +207,24 @@ The :mod:`signal` module defines the following functions: installed from Python. +.. function:: strsignal(signalnum) + + Return the system description of the signal *signalnum*, such as + "Interrupt", "Segmentation fault", etc. Returns :const:`None` if the signal + is not recognized. + + .. versionadded:: 3.8 + + +.. function:: valid_signals() + + Return the set of valid signal numbers on this platform. This can be + less than ``range(1, NSIG)`` if some signals are reserved by the system + for internal use. + + .. versionadded:: 3.8 + + .. function:: pause() Cause the process to sleep until a signal is received; the appropriate handler @@ -259,8 +277,8 @@ The :mod:`signal` module defines the following functions: argument. *mask* is a set of signal numbers (e.g. {:const:`signal.SIGINT`, - :const:`signal.SIGTERM`}). Use ``range(1, signal.NSIG)`` for a full mask - including all signals. + :const:`signal.SIGTERM`}). Use :func:`~signal.valid_signals` for a full + mask including all signals. For example, ``signal.pthread_sigmask(signal.SIG_BLOCK, [])`` reads the signal mask of the calling thread. diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index d7eaea638f82cb..37d2a4f50afda7 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -236,8 +236,8 @@ Module functions and constants Registers a callable to convert a bytestring from the database into a custom Python type. The callable will be invoked for all database values that are of the type *typename*. Confer the parameter *detect_types* of the :func:`connect` - function for how the type detection works. Note that the case of *typename* and - the name of the type in your query must match! + function for how the type detection works. Note that *typename* and the name of + the type in your query are matched in case-insensitive manner. .. function:: register_adapter(type, callable) @@ -337,17 +337,24 @@ Connection Objects :meth:`~Cursor.executescript` method with the given *sql_script*, and returns the cursor. - .. method:: create_function(name, num_params, func) + .. method:: create_function(name, num_params, func, *, deterministic=False) Creates a user-defined function that you can later use from within SQL statements under the function name *name*. *num_params* is the number of parameters the function accepts (if *num_params* is -1, the function may take any number of arguments), and *func* is a Python callable that is - called as the SQL function. + called as the SQL function. If *deterministic* is true, the created function + is marked as `deterministic <https://sqlite.org/deterministic.html>`_, which + allows SQLite to perform additional optimizations. This flag is supported by + SQLite 3.8.3 or higher, :exc:`NotSupportedError` will be raised if used + with older versions. The function can return any of the types supported by SQLite: bytes, str, int, float and ``None``. + .. versionchanged:: 3.8 + The *deterministic* parameter was added. + Example: .. literalinclude:: ../includes/sqlite3/md5func.py @@ -821,6 +828,20 @@ Exceptions exists, syntax error in the SQL statement, wrong number of parameters specified, etc. It is a subclass of :exc:`DatabaseError`. +.. exception:: OperationalError + + Exception raised for errors that are related to the database's operation + and not necessarily under the control of the programmer, e.g. an unexpected + disconnect occurs, the data source name is not found, a transaction could + not be processed, etc. It is a subclass of :exc:`DatabaseError`. + +.. exception:: NotSupportedError + + Exception raised in case a method or database API was used which is not + supported by the database, e.g. calling the :meth:`~Connection.rollback` + method on a connection that does not support transaction or has + transactions turned off. It is a subclass of :exc:`DatabaseError`. + .. _sqlite3-types: diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst index 9b16a8bbed6969..99d1d774b4aed4 100644 --- a/Doc/library/ssl.rst +++ b/Doc/library/ssl.rst @@ -1607,7 +1607,7 @@ to speed up repeated connections from the same clients. Set the available ciphers for sockets created with this context. It should be a string in the `OpenSSL cipher list format - <https://wiki.openssl.org/index.php/Manual:Ciphers(1)#CIPHER_LIST_FORMAT>`_. + <https://www.openssl.org/docs/manmaster/man1/ciphers.html>`_. If no cipher can be selected (because compile-time options or other configuration forbids use of all the specified ciphers), an :class:`SSLError` will be raised. @@ -1991,7 +1991,7 @@ message with one of the parts, you can decrypt it with the other part, and A certificate contains information about two principals. It contains the name of a *subject*, and the subject's public key. It also contains a statement by a -second principal, the *issuer*, that the subject is who he claims to be, and +second principal, the *issuer*, that the subject is who they claim to be, and that this is indeed the subject's public key. The issuer's statement is signed with the issuer's private key, which only the issuer knows. However, anyone can verify the issuer's statement by finding the issuer's public key, decrypting the diff --git a/Doc/library/statistics.rst b/Doc/library/statistics.rst index bc3817836b9398..26bb592b23812b 100644 --- a/Doc/library/statistics.rst +++ b/Doc/library/statistics.rst @@ -169,6 +169,10 @@ However, for reading convenience, most of the examples show sorted sequences. This is suited for when your data is discrete, and you don't mind that the median may not be an actual data point. + If your data is ordinal (supports order operations) but not numeric (doesn't + support addition), you should use :func:`median_low` or :func:`median_high` + instead. + .. seealso:: :func:`median_low`, :func:`median_high`, :func:`median_grouped` diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 62373c1810c55c..c9e3a94786c275 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -2051,7 +2051,7 @@ expression support in the :mod:`re` module). .. method:: str.upper() Return a copy of the string with all the cased characters [4]_ converted to - uppercase. Note that ``str.upper().isupper()`` might be ``False`` if ``s`` + uppercase. Note that ``s.upper().isupper()`` might be ``False`` if ``s`` contains uncased characters or if the Unicode category of the resulting character(s) is not "Lu" (Letter, uppercase), but e.g. "Lt" (Letter, titlecase). @@ -2315,7 +2315,7 @@ data and are closely related to string objects in a variety of other ways. While bytes literals and representations are based on ASCII text, bytes objects actually behave like immutable sequences of integers, with each value in the sequence restricted such that ``0 <= x < 256`` (attempts to - violate this restriction will trigger :exc:`ValueError`. This is done + violate this restriction will trigger :exc:`ValueError`). This is done deliberately to emphasise that while many binary formats include ASCII based elements and can be usefully manipulated with some text-oriented algorithms, this is not generally the case for arbitrary binary data (blindly applying @@ -3388,7 +3388,10 @@ Notes: 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`. +.. seealso:: + + :pep:`461` - Adding % formatting to bytes and bytearray + .. versionadded:: 3.5 .. _typememoryview: @@ -3591,6 +3594,25 @@ copying. :mod:`struct` module syntax as well as multi-dimensional representations. + .. method:: toreadonly() + + Return a readonly version of the memoryview object. The original + memoryview object is unchanged. :: + + >>> m = memoryview(bytearray(b'abc')) + >>> mm = m.toreadonly() + >>> mm.tolist() + [89, 98, 99] + >>> mm[0] = 42 + Traceback (most recent call last): + File "<stdin>", line 1, in <module> + TypeError: cannot modify read-only memory + >>> m[0] = 43 + >>> mm.tolist() + [43, 98, 99] + + .. versionadded:: 3.8 + .. method:: release() Release the underlying buffer exposed by the memoryview object. Many diff --git a/Doc/library/string.rst b/Doc/library/string.rst index ee8ea857da4b96..89955cfddb381a 100644 --- a/Doc/library/string.rst +++ b/Doc/library/string.rst @@ -231,8 +231,11 @@ attribute using :func:`getattr`, while an expression of the form ``'[index]'`` does an index lookup using :func:`__getitem__`. .. versionchanged:: 3.1 - The positional argument specifiers can be omitted, so ``'{} {}'`` is - equivalent to ``'{0} {1}'``. + The positional argument specifiers can be omitted for :meth:`str.format`, + so ``'{} {}'.format(a, b)`` is equivalent to ``'{0} {1}'.format(a, b)``. + +.. versionchanged:: 3.4 + The positional argument specifiers can be omitted for :class:`Formatter`. Some simple format string examples:: diff --git a/Doc/library/struct.rst b/Doc/library/struct.rst index 2d0866c7e09e7c..d6a3cb721e8388 100644 --- a/Doc/library/struct.rst +++ b/Doc/library/struct.rst @@ -74,8 +74,8 @@ The module defines the following exception and functions: Unpack from *buffer* starting at position *offset*, according to the format string *format*. The result is a tuple even if it contains exactly one - item. The buffer's size in bytes, minus *offset*, must be at least - the size required by the format, as reflected by :func:`calcsize`. + item. The buffer's size in bytes, starting at position *offset*, must be at + least the size required by the format, as reflected by :func:`calcsize`. .. function:: iter_unpack(format, buffer) @@ -428,7 +428,7 @@ The :mod:`struct` module also defines the following type: .. method:: unpack_from(buffer, offset=0) Identical to the :func:`unpack_from` function, using the compiled format. - The buffer's size in bytes, minus *offset*, must be at least + The buffer's size in bytes, starting at position *offset*, must be at least :attr:`size`. diff --git a/Doc/library/subprocess.rst b/Doc/library/subprocess.rst index 58439864f37a08..9f733bcfffb078 100644 --- a/Doc/library/subprocess.rst +++ b/Doc/library/subprocess.rst @@ -485,7 +485,7 @@ functions. between the parent and child. Providing any *pass_fds* forces *close_fds* to be :const:`True`. (POSIX only) - .. versionadded:: 3.2 + .. versionchanged:: 3.2 The *pass_fds* parameter was added. If *cwd* is not ``None``, the function changes the working directory to diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index 23ffe560c58581..a9a8d5fa8c0ab8 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -242,6 +242,26 @@ always available. yourself to control bytecode file generation. +.. data:: pycache_prefix + + If this is set (not ``None``), Python will write bytecode-cache ``.pyc`` + files to (and read them from) a parallel directory tree rooted at this + directory, rather than from ``__pycache__`` directories in the source code + tree. Any ``__pycache__`` directories in the source code tree will be ignored + and new `.pyc` files written within the pycache prefix. Thus if you use + :mod:`compileall` as a pre-build step, you must ensure you run it with the + same pycache prefix (if any) that you will use at runtime. + + A relative path is interpreted relative to the current working directory. + + This value is initially set based on the value of the :option:`-X` + ``pycache_prefix=PATH`` command-line option or the + :envvar:`PYTHONPYCACHEPREFIX` environment variable (command-line takes + precedence). If neither are set, it is ``None``. + + .. versionadded:: 3.8 + + .. function:: excepthook(type, value, traceback) This function prints out a given traceback and exception to ``sys.stderr``. diff --git a/Doc/library/tempfile.rst b/Doc/library/tempfile.rst index c59aca1e189086..20046ee0fb4ea0 100644 --- a/Doc/library/tempfile.rst +++ b/Doc/library/tempfile.rst @@ -31,7 +31,7 @@ is recommended to use keyword arguments for clarity. The module defines the following user-callable items: -.. function:: TemporaryFile(mode='w+b', buffering=None, encoding=None, newline=None, suffix=None, prefix=None, dir=None) +.. function:: TemporaryFile(mode='w+b', buffering=None, encoding=None, newline=None, suffix=None, prefix=None, dir=None, *, errors=None) Return a :term:`file-like object` that can be used as a temporary storage area. The file is created securely, using the same rules as :func:`mkstemp`. It will be destroyed as soon @@ -49,7 +49,7 @@ The module defines the following user-callable items: The *mode* parameter defaults to ``'w+b'`` so that the file created can be read and written without being closed. Binary mode is used so that it behaves consistently on all platforms without regard for the data that is - stored. *buffering*, *encoding* and *newline* are interpreted as for + stored. *buffering*, *encoding*, *errors* and *newline* are interpreted as for :func:`open`. The *dir*, *prefix* and *suffix* parameters have the same meaning and @@ -66,8 +66,11 @@ The module defines the following user-callable items: The :py:data:`os.O_TMPFILE` flag is now used if available. + .. versionchanged:: 3.8 + Added *errors* parameter. -.. function:: NamedTemporaryFile(mode='w+b', buffering=None, encoding=None, newline=None, suffix=None, prefix=None, dir=None, delete=True) + +.. function:: NamedTemporaryFile(mode='w+b', buffering=None, encoding=None, newline=None, suffix=None, prefix=None, dir=None, delete=True, *, errors=None) This function operates exactly as :func:`TemporaryFile` does, except that the file is guaranteed to have a visible name in the file system (on @@ -82,8 +85,11 @@ The module defines the following user-callable items: attribute is the underlying true file object. This file-like object can be used in a :keyword:`with` statement, just like a normal file. + .. versionchanged:: 3.8 + Added *errors* parameter. + -.. function:: SpooledTemporaryFile(max_size=0, mode='w+b', buffering=None, encoding=None, newline=None, suffix=None, prefix=None, dir=None) +.. function:: SpooledTemporaryFile(max_size=0, mode='w+b', buffering=None, encoding=None, newline=None, suffix=None, prefix=None, dir=None, *, errors=None) This function operates exactly as :func:`TemporaryFile` does, except that data is spooled in memory until the file size exceeds *max_size*, or @@ -104,6 +110,9 @@ The module defines the following user-callable items: .. versionchanged:: 3.3 the truncate method now accepts a ``size`` argument. + .. versionchanged:: 3.8 + Added *errors* parameter. + .. function:: TemporaryDirectory(suffix=None, prefix=None, dir=None) @@ -253,7 +262,7 @@ to specify the directory and this is the recommended approach. default value for the *dir* argument to the functions defined in this module. - If ``tempdir`` is unset or ``None`` at any call to any of the above + If ``tempdir`` is ``None`` (the default) at any call to any of the above functions except :func:`gettempprefix` it is initialized following the algorithm described in :func:`gettempdir`. diff --git a/Doc/library/tkinter.ttk.rst b/Doc/library/tkinter.ttk.rst index 76ecfcce497775..5ba31feae1444d 100644 --- a/Doc/library/tkinter.ttk.rst +++ b/Doc/library/tkinter.ttk.rst @@ -1175,14 +1175,13 @@ ttk.Treeview the tree. - .. method:: selection(selop=None, items=None) + .. method:: selection() - If *selop* is not specified, returns selected items. Otherwise, it will - act according to the following selection methods. + Returns a tuple of selected items. - .. deprecated-removed:: 3.6 3.8 - Using ``selection()`` for changing the selection state is deprecated. - Use the following selection methods instead. + .. versionchanged:: 3.8 + ``selection()`` no longer takes arguments. For changing the selection + state use the following selection methods. .. method:: selection_set(*items) diff --git a/Doc/library/tokenize.rst b/Doc/library/tokenize.rst index 4c0a0ceef7dc4e..111289c767f35c 100644 --- a/Doc/library/tokenize.rst +++ b/Doc/library/tokenize.rst @@ -57,6 +57,16 @@ The primary entry point is a :term:`generator`: :func:`.tokenize` determines the source encoding of the file by looking for a UTF-8 BOM or encoding cookie, according to :pep:`263`. +.. function:: generate_tokens(readline) + + Tokenize a source reading unicode strings instead of bytes. + + Like :func:`.tokenize`, the *readline* argument is a callable returning + a single line of input. However, :func:`generate_tokens` expects *readline* + to return a str object rather than bytes. + + The result is an iterator yielding named tuples, exactly like + :func:`.tokenize`. It does not yield an :data:`~token.ENCODING` token. All constants from the :mod:`token` module are also exported from :mod:`tokenize`. @@ -79,7 +89,8 @@ write back the modified script. positions) may change. It returns bytes, encoded using the :data:`~token.ENCODING` token, which - is the first token sequence output by :func:`.tokenize`. + is the first token sequence output by :func:`.tokenize`. If there is no + encoding token in the input, it returns a str instead. :func:`.tokenize` needs to detect the encoding of source files it tokenizes. The diff --git a/Doc/library/tulip_coro.png b/Doc/library/tulip_coro.png index 36ced8ddbfd91d..aad41c93015d09 100644 Binary files a/Doc/library/tulip_coro.png and b/Doc/library/tulip_coro.png differ diff --git a/Doc/library/turtle-star.png b/Doc/library/turtle-star.png index caf36a3ab3a505..0961e1e2153f72 100644 Binary files a/Doc/library/turtle-star.png and b/Doc/library/turtle-star.png differ diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst index bb647bb6a81150..fd4e067546e5ea 100644 --- a/Doc/library/unittest.mock.rst +++ b/Doc/library/unittest.mock.rst @@ -1660,7 +1660,7 @@ The full list of supported magic methods is: * ``__hash__``, ``__sizeof__``, ``__repr__`` and ``__str__`` * ``__dir__``, ``__format__`` and ``__subclasses__`` -* ``__floor__``, ``__trunc__`` and ``__ceil__`` +* ``__round__``, ``__floor__``, ``__trunc__`` and ``__ceil__`` * Comparisons: ``__lt__``, ``__gt__``, ``__le__``, ``__ge__``, ``__eq__`` and ``__ne__`` * Container methods: ``__getitem__``, ``__setitem__``, ``__delitem__``, @@ -1825,12 +1825,12 @@ sentinel .. data:: sentinel - The ``sentinel`` object provides a convenient way of providing unique - objects for your tests. + The ``sentinel`` object provides a convenient way of providing unique + objects for your tests. - Attributes are created on demand when you access them by name. Accessing - the same attribute will always return the same object. The objects - returned have a sensible repr so that test failure messages are readable. + Attributes are created on demand when you access them by name. Accessing + the same attribute will always return the same object. The objects + returned have a sensible repr so that test failure messages are readable. .. versionchanged:: 3.7 The ``sentinel`` attributes now preserve their identity when they are @@ -2070,22 +2070,22 @@ mock_open .. function:: mock_open(mock=None, read_data=None) - 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 :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`, - :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 - simplistic: every time the *mock* is called, the *read_data* is rewound to - the start. If you need more control over the data that you are feeding to - the tested code you will need to customize this mock for yourself. When that - is insufficient, one of the in-memory filesystem packages on `PyPI - <https://pypi.org>`_ can offer a realistic filesystem for testing. + 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 :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`, + :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 + simplistic: every time the *mock* is called, the *read_data* is rewound to + the start. If you need more control over the data that you are feeding to + the tested code you will need to customize this mock for yourself. When that + is insufficient, one of the in-memory filesystem packages on `PyPI + <https://pypi.org>`_ can offer a realistic filesystem for testing. .. versionchanged:: 3.4 Added :meth:`~io.IOBase.readline` and :meth:`~io.IOBase.readlines` support. diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst index b7116fabcd99c2..0a9d9dae218f65 100644 --- a/Doc/library/urllib.request.rst +++ b/Doc/library/urllib.request.rst @@ -1339,9 +1339,9 @@ some point in the future. The second argument, if present, specifies the file location to copy to (if absent, the location will be a tempfile with a generated name). The third - argument, if present, is a hook function that will be called once on + argument, if present, is a callable that will be called once on establishment of the network connection and once after each block read - thereafter. The hook will be passed three arguments; a count of blocks + thereafter. The callable will be passed three arguments; a count of blocks transferred so far, a block size in bytes, and the total size of the file. The third argument may be ``-1`` on older FTP servers which do not return a file size in response to a retrieval request. diff --git a/Doc/library/urllib.robotparser.rst b/Doc/library/urllib.robotparser.rst index e3b90e673caaf0..544f50273dd17c 100644 --- a/Doc/library/urllib.robotparser.rst +++ b/Doc/library/urllib.robotparser.rst @@ -76,6 +76,15 @@ structure of :file:`robots.txt` files, see http://www.robotstxt.org/orig.html. .. versionadded:: 3.6 + .. method:: site_maps() + + Returns the contents of the ``Sitemap`` parameter from + ``robots.txt`` in the form of a :func:`list`. If there is no such + parameter or the ``robots.txt`` entry for this parameter has + invalid syntax, return ``None``. + + .. versionadded:: 3.8 + The following example demonstrates basic use of the :class:`RobotFileParser` class:: diff --git a/Doc/library/venv.rst b/Doc/library/venv.rst index 035fac41c52c6d..b85d642ee61c52 100644 --- a/Doc/library/venv.rst +++ b/Doc/library/venv.rst @@ -23,10 +23,6 @@ independent set of installed Python packages in its site directories. See :pep:`405` for more information about Python virtual environments. -.. note:: - The ``pyvenv`` script has been deprecated as of Python 3.6 in favor of using - ``python3 -m venv`` to help prevent any potential confusion as to which - Python interpreter a virtual environment will be based on. Creating virtual environments diff --git a/Doc/library/xmlrpc.client.rst b/Doc/library/xmlrpc.client.rst index ed2ccaeae07a91..27d92e324722ea 100644 --- a/Doc/library/xmlrpc.client.rst +++ b/Doc/library/xmlrpc.client.rst @@ -145,7 +145,7 @@ between conformable Python objects and XML on the wire. .. versionchanged:: 3.6 Added support of type tags with prefixes (e.g. ``ex:nil``). - Added support of unmarsalling additional types used by Apache XML-RPC + Added support of unmarshalling additional types used by Apache XML-RPC implementation for numerics: ``i1``, ``i2``, ``i8``, ``biginteger``, ``float`` and ``bigdecimal``. See http://ws.apache.org/xmlrpc/types.html for a description. diff --git a/Doc/library/zlib.rst b/Doc/library/zlib.rst index 8a531c92b8ff15..aa61278e099ac6 100644 --- a/Doc/library/zlib.rst +++ b/Doc/library/zlib.rst @@ -231,6 +231,11 @@ Compression objects support the following methods: compress a set of data that share a common initial prefix. +.. versionchanged:: 3.8 + Added :func:`copy.copy` and :func:`copy.deepcopy` support to compression + objects. + + Decompression objects support the following methods and attributes: @@ -298,6 +303,11 @@ Decompression objects support the following methods and attributes: seeks into the stream at a future point. +.. versionchanged:: 3.8 + Added :func:`copy.copy` and :func:`copy.deepcopy` support to decompression + objects. + + Information about the version of the zlib library in use is available through the following constants: diff --git a/Doc/make.bat b/Doc/make.bat index cff85ceabae9d6..d28dae78e86d4f 100644 --- a/Doc/make.bat +++ b/Doc/make.bat @@ -131,6 +131,9 @@ if exist ..\Misc\NEWS ( if NOT "%PAPER%" == "" ( set SPHINXOPTS=-D latex_elements.papersize=%PAPER% %SPHINXOPTS% ) +if "%1" EQU "htmlhelp" ( + set SPHINXOPTS=-D html_theme_options.body_max_width=none %SPHINXOPTS% +) cmd /S /C "%SPHINXBUILD% %SPHINXOPTS% -b%1 -dbuild\doctrees . "%BUILDDIR%\%1" %2 %3 %4 %5 %6 %7 %8 %9" if "%1" EQU "htmlhelp" ( diff --git a/Doc/reference/compound_stmts.rst b/Doc/reference/compound_stmts.rst index c695feaa50e582..3372d27aa13fb0 100644 --- a/Doc/reference/compound_stmts.rst +++ b/Doc/reference/compound_stmts.rst @@ -91,7 +91,7 @@ The :keyword:`if` statement is used for conditional execution: .. productionlist:: if_stmt: "if" `expression` ":" `suite` - : ( "elif" `expression` ":" `suite` )* + : ("elif" `expression` ":" `suite`)* : ["else" ":" `suite`] It selects exactly one of the suites by evaluating the expressions one by one @@ -235,7 +235,7 @@ The :keyword:`try` statement specifies exception handlers and/or cleanup code for a group of statements: .. productionlist:: - try_stmt: try1_stmt | try2_stmt + try_stmt: `try1_stmt` | `try2_stmt` try1_stmt: "try" ":" `suite` : ("except" [`expression` ["as" `identifier`]] ":" `suite`)+ : ["else" ":" `suite`] @@ -321,8 +321,8 @@ not handled, the exception is temporarily saved. The :keyword:`finally` clause is executed. If there is a saved exception it is re-raised at the end of the :keyword:`finally` clause. If the :keyword:`finally` clause raises another 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:: +If the :keyword:`finally` clause executes a :keyword:`return`, :keyword:`break` +or :keyword:`continue` statement, the saved exception is discarded:: >>> def f(): ... try: @@ -343,10 +343,7 @@ the :keyword:`finally` clause. When a :keyword:`return`, :keyword:`break` or :keyword:`continue` statement is executed in the :keyword:`try` suite of a :keyword:`try`...\ :keyword:`finally` -statement, the :keyword:`finally` clause is also executed 'on the way out.' A -:keyword:`continue` statement is illegal in the :keyword:`finally` clause. (The -reason is a problem with the current implementation --- this restriction may be -lifted in the future). +statement, the :keyword:`finally` clause is also executed 'on the way out.' The return value of a function is determined by the last :keyword:`return` statement executed. Since the :keyword:`finally` clause always executes, a @@ -366,6 +363,10 @@ 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`. +.. versionchanged:: 3.8 + Prior to Python 3.8, a :keyword:`continue` statement was illegal in the + :keyword:`finally` clause due to a problem with the implementation. + .. _with: .. _as: @@ -383,7 +384,7 @@ This allows common :keyword:`try`...\ :keyword:`except`...\ :keyword:`finally` usage patterns to be encapsulated for convenient reuse. .. productionlist:: - with_stmt: "with" with_item ("," with_item)* ":" `suite` + with_stmt: "with" `with_item` ("," `with_item`)* ":" `suite` with_item: `expression` ["as" `target`] The execution of the :keyword:`with` statement with one "item" proceeds as follows: @@ -467,14 +468,15 @@ A function definition defines a user-defined function object (see section :ref:`types`): .. productionlist:: - funcdef: [`decorators`] "def" `funcname` "(" [`parameter_list`] ")" ["->" `expression`] ":" `suite` + funcdef: [`decorators`] "def" `funcname` "(" [`parameter_list`] ")" + : ["->" `expression`] ":" `suite` decorators: `decorator`+ decorator: "@" `dotted_name` ["(" [`argument_list` [","]] ")"] NEWLINE dotted_name: `identifier` ("." `identifier`)* parameter_list: `defparameter` ("," `defparameter`)* ["," [`parameter_list_starargs`]] : | `parameter_list_starargs` parameter_list_starargs: "*" [`parameter`] ("," `defparameter`)* ["," ["**" `parameter` [","]]] - : | "**" `parameter` [","] + : | "**" `parameter` [","] parameter: `identifier` [":" `expression`] defparameter: `parameter` ["=" `expression`] funcname: `identifier` @@ -697,7 +699,8 @@ Coroutine function definition ----------------------------- .. productionlist:: - async_funcdef: [`decorators`] "async" "def" `funcname` "(" [`parameter_list`] ")" ["->" `expression`] ":" `suite` + async_funcdef: [`decorators`] "async" "def" `funcname` "(" [`parameter_list`] ")" + : ["->" `expression`] ":" `suite` .. index:: keyword: async diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index f3f9e5f00bfce6..b6a6d48862bc66 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -1967,8 +1967,7 @@ current call is identified based on the first argument passed to the method. as a ``__classcell__`` entry in the class namespace. If present, this must be propagated up to the ``type.__new__`` call in order for the class to be initialised correctly. - Failing to do so will result in a :exc:`DeprecationWarning` in Python 3.6, - and a :exc:`RuntimeError` in Python 3.8. + Failing to do so will result in a :exc:`RuntimeError` in Python 3.8. When using the default metaclass :class:`type`, or any metaclass that ultimately calls ``type.__new__``, the following additional customisation steps are diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index 6b2d6a9e0a8568..33f7575a8fced7 100644 --- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -196,8 +196,7 @@ they may depend on the values obtained from the leftmost iterable. For example: To ensure the comprehension always results in a container of the appropriate type, ``yield`` and ``yield from`` expressions are prohibited in the implicitly -nested scope (in Python 3.7, such expressions emit :exc:`DeprecationWarning` -when compiled, in Python 3.8+ they will emit :exc:`SyntaxError`). +nested scope. Since Python 3.6, in an :keyword:`async def` function, an :keyword:`async for` clause may be used to iterate over a :term:`asynchronous iterator`. @@ -214,8 +213,8 @@ See also :pep:`530`. .. versionadded:: 3.6 Asynchronous comprehensions were introduced. -.. deprecated:: 3.7 - ``yield`` and ``yield from`` deprecated in the implicitly nested scope. +.. versionchanged:: 3.8 + ``yield`` and ``yield from`` prohibited in the implicitly nested scope. .. _lists: @@ -350,9 +349,7 @@ The parentheses can be omitted on calls with only one argument. See section To avoid interfering with the expected operation of the generator expression itself, ``yield`` and ``yield from`` expressions are prohibited in the -implicitly defined generator (in Python 3.7, such expressions emit -:exc:`DeprecationWarning` when compiled, in Python 3.8+ they will emit -:exc:`SyntaxError`). +implicitly defined generator. If a generator expression contains either :keyword:`async for` clauses or :keyword:`await` expressions it is called an @@ -368,8 +365,8 @@ which is an asynchronous iterator (see :ref:`async-iterators`). only appear in :keyword:`async def` coroutines. Starting with 3.7, any function can use asynchronous generator expressions. -.. deprecated:: 3.7 - ``yield`` and ``yield from`` deprecated in the implicitly nested scope. +.. versionchanged:: 3.8 + ``yield`` and ``yield from`` prohibited in the implicitly nested scope. .. _yieldexpr: @@ -401,12 +398,10 @@ coroutine function to be an asynchronous generator. For example:: Due to their side effects on the containing scope, ``yield`` expressions are not permitted as part of the implicitly defined scopes used to -implement comprehensions and generator expressions (in Python 3.7, such -expressions emit :exc:`DeprecationWarning` when compiled, in Python 3.8+ -they will emit :exc:`SyntaxError`).. +implement comprehensions and generator expressions. -.. deprecated:: 3.7 - Yield expressions deprecated in the implicitly nested scopes used to +.. versionchanged:: 3.8 + Yield expressions prohibited in the implicitly nested scopes used to implement comprehensions and generator expressions. Generator functions are described below, while asynchronous generator @@ -777,7 +772,7 @@ whose value is one of the keys of the mapping, and the subscription selects the value in the mapping that corresponds to that key. (The expression list is a tuple except if it has exactly one item.) -If the primary is a sequence, the expression (list) must evaluate to an integer +If the primary is a sequence, the expression list must evaluate to an integer or a slice (as discussed in the following section). The formal syntax makes no special provision for negative indices in @@ -1060,7 +1055,7 @@ The power operator binds more tightly than unary operators on its left; it binds less tightly than unary operators on its right. The syntax is: .. productionlist:: - power: ( `await_expr` | `primary` ) ["**" `u_expr`] + power: (`await_expr` | `primary`) ["**" `u_expr`] Thus, in an unparenthesized sequence of power and unary operators, the operators are evaluated from right to left (this does not constrain the evaluation order @@ -1132,7 +1127,7 @@ operators and one for additive operators: .. productionlist:: m_expr: `u_expr` | `m_expr` "*" `u_expr` | `m_expr` "@" `m_expr` | - : `m_expr` "//" `u_expr`| `m_expr` "/" `u_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` @@ -1144,7 +1139,9 @@ 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 +.. index:: + single: matrix multiplication + operator: @ The ``@`` (at) operator is intended to be used for matrix multiplication. No builtin Python types implement this operator. @@ -1210,7 +1207,7 @@ Shifting operations The shifting operations have lower priority than the arithmetic operations: .. productionlist:: - shift_expr: `a_expr` | `shift_expr` ( "<<" | ">>" ) `a_expr` + shift_expr: `a_expr` | `shift_expr` ("<<" | ">>") `a_expr` These operators accept integers as arguments. They shift the first argument to the left or right by the number of bits given by the second argument. @@ -1270,7 +1267,7 @@ C, expressions like ``a < b < c`` have the interpretation that is conventional in mathematics: .. productionlist:: - comparison: `or_expr` ( `comp_operator` `or_expr` )* + comparison: `or_expr` (`comp_operator` `or_expr`)* comp_operator: "<" | ">" | "==" | ">=" | "<=" | "!=" : | "is" ["not"] | ["not"] "in" @@ -1634,9 +1631,9 @@ Expression lists .. index:: pair: expression; list .. productionlist:: - expression_list: `expression` ( "," `expression` )* [","] - starred_list: `starred_item` ( "," `starred_item` )* [","] - starred_expression: `expression` | ( `starred_item` "," )* [`starred_item`] + expression_list: `expression` ("," `expression`)* [","] + starred_list: `starred_item` ("," `starred_item`)* [","] + starred_expression: `expression` | (`starred_item` ",")* [`starred_item`] starred_item: `expression` | "*" `or_expr` .. index:: object: tuple diff --git a/Doc/reference/simple_stmts.rst b/Doc/reference/simple_stmts.rst index ef9a5f0dc85422..bb1eea66f98bbc 100644 --- a/Doc/reference/simple_stmts.rst +++ b/Doc/reference/simple_stmts.rst @@ -686,9 +686,8 @@ The :keyword:`continue` statement continue_stmt: "continue" :keyword:`continue` may only occur syntactically nested in a :keyword:`for` or -:keyword:`while` loop, but not nested in a function or class definition or -:keyword:`finally` clause within that loop. It continues with the next -cycle of the nearest enclosing loop. +:keyword:`while` loop, but not nested in a function or class definition within +that loop. It continues with the next cycle of the nearest enclosing loop. When :keyword:`continue` passes control out of a :keyword:`try` statement with a :keyword:`finally` clause, that :keyword:`finally` clause is executed before @@ -708,15 +707,14 @@ The :keyword:`import` statement keyword: from .. productionlist:: - import_stmt: "import" `module` ["as" `name`] ( "," `module` ["as" `name`] )* - : | "from" `relative_module` "import" `identifier` ["as" `name`] - : ( "," `identifier` ["as" `name`] )* - : | "from" `relative_module` "import" "(" `identifier` ["as" `name`] - : ( "," `identifier` ["as" `name`] )* [","] ")" + import_stmt: "import" `module` ["as" `identifier`] ("," `module` ["as" `identifier`])* + : | "from" `relative_module` "import" `identifier` ["as" `identifier`] + : ("," `identifier` ["as" `identifier`])* + : | "from" `relative_module` "import" "(" `identifier` ["as" `identifier`] + : ("," `identifier` ["as" `identifier`])* [","] ")" : | "from" `module` "import" "*" module: (`identifier` ".")* `identifier` relative_module: "."* `module` | "."+ - name: `identifier` The basic import statement (no :keyword:`from` clause) is executed in two steps: @@ -838,12 +836,11 @@ features on a per-module basis before the release in which the feature becomes standard. .. productionlist:: * - future_statement: "from" "__future__" "import" feature ["as" name] - : ("," feature ["as" name])* - : | "from" "__future__" "import" "(" feature ["as" name] - : ("," feature ["as" name])* [","] ")" - feature: identifier - name: identifier + future_stmt: "from" "__future__" "import" `feature` ["as" `identifier`] + : ("," `feature` ["as" `identifier`])* + : | "from" "__future__" "import" "(" `feature` ["as" `identifier`] + : ("," `feature` ["as" `identifier`])* [","] ")" + feature: `identifier` A future statement must appear near the top of the module. The only lines that can appear before a future statement are: diff --git a/Doc/reference/toplevel_components.rst b/Doc/reference/toplevel_components.rst index e1687ff04d3286..d5ffb37b2e58cd 100644 --- a/Doc/reference/toplevel_components.rst +++ b/Doc/reference/toplevel_components.rst @@ -48,14 +48,15 @@ a complete program; each statement is executed in the namespace of .. index:: single: UNIX + single: Windows single: command line single: standard input -Under Unix, a complete program can be passed to the interpreter in three forms: -with the :option:`-c` *string* command line option, as a file passed as the -first command line argument, or as standard input. If the file or standard -input is a tty device, the interpreter enters interactive mode; otherwise, it -executes the file as a complete program. +A complete program can be passed to the interpreter +in three forms: with the :option:`-c` *string* command line option, as a file +passed as the first command line argument, or as standard input. If the file +or standard input is a tty device, the interpreter enters interactive mode; +otherwise, it executes the file as a complete program. .. _file-input: diff --git a/Doc/tools/pydoctheme/static/pydoctheme.css b/Doc/tools/pydoctheme/static/pydoctheme.css deleted file mode 100644 index 1d5c18e5f62396..00000000000000 --- a/Doc/tools/pydoctheme/static/pydoctheme.css +++ /dev/null @@ -1,194 +0,0 @@ -@import url("default.css"); - -body { - background-color: white; - margin-left: 1em; - margin-right: 1em; -} - -div.related { - margin-bottom: 1.2em; - padding: 0.5em 0; - border-top: 1px solid #ccc; - margin-top: 0.5em; -} - -div.related a:hover { - color: #0095C4; -} - -div.related:first-child { - border-top: 0; - border-bottom: 1px solid #ccc; -} - -.inline-search { - display: inline; -} -form.inline-search input { - display: inline; -} -form.inline-search input[type="submit"] { - width: 30px; -} - -div.sphinxsidebar { - background-color: #eeeeee; - border-radius: 5px; - line-height: 130%; - font-size: smaller; -} - -div.sphinxsidebar h3, div.sphinxsidebar h4 { - margin-top: 1.5em; -} - -div.sphinxsidebarwrapper > h3:first-child { - margin-top: 0.2em; -} - -div.sphinxsidebarwrapper > ul > li > ul > li { - margin-bottom: 0.4em; -} - -div.sphinxsidebar a:hover { - color: #0095C4; -} - -form.inline-search input, -div.sphinxsidebar input { - font-family: 'Lucida Grande',Arial,sans-serif; - border: 1px solid #999999; - font-size: smaller; - border-radius: 3px; -} - -div.sphinxsidebar input[type=text] { - max-width: 150px; -} - -div.body { - padding: 0 0 0 1.2em; -} - -div.body p { - line-height: 140%; -} - -div.body h1, div.body h2, div.body h3, div.body h4, div.body h5, div.body h6 { - margin: 0; - border: 0; - padding: 0.3em 0; -} - -div.body hr { - border: 0; - background-color: #ccc; - height: 1px; -} - -div.body pre { - border-radius: 3px; - border: 1px solid #ac9; -} - -div.body div.admonition, div.body div.impl-detail { - border-radius: 3px; -} - -div.body div.impl-detail > p { - margin: 0; -} - -div.body div.seealso { - border: 1px solid #dddd66; -} - -div.body a { - color: #0072aa; -} - -div.body a:visited { - color: #6363bb; -} - -div.body a:hover { - color: #00B0E4; -} - -tt, code, pre { - font-family: monospace, sans-serif; - font-size: 96.5%; -} - -div.body tt, div.body code { - border-radius: 3px; -} - -div.body tt.descname, div.body code.descname { - font-size: 120%; -} - -div.body tt.xref, div.body a tt, div.body code.xref, div.body a code { - font-weight: normal; -} - -.deprecated { - border-radius: 3px; -} - -table.docutils { - border: 1px solid #ddd; - min-width: 20%; - border-radius: 3px; - margin-top: 10px; - margin-bottom: 10px; -} - -table.docutils td, table.docutils th { - border: 1px solid #ddd !important; - border-radius: 3px; -} - -table p, table li { - text-align: left !important; -} - -table.docutils th { - background-color: #eee; - padding: 0.3em 0.5em; -} - -table.docutils td { - background-color: white; - padding: 0.3em 0.5em; -} - -table.footnote, table.footnote td { - border: 0 !important; -} - -div.footer { - line-height: 150%; - margin-top: -2em; - text-align: right; - width: auto; - margin-right: 10px; -} - -div.footer a:hover { - color: #0095C4; -} - -.refcount { - color: #060; -} - -.stableabi { - color: #229; -} - -.highlight { - background: none !important; -} - diff --git a/Doc/tools/pydoctheme/theme.conf b/Doc/tools/pydoctheme/theme.conf deleted file mode 100644 index 0c438816740eec..00000000000000 --- a/Doc/tools/pydoctheme/theme.conf +++ /dev/null @@ -1,23 +0,0 @@ -[theme] -inherit = default -stylesheet = pydoctheme.css -pygments_style = sphinx - -[options] -bodyfont = 'Lucida Grande', Arial, sans-serif -headfont = 'Lucida Grande', Arial, sans-serif -footerbgcolor = white -footertextcolor = #555555 -relbarbgcolor = white -relbartextcolor = #666666 -relbarlinkcolor = #444444 -sidebarbgcolor = white -sidebartextcolor = #444444 -sidebarlinkcolor = #444444 -bgcolor = white -textcolor = #222222 -linkcolor = #0090c0 -visitedlinkcolor = #00608f -headtextcolor = #1a1a1a -headbgcolor = white -headlinkcolor = #aaaaaa diff --git a/Doc/tools/static/changelog_search.js b/Doc/tools/static/changelog_search.js new file mode 100644 index 00000000000000..c881a9bd4c84a7 --- /dev/null +++ b/Doc/tools/static/changelog_search.js @@ -0,0 +1,53 @@ +$(document).ready(function() { + // add the search form and bind the events + $('h1').after([ + '<p>Filter entries by content:', + '<input type="text" value="" id="searchbox" style="width: 50%">', + '<input type="submit" id="searchbox-submit" value="Filter"></p>' + ].join('\n')); + + function dofilter() { + try { + var query = new RegExp($('#searchbox').val(), 'i'); + } + catch (e) { + return; // not a valid regex (yet) + } + // find headers for the versions (What's new in Python X.Y.Z?) + $('#changelog h2').each(function(index1, h2) { + var h2_parent = $(h2).parent(); + var sections_found = 0; + // find headers for the sections (Core, Library, etc.) + h2_parent.find('h3').each(function(index2, h3) { + var h3_parent = $(h3).parent(); + var entries_found = 0; + // find all the entries + h3_parent.find('li').each(function(index3, li) { + var li = $(li); + // check if the query matches the entry + if (query.test(li.text())) { + li.show(); + entries_found++; + } + else { + li.hide(); + } + }); + // if there are entries, show the section, otherwise hide it + if (entries_found > 0) { + h3_parent.show(); + sections_found++; + } + else { + h3_parent.hide(); + } + }); + if (sections_found > 0) + h2_parent.show(); + else + h2_parent.hide(); + }); + } + $('#searchbox').keyup(dofilter); + $('#searchbox-submit').click(dofilter); +}); diff --git a/Doc/tools/static/copybutton.js b/Doc/tools/static/copybutton.js deleted file mode 100644 index 716c9e472f4beb..00000000000000 --- a/Doc/tools/static/copybutton.js +++ /dev/null @@ -1,62 +0,0 @@ -$(document).ready(function() { - /* Add a [>>>] button on the top-right corner of code samples to hide - * the >>> and ... prompts and the output and thus make the code - * copyable. */ - var div = $('.highlight-python .highlight,' + - '.highlight-python3 .highlight') - var pre = div.find('pre'); - - // get the styles from the current theme - pre.parent().parent().css('position', 'relative'); - var hide_text = 'Hide the prompts and output'; - var show_text = 'Show the prompts and output'; - var border_width = pre.css('border-top-width'); - var border_style = pre.css('border-top-style'); - var border_color = pre.css('border-top-color'); - var button_styles = { - 'cursor':'pointer', 'position': 'absolute', 'top': '0', 'right': '0', - 'border-color': border_color, 'border-style': border_style, - 'border-width': border_width, 'color': border_color, 'text-size': '75%', - 'font-family': 'monospace', 'padding-left': '0.2em', 'padding-right': '0.2em', - 'border-radius': '0 3px 0 0' - } - - // create and add the button to all the code blocks that contain >>> - div.each(function(index) { - var jthis = $(this); - if (jthis.find('.gp').length > 0) { - var button = $('<span class="copybutton">>>></span>'); - button.css(button_styles) - button.attr('title', hide_text); - button.data('hidden', 'false'); - jthis.prepend(button); - } - // tracebacks (.gt) contain bare text elements that need to be - // wrapped in a span to work with .nextUntil() (see later) - jthis.find('pre:has(.gt)').contents().filter(function() { - return ((this.nodeType == 3) && (this.data.trim().length > 0)); - }).wrap('<span>'); - }); - - // define the behavior of the button when it's clicked - $('.copybutton').click(function(e){ - e.preventDefault(); - var button = $(this); - if (button.data('hidden') === 'false') { - // hide the code output - button.parent().find('.go, .gp, .gt').hide(); - button.next('pre').find('.gt').nextUntil('.gp, .go').css('visibility', 'hidden'); - button.css('text-decoration', 'line-through'); - button.attr('title', show_text); - button.data('hidden', 'true'); - } else { - // show the code output - button.parent().find('.go, .gp, .gt').show(); - button.next('pre').find('.gt').nextUntil('.gp, .go').css('visibility', 'visible'); - button.css('text-decoration', 'none'); - button.attr('title', hide_text); - button.data('hidden', 'false'); - } - }); -}); - diff --git a/Doc/tools/static/py.png b/Doc/tools/static/py.png deleted file mode 100644 index 93e4a02c3d321c..00000000000000 Binary files a/Doc/tools/static/py.png and /dev/null differ diff --git a/Doc/tools/static/sidebar.js b/Doc/tools/static/sidebar.js deleted file mode 100644 index e8d58f4bfaac49..00000000000000 --- a/Doc/tools/static/sidebar.js +++ /dev/null @@ -1,193 +0,0 @@ -/* - * sidebar.js - * ~~~~~~~~~~ - * - * This script makes the Sphinx sidebar collapsible and implements intelligent - * scrolling. - * - * .sphinxsidebar contains .sphinxsidebarwrapper. This script adds in - * .sphixsidebar, after .sphinxsidebarwrapper, the #sidebarbutton used to - * collapse and expand the sidebar. - * - * When the sidebar is collapsed the .sphinxsidebarwrapper is hidden and the - * width of the sidebar and the margin-left of the document are decreased. - * When the sidebar is expanded the opposite happens. This script saves a - * per-browser/per-session cookie used to remember the position of the sidebar - * among the pages. Once the browser is closed the cookie is deleted and the - * position reset to the default (expanded). - * - * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ - -$(function() { - // global elements used by the functions. - // the 'sidebarbutton' element is defined as global after its - // creation, in the add_sidebar_button function - var jwindow = $(window); - var jdocument = $(document); - var bodywrapper = $('.bodywrapper'); - var sidebar = $('.sphinxsidebar'); - var sidebarwrapper = $('.sphinxsidebarwrapper'); - - // original margin-left of the bodywrapper and width of the sidebar - // with the sidebar expanded - var bw_margin_expanded = bodywrapper.css('margin-left'); - var ssb_width_expanded = sidebar.width(); - - // margin-left of the bodywrapper and width of the sidebar - // with the sidebar collapsed - var bw_margin_collapsed = '.8em'; - var ssb_width_collapsed = '.8em'; - - // colors used by the current theme - var dark_color = '#AAAAAA'; - var light_color = '#CCCCCC'; - - function get_viewport_height() { - if (window.innerHeight) - return window.innerHeight; - else - return jwindow.height(); - } - - function sidebar_is_collapsed() { - return sidebarwrapper.is(':not(:visible)'); - } - - function toggle_sidebar() { - if (sidebar_is_collapsed()) - expand_sidebar(); - else - collapse_sidebar(); - // adjust the scrolling of the sidebar - scroll_sidebar(); - } - - function collapse_sidebar() { - sidebarwrapper.hide(); - sidebar.css('width', ssb_width_collapsed); - bodywrapper.css('margin-left', bw_margin_collapsed); - sidebarbutton.css({ - 'margin-left': '0', - 'height': bodywrapper.height(), - 'border-radius': '5px' - }); - sidebarbutton.find('span').text('»'); - sidebarbutton.attr('title', _('Expand sidebar')); - document.cookie = 'sidebar=collapsed'; - } - - function expand_sidebar() { - bodywrapper.css('margin-left', bw_margin_expanded); - sidebar.css('width', ssb_width_expanded); - sidebarwrapper.show(); - sidebarbutton.css({ - 'margin-left': ssb_width_expanded-12, - 'height': bodywrapper.height(), - 'border-radius': '0 5px 5px 0' - }); - sidebarbutton.find('span').text('«'); - sidebarbutton.attr('title', _('Collapse sidebar')); - //sidebarwrapper.css({'padding-top': - // Math.max(window.pageYOffset - sidebarwrapper.offset().top, 10)}); - document.cookie = 'sidebar=expanded'; - } - - function add_sidebar_button() { - sidebarwrapper.css({ - 'float': 'left', - 'margin-right': '0', - 'width': ssb_width_expanded - 28 - }); - // create the button - sidebar.append( - '<div id="sidebarbutton"><span>«</span></div>' - ); - var sidebarbutton = $('#sidebarbutton'); - // find the height of the viewport to center the '<<' in the page - var viewport_height = get_viewport_height(); - var sidebar_offset = sidebar.offset().top; - var sidebar_height = Math.max(bodywrapper.height(), sidebar.height()); - sidebarbutton.find('span').css({ - 'display': 'block', - 'position': 'fixed', - 'top': Math.min(viewport_height/2, sidebar_height/2 + sidebar_offset) - 10 - }); - - sidebarbutton.click(toggle_sidebar); - sidebarbutton.attr('title', _('Collapse sidebar')); - sidebarbutton.css({ - 'border-radius': '0 5px 5px 0', - 'color': '#444444', - 'background-color': '#CCCCCC', - 'font-size': '1.2em', - 'cursor': 'pointer', - 'height': sidebar_height, - 'padding-top': '1px', - 'padding-left': '1px', - 'margin-left': ssb_width_expanded - 12 - }); - - sidebarbutton.hover( - function () { - $(this).css('background-color', dark_color); - }, - function () { - $(this).css('background-color', light_color); - } - ); - } - - function set_position_from_cookie() { - if (!document.cookie) - return; - var items = document.cookie.split(';'); - for(var k=0; k<items.length; k++) { - var key_val = items[k].split('='); - var key = key_val[0]; - if (key == 'sidebar') { - var value = key_val[1]; - if ((value == 'collapsed') && (!sidebar_is_collapsed())) - collapse_sidebar(); - else if ((value == 'expanded') && (sidebar_is_collapsed())) - expand_sidebar(); - } - } - } - - add_sidebar_button(); - var sidebarbutton = $('#sidebarbutton'); - set_position_from_cookie(); - - - /* intelligent scrolling */ - function scroll_sidebar() { - var sidebar_height = sidebarwrapper.height(); - var viewport_height = get_viewport_height(); - var offset = sidebar.position()['top']; - var wintop = jwindow.scrollTop(); - var winbot = wintop + viewport_height; - var curtop = sidebarwrapper.position()['top']; - var curbot = curtop + sidebar_height; - // does sidebar fit in window? - if (sidebar_height < viewport_height) { - // yes: easy case -- always keep at the top - sidebarwrapper.css('top', $u.min([$u.max([0, wintop - offset - 10]), - jdocument.height() - sidebar_height - 200])); - } - else { - // no: only scroll if top/bottom edge of sidebar is at - // top/bottom edge of window - if (curtop > wintop && curbot > winbot) { - sidebarwrapper.css('top', $u.max([wintop - offset - 10, 0])); - } - else if (curtop < wintop && curbot < winbot) { - sidebarwrapper.css('top', $u.min([winbot - sidebar_height - offset - 20, - jdocument.height() - sidebar_height - 200])); - } - } - } - jwindow.scroll(scroll_sidebar); -}); diff --git a/Doc/tools/templates/indexsidebar.html b/Doc/tools/templates/indexsidebar.html index 9c58036d6592ac..327452484cc8a7 100644 --- a/Doc/tools/templates/indexsidebar.html +++ b/Doc/tools/templates/indexsidebar.html @@ -2,7 +2,7 @@ <h3>{% trans %}Download{% endtrans %}</h3> <p><a href="{{ pathto('download') }}">{% trans %}Download these documents{% endtrans %}</a></p> <h3>{% trans %}Docs for other versions{% endtrans %}</h3> <ul> - <li><a href="https://docs.python.org/3.8/">{% trans %}Python 3.8 (in development){% endtrans %}</a></li> + <li><a href="https://docs.python.org/3.7/">{% trans %}Python 3.7 (stable){% endtrans %}</a></li> <li><a href="https://docs.python.org/3.6/">{% trans %}Python 3.6 (stable){% endtrans %}</a></li> <li><a href="https://docs.python.org/3.5/">{% trans %}Python 3.5 (security-fixes){% endtrans %}</a></li> <li><a href="https://docs.python.org/2.7/">{% trans %}Python 2.7 (stable){% endtrans %}</a></li> diff --git a/Doc/tools/templates/layout.html b/Doc/tools/templates/layout.html index c2106678ac60f4..37811725d86bfe 100644 --- a/Doc/tools/templates/layout.html +++ b/Doc/tools/templates/layout.html @@ -1,118 +1,25 @@ {% extends "!layout.html" %} + {% block rootrellink %} - <li><img src="{{ pathto('_static/py.png', 1) }}" alt="" - style="vertical-align: middle; margin-top: -1px"/></li> - <li><a href="https://www.python.org/">Python</a>{{ reldelim1 }}</li> - <li> - {%- if switchers is defined %} - <span class="language_switcher_placeholder">{{ language or 'en' }}</span> - <span class="version_switcher_placeholder">{{ release }}</span> - <a href="{{ pathto('index') }}">{% trans %}Documentation {% endtrans %}</a>{{ reldelim1 }} - {%- else %} - <a href="{{ pathto('index') }}">{{ shorttitle }}</a>{{ reldelim1 }} - {%- endif %} - </li> -{% endblock %} -{%- macro searchbox() %} -{# modified from sphinx/themes/basic/searchbox.html #} - {%- if builder != "htmlhelp" %} - <div class="inline-search" style="display: none" role="search"> - <form class="inline-search" action="{{ pathto('search') }}" method="get"> - <input placeholder="{{ _('Quick search') }}" type="text" name="q" /> - <input type="submit" value="{{ _('Go') }}" /> - <input type="hidden" name="check_keywords" value="yes" /> - <input type="hidden" name="area" value="default" /> - </form> - </div> - <script type="text/javascript">$('.inline-search').show(0);</script> - {%- endif %} -{%- endmacro %} -{% block relbar1 %} {% if builder != 'qthelp' %} {{ relbar() }} {% endif %} {% endblock %} -{% block relbar2 %} {% if builder != 'qthelp' %} {{ relbar() }} {% endif %} {% endblock %} -{% block relbaritems %} - {%- if pagename != "search" and builder != "singlehtml" and builder != "htmlhelp" %} - <li class="right"> - {{ searchbox() }} - {{ reldelim2 }} +{{ super() }} + <li> + {%- if switchers is defined %} + <span class="language_switcher_placeholder">{{ language or 'en' }}</span> + <span class="version_switcher_placeholder">{{ release }}</span> + <a href="{{ pathto('index') }}">{% trans %}Documentation {% endtrans %}</a>{{ reldelim1 }} + {%- else %} + <a href="{{ pathto('index') }}">{{ shorttitle }}</a>{{ reldelim1 }} + {%- endif %} </li> - {%- endif %} {% endblock %} + {% block extrahead %} - <link rel="shortcut icon" type="image/png" href="{{ pathto('_static/py.png', 1) }}" /> <link rel="canonical" href="https://docs.python.org/3/{{pagename}}.html" /> {% if builder != "htmlhelp" %} - {% if not embedded %}<script type="text/javascript" src="{{ pathto('_static/copybutton.js', 1) }}"></script>{% endif %} - {% if switchers is defined and not embedded %}<script type="text/javascript" src="{{ pathto('_static/switchers.js', 1) }}"></script>{% endif %} - {% if pagename == 'whatsnew/changelog' and not embedded %} - <script type="text/javascript"> - $(document).ready(function() { - // add the search form and bind the events - $('h1').after([ - '<p>Filter entries by content:', - '<input type="text" value="" id="searchbox" style="width: 50%">', - '<input type="submit" id="searchbox-submit" value="Filter"></p>' - ].join('\n')); - - function dofilter() { - try { - var query = new RegExp($('#searchbox').val(), 'i'); - } - catch (e) { - return; // not a valid regex (yet) - } - // find headers for the versions (What's new in Python X.Y.Z?) - $('#changelog h2').each(function(index1, h2) { - var h2_parent = $(h2).parent(); - var sections_found = 0; - // find headers for the sections (Core, Library, etc.) - h2_parent.find('h3').each(function(index2, h3) { - var h3_parent = $(h3).parent(); - var entries_found = 0; - // find all the entries - h3_parent.find('li').each(function(index3, li) { - var li = $(li); - // check if the query matches the entry - if (query.test(li.text())) { - li.show(); - entries_found++; - } - else { - li.hide(); - } - }); - // if there are entries, show the section, otherwise hide it - if (entries_found > 0) { - h3_parent.show(); - sections_found++; - } - else { - h3_parent.hide(); - } - }); - if (sections_found > 0) - h2_parent.show(); - else - h2_parent.hide(); - }); - } - $('#searchbox').keyup(dofilter); - $('#searchbox-submit').click(dofilter); - }); - </script> - {% endif %} + {% if switchers is defined and not embedded %} + <script type="text/javascript" src="{{ pathto('_static/switchers.js', 1) }}"></script>{% endif %} + {% if pagename == 'whatsnew/changelog' and not embedded %} + <script type="text/javascript" src="{{ pathto('_static/changelog_search.js', 1) }}"></script>{% endif %} {% endif %} {{ super() }} {% endblock %} -{% block footer %} - <div class="footer"> - © <a href="{{ pathto('copyright') }}">{% trans %}Copyright{% endtrans %}</a> {{ copyright|e }}. - <br /> - {% trans %}The Python Software Foundation is a non-profit corporation.{% endtrans %} - <a href="https://www.python.org/psf/donations/">{% trans %}Please donate.{% endtrans %}</a> - <br /> - {% trans last_updated=last_updated|e %}Last updated on {{ last_updated }}.{% endtrans %} - {% trans pathto_bugs=pathto('bugs') %}<a href="{{ pathto_bugs }}">Found a bug</a>?{% endtrans %} - <br /> - {% trans sphinx_version=sphinx_version|e %}Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> {{ sphinx_version }}.{% endtrans %} - </div> -{% endblock %} diff --git a/Doc/tutorial/classes.rst b/Doc/tutorial/classes.rst index 4676ef4b8a6044..b8f1226e54a01a 100644 --- a/Doc/tutorial/classes.rst +++ b/Doc/tutorial/classes.rst @@ -892,10 +892,7 @@ Examples:: >>> sum(x*y for x,y in zip(xvec, yvec)) # dot product 260 - >>> from math import pi, sin - >>> sine_table = {x: sin(x*pi/180) for x in range(0, 91)} - - >>> unique_words = set(word for line in page for word in line.split()) + >>> unique_words = set(word for line in page for word in line.split()) >>> valedictorian = max((student.gpa, student.name) for student in graduates) diff --git a/Doc/tutorial/inputoutput.rst b/Doc/tutorial/inputoutput.rst index d5531029d064c2..dfa2806e1752a8 100644 --- a/Doc/tutorial/inputoutput.rst +++ b/Doc/tutorial/inputoutput.rst @@ -20,20 +20,39 @@ of file objects; the standard output file can be referenced as ``sys.stdout``. See the Library Reference for more information on this.) Often you'll want more control over the formatting of your output than simply -printing space-separated values. There are two ways to format your output; the -first way is to do all the string handling yourself; using string slicing and -concatenation operations you can create any layout you can imagine. The -string type has some methods that perform useful operations for padding -strings to a given column width; these will be discussed shortly. The second -way is to use :ref:`formatted string literals <f-strings>`, or the -:meth:`str.format` method. +printing space-separated values. There are several ways to format output. -The :mod:`string` module contains a :class:`~string.Template` class which offers -yet another way to substitute values into strings. +* To use :ref:`formatted string literals <tut-f-strings>`, begin a string + with ``f`` or ``F`` before the opening quotation mark or triple quotation mark. + Inside this string, you can write a Python expression between ``{`` and ``}`` + characters that can refer to variables or literal values. -One question remains, of course: how do you convert values to strings? Luckily, -Python has ways to convert any value to a string: pass it to the :func:`repr` -or :func:`str` functions. + :: + + >>> year = 2016 ; event = 'Referendum' + >>> f'Results of the {year} {event}' + 'Results of the 2016 Referendum' + +* The :meth:`str.format` method of strings requires more manual + effort. You'll still use ``{`` and ``}`` to mark where a variable + will be substituted and can provide detailed formatting directives, + but you'll also need to provide the information to be formatted. + + :: + + >>> yes_votes = 42_572_654 ; no_votes = 43_132_495 + >>> percentage = (yes_votes/(yes_votes+no_votes) + >>> '{:-9} YES votes {:2.2%}'.format(yes_votes, percentage)) + ' 42572654 YES votes 49.67%' + +* Finally, you can do all the string handling yourself by using string slicing and + concatenation operations to create any layout you can imagine. The + string type has some methods that perform useful operations for padding + strings to a given column width. + +When you don't need fancy output but just want a quick display of some +variables for debugging purposes, you can convert any value to a string with +the :func:`repr` or :func:`str` functions. The :func:`str` function is meant to return representations of values which are fairly human-readable, while :func:`repr` is meant to generate representations @@ -67,60 +86,57 @@ Some examples:: ... repr((x, y, ('spam', 'eggs'))) "(32.5, 40000, ('spam', 'eggs'))" -Here are two ways to write a table of squares and cubes:: +The :mod:`string` module contains a :class:`~string.Template` class that offers +yet another way to substitute values into strings, using placeholders like +``$x`` and replacing them with values from a dictionary, but offers much less +control of the formatting. - >>> for x in range(1, 11): - ... print(repr(x).rjust(2), repr(x*x).rjust(3), end=' ') - ... # Note use of 'end' on previous line - ... print(repr(x*x*x).rjust(4)) - ... - 1 1 1 - 2 4 8 - 3 9 27 - 4 16 64 - 5 25 125 - 6 36 216 - 7 49 343 - 8 64 512 - 9 81 729 - 10 100 1000 - >>> for x in range(1, 11): - ... print('{0:2d} {1:3d} {2:4d}'.format(x, x*x, x*x*x)) +.. _tut-f-strings: + +Formatted String Literals +------------------------- + +:ref:`Formatted string literals <f-strings>` (also called f-strings for +short) let you include the value of Python expressions inside a string by +prefixing the string with ``f`` or ``F`` and writing expressions as +``{expression}``. + +An optional format specifier can follow the expression. This allows greater +control over how the value is formatted. The following example rounds pi to +three places after the decimal:: + + >>> import math + >>> print(f'The value of pi is approximately {math.pi:.3f}.') + +Passing an integer after the ``':'`` will cause that field to be a minimum +number of characters wide. This is useful for making columns line up. :: + + >>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678} + >>> for name, phone in table.items(): + ... print(f'{name:10} ==> {phone:10d}') ... - 1 1 1 - 2 4 8 - 3 9 27 - 4 16 64 - 5 25 125 - 6 36 216 - 7 49 343 - 8 64 512 - 9 81 729 - 10 100 1000 + Sjoerd ==> 4127 + Jack ==> 4098 + Dcab ==> 7678 -(Note that in the first example, one space between each column was added by the -way :func:`print` works: by default it adds spaces between its arguments.) +Other modifiers can be used to convert the value before it is formatted. +``'!a'`` applies :func:`ascii`, ``'!s'`` applies :func:`str`, and ``'!r'`` +applies :func:`repr`:: -This example demonstrates the :meth:`str.rjust` method of string -objects, which right-justifies a string in a field of a given width by padding -it with spaces on the left. There are similar methods :meth:`str.ljust` and -:meth:`str.center`. These methods do not write anything, they just return a -new string. If the input string is too long, they don't truncate it, but -return it unchanged; this will mess up your column lay-out but that's usually -better than the alternative, which would be lying about a value. (If you -really want truncation you can always add a slice operation, as in -``x.ljust(n)[:n]``.) + >>> animals = 'eels' + >>> print(f'My hovercraft is full of {animals}.') + My hovercraft is full of eels. + >>> print('My hovercraft is full of {animals !r}.') + My hovercraft is full of 'eels'. -There is another method, :meth:`str.zfill`, which pads a numeric string on the -left with zeros. It understands about plus and minus signs:: +For a reference on these format specifications, see +the reference guide for the :ref:`formatspec`. - >>> '12'.zfill(5) - '00012' - >>> '-3.14'.zfill(7) - '-003.14' - >>> '3.14159265359'.zfill(5) - '3.14159265359' +.. _tut-string-format: + +The String format() Method +-------------------------- Basic usage of the :meth:`str.format` method looks like this:: @@ -150,34 +166,6 @@ Positional and keyword arguments can be arbitrarily combined:: other='Georg')) The story of Bill, Manfred, and Georg. -``'!a'`` (apply :func:`ascii`), ``'!s'`` (apply :func:`str`) and ``'!r'`` -(apply :func:`repr`) can be used to convert the value before it is formatted:: - - >>> contents = 'eels' - >>> print('My hovercraft is full of {}.'.format(contents)) - My hovercraft is full of eels. - >>> print('My hovercraft is full of {!r}.'.format(contents)) - My hovercraft is full of 'eels'. - -An optional ``':'`` and format specifier can follow the field name. This allows -greater control over how the value is formatted. The following example -rounds Pi to three places after the decimal. - - >>> import math - >>> print('The value of PI is approximately {0:.3f}.'.format(math.pi)) - The value of PI is approximately 3.142. - -Passing an integer after the ``':'`` will cause that field to be a minimum -number of characters wide. This is useful for making tables pretty. :: - - >>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678} - >>> for name, phone in table.items(): - ... print('{0:10} ==> {1:10d}'.format(name, phone)) - ... - Jack ==> 4098 - Dcab ==> 7678 - Sjoerd ==> 4127 - If you have a really long format string that you don't want to split up, it would be nice if you could reference the variables to be formatted by name instead of by position. This can be done by simply passing the dict and using @@ -198,10 +186,71 @@ notation. :: This is particularly useful in combination with the built-in function :func:`vars`, which returns a dictionary containing all local variables. +As an example, the following lines produce a tidily-aligned +set of columns giving integers and their squares and cubes:: + + >>> for x in range(1, 11): + ... print('{0:2d} {1:3d} {2:4d}'.format(x, x*x, x*x*x)) + ... + 1 1 1 + 2 4 8 + 3 9 27 + 4 16 64 + 5 25 125 + 6 36 216 + 7 49 343 + 8 64 512 + 9 81 729 + 10 100 1000 + For a complete overview of string formatting with :meth:`str.format`, see :ref:`formatstrings`. +Manual String Formatting +------------------------ + +Here's the same table of squares and cubes, formatted manually:: + + >>> for x in range(1, 11): + ... print(repr(x).rjust(2), repr(x*x).rjust(3), end=' ') + ... # Note use of 'end' on previous line + ... print(repr(x*x*x).rjust(4)) + ... + 1 1 1 + 2 4 8 + 3 9 27 + 4 16 64 + 5 25 125 + 6 36 216 + 7 49 343 + 8 64 512 + 9 81 729 + 10 100 1000 + +(Note that the one space between each column was added by the +way :func:`print` works: it always adds spaces between its arguments.) + +The :meth:`str.rjust` method of string objects right-justifies a string in a +field of a given width by padding it with spaces on the left. There are +similar methods :meth:`str.ljust` and :meth:`str.center`. These methods do +not write anything, they just return a new string. If the input string is too +long, they don't truncate it, but return it unchanged; this will mess up your +column lay-out but that's usually better than the alternative, which would be +lying about a value. (If you really want truncation you can always add a +slice operation, as in ``x.ljust(n)[:n]``.) + +There is another method, :meth:`str.zfill`, which pads a numeric string on the +left with zeros. It understands about plus and minus signs:: + + >>> '12'.zfill(5) + '00012' + >>> '-3.14'.zfill(7) + '-003.14' + >>> '3.14159265359'.zfill(5) + '3.14159265359' + + Old string formatting --------------------- @@ -211,8 +260,8 @@ to the right argument, and returns the string resulting from this formatting operation. For example:: >>> import math - >>> print('The value of PI is approximately %5.3f.' % math.pi) - The value of PI is approximately 3.142. + >>> print('The value of pi is approximately %5.3f.' % math.pi) + The value of pi is approximately 3.142. More information can be found in the :ref:`old-string-formatting` section. diff --git a/Doc/tutorial/interpreter.rst b/Doc/tutorial/interpreter.rst index a2766e8810a579..6cdc6c8419aff8 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.7` +The Python interpreter is usually installed as :file:`/usr/local/bin/python3.8` 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.7 + python3.8 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 @@ -98,8 +98,8 @@ before printing the first prompt: .. code-block:: shell-session - $ python3.7 - Python 3.7 (default, Sep 16 2015, 09:25:04) + $ python3.8 + Python 3.8 (default, Sep 16 2015, 09:25:04) [GCC 4.8.2] on linux Type "help", "copyright", "credits" or "license" for more information. >>> diff --git a/Doc/tutorial/introduction.rst b/Doc/tutorial/introduction.rst index 7176d819425094..22a209c10333e2 100644 --- a/Doc/tutorial/introduction.rst +++ b/Doc/tutorial/introduction.rst @@ -143,12 +143,12 @@ to escape quotes:: "doesn't" >>> "doesn't" # ...or use double quotes instead "doesn't" - >>> '"Yes," he said.' - '"Yes," he said.' - >>> "\"Yes,\" he said." - '"Yes," he said.' - >>> '"Isn\'t," she said.' - '"Isn\'t," she said.' + >>> '"Yes," they said.' + '"Yes," they said.' + >>> "\"Yes,\" they said." + '"Yes," they said.' + >>> '"Isn\'t," they said.' + '"Isn\'t," they said.' In the interactive interpreter, the output string is enclosed in quotes and special characters are escaped with backslashes. While this might sometimes @@ -159,10 +159,10 @@ enclosed in single quotes. The :func:`print` function produces a more readable output, by omitting the enclosing quotes and by printing escaped and special characters:: - >>> '"Isn\'t," she said.' - '"Isn\'t," she said.' - >>> print('"Isn\'t," she said.') - "Isn't," she said. + >>> '"Isn\'t," they said.' + '"Isn\'t," they said.' + >>> print('"Isn\'t," they said.') + "Isn't," they said. >>> s = 'First line.\nSecond line.' # \n means newline >>> s # without print(), \n is included in the output 'First line.\nSecond line.' diff --git a/Doc/tutorial/modules.rst b/Doc/tutorial/modules.rst index 3f689327a0c793..0aadad309a8279 100644 --- a/Doc/tutorial/modules.rst +++ b/Doc/tutorial/modules.rst @@ -249,7 +249,7 @@ Some tips for experts: directory. * There is more detail on this process, including a flow chart of the - decisions, in PEP 3147. + decisions, in :pep:`3147`. .. _tut-standardmodules: diff --git a/Doc/tutorial/stdlib.rst b/Doc/tutorial/stdlib.rst index f5ec8acf58ad7f..82261a6513489a 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:\\Python37' + 'C:\\Python38' >>> os.chdir('/server/accesslogs') # Change current working directory >>> os.system('mkdir today') # Run the command mkdir in the system shell 0 diff --git a/Doc/tutorial/stdlib2.rst b/Doc/tutorial/stdlib2.rst index 99472314ea25e8..d2ac57b8e4d3a7 100644 --- a/Doc/tutorial/stdlib2.rst +++ b/Doc/tutorial/stdlib2.rst @@ -278,7 +278,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:/python37/lib/weakref.py", line 46, in __getitem__ + File "C:/python38/lib/weakref.py", line 46, in __getitem__ o = self.data[key]() KeyError: 'primary' diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index c6bb0be6bc4cf9..b61df8a4b77dff 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -442,6 +442,9 @@ Miscellaneous options the default locale-aware mode. ``-X utf8=0`` explicitly disables UTF-8 mode (even when it would otherwise activate automatically). See :envvar:`PYTHONUTF8` for more details. + * ``-X pycache_prefix=PATH`` enables writing ``.pyc`` files to a parallel + tree rooted at the given directory instead of to the code tree. See also + :envvar:`PYTHONPYCACHEPREFIX`. It also allows passing arbitrary values and retrieving them through the :data:`sys._xoptions` dictionary. @@ -461,6 +464,9 @@ Miscellaneous options .. versionadded:: 3.7 The ``-X importtime``, ``-X dev`` and ``-X utf8`` options. + .. versionadded:: 3.8 + The ``-X pycache_prefix`` option. + Options you shouldn't use ~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -587,6 +593,16 @@ conflict. specifying the :option:`-B` option. +.. envvar:: PYTHONPYCACHEPREFIX + + If this is set, Python will write ``.pyc`` files in a mirror directory tree + at this path, instead of in ``__pycache__`` directories within the source + tree. This is equivalent to specifying the :option:`-X` + ``pycache_prefix=PATH`` option. + + .. versionadded:: 3.8 + + .. envvar:: PYTHONHASHSEED If this variable is not set or set to ``random``, a random value is used @@ -889,7 +905,7 @@ conflict. If this environment variable is not set at all, then the interpreter defaults to using the current locale settings, *unless* the current locale is identified as a legacy ASCII-based locale - (as descibed for :envvar:`PYTHONCOERCECLOCALE`), and locale coercion is + (as described for :envvar:`PYTHONCOERCECLOCALE`), and locale coercion is either disabled or fails. In such legacy locales, the interpreter will default to enabling UTF-8 mode unless explicitly instructed not to do so. diff --git a/Doc/using/win_installer.png b/Doc/using/win_installer.png index 00c88a830febd6..0d2250c186c414 100644 Binary files a/Doc/using/win_installer.png and b/Doc/using/win_installer.png differ diff --git a/Doc/whatsnew/3.3.rst b/Doc/whatsnew/3.3.rst index 7e5133dbb7208c..0575ac9e68187e 100644 --- a/Doc/whatsnew/3.3.rst +++ b/Doc/whatsnew/3.3.rst @@ -1414,7 +1414,7 @@ http :class:`http.server.BaseHTTPRequestHandler` now buffers the headers and writes them all at once when :meth:`~http.server.BaseHTTPRequestHandler.end_headers` is called. A new method :meth:`~http.server.BaseHTTPRequestHandler.flush_headers` -can be used to directly manage when the accumlated headers are sent. +can be used to directly manage when the accumulated headers are sent. (Contributed by Andrew Schaaf in :issue:`3709`.) :class:`http.server` now produces valid ``HTML 4.01 strict`` output. diff --git a/Doc/whatsnew/3.6.rst b/Doc/whatsnew/3.6.rst index bb323619010400..1360af79d0731e 100644 --- a/Doc/whatsnew/3.6.rst +++ b/Doc/whatsnew/3.6.rst @@ -1856,7 +1856,7 @@ Build and C API Changes For more information, see :pep:`7` and :issue:`17884`. * Cross-compiling CPython with the Android NDK and the Android API level set to - 21 (Android 5.0 Lollilop) or greater runs successfully. While Android is not + 21 (Android 5.0 Lollipop) or greater runs successfully. While Android is not yet a supported platform, the Python test suite runs on the Android emulator with only about 16 tests failures. See the Android meta-issue :issue:`26865`. diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst index cbcb51a7e8a288..c9441f6a7a61aa 100644 --- a/Doc/whatsnew/3.7.rst +++ b/Doc/whatsnew/3.7.rst @@ -320,7 +320,8 @@ PEP 562: Customization of Access to Module Attributes ----------------------------------------------------- Python 3.7 allows defining :meth:`__getattr__` on modules and will call -it whenever a module attribute is otherwise not found. +it whenever a module attribute is otherwise not found. Defining +:meth:`__dir__` on modules is now also allowed. A typical example of where this may be useful is module attribute deprecation and lazy loading. @@ -336,8 +337,11 @@ and lazy loading. PEP 564: New Time Functions With Nanosecond Resolution ------------------------------------------------------ -:pep:`564` adds six new "nanosecond" variants of existing functions -to the :mod:`time` module: +The resolution of clocks in modern systems can exceed the limited precision +of a floating point number returned by the :func:`time.time` function +and its variants. To avoid loss of precision, :pep:`564` adds six new +"nanosecond" variants of the existing timer functions to the :mod:`time` +module: * :func:`time.clock_gettime_ns` * :func:`time.clock_settime_ns` @@ -346,12 +350,11 @@ to the :mod:`time` module: * :func:`time.process_time_ns` * :func:`time.time_ns` -The new functions are similar in function to the existing functions -without the ``_ns`` suffix. They differ by returning nanoseconds as -integers instead of fractional seconds. +The new functions return the number of nanoseconds as an integer value. -On Linux and Windows the resolution of :func:`time.time_ns` is 3 times -better than that of :func:`time.time`. +`Measurements <https://www.python.org/dev/peps/pep-0564/#annex-clocks-resolution-in-python>`_ +show that on Linux and Windows the resolution of :func:`time.time_ns` is +approximately 3 times better than that of :func:`time.time`. .. seealso:: @@ -417,12 +420,6 @@ fixed. :pep:`560` -- Core support for typing module and generic types PEP written and implemented by Ivan Levkivskyi - -.. _whatsnew37-devmode: - -Development Runtime Mode: -X dev --------------------------------- - The new :option:`-X` ``dev`` command line option or the new :envvar:`PYTHONDEVMODE` environment variable can be used to enable CPython's *development mode*. When in development mode, CPython performs @@ -430,7 +427,6 @@ additional runtime checks which are too expensive to be enabled by default. See :option:`-X` ``dev`` documentation for the full description of the effects of this mode. - .. _whatsnew37-pep552: PEP 552: Hash-based .pyc Files @@ -460,6 +456,45 @@ keeping ``.pyc`` files up-to-date. See :ref:`pyc-invalidation` for more information. +.. seealso:: + + :pep:`552` -- Deterministic pycs + PEP written and implemented by Benjamin Peterson + + +.. _whatsnew37-pep545: + +PEP 545: Python Documentation Translations +------------------------------------------ + +:pep:`545` describes the process of creating and maintaining Python +documentation translations. + +Three new translations have been added: + +- Japanese: https://docs.python.org/ja/ +- French: https://docs.python.org/fr/ +- Korean: https://docs.python.org/ko/ + +.. seealso:: + + :pep:`545` -- Python Documentation Translations + PEP written and implemented by Julien Palard, Inada Naoki, and + Victor Stinner. + + +.. _whatsnew37-devmode: + +Development Runtime Mode: -X dev +-------------------------------- + +The new :option:`-X` ``dev`` command line option or the new +:envvar:`PYTHONDEVMODE` environment variable can be used to enable +CPython's *development mode*. When in development mode, CPython performs +additional runtime checks that are too expensive to be enabled by default. +See :option:`-X` ``dev`` documentation for the full description of the effects +of this mode. + .. _whatsnew37-pep545: @@ -2262,7 +2297,7 @@ Changes in the Python API * Because :func:`shutil.rmtree` is now implemented using the :func:`os.scandir` function, the user specified handler *onerror* is now called with the first - argument ``os.scandir`` instead of ``os.listdir`` when listing the direcory + argument ``os.scandir`` instead of ``os.listdir`` when listing the directory is failed. * Support for nested sets and set operations in regular expressions as in diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst new file mode 100644 index 00000000000000..5fe1c7166fe6fb --- /dev/null +++ b/Doc/whatsnew/3.8.rst @@ -0,0 +1,223 @@ +**************************** + What's New In Python 3.8 +**************************** + +.. 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.8, compared to 3.7. + +For full details, see the :ref:`changelog <changelog>`. + +.. note:: + + Prerelease users should be aware that this document is currently in draft + form. It will be updated substantially as Python 3.8 moves towards release, + so it's worth checking back even after reading earlier versions. + + +Summary -- Release highlights +============================= + +.. This section singles out the most important changes in Python 3.8. + Brevity is key. + + +.. PEP-sized items next. + + + +New Features +============ + +Parallel filesystem cache for compiled bytecode files +----------------------------------------------------- + +The new :envvar:`PYTHONPYCACHEPREFIX` setting (also available as +:option:`-X` ``pycache_prefix``) configures the implicit bytecode +cache to use a separate parallel filesystem tree, rather than +the default ``__pycache__`` subdirectories within each source +directory. + +The location of the cache is reported in :data:`sys.pycache_prefix` +(:const:`None` indicates the default location in ``__pycache__`` +subdirectories). + +(Contributed by Carl Meyer in :issue:`33499`.) + + +Other Language Changes +====================== + +* A :keyword:`continue` statement was illegal in the :keyword:`finally` clause + due to a problem with the implementation. In Python 3.8 this restriction + was lifted. + (Contributed by Serhiy Storchaka in :issue:`32489`.) + +* Added support of ``\N{name}`` escapes in :mod:`regular expressions <re>`. + (Contributed by Jonathan Eunice and Serhiy Storchaka in :issue:`30688`.) + + +New Modules +=========== + +* None yet. + + +Improved Modules +================ + +Optimizations +============= + +* :func:`shutil.copyfile`, :func:`shutil.copy`, :func:`shutil.copy2`, + :func:`shutil.copytree` and :func:`shutil.move` use platform-specific + "fast-copy" syscalls on Linux, macOS and Solaris in order to copy the file + more efficiently. + "fast-copy" means that the copying operation occurs within the kernel, + avoiding the use of userspace buffers in Python as in + "``outfd.write(infd.read())``". + On Windows :func:`shutil.copyfile` uses a bigger default buffer size (1 MiB + instead of 16 KiB) and a :func:`memoryview`-based variant of + :func:`shutil.copyfileobj` is used. + The speedup for copying a 512 MiB file within the same partition is about + +26% on Linux, +50% on macOS and +40% on Windows. Also, much less CPU cycles + are consumed. + See :ref:`shutil-platform-dependent-efficient-copy-operations` section. + (Contributed by Giampaolo Rodola' in :issue:`25427`.) + +* The default protocol in the :mod:`pickle` module is now Protocol 4, + first introduced in Python 3.4. It offers better performance and smaller + size compared to Protocol 3 available since Python 3.0. + + +Build and C API Changes +======================= + +* The result of :c:func:`PyExceptionClass_Name` is now of type + ``const char *`` rather of ``char *``. + (Contributed by Serhiy Storchaka in :issue:`33818`.) + + +Deprecated +========== + + + +Removed +======= + +* The ``pyvenv`` script has been removed in favor of ``python3.8 -m venv`` + to help eliminate confusion as to what Python interpreter the ``pyvenv`` + script is tied to. (Contributed by Brett Cannon in :issue:`25427`.) + +* ``parse_qs``, ``parse_qsl``, and ``escape`` are removed from :mod:`cgi` + module. They are deprecated from Python 3.2 or older. + +* ``filemode`` function is removed from :mod:`tarfile` module. + It is not documented and deprecated since Python 3.3. + + +Porting to Python 3.8 +===================== + +This section lists previously described changes and other bugfixes +that may require changes to your code. + + +Changes in Python behavior +-------------------------- + +* Yield expressions (both ``yield`` and ``yield from`` clauses) are now disallowed + in comprehensions and generator expressions (aside from the iterable expression + in the leftmost :keyword:`for` clause). + (Contributed by Serhiy Storchaka in :issue:`10544`.) + + +Changes in the Python API +------------------------- + +* The :meth:`~tkinter.ttk.Treeview.selection` method of the + :class:`tkinter.ttk.Treeview` class no longer takes arguments. Using it with + arguments for changing the selection was deprecated in Python 3.6. Use + specialized methods like :meth:`~tkinter.ttk.Treeview.selection_set` for + changing the selection. (Contributed by Serhiy Storchaka in :issue:`31508`.) + +* A :mod:`dbm.dumb` database opened with flags ``'r'`` is now read-only. + :func:`dbm.dumb.open` with flags ``'r'`` and ``'w'`` no longer creates + a database if it does not exist. + (Contributed by Serhiy Storchaka in :issue:`32749`.) + +* A :exc:`RuntimeError` is now raised when the custom metaclass doesn't + provide the ``__classcell__`` entry in the namespace passed to + ``type.__new__``. A :exc:`DeprecationWarning` was emitted in Python + 3.6--3.7. (Contributed by Serhiy Storchaka in :issue:`23722`.) + +* The :class:`cProfile.Profile` class can now be used as a context + manager. (Contributed by Scott Sanderson in :issue:`29235`.) + +* :func:`shutil.copyfile`, :func:`shutil.copy`, :func:`shutil.copy2`, + :func:`shutil.copytree` and :func:`shutil.move` use platform-specific + "fast-copy" syscalls (see + :ref:`shutil-platform-dependent-efficient-copy-operations` section). + +* :func:`shutil.copyfile` default buffer size on Windows was changed from + 16 KiB to 1 MiB. + +CPython bytecode changes +------------------------ + +* The interpreter loop has been simplified by moving the logic of unrolling + the stack of blocks into the compiler. The compiler emits now explicit + instructions for adjusting the stack of values and calling the cleaning + up code for :keyword:`break`, :keyword:`continue` and :keyword:`return`. + + Removed opcodes :opcode:`BREAK_LOOP`, :opcode:`CONTINUE_LOOP`, + :opcode:`SETUP_LOOP` and :opcode:`SETUP_EXCEPT`. Added new opcodes + :opcode:`ROT_FOUR`, :opcode:`BEGIN_FINALLY`, :opcode:`CALL_FINALLY` and + :opcode:`POP_FINALLY`. Changed the behavior of :opcode:`END_FINALLY` + and :opcode:`WITH_CLEANUP_START`. + + (Contributed by Mark Shannon, Antoine Pitrou and Serhiy Storchaka in + :issue:`17611`.) + +* Added new opcode :opcode:`END_ASYNC_FOR` for handling exceptions raised + when awaiting a next item in an :keyword:`async for` loop. + (Contributed by Serhiy Storchaka in :issue:`33041`.) diff --git a/Doc/whatsnew/index.rst b/Doc/whatsnew/index.rst index 721dc03f42a5cc..b1160c03982152 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.8.rst 3.7.rst 3.6.rst 3.5.rst diff --git a/Include/abstract.h b/Include/abstract.h index 4088f75ff3c7ee..85550a34ca2686 100644 --- a/Include/abstract.h +++ b/Include/abstract.h @@ -590,9 +590,15 @@ PyAPI_FUNC(PyObject *) PyObject_Format(PyObject *obj, returns itself. */ PyAPI_FUNC(PyObject *) PyObject_GetIter(PyObject *); +/* Returns 1 if the object 'obj' provides iterator protocols, and 0 otherwise. + + This function always succeeds. */ +PyAPI_FUNC(int) PyIter_Check(PyObject *); +#ifndef Py_LIMITED_API #define PyIter_Check(obj) \ ((obj)->ob_type->tp_iternext != NULL && \ (obj)->ob_type->tp_iternext != &_PyObject_NextNotImplemented) +#endif /* Takes an iterator object and calls its tp_iternext slot, returning the next value. @@ -710,9 +716,14 @@ PyAPI_FUNC(PyObject *) PyNumber_Xor(PyObject *o1, PyObject *o2); This is the equivalent of the Python expression: o1 | o2. */ PyAPI_FUNC(PyObject *) PyNumber_Or(PyObject *o1, PyObject *o2); +/* Returns 1 if obj is an index integer (has the nb_index slot of the + tp_as_number structure filled in), and 0 otherwise. */ +PyAPI_FUNC(int) PyIndex_Check(PyObject *); +#ifndef Py_LIMITED_API #define PyIndex_Check(obj) \ ((obj)->ob_type->tp_as_number != NULL && \ (obj)->ob_type->tp_as_number->nb_index != NULL) +#endif /* Returns the object 'o' converted to a Python int, or NULL with an exception raised on failure. */ @@ -921,8 +932,10 @@ PyAPI_FUNC(PyObject *) PySequence_Fast(PyObject *o, const char* m); /* Assume tp_as_sequence and sq_item exist and that 'i' does not need to be corrected for a negative index. */ +#ifndef Py_LIMITED_API #define PySequence_ITEM(o, i)\ ( Py_TYPE(o)->tp_as_sequence->sq_item(o, i) ) +#endif /* Return a pointer to the underlying item array for an object retured by PySequence_Fast */ diff --git a/Include/ast.h b/Include/ast.h index 5bc2b05b3e945a..c824554cf49261 100644 --- a/Include/ast.h +++ b/Include/ast.h @@ -21,6 +21,11 @@ PyAPI_FUNC(mod_ty) PyAST_FromNodeObject( /* _PyAST_ExprAsUnicode is defined in ast_unparse.c */ PyAPI_FUNC(PyObject *) _PyAST_ExprAsUnicode(expr_ty); +/* Return the borrowed reference to the first literal string in the + sequence of statemnts or NULL if it doesn't start from a literal string. + Doesn't set exception. */ +PyAPI_FUNC(PyObject *) _PyAST_GetDocString(asdl_seq *); + #endif /* !Py_LIMITED_API */ #ifdef __cplusplus diff --git a/Include/import.h b/Include/import.h index 5ad4c31355cb82..b13a3b9ff8e7db 100644 --- a/Include/import.h +++ b/Include/import.h @@ -54,9 +54,6 @@ PyAPI_FUNC(PyObject *) PyImport_AddModuleObject( PyObject *name ); #endif -#ifndef Py_LIMITED_API -PyAPI_FUNC(PyObject *) _PyImport_AddModuleObject(PyObject *, PyObject *); -#endif PyAPI_FUNC(PyObject *) PyImport_AddModule( const char *name /* UTF-8 encoded string */ ); diff --git a/Include/internal/pystate.h b/Include/internal/pystate.h index 9db4587e5c2ef6..e1d4edf5c79d73 100644 --- a/Include/internal/pystate.h +++ b/Include/internal/pystate.h @@ -73,6 +73,76 @@ PyAPI_FUNC(int) _PyInterpreterState_IDInitref(PyInterpreterState *); PyAPI_FUNC(void) _PyInterpreterState_IDIncref(PyInterpreterState *); PyAPI_FUNC(void) _PyInterpreterState_IDDecref(PyInterpreterState *); + +/* cross-interpreter data */ + +struct _xid; + +// _PyCrossInterpreterData is similar to Py_buffer as an effectively +// opaque struct that holds data outside the object machinery. This +// is necessary to pass safely between interpreters in the same process. +typedef struct _xid { + // data is the cross-interpreter-safe derivation of a Python object + // (see _PyObject_GetCrossInterpreterData). It will be NULL if the + // new_object func (below) encodes the data. + void *data; + // obj is the Python object from which the data was derived. This + // is non-NULL only if the data remains bound to the object in some + // way, such that the object must be "released" (via a decref) when + // the data is released. In that case the code that sets the field, + // likely a registered "crossinterpdatafunc", is responsible for + // ensuring it owns the reference (i.e. incref). + PyObject *obj; + // interp is the ID of the owning interpreter of the original + // object. It corresponds to the active interpreter when + // _PyObject_GetCrossInterpreterData() was called. This should only + // be set by the cross-interpreter machinery. + // + // We use the ID rather than the PyInterpreterState to avoid issues + // with deleted interpreters. + int64_t interp; + // new_object is a function that returns a new object in the current + // interpreter given the data. The resulting object (a new + // reference) will be equivalent to the original object. This field + // is required. + PyObject *(*new_object)(struct _xid *); + // free is called when the data is released. If it is NULL then + // nothing will be done to free the data. For some types this is + // okay (e.g. bytes) and for those types this field should be set + // to NULL. However, for most the data was allocated just for + // cross-interpreter use, so it must be freed when + // _PyCrossInterpreterData_Release is called or the memory will + // leak. In that case, at the very least this field should be set + // to PyMem_RawFree (the default if not explicitly set to NULL). + // The call will happen with the original interpreter activated. + void (*free)(void *); +} _PyCrossInterpreterData; + +typedef int (*crossinterpdatafunc)(PyObject *, _PyCrossInterpreterData *); +PyAPI_FUNC(int) _PyObject_CheckCrossInterpreterData(PyObject *); + +PyAPI_FUNC(int) _PyObject_GetCrossInterpreterData(PyObject *, _PyCrossInterpreterData *); +PyAPI_FUNC(PyObject *) _PyCrossInterpreterData_NewObject(_PyCrossInterpreterData *); +PyAPI_FUNC(void) _PyCrossInterpreterData_Release(_PyCrossInterpreterData *); + +/* cross-interpreter data registry */ + +/* For now we use a global registry of shareable classes. An + alternative would be to add a tp_* slot for a class's + crossinterpdatafunc. It would be simpler and more efficient. */ + +PyAPI_FUNC(int) _PyCrossInterpreterData_Register_Class(PyTypeObject *, crossinterpdatafunc); +PyAPI_FUNC(crossinterpdatafunc) _PyCrossInterpreterData_Lookup(PyObject *); + +struct _xidregitem; + +struct _xidregitem { + PyTypeObject *cls; + crossinterpdatafunc getdata; + struct _xidregitem *next; +}; + + /* Full Python runtime state */ typedef struct pyruntimestate { diff --git a/Include/objimpl.h b/Include/objimpl.h index 057bb50cbda9e2..a38906c7dc8b33 100644 --- a/Include/objimpl.h +++ b/Include/objimpl.h @@ -240,8 +240,10 @@ PyAPI_FUNC(Py_ssize_t) _PyGC_CollectIfEnabled(void); #define PyType_IS_GC(t) PyType_HasFeature((t), Py_TPFLAGS_HAVE_GC) /* Test if an object has a GC head */ +#ifndef Py_LIMITED_API #define PyObject_IS_GC(o) (PyType_IS_GC(Py_TYPE(o)) && \ (Py_TYPE(o)->tp_is_gc == NULL || Py_TYPE(o)->tp_is_gc(o))) +#endif PyAPI_FUNC(PyVarObject *) _PyObject_GC_Resize(PyVarObject *, Py_ssize_t); #define PyObject_GC_Resize(type, op, n) \ @@ -359,10 +361,12 @@ PyAPI_FUNC(void) PyObject_GC_Del(void *); /* Test if a type supports weak references */ +#ifndef Py_LIMITED_API #define PyType_SUPPORTS_WEAKREFS(t) ((t)->tp_weaklistoffset > 0) #define PyObject_GET_WEAKREFS_LISTPTR(o) \ ((PyObject **) (((char *) (o)) + Py_TYPE(o)->tp_weaklistoffset)) +#endif #ifdef __cplusplus } diff --git a/Include/opcode.h b/Include/opcode.h index fc6cbf3a7af483..e564bb9d598dbc 100644 --- a/Include/opcode.h +++ b/Include/opcode.h @@ -12,6 +12,7 @@ extern "C" { #define ROT_THREE 3 #define DUP_TOP 4 #define DUP_TOP_TWO 5 +#define ROT_FOUR 6 #define NOP 9 #define UNARY_POSITIVE 10 #define UNARY_NEGATIVE 11 @@ -32,6 +33,8 @@ extern "C" { #define GET_AITER 50 #define GET_ANEXT 51 #define BEFORE_ASYNC_WITH 52 +#define BEGIN_FINALLY 53 +#define END_ASYNC_FOR 54 #define INPLACE_ADD 55 #define INPLACE_SUBTRACT 56 #define INPLACE_MULTIPLY 57 @@ -55,7 +58,6 @@ extern "C" { #define INPLACE_AND 77 #define INPLACE_XOR 78 #define INPLACE_OR 79 -#define BREAK_LOOP 80 #define WITH_CLEANUP_START 81 #define WITH_CLEANUP_FINISH 82 #define RETURN_VALUE 83 @@ -92,9 +94,6 @@ extern "C" { #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 @@ -127,6 +126,8 @@ extern "C" { #define BUILD_TUPLE_UNPACK_WITH_CALL 158 #define LOAD_METHOD 160 #define CALL_METHOD 161 +#define CALL_FINALLY 162 +#define POP_FINALLY 163 /* 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 diff --git a/Include/patchlevel.h b/Include/patchlevel.h index 13876bdcb639cd..68c29f58ab418d 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 7 +#define PY_MINOR_VERSION 8 #define PY_MICRO_VERSION 0 -#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL +#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_ALPHA #define PY_RELEASE_SERIAL 0 /* Version as a string */ -#define PY_VERSION "3.7.0" +#define PY_VERSION "3.8.0a0" /*--end constants--*/ /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. diff --git a/Include/py_curses.h b/Include/py_curses.h index 0eebc362a15e16..2702b37ea7cfe9 100644 --- a/Include/py_curses.h +++ b/Include/py_curses.h @@ -91,65 +91,6 @@ static void **PyCurses_API; static const char catchall_ERR[] = "curses function returned ERR"; static const char catchall_NULL[] = "curses function returned NULL"; -/* Function Prototype Macros - They are ugly but very, very useful. ;-) - - X - function name - TYPE - parameter Type - ERGSTR - format string for construction of the return value - PARSESTR - format string for argument parsing - */ - -#define NoArgNoReturnFunction(X) \ -static PyObject *PyCurses_ ## X (PyObject *self) \ -{ \ - PyCursesInitialised \ - return PyCursesCheckERR(X(), # X); } - -#define NoArgOrFlagNoReturnFunction(X) \ -static PyObject *PyCurses_ ## X (PyObject *self, PyObject *args) \ -{ \ - int flag = 0; \ - PyCursesInitialised \ - switch(PyTuple_Size(args)) { \ - case 0: \ - return PyCursesCheckERR(X(), # X); \ - case 1: \ - if (!PyArg_ParseTuple(args, "i;True(1) or False(0)", &flag)) return NULL; \ - if (flag) return PyCursesCheckERR(X(), # X); \ - else return PyCursesCheckERR(no ## X (), # X); \ - default: \ - PyErr_SetString(PyExc_TypeError, # X " requires 0 or 1 arguments"); \ - return NULL; } } - -#define NoArgReturnIntFunction(X) \ -static PyObject *PyCurses_ ## X (PyObject *self) \ -{ \ - PyCursesInitialised \ - return PyLong_FromLong((long) X()); } - - -#define NoArgReturnStringFunction(X) \ -static PyObject *PyCurses_ ## X (PyObject *self) \ -{ \ - PyCursesInitialised \ - return PyBytes_FromString(X()); } - -#define NoArgTrueFalseFunction(X) \ -static PyObject *PyCurses_ ## X (PyObject *self) \ -{ \ - PyCursesInitialised \ - if (X () == FALSE) { \ - Py_RETURN_FALSE; \ - } \ - Py_RETURN_TRUE; } - -#define NoArgNoReturnVoidFunction(X) \ -static PyObject *PyCurses_ ## X (PyObject *self) \ -{ \ - PyCursesInitialised \ - X(); \ - Py_RETURN_NONE; } - #ifdef __cplusplus } #endif diff --git a/Include/pyerrors.h b/Include/pyerrors.h index f289471be20ccf..416d750d9b1f0f 100644 --- a/Include/pyerrors.h +++ b/Include/pyerrors.h @@ -140,8 +140,10 @@ PyAPI_FUNC(void) _PyErr_ChainExceptions(PyObject *, PyObject *, PyObject *); #define PyExceptionInstance_Check(x) \ PyType_FastSubclass((x)->ob_type, Py_TPFLAGS_BASE_EXC_SUBCLASS) -#define PyExceptionClass_Name(x) \ - ((char *)(((PyTypeObject*)(x))->tp_name)) +PyAPI_FUNC(const char *) PyExceptionClass_Name(PyObject *); +#ifndef Py_LIMITED_API +#define PyExceptionClass_Name(x) (((PyTypeObject*)(x))->tp_name) +#endif #define PyExceptionInstance_Class(x) ((PyObject*)((x)->ob_type)) diff --git a/Include/pylifecycle.h b/Include/pylifecycle.h index 659c6df644e34f..95dd55b0517370 100644 --- a/Include/pylifecycle.h +++ b/Include/pylifecycle.h @@ -148,7 +148,6 @@ PyAPI_FUNC(int) _PySys_EndInit(PyObject *sysdict, _PyMainInterpreterConfig *conf PyAPI_FUNC(_PyInitError) _PyImport_Init(PyInterpreterState *interp); PyAPI_FUNC(void) _PyExc_Init(PyObject * bltinmod); PyAPI_FUNC(_PyInitError) _PyImportHooks_Init(void); -PyAPI_FUNC(int) _PyFrame_Init(void); PyAPI_FUNC(int) _PyFloat_Init(void); PyAPI_FUNC(int) PyByteArray_Init(void); PyAPI_FUNC(_PyInitError) _Py_HashRandomization_Init(const _PyCoreConfig *); diff --git a/Include/pystate.h b/Include/pystate.h index 29d7148bf9a3e9..8158cabc7171f3 100644 --- a/Include/pystate.h +++ b/Include/pystate.h @@ -1,4 +1,3 @@ - /* Thread and interpreter state structures and their interfaces */ @@ -44,6 +43,7 @@ typedef struct { int coerce_c_locale; /* PYTHONCOERCECLOCALE, -1 means unknown */ int coerce_c_locale_warn; /* PYTHONCOERCECLOCALE=warn */ int utf8_mode; /* PYTHONUTF8, -X utf8; -1 means unknown */ + wchar_t *pycache_prefix; /* PYTHONPYCACHEPREFIX, -X pycache_prefix=PATH */ wchar_t *program_name; /* Program name, see also Py_GetProgramName() */ int argc; /* Number of command line arguments, @@ -101,6 +101,7 @@ typedef struct { PyObject *warnoptions; /* sys.warnoptions list, can be NULL */ PyObject *xoptions; /* sys._xoptions dict, can be NULL */ PyObject *module_search_path; /* sys.path list */ + PyObject *pycache_prefix; /* sys.pycache_prefix str, can be NULL */ } _PyMainInterpreterConfig; #define _PyMainInterpreterConfig_INIT \ diff --git a/Lib/_pyio.py b/Lib/_pyio.py index c91a647a2f67b0..f0d4f4ed27a243 100644 --- a/Lib/_pyio.py +++ b/Lib/_pyio.py @@ -2149,6 +2149,7 @@ def write(self, s): self.buffer.write(b) if self._line_buffering and (haslf or "\r" in s): self.flush() + self._set_decoded_chars('') self._snapshot = None if self._decoder: self._decoder.reset() diff --git a/Lib/_strptime.py b/Lib/_strptime.py index c8f2f94e5500cf..f4f3c0b80c1d05 100644 --- a/Lib/_strptime.py +++ b/Lib/_strptime.py @@ -77,15 +77,6 @@ def __init__(self): if time.tzname != self.tzname or time.daylight != self.daylight: raise ValueError("timezone changed during initialization") - def __pad(self, seq, front): - # Add '' to seq to either the front (is True), else the back. - seq = list(seq) - if front: - seq.insert(0, '') - else: - seq.append('') - return seq - def __calc_weekday(self): # Set self.a_weekday and self.f_weekday using the calendar # module. diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index 6b4756ad088220..dc0ca3f02b9bf6 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -61,6 +61,8 @@ _FATAL_ERROR_IGNORE = (BrokenPipeError, ConnectionResetError, ConnectionAbortedError) +_HAS_IPv6 = hasattr(socket, 'AF_INET6') + def _format_handle(handle): cb = handle._callback @@ -123,7 +125,7 @@ def _ipaddr_info(host, port, family, type, proto): if family == socket.AF_UNSPEC: afs = [socket.AF_INET] - if hasattr(socket, 'AF_INET6'): + if _HAS_IPv6: afs.append(socket.AF_INET6) else: afs = [family] @@ -139,7 +141,10 @@ def _ipaddr_info(host, port, family, type, proto): try: socket.inet_pton(af, host) # The host has already been resolved. - return af, type, proto, '', (host, port) + if _HAS_IPv6 and af == socket.AF_INET6: + return af, type, proto, '', (host, port, 0, 0) + else: + return af, type, proto, '', (host, port) except OSError: pass @@ -1309,7 +1314,6 @@ async def create_server( raise ValueError( 'host/port and sock can not be specified at the same time') - AF_INET6 = getattr(socket, 'AF_INET6', 0) if reuse_address is None: reuse_address = os.name == 'posix' and sys.platform != 'cygwin' sockets = [] @@ -1349,7 +1353,9 @@ async def create_server( # Disable IPv4/IPv6 dual stack support (enabled by # default on Linux) which makes a single socket # listen on both address families. - if af == AF_INET6 and hasattr(socket, 'IPPROTO_IPV6'): + if (_HAS_IPv6 and + af == socket.AF_INET6 and + hasattr(socket, 'IPPROTO_IPV6')): sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, True) diff --git a/Lib/asyncio/base_futures.py b/Lib/asyncio/base_futures.py index 5182884e16d64b..bd65beec553cbc 100644 --- a/Lib/asyncio/base_futures.py +++ b/Lib/asyncio/base_futures.py @@ -1,17 +1,13 @@ __all__ = () -import concurrent.futures._base +import concurrent.futures import reprlib from . import format_helpers -Error = concurrent.futures._base.Error CancelledError = concurrent.futures.CancelledError TimeoutError = concurrent.futures.TimeoutError - - -class InvalidStateError(Error): - """The operation is not allowed in this state.""" +InvalidStateError = concurrent.futures.InvalidStateError # States for Future. diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py index 639300f976ab8d..7cad7e3637a11f 100644 --- a/Lib/asyncio/unix_events.py +++ b/Lib/asyncio/unix_events.py @@ -168,8 +168,8 @@ def _check_signal(self, sig): if not isinstance(sig, int): raise TypeError(f'sig must be an int, not {sig!r}') - if not (1 <= sig < signal.NSIG): - raise ValueError(f'sig {sig} out of range(1, {signal.NSIG})') + if sig not in signal.valid_signals(): + raise ValueError(f'invalid signal number {sig}') def _make_read_pipe_transport(self, pipe, protocol, waiter=None, extra=None): diff --git a/Lib/cProfile.py b/Lib/cProfile.py index f166a1c4375207..c8045043cbcfe4 100755 --- a/Lib/cProfile.py +++ b/Lib/cProfile.py @@ -110,6 +110,13 @@ def runcall(self, func, *args, **kw): finally: self.disable() + def __enter__(self): + self.enable() + return self + + def __exit__(self, *exc_info): + self.disable() + # ____________________________________________________________ def label(code): diff --git a/Lib/cgi.py b/Lib/cgi.py index f82cc6c8bd56d3..b655a057d4be48 100755 --- a/Lib/cgi.py +++ b/Lib/cgi.py @@ -38,16 +38,14 @@ import urllib.parse from email.parser import FeedParser from email.message import Message -from warnings import warn import html import locale import tempfile -__all__ = ["MiniFieldStorage", "FieldStorage", - "parse", "parse_qs", "parse_qsl", "parse_multipart", +__all__ = ["MiniFieldStorage", "FieldStorage", "parse", "parse_multipart", "parse_header", "test", "print_exception", "print_environ", "print_form", "print_directory", "print_arguments", - "print_environ_usage", "escape"] + "print_environ_usage"] # Logging support # =============== @@ -183,21 +181,6 @@ def parse(fp=None, environ=os.environ, keep_blank_values=0, strict_parsing=0): encoding=encoding) -# parse query string function called from urlparse, -# this is done in order to maintain backward compatibility. - -def parse_qs(qs, keep_blank_values=0, strict_parsing=0): - """Parse a query given as a string argument.""" - warn("cgi.parse_qs is deprecated, use urllib.parse.parse_qs instead", - DeprecationWarning, 2) - return urllib.parse.parse_qs(qs, keep_blank_values, strict_parsing) - -def parse_qsl(qs, keep_blank_values=0, strict_parsing=0): - """Parse a query given as a string argument.""" - warn("cgi.parse_qsl is deprecated, use urllib.parse.parse_qsl instead", - DeprecationWarning, 2) - return urllib.parse.parse_qsl(qs, keep_blank_values, strict_parsing) - def parse_multipart(fp, pdict, encoding="utf-8", errors="replace"): """Parse multipart input. @@ -974,18 +957,6 @@ def print_environ_usage(): # Utilities # ========= -def escape(s, quote=None): - """Deprecated API.""" - warn("cgi.escape is deprecated, use html.escape instead", - DeprecationWarning, stacklevel=2) - s = s.replace("&", "&") # Must be done first! - s = s.replace("<", "<") - s = s.replace(">", ">") - if quote: - s = s.replace('"', """) - return s - - def valid_boundary(s): import re if isinstance(s, bytes): diff --git a/Lib/cgitb.py b/Lib/cgitb.py index 0f5f32c0fadee1..4f81271be3ca78 100644 --- a/Lib/cgitb.py +++ b/Lib/cgitb.py @@ -124,8 +124,9 @@ def html(einfo, context=5): args, varargs, varkw, locals = inspect.getargvalues(frame) call = '' if func != '?': - call = 'in ' + strong(pydoc.html.escape(func)) + \ - inspect.formatargvalues(args, varargs, varkw, locals, + call = 'in ' + strong(pydoc.html.escape(func)) + if func != "<module>": + call += inspect.formatargvalues(args, varargs, varkw, locals, formatvalue=lambda value: '=' + pydoc.html.repr(value)) highlight = {} @@ -207,8 +208,9 @@ def text(einfo, context=5): args, varargs, varkw, locals = inspect.getargvalues(frame) call = '' if func != '?': - call = 'in ' + func + \ - inspect.formatargvalues(args, varargs, varkw, locals, + call = 'in ' + func + if func != "<module>": + call += inspect.formatargvalues(args, varargs, varkw, locals, formatvalue=lambda value: '=' + pydoc.text.repr(value)) highlight = {} diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py index 9a753db71caeae..4724b0edf33a7c 100644 --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -609,8 +609,13 @@ def elements(self): @classmethod def fromkeys(cls, iterable, v=None): - # There is no equivalent method for counters because setting v=1 - # means that no element can have a count greater than one. + # There is no equivalent method for counters because the semantics + # would be ambiguous in cases such as Counter.fromkeys('aaabbc', v=2). + # Initializing counters to zero values isn't necessary because zero + # is already the default value for counter lookups. Initializing + # to one is easily accomplished with Counter(set(iterable)). For + # more exotic cases, create a dictionary first using a dictionary + # comprehension or dict.fromkeys(). raise NotImplementedError( 'Counter.fromkeys() is undefined. Use Counter(iterable) instead.') @@ -933,8 +938,7 @@ def __bool__(self): @_recursive_repr() def __repr__(self): - return '{0.__class__.__name__}({1})'.format( - self, ', '.join(map(repr, self.maps))) + return f'{self.__class__.__name__}({", ".join(map(repr, self.maps))})' @classmethod def fromkeys(cls, iterable, *args): diff --git a/Lib/concurrent/futures/__init__.py b/Lib/concurrent/futures/__init__.py index 8434fcf4b5ead4..d746aeac50a997 100644 --- a/Lib/concurrent/futures/__init__.py +++ b/Lib/concurrent/futures/__init__.py @@ -10,6 +10,7 @@ ALL_COMPLETED, CancelledError, TimeoutError, + InvalidStateError, BrokenExecutor, Future, Executor, diff --git a/Lib/concurrent/futures/_base.py b/Lib/concurrent/futures/_base.py index 4f22f7ee0e6d0a..d4416c62450e81 100644 --- a/Lib/concurrent/futures/_base.py +++ b/Lib/concurrent/futures/_base.py @@ -53,6 +53,10 @@ class TimeoutError(Error): """The operation exceeded the given deadline.""" pass +class InvalidStateError(Error): + """The operation is not allowed in this state.""" + pass + class _Waiter(object): """Provides the event that wait() and as_completed() block on.""" def __init__(self): @@ -513,6 +517,8 @@ def set_result(self, result): Should only be used by Executor implementations and unit tests. """ with self._condition: + if self._state in {CANCELLED, CANCELLED_AND_NOTIFIED, FINISHED}: + raise InvalidStateError('{}: {!r}'.format(self._state, self)) self._result = result self._state = FINISHED for waiter in self._waiters: @@ -526,6 +532,8 @@ def set_exception(self, exception): Should only be used by Executor implementations and unit tests. """ with self._condition: + if self._state in {CANCELLED, CANCELLED_AND_NOTIFIED, FINISHED}: + raise InvalidStateError('{}: {!r}'.format(self._state, self)) self._exception = exception self._state = FINISHED for waiter in self._waiters: diff --git a/Lib/configparser.py b/Lib/configparser.py index 445fa99ccb4b3b..4a16101c7a3ab6 100644 --- a/Lib/configparser.py +++ b/Lib/configparser.py @@ -139,7 +139,7 @@ """ from collections.abc import MutableMapping -from collections import OrderedDict as _default_dict, ChainMap as _ChainMap +from collections import ChainMap as _ChainMap import functools import io import itertools @@ -157,6 +157,7 @@ "LegacyInterpolation", "SectionProxy", "ConverterMapping", "DEFAULTSECT", "MAX_INTERPOLATION_DEPTH"] +_default_dict = dict DEFAULTSECT = "DEFAULT" MAX_INTERPOLATION_DEPTH = 10 @@ -846,6 +847,7 @@ def items(self, section=_UNSET, raw=False, vars=None): except KeyError: if section != self.default_section: raise NoSectionError(section) + orig_keys = list(d.keys()) # Update with the entry specific variables if vars: for key, value in vars.items(): @@ -854,7 +856,7 @@ def items(self, section=_UNSET, raw=False, vars=None): section, option, d[option], d) if raw: value_getter = lambda option: d[option] - return [(option, value_getter(option)) for option in d.keys()] + return [(option, value_getter(option)) for option in orig_keys] def popitem(self): """Remove a section from the parser and return it as @@ -961,7 +963,8 @@ def __getitem__(self, key): def __setitem__(self, key, value): # To conform with the mapping protocol, overwrites existing values in # the section. - + if key in self and self[key] is value: + return # XXX this is not atomic if read_dict fails at any point. Then again, # no update method in configparser is atomic in this implementation. if key == self.default_section: diff --git a/Lib/contextlib.py b/Lib/contextlib.py index 1ff8cdf1cecf8f..c06ec73f489d06 100644 --- a/Lib/contextlib.py +++ b/Lib/contextlib.py @@ -4,6 +4,7 @@ import _collections_abc from collections import deque from functools import wraps +from types import MethodType __all__ = ["asynccontextmanager", "contextmanager", "closing", "nullcontext", "AbstractContextManager", "AbstractAsyncContextManager", @@ -186,7 +187,7 @@ async def __aexit__(self, typ, value, traceback): # in this implementation try: await self.gen.athrow(typ, value, traceback) - raise RuntimeError("generator didn't stop after throw()") + raise RuntimeError("generator didn't stop after athrow()") except StopAsyncIteration as exc: return exc is not value except RuntimeError as exc: @@ -373,9 +374,7 @@ class _BaseExitStack: @staticmethod def _create_exit_wrapper(cm, cm_exit): - def _exit_wrapper(exc_type, exc, tb): - return cm_exit(cm, exc_type, exc, tb) - return _exit_wrapper + return MethodType(cm_exit, cm) @staticmethod def _create_cb_wrapper(callback, *args, **kwds): @@ -443,7 +442,6 @@ def callback(self, callback, *args, **kwds): def _push_cm_exit(self, cm, cm_exit): """Helper to correctly register callbacks to __exit__ methods.""" _exit_wrapper = self._create_exit_wrapper(cm, cm_exit) - _exit_wrapper.__self__ = cm self._push_exit_callback(_exit_wrapper, True) def _push_exit_callback(self, callback, is_sync=True): @@ -535,9 +533,7 @@ class AsyncExitStack(_BaseExitStack, AbstractAsyncContextManager): @staticmethod def _create_async_exit_wrapper(cm, cm_exit): - async def _exit_wrapper(exc_type, exc, tb): - return await cm_exit(cm, exc_type, exc, tb) - return _exit_wrapper + return MethodType(cm_exit, cm) @staticmethod def _create_async_cb_wrapper(callback, *args, **kwds): @@ -596,7 +592,6 @@ def _push_async_cm_exit(self, cm, cm_exit): """Helper to correctly register coroutine function to __aexit__ method.""" _exit_wrapper = self._create_async_exit_wrapper(cm, cm_exit) - _exit_wrapper.__self__ = cm self._push_exit_callback(_exit_wrapper, False) async def __aenter__(self): diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py index 96bf6e1df47a0d..e00a125bbd8711 100644 --- a/Lib/dataclasses.py +++ b/Lib/dataclasses.py @@ -257,7 +257,7 @@ def __repr__(self): # This is used to support the PEP 487 __set_name__ protocol in the # case where we're using a field that contains a descriptor as a - # defaul value. For details on __set_name__, see + # default value. For details on __set_name__, see # https://www.python.org/dev/peps/pep-0487/#implementation-details. # # Note that in _process_class, this Field object is overwritten @@ -1173,6 +1173,9 @@ class C: continue if f.name not in changes: + if f._field_type is _FIELD_INITVAR: + raise ValueError(f"InitVar {f.name!r} " + 'must be specified with replace()') changes[f.name] = getattr(obj, f.name) # Create the new object, which calls __init__() and diff --git a/Lib/datetime.py b/Lib/datetime.py index dd6eca907dd440..5e922c80b017ff 100644 --- a/Lib/datetime.py +++ b/Lib/datetime.py @@ -1759,17 +1759,10 @@ def _local_timezone(self): ts = (self - _EPOCH) // timedelta(seconds=1) localtm = _time.localtime(ts) local = datetime(*localtm[:6]) - try: - # Extract TZ data if available - gmtoff = localtm.tm_gmtoff - zone = localtm.tm_zone - except AttributeError: - delta = local - datetime(*_time.gmtime(ts)[:6]) - zone = _time.strftime('%Z', localtm) - tz = timezone(delta, zone) - else: - tz = timezone(timedelta(seconds=gmtoff), zone) - return tz + # Extract TZ data + gmtoff = localtm.tm_gmtoff + zone = localtm.tm_zone + return timezone(timedelta(seconds=gmtoff), zone) def astimezone(self, tz=None): if tz is None: diff --git a/Lib/dbm/dumb.py b/Lib/dbm/dumb.py index 5064668c77ea74..e5c17f5ae2eddb 100644 --- a/Lib/dbm/dumb.py +++ b/Lib/dbm/dumb.py @@ -82,10 +82,7 @@ def _create(self, flag): f = _io.open(self._datfile, 'r', encoding="Latin-1") except OSError: if flag not in ('c', 'n'): - import warnings - warnings.warn("The database file is missing, the " - "semantics of the 'c' flag will be used.", - DeprecationWarning, stacklevel=4) + raise with _io.open(self._datfile, 'w', encoding="Latin-1") as f: self._chmod(self._datfile) else: @@ -93,18 +90,15 @@ def _create(self, flag): # Read directory file into the in-memory index dict. def _update(self, flag): + self._modified = False self._index = {} try: f = _io.open(self._dirfile, 'r', encoding="Latin-1") except OSError: - self._modified = not self._readonly if flag not in ('c', 'n'): - import warnings - warnings.warn("The index file is missing, the " - "semantics of the 'c' flag will be used.", - DeprecationWarning, stacklevel=4) + raise + self._modified = True else: - self._modified = False with f: for line in f: line = line.rstrip() @@ -191,9 +185,7 @@ def _addkey(self, key, pos_and_siz_pair): def __setitem__(self, key, val): if self._readonly: - import warnings - warnings.warn('The database is opened for reading only', - DeprecationWarning, stacklevel=2) + raise ValueError('The database is opened for reading only') if isinstance(key, str): key = key.encode('utf-8') elif not isinstance(key, (bytes, bytearray)): @@ -230,9 +222,7 @@ def __setitem__(self, key, val): def __delitem__(self, key): if self._readonly: - import warnings - warnings.warn('The database is opened for reading only', - DeprecationWarning, stacklevel=2) + raise ValueError('The database is opened for reading only') if isinstance(key, str): key = key.encode('utf-8') self._verify_open() @@ -323,7 +313,5 @@ def open(file, flag='c', mode=0o666): # Turn off any bits that are set in the umask mode = mode & (~um) if flag not in ('r', 'w', 'c', 'n'): - import warnings - warnings.warn("Flag must be one of 'r', 'w', 'c', or 'n'", - DeprecationWarning, stacklevel=2) + raise ValueError("Flag must be one of 'r', 'w', 'c', or 'n'") return _Database(file, mode, flag=flag) diff --git a/Lib/dis.py b/Lib/dis.py index 90ddf4f3360324..b2b0003203a44f 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -17,6 +17,15 @@ classmethod, staticmethod, type) FORMAT_VALUE = opmap['FORMAT_VALUE'] +FORMAT_VALUE_CONVERTERS = ( + (None, ''), + (str, 'str'), + (repr, 'repr'), + (ascii, 'ascii'), +) +MAKE_FUNCTION = opmap['MAKE_FUNCTION'] +MAKE_FUNCTION_FLAGS = ('defaults', 'kwdefaults', 'annotations', 'closure') + def _try_compile(source, name): """Attempts to compile the given source, first as an expression and @@ -339,12 +348,15 @@ def _get_instructions_bytes(code, varnames=None, names=None, constants=None, elif op in hasfree: argval, argrepr = _get_name_info(arg, cells) elif op == FORMAT_VALUE: - argval = ((None, str, repr, ascii)[arg & 0x3], bool(arg & 0x4)) - argrepr = ('', 'str', 'repr', 'ascii')[arg & 0x3] + argval, argrepr = FORMAT_VALUE_CONVERTERS[arg & 0x3] + argval = (argval, bool(arg & 0x4)) if argval[1]: if argrepr: argrepr += ', ' argrepr += 'with format' + elif op == MAKE_FUNCTION: + argrepr = ', '.join(s for i, s in enumerate(MAKE_FUNCTION_FLAGS) + if arg & (1<<i)) yield Instruction(opname[op], op, arg, argval, argrepr, offset, starts_line, is_jump_target) diff --git a/Lib/email/_encoded_words.py b/Lib/email/_encoded_words.py index c40ffa917b56c2..295ae7eb21237c 100644 --- a/Lib/email/_encoded_words.py +++ b/Lib/email/_encoded_words.py @@ -98,30 +98,42 @@ def len_q(bstring): # def decode_b(encoded): - defects = [] + # First try encoding with validate=True, fixing the padding if needed. + # This will succeed only if encoded includes no invalid characters. pad_err = len(encoded) % 4 - if pad_err: - defects.append(errors.InvalidBase64PaddingDefect()) - padded_encoded = encoded + b'==='[:4-pad_err] - else: - padded_encoded = encoded + missing_padding = b'==='[:4-pad_err] if pad_err else b'' try: - return base64.b64decode(padded_encoded, validate=True), defects + return ( + base64.b64decode(encoded + missing_padding, validate=True), + [errors.InvalidBase64PaddingDefect()] if pad_err else [], + ) except binascii.Error: - # Since we had correct padding, this must an invalid char error. - defects = [errors.InvalidBase64CharactersDefect()] + # Since we had correct padding, this is likely an invalid char error. + # # The non-alphabet characters are ignored as far as padding - # goes, but we don't know how many there are. So we'll just - # try various padding lengths until something works. - for i in 0, 1, 2, 3: + # goes, but we don't know how many there are. So try without adding + # padding to see if it works. + try: + return ( + base64.b64decode(encoded, validate=False), + [errors.InvalidBase64CharactersDefect()], + ) + except binascii.Error: + # Add as much padding as could possibly be necessary (extra padding + # is ignored). try: - return base64.b64decode(encoded+b'='*i, validate=False), defects + return ( + base64.b64decode(encoded + b'==', validate=False), + [errors.InvalidBase64CharactersDefect(), + errors.InvalidBase64PaddingDefect()], + ) except binascii.Error: - if i==0: - defects.append(errors.InvalidBase64PaddingDefect()) - else: - # This should never happen. - raise AssertionError("unexpected binascii.Error") + # This only happens when the encoded string's length is 1 more + # than a multiple of 4, which is invalid. + # + # bpo-27397: Just return the encoded string since there's no + # way to decode. + return encoded, [errors.InvalidBase64LengthDefect()] def encode_b(bstring): return base64.b64encode(bstring).decode('ascii') diff --git a/Lib/email/errors.py b/Lib/email/errors.py index 791239fa6a54cc..d28a6800104bab 100644 --- a/Lib/email/errors.py +++ b/Lib/email/errors.py @@ -73,6 +73,9 @@ class InvalidBase64PaddingDefect(MessageDefect): class InvalidBase64CharactersDefect(MessageDefect): """base64 encoded sequence had characters not in base64 alphabet""" +class InvalidBase64LengthDefect(MessageDefect): + """base64 encoded sequence had invalid length (1 mod 4)""" + # These errors are specific to header parsing. class HeaderDefect(MessageDefect): diff --git a/Lib/enum.py b/Lib/enum.py index 576de031805dbc..ec6eab273eca15 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -1,12 +1,6 @@ import sys from types import MappingProxyType, DynamicClassAttribute -# try _collections first to reduce startup cost -try: - from _collections import OrderedDict -except ImportError: - from collections import OrderedDict - __all__ = [ 'EnumMeta', @@ -168,7 +162,7 @@ def __new__(metacls, cls, bases, classdict): # create our new Enum type enum_class = super().__new__(metacls, cls, bases, classdict) enum_class._member_names_ = [] # names in definition order - enum_class._member_map_ = OrderedDict() # name->value map + enum_class._member_map_ = {} # name->value map enum_class._member_type_ = member_type # save attributes from super classes so we know if we can take @@ -636,14 +630,12 @@ def _convert(cls, name, module, filter, source=None): source = vars(source) else: source = module_globals - # We use an OrderedDict of sorted source keys so that the - # _value2member_map is populated in the same order every time + # _value2member_map_ is populated in the same order every time # for a consistent reverse mapping of number to name when there - # are multiple names for the same number rather than varying - # between runs due to hash randomization of the module dictionary. + # are multiple names for the same number. members = [ - (name, source[name]) - for name in source.keys() + (name, value) + for name, value in source.items() if filter(name)] try: # sort by value diff --git a/Lib/functools.py b/Lib/functools.py index c8b79c2a7c2bd1..d5f43935e6cf79 100644 --- a/Lib/functools.py +++ b/Lib/functools.py @@ -11,7 +11,7 @@ __all__ = ['update_wrapper', 'wraps', 'WRAPPER_ASSIGNMENTS', 'WRAPPER_UPDATES', 'total_ordering', 'cmp_to_key', 'lru_cache', 'reduce', 'partial', - 'partialmethod', 'singledispatch'] + 'partialmethod', 'singledispatch', 'singledispatchmethod'] try: from _functools import reduce @@ -826,3 +826,40 @@ def wrapper(*args, **kw): wrapper._clear_cache = dispatch_cache.clear update_wrapper(wrapper, func) return wrapper + + +# Descriptor version +class singledispatchmethod: + """Single-dispatch generic method descriptor. + + Supports wrapping existing descriptors and handles non-descriptor + callables as instance methods. + """ + + def __init__(self, func): + if not callable(func) and not hasattr(func, "__get__"): + raise TypeError(f"{func!r} is not callable or a descriptor") + + self.dispatcher = singledispatch(func) + self.func = func + + def register(self, cls, method=None): + """generic_method.register(cls, func) -> func + + Registers a new implementation for the given *cls* on a *generic_method*. + """ + return self.dispatcher.register(cls, func=method) + + def __get__(self, obj, cls): + def _method(*args, **kwargs): + method = self.dispatcher.dispatch(args[0].__class__) + return method.__get__(obj, cls)(*args, **kwargs) + + _method.__isabstractmethod__ = self.__isabstractmethod__ + _method.register = self.register + update_wrapper(_method, self.func) + return _method + + @property + def __isabstractmethod__(self): + return getattr(self.func, '__isabstractmethod__', False) diff --git a/Lib/http/client.py b/Lib/http/client.py index 1292db74784ccc..5aa178d7b127d9 100644 --- a/Lib/http/client.py +++ b/Lib/http/client.py @@ -321,7 +321,7 @@ def begin(self): if self.debuglevel > 0: for hdr in self.headers: - print("header:", hdr, end=" ") + print("header:", hdr + ":", self.headers.get(hdr)) # are we using the chunked-style of transfer encoding? tr_enc = self.headers.get("transfer-encoding") diff --git a/Lib/http/cookies.py b/Lib/http/cookies.py index 6e1034f131a30f..6694f5478bdadf 100644 --- a/Lib/http/cookies.py +++ b/Lib/http/cookies.py @@ -256,8 +256,7 @@ class Morsel(dict): In a cookie, each such pair may have several attributes, so this class is used to keep the attributes associated with the appropriate key,value pair. This class also includes a coded_value attribute, which is used to hold - the network representation of the value. This is most useful when Python - objects are pickled for network transit. + the network representation of the value. """ # RFC 2109 lists these attributes as reserved: # path comment domain @@ -281,6 +280,7 @@ class Morsel(dict): "secure" : "Secure", "httponly" : "HttpOnly", "version" : "Version", + "samesite" : "SameSite", } _flags = {'secure', 'httponly'} diff --git a/Lib/http/server.py b/Lib/http/server.py index ea0e295d283442..ca2dd507392c8e 100644 --- a/Lib/http/server.py +++ b/Lib/http/server.py @@ -474,7 +474,7 @@ def send_error(self, code, message=None, explain=None): }) body = content.encode('UTF-8', 'replace') self.send_header("Content-Type", self.error_content_type) - self.send_header('Content-Length', int(len(body))) + self.send_header('Content-Length', str(len(body))) self.end_headers() if self.command != 'HEAD' and body: diff --git a/Lib/idlelib/autocomplete.py b/Lib/idlelib/autocomplete.py index edf445f08b5869..9caf50d5d0c21c 100644 --- a/Lib/idlelib/autocomplete.py +++ b/Lib/idlelib/autocomplete.py @@ -226,7 +226,6 @@ def get_entity(self, name): AutoComplete.reload() - if __name__ == '__main__': from unittest import main main('idlelib.idle_test.test_autocomplete', verbosity=2) diff --git a/Lib/idlelib/autocomplete_w.py b/Lib/idlelib/autocomplete_w.py index 12113f95e63aa6..9e0d336523d479 100644 --- a/Lib/idlelib/autocomplete_w.py +++ b/Lib/idlelib/autocomplete_w.py @@ -246,7 +246,7 @@ def winconfig_event(self, event): acw.wm_geometry("+%d+%d" % (new_x, new_y)) if platform.system().startswith('Windows'): - # See issue 15786. When on windows platform, Tk will misbehave + # See issue 15786. When on Windows platform, Tk will misbehave # to call winconfig_event multiple times, we need to prevent this, # otherwise mouse button double click will not be able to used. acw.unbind(WINCONFIG_SEQUENCE, self.winconfigid) @@ -269,7 +269,7 @@ def hide_event(self, event): # mouse click on widget / text area. if self.is_active(): if event.type == EventType.FocusOut: - # On windows platform, it will need to delay the check for + # On Windows platform, it will need to delay the check for # acw.focus_get() when click on acw, otherwise it will return # None and close the window self.widget.after(1, self._hide_event_check) @@ -458,3 +458,10 @@ def hide_window(self): self.listbox = None self.autocompletewindow.destroy() self.autocompletewindow = None + + +if __name__ == '__main__': + from unittest import main + main('idlelib.idle_test.test_autocomplete_w', verbosity=2, exit=False) + +# TODO: autocomplete/w htest here diff --git a/Lib/idlelib/autoexpand.py b/Lib/idlelib/autoexpand.py index 42e733a1a9e735..92f5c84eb6f401 100644 --- a/Lib/idlelib/autoexpand.py +++ b/Lib/idlelib/autoexpand.py @@ -92,5 +92,5 @@ def getprevword(self): if __name__ == '__main__': - import unittest - unittest.main('idlelib.idle_test.test_autoexpand', verbosity=2) + from unittest import main + main('idlelib.idle_test.test_autoexpand', verbosity=2) diff --git a/Lib/idlelib/browser.py b/Lib/idlelib/browser.py index 447dafcc515e6c..234883fe860599 100644 --- a/Lib/idlelib/browser.py +++ b/Lib/idlelib/browser.py @@ -16,7 +16,7 @@ from idlelib.config import idleConf from idlelib import pyshell from idlelib.tree import TreeNode, TreeItem, ScrolledCanvas -from idlelib.windows import ListedToplevel +from idlelib.window import ListedToplevel file_open = None # Method...Item and Class...Item use this. diff --git a/Lib/idlelib/calltips.py b/Lib/idlelib/calltip.py similarity index 96% rename from Lib/idlelib/calltips.py rename to Lib/idlelib/calltip.py index ec8f6169895b88..596d2bcb277599 100644 --- a/Lib/idlelib/calltips.py +++ b/Lib/idlelib/calltip.py @@ -15,7 +15,7 @@ import __main__ -class CallTips: +class Calltip: def __init__(self, editwin=None): if editwin is None: # subprocess and test @@ -31,7 +31,7 @@ def close(self): def _make_tk_calltip_window(self): # See __init__ for usage - return calltip_w.CallTip(self.text) + return calltip_w.CalltipWindow(self.text) def _remove_calltip_window(self, event=None): if self.active_calltip: @@ -44,7 +44,7 @@ def force_open_calltip_event(self, event): return "break" def try_open_calltip_event(self, event): - """Happens when it would be nice to open a CallTip, but not really + """Happens when it would be nice to open a calltip, but not really necessary, for example after an opening bracket, so function calls won't be made. """ @@ -175,4 +175,4 @@ def get_argspec(ob): if __name__ == '__main__': from unittest import main - main('idlelib.idle_test.test_calltips', verbosity=2) + main('idlelib.idle_test.test_calltip', verbosity=2) diff --git a/Lib/idlelib/calltip_w.py b/Lib/idlelib/calltip_w.py index bf967f40b6ab1c..34531f431a6763 100644 --- a/Lib/idlelib/calltip_w.py +++ b/Lib/idlelib/calltip_w.py @@ -1,7 +1,7 @@ -"""A CallTip window class for Tkinter/IDLE. +"""A calltip window class for Tkinter/IDLE. After tooltip.py, which uses ideas gleaned from PySol -Used by the calltips IDLE extension. +Used by calltip. """ from tkinter import Toplevel, Label, LEFT, SOLID, TclError @@ -13,7 +13,7 @@ MARK_RIGHT = "calltipwindowregion_right" -class CallTip: +class CalltipWindow: def __init__(self, widget): self.widget = widget @@ -47,7 +47,7 @@ def position_window(self): def showtip(self, text, parenleft, parenright): """Show the calltip, bind events which will close it and reposition it. """ - # Only called in CallTips, where lines are truncated + # Only called in calltip.Calltip, where lines are truncated self.text = text if self.tipwindow or not self.text: return @@ -147,7 +147,7 @@ def _calltip_window(parent): # htest # text.pack(side=LEFT, fill=BOTH, expand=1) text.insert("insert", "string.split") top.update() - calltip = CallTip(text) + calltip = CalltipWindow(text) def calltip_show(event): calltip.showtip("(s=Hello world)", "insert", "end") @@ -159,6 +159,9 @@ def calltip_hide(event): text.bind("<<calltip-hide>>", calltip_hide) text.focus_set() -if __name__=='__main__': +if __name__ == '__main__': + from unittest import main + main('idlelib.idle_test.test_calltip_w', verbosity=2, exit=False) + from idlelib.idle_test.htest import run run(_calltip_window) diff --git a/Lib/idlelib/codecontext.py b/Lib/idlelib/codecontext.py index 8b378bceba250a..7c88a4d015e358 100644 --- a/Lib/idlelib/codecontext.py +++ b/Lib/idlelib/codecontext.py @@ -233,6 +233,8 @@ def config_timer_event(self): CodeContext.reload() -if __name__ == "__main__": # pragma: no cover - import unittest - unittest.main('idlelib.idle_test.test_codecontext', verbosity=2, exit=False) +if __name__ == "__main__": + from unittest import main + main('idlelib.idle_test.test_codecontext', verbosity=2, exit=False) + + # Add htest. diff --git a/Lib/idlelib/colorizer.py b/Lib/idlelib/colorizer.py index 1f31ce22d7e510..d626d23121df74 100644 --- a/Lib/idlelib/colorizer.py +++ b/Lib/idlelib/colorizer.py @@ -286,9 +286,8 @@ def _color_delegator(parent): # htest # p.insertfilter(d) if __name__ == "__main__": - import unittest - unittest.main('idlelib.idle_test.test_colorizer', - verbosity=2, exit=False) + from unittest import main + main('idlelib.idle_test.test_colorizer', verbosity=2, exit=False) from idlelib.idle_test.htest import run run(_color_delegator) diff --git a/Lib/idlelib/config.py b/Lib/idlelib/config.py index 94b20832091691..0eb90fc8dc5fd6 100644 --- a/Lib/idlelib/config.py +++ b/Lib/idlelib/config.py @@ -925,7 +925,7 @@ def dumpCfg(cfg): print('\nlines = ', line, ', crc = ', crc, sep='') if __name__ == '__main__': - import unittest - unittest.main('idlelib.idle_test.test_config', - verbosity=2, exit=False) - #_dump() + from unittest import main + main('idlelib.idle_test.test_config', verbosity=2, exit=False) + + # Run revised _dump() as htest? diff --git a/Lib/idlelib/config_key.py b/Lib/idlelib/config_key.py index 3a865f869a06c4..7f4bb49ec8a6f2 100644 --- a/Lib/idlelib/config_key.py +++ b/Lib/idlelib/config_key.py @@ -291,8 +291,8 @@ def bind_ok(self, keys): if __name__ == '__main__': - import unittest - unittest.main('idlelib.idle_test.test_config_key', verbosity=2, exit=False) + from unittest import main + main('idlelib.idle_test.test_config_key', verbosity=2, exit=False) from idlelib.idle_test.htest import run run(GetKeysDialog) diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py index 75b917d0e19316..c7832380940321 100644 --- a/Lib/idlelib/configdialog.py +++ b/Lib/idlelib/configdialog.py @@ -2269,8 +2269,8 @@ def _configure_canvas(event): if __name__ == '__main__': - import unittest - unittest.main('idlelib.idle_test.test_configdialog', - verbosity=2, exit=False) + from unittest import main + main('idlelib.idle_test.test_configdialog', verbosity=2, exit=False) + from idlelib.idle_test.htest import run run(ConfigDialog) diff --git a/Lib/idlelib/debugger.py b/Lib/idlelib/debugger.py index 114d0d128e883e..09f912c9af336d 100644 --- a/Lib/idlelib/debugger.py +++ b/Lib/idlelib/debugger.py @@ -6,13 +6,13 @@ from idlelib import macosx from idlelib.scrolledlist import ScrolledList -from idlelib.windows import ListedToplevel +from idlelib.window import ListedToplevel class Idb(bdb.Bdb): def __init__(self, gui): - self.gui = gui + self.gui = gui # An instance of Debugger or proxy of remote. bdb.Bdb.__init__(self) def user_line(self, frame): @@ -40,7 +40,7 @@ def in_rpc_code(self, frame): prev_name = prev_frame.f_code.co_filename if 'idlelib' in prev_name and 'debugger' in prev_name: # catch both idlelib/debugger.py and idlelib/debugger_r.py - # on both posix and windows + # on both Posix and Windows return False return self.in_rpc_code(prev_frame) @@ -63,7 +63,7 @@ def __init__(self, pyshell, idb=None): if idb is None: idb = Idb(self) self.pyshell = pyshell - self.idb = idb + self.idb = idb # If passed, a proxy of remote instance. self.frame = None self.make_gui() self.interacting = 0 @@ -542,3 +542,9 @@ def load_dict(self, dict, force=0, rpc_client=None): def close(self): self.frame.destroy() + +if __name__ == "__main__": + from unittest import main + main('idlelib.idle_test.test_debugger', verbosity=2, exit=False) + +# TODO: htest? diff --git a/Lib/idlelib/debugger_r.py b/Lib/idlelib/debugger_r.py index bc971276de6727..01a3bd25998fc0 100644 --- a/Lib/idlelib/debugger_r.py +++ b/Lib/idlelib/debugger_r.py @@ -386,3 +386,8 @@ def restart_subprocess_debugger(rpcclt): idb_adap_oid_ret = rpcclt.remotecall("exec", "start_the_debugger",\ (gui_adap_oid,), {}) assert idb_adap_oid_ret == idb_adap_oid, 'Idb restarted with different oid' + + +if __name__ == "__main__": + from unittest import main + main('idlelib.idle_test.test_debugger', verbosity=2, exit=False) diff --git a/Lib/idlelib/debugobj.py b/Lib/idlelib/debugobj.py index b70b13cec481de..5a4c9978842035 100644 --- a/Lib/idlelib/debugobj.py +++ b/Lib/idlelib/debugobj.py @@ -71,7 +71,7 @@ def GetSubList(self): class AtomicObjectTreeItem(ObjectTreeItem): def IsExpandable(self): - return 0 + return False class SequenceTreeItem(ObjectTreeItem): def IsExpandable(self): @@ -135,5 +135,8 @@ def _object_browser(parent): # htest # node.update() if __name__ == '__main__': + from unittest import main + main('idlelib.idle_test.test_debugobj', verbosity=2, exit=False) + from idlelib.idle_test.htest import run run(_object_browser) diff --git a/Lib/idlelib/debugobj_r.py b/Lib/idlelib/debugobj_r.py index 8031aaeaf1f25a..75e75ebe5acafc 100644 --- a/Lib/idlelib/debugobj_r.py +++ b/Lib/idlelib/debugobj_r.py @@ -34,3 +34,8 @@ def __getattr__(self, name): def _GetSubList(self): sub_list = self.sockio.remotecall(self.oid, "_GetSubList", (), {}) return [StubObjectTreeItem(self.sockio, oid) for oid in sub_list] + + +if __name__ == '__main__': + from unittest import main + main('idlelib.idle_test.test_debugobj_r', verbosity=2) diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py index 7c3f215e9f96a8..2609715dd2da83 100644 --- a/Lib/idlelib/editor.py +++ b/Lib/idlelib/editor.py @@ -25,7 +25,7 @@ from idlelib import query from idlelib import replace from idlelib import search -from idlelib import windows +from idlelib import window # The default tab setting for a Text widget, in average-width characters. TK_TABWIDTH_DEFAULT = 8 @@ -54,11 +54,11 @@ class EditorWindow(object): from idlelib.statusbar import MultiStatusBar from idlelib.autocomplete import AutoComplete from idlelib.autoexpand import AutoExpand - from idlelib.calltips import CallTips + from idlelib.calltip import Calltip from idlelib.codecontext import CodeContext from idlelib.paragraph import FormatParagraph from idlelib.parenmatch import ParenMatch - from idlelib.rstrip import RstripExtension + from idlelib.rstrip import Rstrip from idlelib.zoomheight import ZoomHeight filesystemencoding = sys.getfilesystemencoding() # for file names @@ -101,7 +101,7 @@ def __init__(self, flist=None, filename=None, key=None, root=None): root = root or flist.root self.root = root self.menubar = Menu(root) - self.top = top = windows.ListedToplevel(root, menu=self.menubar) + self.top = top = window.ListedToplevel(root, menu=self.menubar) if flist: self.tkinter_vars = flist.vars #self.top.instance_dict makes flist.inversedict available to @@ -138,7 +138,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 macosx.isAquaTk(): - # Command-W on editorwindows doesn't work without this. + # Command-W on editor windows doesn't work without this. text.bind('<<close-window>>', self.close_event) # Some OS X systems have only one mouse button, so use # control-click for popup context menus there. For two @@ -267,7 +267,7 @@ def __init__(self, flist=None, filename=None, key=None, root=None): self.saved_change_hook() self.update_recent_files_list() self.load_extensions() - menu = self.menudict.get('windows') + menu = self.menudict.get('window') if menu: end = menu.index("end") if end is None: @@ -276,7 +276,7 @@ def __init__(self, flist=None, filename=None, key=None, root=None): menu.add_separator() end = end + 1 self.wmenu_end = end - windows.register_callback(self.postwindowsmenu) + window.register_callback(self.postwindowsmenu) # Some abstractions so IDLE extensions are cross-IDE self.askyesno = tkMessageBox.askyesno @@ -310,12 +310,12 @@ def __init__(self, flist=None, filename=None, key=None, root=None): scriptbinding = ScriptBinding(self) text.bind("<<check-module>>", scriptbinding.check_module_event) text.bind("<<run-module>>", scriptbinding.run_module_event) - text.bind("<<do-rstrip>>", self.RstripExtension(self).do_rstrip) - calltips = self.CallTips(self) - text.bind("<<try-open-calltip>>", calltips.try_open_calltip_event) - #refresh-calltips must come after paren-closed to work right - text.bind("<<refresh-calltip>>", calltips.refresh_calltip_event) - text.bind("<<force-open-calltip>>", calltips.force_open_calltip_event) + text.bind("<<do-rstrip>>", self.Rstrip(self).do_rstrip) + ctip = self.Calltip(self) + text.bind("<<try-open-calltip>>", ctip.try_open_calltip_event) + #refresh-calltip must come after paren-closed to work right + text.bind("<<refresh-calltip>>", ctip.refresh_calltip_event) + text.bind("<<force-open-calltip>>", ctip.force_open_calltip_event) text.bind("<<zoom-height>>", self.ZoomHeight(self).zoom_height_event) text.bind("<<toggle-code-context>>", self.CodeContext(self).toggle_code_context_event) @@ -410,7 +410,7 @@ def set_line_and_column(self, event=None): ("format", "F_ormat"), ("run", "_Run"), ("options", "_Options"), - ("windows", "_Window"), + ("window", "_Window"), ("help", "_Help"), ] @@ -436,14 +436,35 @@ def createmenubar(self): self.reset_help_menu_entries() def postwindowsmenu(self): - # Only called when Windows menu exists - menu = self.menudict['windows'] + # Only called when Window menu exists + menu = self.menudict['window'] end = menu.index("end") if end is None: end = -1 if end > self.wmenu_end: menu.delete(self.wmenu_end+1, end) - windows.add_windows_to_menu(menu) + window.add_windows_to_menu(menu) + + def handle_yview(self, event, *args): + "Handle scrollbar." + if event == 'moveto': + fraction = float(args[0]) + lines = (round(self.getlineno('end') * fraction) - + self.getlineno('@0,0')) + event = 'scroll' + args = (lines, 'units') + self.text.yview(event, *args) + return 'break' + + def mousescroll(self, event): + "Handle scroll wheel." + up = {EventType.MouseWheel: event.delta >= 0 == darwin, + EventType.Button: event.num == 4} + lines = 5 + if up[event.type]: + lines = -lines + self.text.yview_scroll(lines, 'units') + return 'break' def handle_yview(self, event, *args): "Handle scrollbar." @@ -1012,7 +1033,7 @@ def close(self): def _close(self): if self.io.filename: self.update_recent_files_list(new_file=self.io.filename) - windows.unregister_callback(self.postwindowsmenu) + window.unregister_callback(self.postwindowsmenu) self.unload_extensions() self.io.close() self.io = None @@ -1706,8 +1727,8 @@ def _editor_window(parent): # htest # # edit.text.bind("<<close-window>>", edit.close_event) if __name__ == '__main__': - import unittest - unittest.main('idlelib.idle_test.test_editor', verbosity=2, exit=False) + from unittest import main + main('idlelib.idle_test.test_editor', verbosity=2, exit=False) from idlelib.idle_test.htest import run run(_editor_window) diff --git a/Lib/idlelib/filelist.py b/Lib/idlelib/filelist.py index 5e1a3dcd77dc67..52628392e6170c 100644 --- a/Lib/idlelib/filelist.py +++ b/Lib/idlelib/filelist.py @@ -1,7 +1,7 @@ -import os +"idlelib.filelist" -from tkinter import * -import tkinter.messagebox as tkMessageBox +import os +from tkinter import messagebox as tkMessageBox class FileList: @@ -111,7 +111,8 @@ def canonize(self, filename): return os.path.normpath(filename) -def _test(): +def _test(): # TODO check and convert to htest + from tkinter import Tk from idlelib.editor import fixwordbreaks from idlelib.run import fix_scaling import sys @@ -120,13 +121,12 @@ def _test(): fixwordbreaks(root) root.withdraw() flist = FileList(root) - if sys.argv[1:]: - for filename in sys.argv[1:]: - flist.open(filename) - else: - flist.new() + flist.new() if flist.inversedict: root.mainloop() if __name__ == '__main__': - _test() + from unittest import main + main('idlelib.idle_test.test_filelist', verbosity=2) + +# _test() diff --git a/Lib/idlelib/grep.py b/Lib/idlelib/grep.py index c55c48cf2d69bc..8cc293c380dec6 100644 --- a/Lib/idlelib/grep.py +++ b/Lib/idlelib/grep.py @@ -193,8 +193,8 @@ def show_grep_dialog(): button.pack() if __name__ == "__main__": - import unittest - unittest.main('idlelib.idle_test.test_grep', verbosity=2, exit=False) + from unittest import main + 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/help.py b/Lib/idlelib/help.py index fa6112a339444f..21b5ea5a816e3f 100644 --- a/Lib/idlelib/help.py +++ b/Lib/idlelib/help.py @@ -271,5 +271,8 @@ def show_idlehelp(parent): HelpWindow(parent, filename, 'IDLE Help (%s)' % python_version()) if __name__ == '__main__': + from unittest import main + main('idlelib.idle_test.test_help', verbosity=2, exit=False) + from idlelib.idle_test.htest import run run(show_idlehelp) diff --git a/Lib/idlelib/help_about.py b/Lib/idlelib/help_about.py index 77b4b18962066c..2a274a930482d0 100644 --- a/Lib/idlelib/help_about.py +++ b/Lib/idlelib/help_about.py @@ -199,7 +199,8 @@ def ok(self, event=None): if __name__ == '__main__': - import unittest - unittest.main('idlelib.idle_test.test_help_about', verbosity=2, exit=False) + from unittest import main + main('idlelib.idle_test.test_help_about', verbosity=2, exit=False) + from idlelib.idle_test.htest import run run(AboutDialog) diff --git a/Lib/idlelib/hyperparser.py b/Lib/idlelib/hyperparser.py index a42665bb632846..7581fe274b215e 100644 --- a/Lib/idlelib/hyperparser.py +++ b/Lib/idlelib/hyperparser.py @@ -308,5 +308,5 @@ def get_expression(self): if __name__ == '__main__': - import unittest - unittest.main('idlelib.idle_test.test_hyperparser', verbosity=2) + from unittest import main + main('idlelib.idle_test.test_hyperparser', verbosity=2) diff --git a/Lib/idlelib/idle_test/README.txt b/Lib/idlelib/idle_test/README.txt index 5f3678fc7e1de3..566bfd179fdf1b 100644 --- a/Lib/idlelib/idle_test/README.txt +++ b/Lib/idlelib/idle_test/README.txt @@ -15,28 +15,27 @@ python -m idlelib.idle_test.htest 1. Test Files The idle directory, idlelib, has over 60 xyz.py files. The idle_test -subdirectory should contain a test_xyz.py for each, where 'xyz' is -lowercased even if xyz.py is not. Here is a possible template, with the -blanks after '.' and 'as', and before and after '_' to be filled in. +subdirectory contains test_xyz.py for each implementation file xyz.py. +To add a test for abc.py, open idle_test/template.py and immediately +Save As test_abc.py. Insert 'abc' on the first line, and replace +'zzdummy' with 'abc. -import unittest -from test.support import requires -import idlelib. as - -class _Test(unittest.TestCase): +Remove the imports of requires and tkinter if not needed. Otherwise, +add to the tkinter imports as needed. - def test_(self): +Add a prefix to 'Test' for the initial test class. The template class +contains code needed or possibly needed for gui tests. See the next +section if doing gui tests. If not, and not needed for further classes, +this code can be removed. -if __name__ == '__main__': - unittest.main(verbosity=2) - -Add the following at the end of xyy.py, with the appropriate name added -after 'test_'. Some files already have something like this for htest. -If so, insert the import and unittest.main lines before the htest lines. +Add the following at the end of abc.py. If an htest was added first, +insert the import and main lines before the htest lines. if __name__ == "__main__": - import unittest - unittest.main('idlelib.idle_test.test_', verbosity=2, exit=False) + from unittest import main + main('idlelib.idle_test.test_abc', verbosity=2, exit=False) + +The ', exit=False' is only needed if an htest follows. @@ -55,12 +54,14 @@ from test.support import requires requires('gui') To guard a test class, put "requires('gui')" in its setUpClass function. +The template.py file does this. -To avoid interfering with other GUI tests, all GUI objects must be destroyed and -deleted by the end of the test. The Tk root created in a setUpX function should -be destroyed in the corresponding tearDownX and the module or class attribute -deleted. Others widgets should descend from the single root and the attributes -deleted BEFORE root is destroyed. See https://bugs.python.org/issue20567. +To avoid interfering with other GUI tests, all GUI objects must be +destroyed and deleted by the end of the test. The Tk root created in a +setUpX function should be destroyed in the corresponding tearDownX and +the module or class attribute deleted. Others widgets should descend +from the single root and the attributes deleted BEFORE root is +destroyed. See https://bugs.python.org/issue20567. @classmethod def setUpClass(cls): @@ -75,12 +76,23 @@ deleted BEFORE root is destroyed. See https://bugs.python.org/issue20567. cls.root.destroy() del cls.root -The update_idletasks call is sometimes needed to prevent the following warning -either when running a test alone or as part of the test suite (#27196). +The update_idletasks call is sometimes needed to prevent the following +warning either when running a test alone or as part of the test suite +(#27196). It should not hurt if not needed. + can't invoke "event" command: application has been destroyed ... "ttk::ThemeChanged" +If a test creates instance 'e' of EditorWindow, call 'e._close()' before +or as the first part of teardown. The effect of omitting this depends +on the later shutdown. Then enable the after_cancel loop in the +template. This prevents messages like the following. + +bgerror failed to handle background error. + Original error: invalid command name "106096696timer_event" + Error in bgerror: can't invoke "tk" command: application has been destroyed + Requires('gui') causes the test(s) it guards to be skipped if any of these conditions are met: diff --git a/Lib/idlelib/idle_test/htest.py b/Lib/idlelib/idle_test/htest.py index 442f55e283a484..95f627439297cc 100644 --- a/Lib/idlelib/idle_test/htest.py +++ b/Lib/idlelib/idle_test/htest.py @@ -65,6 +65,7 @@ def _wrapper(parent): # htest # outwin.OutputWindow (indirectly being tested with grep test) ''' +import idlelib.pyshell # Set Windows DPI awareness before Tk(). from importlib import import_module import tkinter as tk from tkinter.ttk import Scrollbar @@ -296,16 +297,6 @@ def _wrapper(parent): # htest # "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" - } - _tooltip_spec = { 'file': 'tooltip', 'kwds': {}, diff --git a/Lib/idlelib/idle_test/template.py b/Lib/idlelib/idle_test/template.py new file mode 100644 index 00000000000000..725a55b9c47230 --- /dev/null +++ b/Lib/idlelib/idle_test/template.py @@ -0,0 +1,30 @@ +"Test , coverage %." + +from idlelib import zzdummy +import unittest +from test.support import requires +from tkinter import Tk + + +class Test(unittest.TestCase): + + @classmethod + def setUpClass(cls): + requires('gui') + cls.root = Tk() + cls.root.withdraw() + + @classmethod + def tearDownClass(cls): + cls.root.update_idletasks() +## for id in cls.root.tk.call('after', 'info'): +## cls.root.after_cancel(id) # Need for EditorWindow. + cls.root.destroy() + del cls.root + + def test_init(self): + self.assertTrue(True) + + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_autocomplete.py b/Lib/idlelib/idle_test/test_autocomplete.py index f3f2dea4246df0..d7ee00af94b4da 100644 --- a/Lib/idlelib/idle_test/test_autocomplete.py +++ b/Lib/idlelib/idle_test/test_autocomplete.py @@ -1,7 +1,5 @@ -''' Test autocomplete and autocomple_w +"Test autocomplete, coverage 57%." -Coverage of autocomple: 56% -''' import unittest from test.support import requires from tkinter import Tk, Text @@ -11,9 +9,6 @@ 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): diff --git a/Lib/idlelib/idle_test/test_autocomplete_w.py b/Lib/idlelib/idle_test/test_autocomplete_w.py new file mode 100644 index 00000000000000..b1bdc6c7c6e1a5 --- /dev/null +++ b/Lib/idlelib/idle_test/test_autocomplete_w.py @@ -0,0 +1,32 @@ +"Test autocomplete_w, coverage 11%." + +import unittest +from test.support import requires +from tkinter import Tk, Text + +import idlelib.autocomplete_w as acw + + +class AutoCompleteWindowTest(unittest.TestCase): + + @classmethod + def setUpClass(cls): + requires('gui') + cls.root = Tk() + cls.root.withdraw() + cls.text = Text(cls.root) + cls.acw = acw.AutoCompleteWindow(cls.text) + + @classmethod + def tearDownClass(cls): + del cls.text, cls.acw + cls.root.update_idletasks() + cls.root.destroy() + del cls.root + + def test_init(self): + self.assertEqual(self.acw.widget, self.text) + + +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 index ae8186cdc49f7b..e5f44c46871325 100644 --- a/Lib/idlelib/idle_test/test_autoexpand.py +++ b/Lib/idlelib/idle_test/test_autoexpand.py @@ -1,9 +1,9 @@ -"""Unit tests for idlelib.autoexpand""" +"Test autoexpand, coverage 100%." + +from idlelib.autoexpand import 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: @@ -15,15 +15,27 @@ 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() + requires('gui') + cls.tk = Tk() + cls.text = Text(cls.tk) cls.auto_expand = AutoExpand(Dummy_Editwin(cls.text)) cls.auto_expand.bell = lambda: None +# If mock_tk.Text._decode understood indexes 'insert' with suffixed 'linestart', +# 'wordstart', and 'lineend', used by autoexpand, we could use the following +# to run these test on non-gui machines (but check bell). +## try: +## requires('gui') +## #raise ResourceDenied() # Uncomment to test mock. +## except ResourceDenied: +## from idlelib.idle_test.mock_tk import Text +## cls.text = Text() +## cls.text.bell = lambda: None +## else: +## from tkinter import Tk, Text +## cls.tk = Tk() +## cls.text = Text(cls.tk) + @classmethod def tearDownClass(cls): del cls.text, cls.auto_expand diff --git a/Lib/idlelib/idle_test/test_browser.py b/Lib/idlelib/idle_test/test_browser.py index 34eb332c1df434..905dc1f47e3438 100644 --- a/Lib/idlelib/idle_test/test_browser.py +++ b/Lib/idlelib/idle_test/test_browser.py @@ -1,20 +1,16 @@ -""" Test idlelib.browser. +"Test browser, coverage 90%." -Coverage: 88% -(Higher, because should exclude 3 lines that .coveragerc won't exclude.) -""" +from idlelib import browser +from test.support import requires +import unittest +from unittest import mock +from idlelib.idle_test.mock_idle import Func from collections import deque import os.path import pyclbr from tkinter import Tk -from test.support import requires -import unittest -from unittest import mock -from idlelib.idle_test.mock_idle import Func - -from idlelib import browser from idlelib import filelist from idlelib.tree import TreeNode diff --git a/Lib/idlelib/idle_test/test_calltips.py b/Lib/idlelib/idle_test/test_calltip.py similarity index 80% rename from Lib/idlelib/idle_test/test_calltips.py rename to Lib/idlelib/idle_test/test_calltip.py index a58229d36ede70..0698d4f8b99ea9 100644 --- a/Lib/idlelib/idle_test/test_calltips.py +++ b/Lib/idlelib/idle_test/test_calltip.py @@ -1,9 +1,12 @@ +"Test calltip, coverage 60%" + +from idlelib import calltip import unittest -import idlelib.calltips as ct import textwrap import types -default_tip = ct._default_callable_argspec +default_tip = calltip._default_callable_argspec + # Test Class TC is used in multiple get_argspec test methods class TC(): @@ -31,9 +34,11 @@ def cm(cls, a): 'doc' @staticmethod def sm(b): 'doc' + tc = TC() +signature = calltip.get_argspec # 2.7 and 3.x use different functions + -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 @@ -54,14 +59,18 @@ def gtest(obj, out): self.assertEqual(signature(obj), out) if List.__doc__ is not None: - gtest(List, '(iterable=(), /)' + ct._argument_positional + '\n' + - List.__doc__) + gtest(List, '(iterable=(), /)' + calltip._argument_positional + + '\n' + List.__doc__) gtest(list.__new__, - '(*args, **kwargs)\nCreate and return a new object. See help(type) for accurate signature.') + '(*args, **kwargs)\n' + 'Create and return a new object. ' + 'See help(type) for accurate signature.') gtest(list.__init__, - '(self, /, *args, **kwargs)' + ct._argument_positional + '\n' + - 'Initialize self. See help(type(self)) for accurate signature.') - append_doc = ct._argument_positional + "\nAppend object to the end of the list." + '(self, /, *args, **kwargs)' + + calltip._argument_positional + '\n' + + 'Initialize self. See help(type(self)) for accurate signature.') + append_doc = (calltip._argument_positional + + "\nAppend object to the end of the list.") gtest(list.append, '(self, object, /)' + append_doc) gtest(List.append, '(self, object, /)' + append_doc) gtest([].append, '(object, /)' + append_doc) @@ -70,12 +79,17 @@ def gtest(obj, out): gtest(SB(), default_tip) import re p = re.compile('') - gtest(re.sub, '''(pattern, repl, string, count=0, flags=0)\nReturn the string obtained by replacing the leftmost + gtest(re.sub, '''\ +(pattern, repl, string, count=0, flags=0) +Return the string obtained by replacing the leftmost non-overlapping occurrences of the pattern in string by the replacement repl. repl can be either a string or a callable; if a string, backslash escapes in it are processed. If it is a callable, it's passed the Match object and must return''') - gtest(p.sub, '''(repl, string, count=0)\nReturn the string obtained by replacing the leftmost non-overlapping occurrences o...''') + gtest(p.sub, '''\ +(repl, string, count=0) +Return the string obtained by replacing the leftmost \ +non-overlapping occurrences o...''') def test_signature_wrap(self): if textwrap.TextWrapper.__doc__ is not None: @@ -88,7 +102,7 @@ def test_signature_wrap(self): def test_docline_truncation(self): def f(): pass f.__doc__ = 'a'*300 - self.assertEqual(signature(f), '()\n' + 'a' * (ct._MAX_COLS-3) + '...') + self.assertEqual(signature(f), '()\n' + 'a' * (calltip._MAX_COLS-3) + '...') def test_multiline_docstring(self): # Test fewer lines than max. @@ -107,7 +121,7 @@ def test_multiline_docstring(self): # Test more than max lines def f(): pass f.__doc__ = 'a\n' * 15 - self.assertEqual(signature(f), '()' + '\na' * ct._MAX_LINES) + self.assertEqual(signature(f), '()' + '\na' * calltip._MAX_LINES) def test_functions(self): def t1(): 'doc' @@ -135,8 +149,9 @@ def test_methods(self): def test_bound_methods(self): # test that first parameter is correctly removed from argspec doc = '\ndoc' if TC.__doc__ is not None else '' - for meth, mtip in ((tc.t1, "()"), (tc.t4, "(*args)"), (tc.t6, "(self)"), - (tc.__call__, '(ci)'), (tc, '(ci)'), (TC.cm, "(a)"),): + 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 + doc) def test_starred_parameter(self): @@ -153,7 +168,7 @@ def m2(**kwargs): pass class Test: def __call__(*, a): pass - mtip = ct._invalid_method + mtip = calltip._invalid_method self.assertEqual(signature(C().m2), mtip) self.assertEqual(signature(Test()), mtip) @@ -161,7 +176,7 @@ 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)' + assert calltip._first_param.sub('', uni) == '(a)' def test_no_docstring(self): def nd(s): @@ -194,9 +209,10 @@ def test_non_callables(self): class Get_entityTest(unittest.TestCase): def test_bad_entity(self): - self.assertIsNone(ct.get_entity('1/0')) + self.assertIsNone(calltip.get_entity('1/0')) def test_good_entity(self): - self.assertIs(ct.get_entity('int'), int) + self.assertIs(calltip.get_entity('int'), int) + if __name__ == '__main__': - unittest.main(verbosity=2, exit=False) + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_calltip_w.py b/Lib/idlelib/idle_test/test_calltip_w.py new file mode 100644 index 00000000000000..59e69677e679a4 --- /dev/null +++ b/Lib/idlelib/idle_test/test_calltip_w.py @@ -0,0 +1,29 @@ +"Test calltip_w, coverage 18%." + +from idlelib import calltip_w +import unittest +from test.support import requires +from tkinter import Tk, Text + + +class CallTipWindowTest(unittest.TestCase): + + @classmethod + def setUpClass(cls): + requires('gui') + cls.root = Tk() + cls.root.withdraw() + cls.text = Text(cls.root) + cls.calltip = calltip_w.CalltipWindow(cls.text) + + @classmethod + def tearDownClass(cls): + cls.root.update_idletasks() + cls.root.destroy() + del cls.text, cls.root + + def test_init(self): + self.assertEqual(self.calltip.widget, self.text) + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_codecontext.py b/Lib/idlelib/idle_test/test_codecontext.py index 2e59b8501c9116..ef8170e3b6964d 100644 --- a/Lib/idlelib/idle_test/test_codecontext.py +++ b/Lib/idlelib/idle_test/test_codecontext.py @@ -1,16 +1,12 @@ -"""Test idlelib.codecontext. - -Coverage: 100% -""" - -import re +"Test codecontext, coverage 100%" +from idlelib import codecontext import unittest -from unittest import mock from test.support import requires from tkinter import Tk, Frame, Text, TclError -import idlelib.codecontext as codecontext +from unittest import mock +import re from idlelib import config diff --git a/Lib/idlelib/idle_test/test_colorizer.py b/Lib/idlelib/idle_test/test_colorizer.py index 238bc3e1141363..1e74bed1f0c0f0 100644 --- a/Lib/idlelib/idle_test/test_colorizer.py +++ b/Lib/idlelib/idle_test/test_colorizer.py @@ -1,10 +1,6 @@ -'''Test idlelib/colorizer.py +"Test colorizer, coverage 25%." -Perform minimal sanity checks that module imports and some things run. - -Coverage 22%. -''' -from idlelib import colorizer # always test import +from idlelib import colorizer from test.support import requires from tkinter import Tk, Text import unittest @@ -36,6 +32,7 @@ def tearDownClass(cls): def test_colorizer(self): colorizer.color_config(self.text) + class ColorDelegatorTest(unittest.TestCase): @classmethod diff --git a/Lib/idlelib/idle_test/test_config.py b/Lib/idlelib/idle_test/test_config.py index abfec7993e0744..f3d9f21dd86c77 100644 --- a/Lib/idlelib/idle_test/test_config.py +++ b/Lib/idlelib/idle_test/test_config.py @@ -1,9 +1,9 @@ -'''Test idlelib.config. - -Coverage: 96% (100% for IdleConfParser, IdleUserConfParser*, ConfigChanges). +"""Test config, coverage 93%. +(100% for IdleConfParser, IdleUserConfParser*, ConfigChanges). * Exception is OSError clause in Save method. Much of IdleConf is also exercised by ConfigDialog and test_configdialog. -''' +""" +from idlelib import config import copy import sys import os @@ -12,7 +12,6 @@ import unittest from unittest import mock import idlelib -from idlelib import config from idlelib.idle_test.mock_idle import Func # Tests should not depend on fortuitous user configurations. @@ -256,9 +255,9 @@ def test_get_user_cfg_dir_unix(self): with self.assertRaises(FileNotFoundError): conf.GetUserCfgDir() - @unittest.skipIf(not sys.platform.startswith('win'), 'this is test for windows system') + @unittest.skipIf(not sys.platform.startswith('win'), 'this is test for Windows system') def test_get_user_cfg_dir_windows(self): - "Test to get user config directory under windows" + "Test to get user config directory under Windows" conf = self.new_config(_utest=True) # Check normal way should success diff --git a/Lib/idlelib/idle_test/test_config_key.py b/Lib/idlelib/idle_test/test_config_key.py index 9074e23aab35d1..08471666a4529d 100644 --- a/Lib/idlelib/idle_test/test_config_key.py +++ b/Lib/idlelib/idle_test/test_config_key.py @@ -1,7 +1,5 @@ -''' Test idlelib.config_key. +"Test config_key, coverage 75%" -Coverage: 56% from creating and closing dialog. -''' from idlelib import config_key from test.support import requires import sys diff --git a/Lib/idlelib/idle_test/test_configdialog.py b/Lib/idlelib/idle_test/test_configdialog.py index 26aba32c47e6ab..dbfcd01c63eac4 100644 --- a/Lib/idlelib/idle_test/test_configdialog.py +++ b/Lib/idlelib/idle_test/test_configdialog.py @@ -1,7 +1,6 @@ -"""Test idlelib.configdialog. +"""Test configdialog, coverage 94%. Half the class creates dialog, half works with user customizations. -Coverage: 95%. """ from idlelib import configdialog from test.support import requires @@ -61,6 +60,7 @@ def setUpClass(cls): page = cls.page = dialog.fontpage dialog.note.select(page) page.set_samples = Func() # Mask instance method. + page.update() @classmethod def tearDownClass(cls): @@ -211,6 +211,7 @@ class IndentTest(unittest.TestCase): @classmethod def setUpClass(cls): cls.page = dialog.fontpage + cls.page.update() def test_load_tab_cfg(self): d = self.page @@ -241,6 +242,7 @@ def setUpClass(cls): page.paint_theme_sample = Func() page.set_highlight_target = Func() page.set_color_sample = Func() + page.update() @classmethod def tearDownClass(cls): @@ -1086,6 +1088,7 @@ def setUpClass(cls): dialog.note.select(page) page.set = page.set_add_delete_state = Func() page.upc = page.update_help_changes = Func() + page.update() @classmethod def tearDownClass(cls): diff --git a/Lib/idlelib/idle_test/test_debugger.py b/Lib/idlelib/idle_test/test_debugger.py index bcba9a45c160a9..35efb3411c73b5 100644 --- a/Lib/idlelib/idle_test/test_debugger.py +++ b/Lib/idlelib/idle_test/test_debugger.py @@ -1,11 +1,9 @@ -''' Test idlelib.debugger. +"Test debugger, coverage 19%" -Coverage: 19% -''' from idlelib import debugger +import unittest from test.support import requires requires('gui') -import unittest from tkinter import Tk @@ -25,5 +23,7 @@ def test_init(self): debugger.NamespaceViewer(self.root, 'Test') +# Other classes are Idb, Debugger, and StackViewer. + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_debugger_r.py b/Lib/idlelib/idle_test/test_debugger_r.py new file mode 100644 index 00000000000000..199f63447ce6ca --- /dev/null +++ b/Lib/idlelib/idle_test/test_debugger_r.py @@ -0,0 +1,29 @@ +"Test debugger_r, coverage 30%." + +from idlelib import debugger_r +import unittest +from test.support import requires +from tkinter import Tk + + +class Test(unittest.TestCase): + +## @classmethod +## def setUpClass(cls): +## requires('gui') +## cls.root = Tk() +## +## @classmethod +## def tearDownClass(cls): +## cls.root.destroy() +## del cls.root + + def test_init(self): + self.assertTrue(True) # Get coverage of import + + +# Classes GUIProxy, IdbAdapter, FrameProxy, CodeProxy, DictProxy, +# GUIAdapter, IdbProxy plus 7 module functions. + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_debugobj.py b/Lib/idlelib/idle_test/test_debugobj.py new file mode 100644 index 00000000000000..131ce22b8bb69b --- /dev/null +++ b/Lib/idlelib/idle_test/test_debugobj.py @@ -0,0 +1,57 @@ +"Test debugobj, coverage 40%." + +from idlelib import debugobj +import unittest + + +class ObjectTreeItemTest(unittest.TestCase): + + def test_init(self): + ti = debugobj.ObjectTreeItem('label', 22) + self.assertEqual(ti.labeltext, 'label') + self.assertEqual(ti.object, 22) + self.assertEqual(ti.setfunction, None) + + +class ClassTreeItemTest(unittest.TestCase): + + def test_isexpandable(self): + ti = debugobj.ClassTreeItem('label', 0) + self.assertTrue(ti.IsExpandable()) + + +class AtomicObjectTreeItemTest(unittest.TestCase): + + def test_isexpandable(self): + ti = debugobj.AtomicObjectTreeItem('label', 0) + self.assertFalse(ti.IsExpandable()) + + +class SequenceTreeItemTest(unittest.TestCase): + + def test_isexpandable(self): + ti = debugobj.SequenceTreeItem('label', ()) + self.assertFalse(ti.IsExpandable()) + ti = debugobj.SequenceTreeItem('label', (1,)) + self.assertTrue(ti.IsExpandable()) + + def test_keys(self): + ti = debugobj.SequenceTreeItem('label', 'abc') + self.assertEqual(list(ti.keys()), [0, 1, 2]) + + +class DictTreeItemTest(unittest.TestCase): + + def test_isexpandable(self): + ti = debugobj.DictTreeItem('label', {}) + self.assertFalse(ti.IsExpandable()) + ti = debugobj.DictTreeItem('label', {1:1}) + self.assertTrue(ti.IsExpandable()) + + def test_keys(self): + ti = debugobj.DictTreeItem('label', {1:1, 0:0, 2:2}) + self.assertEqual(ti.keys(), [0, 1, 2]) + + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_debugobj_r.py b/Lib/idlelib/idle_test/test_debugobj_r.py new file mode 100644 index 00000000000000..86e51b6cb2cb22 --- /dev/null +++ b/Lib/idlelib/idle_test/test_debugobj_r.py @@ -0,0 +1,22 @@ +"Test debugobj_r, coverage 56%." + +from idlelib import debugobj_r +import unittest + + +class WrappedObjectTreeItemTest(unittest.TestCase): + + def test_getattr(self): + ti = debugobj_r.WrappedObjectTreeItem(list) + self.assertEqual(ti.append, list.append) + +class StubObjectTreeItemTest(unittest.TestCase): + + def test_init(self): + ti = debugobj_r.StubObjectTreeItem('socket', 1111) + self.assertEqual(ti.sockio, 'socket') + self.assertEqual(ti.oid, 1111) + + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_delegator.py b/Lib/idlelib/idle_test/test_delegator.py index 85624fbc127c85..922416297a42e0 100644 --- a/Lib/idlelib/idle_test/test_delegator.py +++ b/Lib/idlelib/idle_test/test_delegator.py @@ -1,5 +1,8 @@ -import unittest +"Test delegator, coverage 100%." + from idlelib.delegator import Delegator +import unittest + class DelegatorTest(unittest.TestCase): @@ -36,5 +39,6 @@ def test_mydel(self): self.assertEqual(mydel._Delegator__cache, set()) self.assertIs(mydel.delegate, float) + if __name__ == '__main__': unittest.main(verbosity=2, exit=2) diff --git a/Lib/idlelib/idle_test/test_editor.py b/Lib/idlelib/idle_test/test_editor.py index 64a2a88b7e3765..12bc8473668334 100644 --- a/Lib/idlelib/idle_test/test_editor.py +++ b/Lib/idlelib/idle_test/test_editor.py @@ -1,14 +1,46 @@ +"Test editor, coverage 35%." + +from idlelib import editor import unittest -from idlelib.editor import EditorWindow +from test.support import requires +from tkinter import Tk + +Editor = editor.EditorWindow + + +class EditorWindowTest(unittest.TestCase): + + @classmethod + def setUpClass(cls): + requires('gui') + cls.root = Tk() + cls.root.withdraw() + + @classmethod + def tearDownClass(cls): + cls.root.update_idletasks() + for id in cls.root.tk.call('after', 'info'): + cls.root.after_cancel(id) + cls.root.destroy() + del cls.root + + def test_init(self): + e = Editor(root=self.root) + self.assertEqual(e.root, self.root) + e._close() + + +class EditorFunctionTest(unittest.TestCase): -class Editor_func_test(unittest.TestCase): def test_filename_to_unicode(self): - func = EditorWindow._filename_to_unicode - class dummy(): filesystemencoding = 'utf-8' + func = Editor._filename_to_unicode + class dummy(): + filesystemencoding = 'utf-8' pairs = (('abc', 'abc'), ('a\U00011111c', 'a\ufffdc'), (b'abc', 'abc'), (b'a\xf0\x91\x84\x91c', 'a\ufffdc')) for inp, out in pairs: self.assertEqual(func(dummy, inp), out) + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_filelist.py b/Lib/idlelib/idle_test/test_filelist.py new file mode 100644 index 00000000000000..731f1975e50e23 --- /dev/null +++ b/Lib/idlelib/idle_test/test_filelist.py @@ -0,0 +1,33 @@ +"Test filelist, coverage 19%." + +from idlelib import filelist +import unittest +from test.support import requires +from tkinter import Tk + +class FileListTest(unittest.TestCase): + + @classmethod + def setUpClass(cls): + requires('gui') + cls.root = Tk() + cls.root.withdraw() + + @classmethod + def tearDownClass(cls): + cls.root.update_idletasks() + for id in cls.root.tk.call('after', 'info'): + cls.root.after_cancel(id) + cls.root.destroy() + del cls.root + + def test_new_empty(self): + flist = filelist.FileList(self.root) + self.assertEqual(flist.root, self.root) + e = flist.new() + self.assertEqual(type(e), flist.EditorWindow) + e._close() + + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_grep.py b/Lib/idlelib/idle_test/test_grep.py index 6b54c1313153d1..ab0d7860f78953 100644 --- a/Lib/idlelib/idle_test/test_grep.py +++ b/Lib/idlelib/idle_test/test_grep.py @@ -3,14 +3,15 @@ dummy_command calls grep_it calls findfiles. An exception raised in one method will fail callers. Otherwise, tests are mostly independent. -*** Currently only test grep_it. +Currently only test grep_it, coverage 51%. """ +from idlelib.grep import GrepDialog import unittest from test.support import captured_stdout from idlelib.idle_test.mock_tk import Var -from idlelib.grep import GrepDialog import re + class Dummy_searchengine: '''GrepDialog.__init__ calls parent SearchDiabolBase which attaches the passed in SearchEngine instance as attribute 'engine'. Only a few of the @@ -21,6 +22,7 @@ def getpat(self): searchengine = Dummy_searchengine() + class Dummy_grep: # Methods tested #default_command = GrepDialog.default_command @@ -34,6 +36,7 @@ def close(self): # gui method grep = Dummy_grep() + class FindfilesTest(unittest.TestCase): # findfiles is really a function, not a method, could be iterator # test that filename return filename @@ -41,6 +44,7 @@ class FindfilesTest(unittest.TestCase): # test that recursive flag adds idle_test .py files pass + class Grep_itTest(unittest.TestCase): # Test captured reports with 0 and some hits. # Should test file names, but Windows reports have mixed / and \ separators @@ -71,10 +75,12 @@ def test_found(self): self.assertIn('2', lines[3]) # hits found 2 self.assertTrue(lines[4].startswith('(Hint:')) + class Default_commandTest(unittest.TestCase): # To write this, move outwin import to top of GrepDialog # so it can be replaced by captured_stdout in class setup/teardown. pass + if __name__ == '__main__': - unittest.main(verbosity=2, exit=False) + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_help.py b/Lib/idlelib/idle_test/test_help.py index 2c68e23b328c24..b542659981894d 100644 --- a/Lib/idlelib/idle_test/test_help.py +++ b/Lib/idlelib/idle_test/test_help.py @@ -1,13 +1,12 @@ -'''Test idlelib.help. +"Test help, coverage 87%." -Coverage: 87% -''' from idlelib import help +import unittest from test.support import requires requires('gui') from os.path import abspath, dirname, join from tkinter import Tk -import unittest + class HelpFrameTest(unittest.TestCase): @@ -30,5 +29,6 @@ def test_line1(self): text = self.frame.text self.assertEqual(text.get('1.0', '1.end'), ' IDLE ') + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_help_about.py b/Lib/idlelib/idle_test/test_help_about.py index 9c6a834a461bae..5839b5d045d89e 100644 --- a/Lib/idlelib/idle_test/test_help_about.py +++ b/Lib/idlelib/idle_test/test_help_about.py @@ -1,18 +1,19 @@ -'''Test idlelib.help_about. +"""Test help_about, coverage 100%. +help_about.build_bits branches on sys.platform='darwin'. +'100% combines coverage on Mac and others. +""" -Coverage: 100% -''' +from idlelib import help_about +import unittest from test.support import requires, findfile from tkinter import Tk, TclError -import unittest -from unittest import mock from idlelib.idle_test.mock_idle import Func from idlelib.idle_test.mock_tk import Mbox_func -from idlelib.help_about import AboutDialog as About -from idlelib import help_about from idlelib import textview import os.path -from platform import python_version, architecture +from platform import python_version + +About = help_about.AboutDialog class LiveDialogTest(unittest.TestCase): diff --git a/Lib/idlelib/idle_test/test_history.py b/Lib/idlelib/idle_test/test_history.py index b27801071be649..67539651444751 100644 --- a/Lib/idlelib/idle_test/test_history.py +++ b/Lib/idlelib/idle_test/test_history.py @@ -1,15 +1,18 @@ +" Test history, coverage 100%." + +from idlelib.history import History import unittest from test.support import requires import tkinter as tk from tkinter import Text as tkText from idlelib.idle_test.mock_tk import Text as mkText -from idlelib.history import History from idlelib.config import idleConf line1 = 'a = 7' line2 = 'b = a' + class StoreTest(unittest.TestCase): '''Tests History.__init__ and History.store with mock Text''' @@ -61,6 +64,7 @@ def __getattr__(self, name): def bell(self): self._bell = True + class FetchTest(unittest.TestCase): '''Test History.fetch with wrapped tk.Text. ''' diff --git a/Lib/idlelib/idle_test/test_hyperparser.py b/Lib/idlelib/idle_test/test_hyperparser.py index 73c8281e430d64..8dbfc63779d380 100644 --- a/Lib/idlelib/idle_test/test_hyperparser.py +++ b/Lib/idlelib/idle_test/test_hyperparser.py @@ -1,9 +1,10 @@ -"""Unittest for idlelib.hyperparser.py.""" +"Test hyperparser, coverage 98%." + +from idlelib.hyperparser import HyperParser import unittest from test.support import requires from tkinter import Tk, Text from idlelib.editor import EditorWindow -from idlelib.hyperparser import HyperParser class DummyEditwin: def __init__(self, text): @@ -270,5 +271,6 @@ def test_eat_identifier_various_lengths(self): 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_iomenu.py b/Lib/idlelib/idle_test/test_iomenu.py index 65bf5930559562..743a05b3c3134e 100644 --- a/Lib/idlelib/idle_test/test_iomenu.py +++ b/Lib/idlelib/idle_test/test_iomenu.py @@ -1,233 +1,36 @@ -import unittest -import io - -from idlelib.run import PseudoInputFile, PseudoOutputFile - - -class S(str): - def __str__(self): - return '%s:str' % type(self).__name__ - def __unicode__(self): - return '%s:unicode' % type(self).__name__ - def __len__(self): - return 3 - def __iter__(self): - return iter('abc') - def __getitem__(self, *args): - return '%s:item' % type(self).__name__ - def __getslice__(self, *args): - return '%s:slice' % type(self).__name__ - -class MockShell: - def __init__(self): - self.reset() - - def write(self, *args): - self.written.append(args) - - def readline(self): - return self.lines.pop() - - def close(self): - pass - - def reset(self): - self.written = [] - - def push(self, lines): - self.lines = list(lines)[::-1] - - -class PseudeOutputFilesTest(unittest.TestCase): - def test_misc(self): - shell = MockShell() - f = PseudoOutputFile(shell, 'stdout', 'utf-8') - self.assertIsInstance(f, io.TextIOBase) - self.assertEqual(f.encoding, 'utf-8') - self.assertIsNone(f.errors) - self.assertIsNone(f.newlines) - self.assertEqual(f.name, '<stdout>') - self.assertFalse(f.closed) - self.assertTrue(f.isatty()) - self.assertFalse(f.readable()) - self.assertTrue(f.writable()) - self.assertFalse(f.seekable()) - - def test_unsupported(self): - shell = MockShell() - f = PseudoOutputFile(shell, 'stdout', 'utf-8') - self.assertRaises(OSError, f.fileno) - self.assertRaises(OSError, f.tell) - self.assertRaises(OSError, f.seek, 0) - self.assertRaises(OSError, f.read, 0) - self.assertRaises(OSError, f.readline, 0) - - def test_write(self): - shell = MockShell() - f = PseudoOutputFile(shell, 'stdout', 'utf-8') - f.write('test') - self.assertEqual(shell.written, [('test', 'stdout')]) - shell.reset() - f.write('t\xe8st') - self.assertEqual(shell.written, [('t\xe8st', 'stdout')]) - shell.reset() - - f.write(S('t\xe8st')) - self.assertEqual(shell.written, [('t\xe8st', 'stdout')]) - self.assertEqual(type(shell.written[0][0]), str) - shell.reset() +"Test , coverage 16%." - self.assertRaises(TypeError, f.write) - self.assertEqual(shell.written, []) - self.assertRaises(TypeError, f.write, b'test') - self.assertRaises(TypeError, f.write, 123) - self.assertEqual(shell.written, []) - self.assertRaises(TypeError, f.write, 'test', 'spam') - self.assertEqual(shell.written, []) - - def test_writelines(self): - shell = MockShell() - f = PseudoOutputFile(shell, 'stdout', 'utf-8') - f.writelines([]) - self.assertEqual(shell.written, []) - shell.reset() - f.writelines(['one\n', 'two']) - self.assertEqual(shell.written, - [('one\n', 'stdout'), ('two', 'stdout')]) - shell.reset() - f.writelines(['on\xe8\n', 'tw\xf2']) - self.assertEqual(shell.written, - [('on\xe8\n', 'stdout'), ('tw\xf2', 'stdout')]) - shell.reset() - - f.writelines([S('t\xe8st')]) - self.assertEqual(shell.written, [('t\xe8st', 'stdout')]) - self.assertEqual(type(shell.written[0][0]), str) - shell.reset() - - self.assertRaises(TypeError, f.writelines) - self.assertEqual(shell.written, []) - self.assertRaises(TypeError, f.writelines, 123) - self.assertEqual(shell.written, []) - self.assertRaises(TypeError, f.writelines, [b'test']) - self.assertRaises(TypeError, f.writelines, [123]) - self.assertEqual(shell.written, []) - self.assertRaises(TypeError, f.writelines, [], []) - self.assertEqual(shell.written, []) - - def test_close(self): - shell = MockShell() - f = PseudoOutputFile(shell, 'stdout', 'utf-8') - self.assertFalse(f.closed) - f.write('test') - f.close() - self.assertTrue(f.closed) - self.assertRaises(ValueError, f.write, 'x') - self.assertEqual(shell.written, [('test', 'stdout')]) - f.close() - self.assertRaises(TypeError, f.close, 1) - - -class PseudeInputFilesTest(unittest.TestCase): - def test_misc(self): - shell = MockShell() - f = PseudoInputFile(shell, 'stdin', 'utf-8') - self.assertIsInstance(f, io.TextIOBase) - self.assertEqual(f.encoding, 'utf-8') - self.assertIsNone(f.errors) - self.assertIsNone(f.newlines) - self.assertEqual(f.name, '<stdin>') - self.assertFalse(f.closed) - self.assertTrue(f.isatty()) - self.assertTrue(f.readable()) - self.assertFalse(f.writable()) - self.assertFalse(f.seekable()) - - def test_unsupported(self): - shell = MockShell() - f = PseudoInputFile(shell, 'stdin', 'utf-8') - self.assertRaises(OSError, f.fileno) - self.assertRaises(OSError, f.tell) - self.assertRaises(OSError, f.seek, 0) - self.assertRaises(OSError, f.write, 'x') - self.assertRaises(OSError, f.writelines, ['x']) - - def test_read(self): - shell = MockShell() - f = PseudoInputFile(shell, 'stdin', 'utf-8') - shell.push(['one\n', 'two\n', '']) - self.assertEqual(f.read(), 'one\ntwo\n') - shell.push(['one\n', 'two\n', '']) - self.assertEqual(f.read(-1), 'one\ntwo\n') - shell.push(['one\n', 'two\n', '']) - self.assertEqual(f.read(None), 'one\ntwo\n') - shell.push(['one\n', 'two\n', 'three\n', '']) - self.assertEqual(f.read(2), 'on') - self.assertEqual(f.read(3), 'e\nt') - self.assertEqual(f.read(10), 'wo\nthree\n') - - shell.push(['one\n', 'two\n']) - self.assertEqual(f.read(0), '') - self.assertRaises(TypeError, f.read, 1.5) - self.assertRaises(TypeError, f.read, '1') - self.assertRaises(TypeError, f.read, 1, 1) - - def test_readline(self): - shell = MockShell() - f = PseudoInputFile(shell, 'stdin', 'utf-8') - shell.push(['one\n', 'two\n', 'three\n', 'four\n']) - self.assertEqual(f.readline(), 'one\n') - self.assertEqual(f.readline(-1), 'two\n') - self.assertEqual(f.readline(None), 'three\n') - shell.push(['one\ntwo\n']) - self.assertEqual(f.readline(), 'one\n') - self.assertEqual(f.readline(), 'two\n') - shell.push(['one', 'two', 'three']) - self.assertEqual(f.readline(), 'one') - self.assertEqual(f.readline(), 'two') - shell.push(['one\n', 'two\n', 'three\n']) - self.assertEqual(f.readline(2), 'on') - self.assertEqual(f.readline(1), 'e') - self.assertEqual(f.readline(1), '\n') - self.assertEqual(f.readline(10), 'two\n') - - shell.push(['one\n', 'two\n']) - self.assertEqual(f.readline(0), '') - self.assertRaises(TypeError, f.readlines, 1.5) - self.assertRaises(TypeError, f.readlines, '1') - self.assertRaises(TypeError, f.readlines, 1, 1) - - def test_readlines(self): - shell = MockShell() - f = PseudoInputFile(shell, 'stdin', 'utf-8') - shell.push(['one\n', 'two\n', '']) - self.assertEqual(f.readlines(), ['one\n', 'two\n']) - shell.push(['one\n', 'two\n', '']) - self.assertEqual(f.readlines(-1), ['one\n', 'two\n']) - shell.push(['one\n', 'two\n', '']) - self.assertEqual(f.readlines(None), ['one\n', 'two\n']) - shell.push(['one\n', 'two\n', '']) - self.assertEqual(f.readlines(0), ['one\n', 'two\n']) - shell.push(['one\n', 'two\n', '']) - self.assertEqual(f.readlines(3), ['one\n']) - shell.push(['one\n', 'two\n', '']) - self.assertEqual(f.readlines(4), ['one\n', 'two\n']) - - shell.push(['one\n', 'two\n', '']) - self.assertRaises(TypeError, f.readlines, 1.5) - self.assertRaises(TypeError, f.readlines, '1') - self.assertRaises(TypeError, f.readlines, 1, 1) - - def test_close(self): - shell = MockShell() - f = PseudoInputFile(shell, 'stdin', 'utf-8') - shell.push(['one\n', 'two\n', '']) - self.assertFalse(f.closed) - self.assertEqual(f.readline(), 'one\n') - f.close() - self.assertFalse(f.closed) - self.assertEqual(f.readline(), 'two\n') - self.assertRaises(TypeError, f.close, 1) +from idlelib import iomenu +import unittest +from test.support import requires +from tkinter import Tk + +from idlelib.editor import EditorWindow + + +class IOBindigTest(unittest.TestCase): + + @classmethod + def setUpClass(cls): + requires('gui') + cls.root = Tk() + cls.root.withdraw() + cls.editwin = EditorWindow(root=cls.root) + + @classmethod + def tearDownClass(cls): + cls.editwin._close() + del cls.editwin + cls.root.update_idletasks() + for id in cls.root.tk.call('after', 'info'): + cls.root.after_cancel(id) # Need for EditorWindow. + cls.root.destroy() + del cls.root + + def test_init(self): + io = iomenu.IOBinding(self.editwin) + self.assertIs(io.editwin, self.editwin) + io.close if __name__ == '__main__': diff --git a/Lib/idlelib/idle_test/test_macosx.py b/Lib/idlelib/idle_test/test_macosx.py index 3d85f3ca72254c..b6bd922e4b99dd 100644 --- a/Lib/idlelib/idle_test/test_macosx.py +++ b/Lib/idlelib/idle_test/test_macosx.py @@ -1,11 +1,9 @@ -'''Test idlelib.macosx.py. +"Test macosx, coverage 45% on Windows." -Coverage: 71% on Windows. -''' from idlelib import macosx +import unittest from test.support import requires import tkinter as tk -import unittest import unittest.mock as mock from idlelib.filelist import FileList diff --git a/Lib/idlelib/idle_test/test_mainmenu.py b/Lib/idlelib/idle_test/test_mainmenu.py new file mode 100644 index 00000000000000..7ec0368371c7df --- /dev/null +++ b/Lib/idlelib/idle_test/test_mainmenu.py @@ -0,0 +1,21 @@ +"Test mainmenu, coverage 100%." +# Reported as 88%; mocking turtledemo absence would have no point. + +from idlelib import mainmenu +import unittest + + +class MainMenuTest(unittest.TestCase): + + def test_menudefs(self): + actual = [item[0] for item in mainmenu.menudefs] + expect = ['file', 'edit', 'format', 'run', 'shell', + 'debug', 'options', 'window', 'help'] + self.assertEqual(actual, expect) + + def test_default_keydefs(self): + self.assertGreaterEqual(len(mainmenu.default_keydefs), 50) + + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_multicall.py b/Lib/idlelib/idle_test/test_multicall.py new file mode 100644 index 00000000000000..68156a743d7b9b --- /dev/null +++ b/Lib/idlelib/idle_test/test_multicall.py @@ -0,0 +1,40 @@ +"Test multicall, coverage 33%." + +from idlelib import multicall +import unittest +from test.support import requires +from tkinter import Tk, Text + + +class MultiCallTest(unittest.TestCase): + + @classmethod + def setUpClass(cls): + requires('gui') + cls.root = Tk() + cls.root.withdraw() + cls.mc = multicall.MultiCallCreator(Text) + + @classmethod + def tearDownClass(cls): + del cls.mc + cls.root.update_idletasks() +## for id in cls.root.tk.call('after', 'info'): +## cls.root.after_cancel(id) # Need for EditorWindow. + cls.root.destroy() + del cls.root + + def test_creator(self): + mc = self.mc + self.assertIs(multicall._multicall_dict[Text], mc) + self.assertTrue(issubclass(mc, Text)) + mc2 = multicall.MultiCallCreator(Text) + self.assertIs(mc, mc2) + + def test_init(self): + mctext = self.mc(self.root) + self.assertIsInstance(mctext._MultiCall__binders, list) + + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_outwin.py b/Lib/idlelib/idle_test/test_outwin.py index 231c7bf9cfb620..cd099ecd841b3c 100644 --- a/Lib/idlelib/idle_test/test_outwin.py +++ b/Lib/idlelib/idle_test/test_outwin.py @@ -1,12 +1,11 @@ -""" Test idlelib.outwin. -""" +"Test outwin, coverage 76%." +from idlelib import outwin import unittest +from test.support import requires from tkinter import Tk, Text from idlelib.idle_test.mock_tk import Mbox_func from idlelib.idle_test.mock_idle import Func -from idlelib import outwin -from test.support import requires from unittest import mock diff --git a/Lib/idlelib/idle_test/test_paragraph.py b/Lib/idlelib/idle_test/test_paragraph.py index ba350c976534e8..0cb966fb96ca0e 100644 --- a/Lib/idlelib/idle_test/test_paragraph.py +++ b/Lib/idlelib/idle_test/test_paragraph.py @@ -1,9 +1,10 @@ -# Test the functions and main class method of paragraph.py +"Test paragraph, coverage 76%." + +from idlelib import paragraph as pg import unittest -from idlelib import paragraph as fp -from idlelib.editor import EditorWindow -from tkinter import Tk, Text from test.support import requires +from tkinter import Tk, Text +from idlelib.editor import EditorWindow class Is_Get_Test(unittest.TestCase): @@ -15,26 +16,26 @@ class Is_Get_Test(unittest.TestCase): leadingws_nocomment = ' This is not a comment' def test_is_all_white(self): - self.assertTrue(fp.is_all_white('')) - self.assertTrue(fp.is_all_white('\t\n\r\f\v')) - self.assertFalse(fp.is_all_white(self.test_comment)) + self.assertTrue(pg.is_all_white('')) + self.assertTrue(pg.is_all_white('\t\n\r\f\v')) + self.assertFalse(pg.is_all_white(self.test_comment)) def test_get_indent(self): Equal = self.assertEqual - Equal(fp.get_indent(self.test_comment), '') - Equal(fp.get_indent(self.trailingws_comment), '') - Equal(fp.get_indent(self.leadingws_comment), ' ') - Equal(fp.get_indent(self.leadingws_nocomment), ' ') + Equal(pg.get_indent(self.test_comment), '') + Equal(pg.get_indent(self.trailingws_comment), '') + Equal(pg.get_indent(self.leadingws_comment), ' ') + Equal(pg.get_indent(self.leadingws_nocomment), ' ') def test_get_comment_header(self): Equal = self.assertEqual # Test comment strings - Equal(fp.get_comment_header(self.test_comment), '#') - Equal(fp.get_comment_header(self.trailingws_comment), '#') - Equal(fp.get_comment_header(self.leadingws_comment), ' #') + Equal(pg.get_comment_header(self.test_comment), '#') + Equal(pg.get_comment_header(self.trailingws_comment), '#') + Equal(pg.get_comment_header(self.leadingws_comment), ' #') # Test non-comment strings - Equal(fp.get_comment_header(self.leadingws_nocomment), ' ') - Equal(fp.get_comment_header(self.test_nocomment), '') + Equal(pg.get_comment_header(self.leadingws_nocomment), ' ') + Equal(pg.get_comment_header(self.test_nocomment), '') class FindTest(unittest.TestCase): @@ -62,7 +63,7 @@ def runcase(self, inserttext, stopline, expected): linelength = int(text.index("%d.end" % line).split('.')[1]) for col in (0, linelength//2, linelength): tempindex = "%d.%d" % (line, col) - self.assertEqual(fp.find_paragraph(text, tempindex), expected) + self.assertEqual(pg.find_paragraph(text, tempindex), expected) text.delete('1.0', 'end') def test_find_comment(self): @@ -161,7 +162,7 @@ class ReformatFunctionTest(unittest.TestCase): def test_reformat_paragraph(self): Equal = self.assertEqual - reform = fp.reformat_paragraph + reform = pg.reformat_paragraph hw = "O hello world" Equal(reform(' ', 1), ' ') Equal(reform("Hello world", 20), "Hello world") @@ -192,7 +193,7 @@ def test_reformat_comment(self): test_string = ( " \"\"\"this is a test of a reformat for a triple quoted string" " will it reformat to less than 70 characters for me?\"\"\"") - result = fp.reformat_comment(test_string, 70, " ") + result = pg.reformat_comment(test_string, 70, " ") expected = ( " \"\"\"this is a test of a reformat for a triple quoted string will it\n" " reformat to less than 70 characters for me?\"\"\"") @@ -201,7 +202,7 @@ def test_reformat_comment(self): test_comment = ( "# this is a test of a reformat for a triple quoted string will " "it reformat to less than 70 characters for me?") - result = fp.reformat_comment(test_comment, 70, "#") + result = pg.reformat_comment(test_comment, 70, "#") expected = ( "# this is a test of a reformat for a triple quoted string will it\n" "# reformat to less than 70 characters for me?") @@ -210,7 +211,7 @@ def test_reformat_comment(self): class FormatClassTest(unittest.TestCase): def test_init_close(self): - instance = fp.FormatParagraph('editor') + instance = pg.FormatParagraph('editor') self.assertEqual(instance.editwin, 'editor') instance.close() self.assertEqual(instance.editwin, None) @@ -269,14 +270,16 @@ class FormatEventTest(unittest.TestCase): def setUpClass(cls): requires('gui') cls.root = Tk() + cls.root.withdraw() editor = Editor(root=cls.root) cls.text = editor.text.text # Test code does not need the wrapper. - cls.formatter = fp.FormatParagraph(editor).format_paragraph_event + cls.formatter = pg.FormatParagraph(editor).format_paragraph_event # Sets the insert mark just after the re-wrapped and inserted text. @classmethod def tearDownClass(cls): del cls.text, cls.formatter + cls.root.update_idletasks() cls.root.destroy() del cls.root diff --git a/Lib/idlelib/idle_test/test_parenmatch.py b/Lib/idlelib/idle_test/test_parenmatch.py index 3caa2754a6d8a2..f58819abf11211 100644 --- a/Lib/idlelib/idle_test/test_parenmatch.py +++ b/Lib/idlelib/idle_test/test_parenmatch.py @@ -1,8 +1,8 @@ -'''Test idlelib.parenmatch. +"""Test parenmatch, coverage 91%. This must currently be a gui test because ParenMatch methods use several text methods not defined on idlelib.idle_test.mock_tk.Text. -''' +""" from idlelib.parenmatch import ParenMatch from test.support import requires requires('gui') diff --git a/Lib/idlelib/idle_test/test_pathbrowser.py b/Lib/idlelib/idle_test/test_pathbrowser.py index 74b716a3199327..13d8b9e1ba9572 100644 --- a/Lib/idlelib/idle_test/test_pathbrowser.py +++ b/Lib/idlelib/idle_test/test_pathbrowser.py @@ -1,19 +1,17 @@ -""" Test idlelib.pathbrowser. -""" +"Test pathbrowser, coverage 95%." +from idlelib import pathbrowser +import unittest +from test.support import requires +from tkinter import Tk import os.path import pyclbr # for _modules import sys # for sys.path -from tkinter import Tk -from test.support import requires -import unittest from idlelib.idle_test.mock_idle import Func - import idlelib # for __file__ from idlelib import browser -from idlelib import pathbrowser from idlelib.tree import TreeNode diff --git a/Lib/idlelib/idle_test/test_percolator.py b/Lib/idlelib/idle_test/test_percolator.py index 573b9a1e8e69e3..17668ccd1227b7 100644 --- a/Lib/idlelib/idle_test/test_percolator.py +++ b/Lib/idlelib/idle_test/test_percolator.py @@ -1,10 +1,10 @@ -'''Test percolator.py.''' -from test.support import requires -requires('gui') +"Test percolator, coverage 100%." +from idlelib.percolator import Percolator, Delegator import unittest +from test.support import requires +requires('gui') from tkinter import Text, Tk, END -from idlelib.percolator import Percolator, Delegator class MyFilter(Delegator): diff --git a/Lib/idlelib/idle_test/test_pyparse.py b/Lib/idlelib/idle_test/test_pyparse.py index 574b19d9d6f15c..0534301b36102f 100644 --- a/Lib/idlelib/idle_test/test_pyparse.py +++ b/Lib/idlelib/idle_test/test_pyparse.py @@ -1,11 +1,8 @@ -"""Unittest for idlelib.pyparse.py. +"Test pyparse, coverage 96%." -Coverage: 97% -""" - -from collections import namedtuple -import unittest from idlelib import pyparse +import unittest +from collections import namedtuple class ParseMapTest(unittest.TestCase): diff --git a/Lib/idlelib/idle_test/test_pyshell.py b/Lib/idlelib/idle_test/test_pyshell.py new file mode 100644 index 00000000000000..581444ca5ef21f --- /dev/null +++ b/Lib/idlelib/idle_test/test_pyshell.py @@ -0,0 +1,42 @@ +"Test pyshell, coverage 12%." +# Plus coverage of test_warning. Was 20% with test_openshell. + +from idlelib import pyshell +import unittest +from test.support import requires +from tkinter import Tk + + +class PyShellFileListTest(unittest.TestCase): + + @classmethod + def setUpClass(cls): + requires('gui') + cls.root = Tk() + cls.root.withdraw() + + @classmethod + def tearDownClass(cls): + #cls.root.update_idletasks() +## for id in cls.root.tk.call('after', 'info'): +## cls.root.after_cancel(id) # Need for EditorWindow. + cls.root.destroy() + del cls.root + + def test_init(self): + psfl = pyshell.PyShellFileList(self.root) + self.assertEqual(psfl.EditorWindow, pyshell.PyShellEditorWindow) + self.assertIsNone(psfl.pyshell) + +# The following sometimes causes 'invalid command name "109734456recolorize"'. +# Uncommenting after_cancel above prevents this, but results in +# TclError: bad window path name ".!listedtoplevel.!frame.text" +# which is normally prevented by after_cancel. +## def test_openshell(self): +## pyshell.use_subprocess = False +## ps = pyshell.PyShellFileList(self.root).open_shell() +## self.assertIsInstance(ps, pyshell.PyShell) + + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_query.py b/Lib/idlelib/idle_test/test_query.py index 953f24f0a5ac82..c1c4a25cc50608 100644 --- a/Lib/idlelib/idle_test/test_query.py +++ b/Lib/idlelib/idle_test/test_query.py @@ -1,4 +1,4 @@ -"""Test idlelib.query. +"""Test query, coverage 91%). Non-gui tests for Query, SectionName, ModuleName, and HelpSource use dummy versions that extract the non-gui methods and add other needed @@ -8,17 +8,15 @@ The appearance of the widgets is checked by the Query and HelpSource htests. These are run by running query.py. - -Coverage: 94% (100% for Query and SectionName). -6 of 8 missing are ModuleName exceptions I don't know how to trigger. """ +from idlelib import query +import unittest from test.support import requires -import sys from tkinter import Tk -import unittest + +import sys from unittest import mock from idlelib.idle_test.mock_tk import Var -from idlelib import query # NON-GUI TESTS diff --git a/Lib/idlelib/idle_test/test_redirector.py b/Lib/idlelib/idle_test/test_redirector.py index b0385fa78cd974..a97b3002afcf12 100644 --- a/Lib/idlelib/idle_test/test_redirector.py +++ b/Lib/idlelib/idle_test/test_redirector.py @@ -1,12 +1,10 @@ -'''Test idlelib.redirector. +"Test redirector, coverage 100%." -100% coverage -''' -from test.support import requires +from idlelib.redirector import WidgetRedirector import unittest -from idlelib.idle_test.mock_idle import Func +from test.support import requires from tkinter import Tk, Text, TclError -from idlelib.redirector import WidgetRedirector +from idlelib.idle_test.mock_idle import Func class InitCloseTest(unittest.TestCase): diff --git a/Lib/idlelib/idle_test/test_replace.py b/Lib/idlelib/idle_test/test_replace.py index df76dec3e6276d..c3c5d2eeb94998 100644 --- a/Lib/idlelib/idle_test/test_replace.py +++ b/Lib/idlelib/idle_test/test_replace.py @@ -1,13 +1,14 @@ -"""Unittest for idlelib.replace.py""" +"Test replace, coverage 78%." + +from idlelib.replace import ReplaceDialog +import unittest from test.support import requires requires('gui') +from tkinter import Tk, Text -import unittest from unittest.mock import Mock -from tkinter import Tk, Text from idlelib.idle_test.mock_tk import Mbox import idlelib.searchengine as se -from idlelib.replace import ReplaceDialog orig_mbox = se.tkMessageBox showerror = Mbox.showerror diff --git a/Lib/idlelib/idle_test/test_rpc.py b/Lib/idlelib/idle_test/test_rpc.py new file mode 100644 index 00000000000000..48be65ba10b9cd --- /dev/null +++ b/Lib/idlelib/idle_test/test_rpc.py @@ -0,0 +1,30 @@ +"Test rpc, coverage 20%." + +from idlelib import rpc +import unittest + +import marshal + + +class CodePicklerTest(unittest.TestCase): + + def test_pickle_unpickle(self): + def f(): return a + b + c + func, (cbytes,) = rpc.pickle_code(f.__code__) + self.assertIs(func, rpc.unpickle_code) + self.assertIn(b'test_rpc.py', cbytes) + code = rpc.unpickle_code(cbytes) + self.assertEqual(code.co_names, ('a', 'b', 'c')) + + def test_code_pickler(self): + self.assertIn(type((lambda:None).__code__), + rpc.CodePickler.dispatch_table) + + def test_dumps(self): + def f(): pass + # The main test here is that pickling code does not raise. + self.assertIn(b'test_rpc.py', rpc.dumps(f.__code__)) + + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_rstrip.py b/Lib/idlelib/idle_test/test_rstrip.py index 130e6be257fe58..2bc7c6f035e96b 100644 --- a/Lib/idlelib/idle_test/test_rstrip.py +++ b/Lib/idlelib/idle_test/test_rstrip.py @@ -1,5 +1,7 @@ +"Test rstrip, coverage 100%." + +from idlelib import rstrip import unittest -import idlelib.rstrip as rs from idlelib.idle_test.mock_idle import Editor class rstripTest(unittest.TestCase): @@ -7,7 +9,7 @@ class rstripTest(unittest.TestCase): def test_rstrip_line(self): editor = Editor() text = editor.text - do_rstrip = rs.RstripExtension(editor).do_rstrip + do_rstrip = rstrip.Rstrip(editor).do_rstrip do_rstrip() self.assertEqual(text.get('1.0', 'insert'), '') @@ -20,12 +22,12 @@ def test_rstrip_line(self): def test_rstrip_multiple(self): editor = Editor() - # Uncomment following to verify that test passes with real widgets. -## from idlelib.editor import EditorWindow as Editor -## from tkinter import Tk -## editor = Editor(root=Tk()) + # Comment above, uncomment 3 below to test with real Editor & Text. + #from idlelib.editor import EditorWindow as Editor + #from tkinter import Tk + #editor = Editor(root=Tk()) text = editor.text - do_rstrip = rs.RstripExtension(editor).do_rstrip + do_rstrip = rstrip.Rstrip(editor).do_rstrip original = ( "Line with an ending tab \n" @@ -45,5 +47,7 @@ def test_rstrip_multiple(self): do_rstrip() self.assertEqual(text.get('1.0', 'insert'), stripped) + + if __name__ == '__main__': - unittest.main(verbosity=2, exit=False) + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_run.py b/Lib/idlelib/idle_test/test_run.py index d7e627d23d3841..46f0235fbfdca1 100644 --- a/Lib/idlelib/idle_test/test_run.py +++ b/Lib/idlelib/idle_test/test_run.py @@ -1,11 +1,14 @@ +"Test run, coverage 42%." + +from idlelib import run import unittest from unittest import mock - from test.support import captured_stderr -import idlelib.run as idlerun +import io class RunTest(unittest.TestCase): + def test_print_exception_unhashable(self): class UnhashableException(Exception): def __eq__(self, other): @@ -20,10 +23,10 @@ def __eq__(self, other): raise ex1 except UnhashableException: with captured_stderr() as output: - with mock.patch.object(idlerun, + with mock.patch.object(run, 'cleanup_traceback') as ct: ct.side_effect = lambda t, e: t - idlerun.print_exception() + run.print_exception() tb = output.getvalue().strip().splitlines() self.assertEqual(11, len(tb)) @@ -31,5 +34,231 @@ def __eq__(self, other): self.assertIn('UnhashableException: ex1', tb[10]) +# PseudoFile tests. + +class S(str): + def __str__(self): + return '%s:str' % type(self).__name__ + def __unicode__(self): + return '%s:unicode' % type(self).__name__ + def __len__(self): + return 3 + def __iter__(self): + return iter('abc') + def __getitem__(self, *args): + return '%s:item' % type(self).__name__ + def __getslice__(self, *args): + return '%s:slice' % type(self).__name__ + + +class MockShell: + def __init__(self): + self.reset() + def write(self, *args): + self.written.append(args) + def readline(self): + return self.lines.pop() + def close(self): + pass + def reset(self): + self.written = [] + def push(self, lines): + self.lines = list(lines)[::-1] + + +class PseudeInputFilesTest(unittest.TestCase): + + def test_misc(self): + shell = MockShell() + f = run.PseudoInputFile(shell, 'stdin', 'utf-8') + self.assertIsInstance(f, io.TextIOBase) + self.assertEqual(f.encoding, 'utf-8') + self.assertIsNone(f.errors) + self.assertIsNone(f.newlines) + self.assertEqual(f.name, '<stdin>') + self.assertFalse(f.closed) + self.assertTrue(f.isatty()) + self.assertTrue(f.readable()) + self.assertFalse(f.writable()) + self.assertFalse(f.seekable()) + + def test_unsupported(self): + shell = MockShell() + f = run.PseudoInputFile(shell, 'stdin', 'utf-8') + self.assertRaises(OSError, f.fileno) + self.assertRaises(OSError, f.tell) + self.assertRaises(OSError, f.seek, 0) + self.assertRaises(OSError, f.write, 'x') + self.assertRaises(OSError, f.writelines, ['x']) + + def test_read(self): + shell = MockShell() + f = run.PseudoInputFile(shell, 'stdin', 'utf-8') + shell.push(['one\n', 'two\n', '']) + self.assertEqual(f.read(), 'one\ntwo\n') + shell.push(['one\n', 'two\n', '']) + self.assertEqual(f.read(-1), 'one\ntwo\n') + shell.push(['one\n', 'two\n', '']) + self.assertEqual(f.read(None), 'one\ntwo\n') + shell.push(['one\n', 'two\n', 'three\n', '']) + self.assertEqual(f.read(2), 'on') + self.assertEqual(f.read(3), 'e\nt') + self.assertEqual(f.read(10), 'wo\nthree\n') + + shell.push(['one\n', 'two\n']) + self.assertEqual(f.read(0), '') + self.assertRaises(TypeError, f.read, 1.5) + self.assertRaises(TypeError, f.read, '1') + self.assertRaises(TypeError, f.read, 1, 1) + + def test_readline(self): + shell = MockShell() + f = run.PseudoInputFile(shell, 'stdin', 'utf-8') + shell.push(['one\n', 'two\n', 'three\n', 'four\n']) + self.assertEqual(f.readline(), 'one\n') + self.assertEqual(f.readline(-1), 'two\n') + self.assertEqual(f.readline(None), 'three\n') + shell.push(['one\ntwo\n']) + self.assertEqual(f.readline(), 'one\n') + self.assertEqual(f.readline(), 'two\n') + shell.push(['one', 'two', 'three']) + self.assertEqual(f.readline(), 'one') + self.assertEqual(f.readline(), 'two') + shell.push(['one\n', 'two\n', 'three\n']) + self.assertEqual(f.readline(2), 'on') + self.assertEqual(f.readline(1), 'e') + self.assertEqual(f.readline(1), '\n') + self.assertEqual(f.readline(10), 'two\n') + + shell.push(['one\n', 'two\n']) + self.assertEqual(f.readline(0), '') + self.assertRaises(TypeError, f.readlines, 1.5) + self.assertRaises(TypeError, f.readlines, '1') + self.assertRaises(TypeError, f.readlines, 1, 1) + + def test_readlines(self): + shell = MockShell() + f = run.PseudoInputFile(shell, 'stdin', 'utf-8') + shell.push(['one\n', 'two\n', '']) + self.assertEqual(f.readlines(), ['one\n', 'two\n']) + shell.push(['one\n', 'two\n', '']) + self.assertEqual(f.readlines(-1), ['one\n', 'two\n']) + shell.push(['one\n', 'two\n', '']) + self.assertEqual(f.readlines(None), ['one\n', 'two\n']) + shell.push(['one\n', 'two\n', '']) + self.assertEqual(f.readlines(0), ['one\n', 'two\n']) + shell.push(['one\n', 'two\n', '']) + self.assertEqual(f.readlines(3), ['one\n']) + shell.push(['one\n', 'two\n', '']) + self.assertEqual(f.readlines(4), ['one\n', 'two\n']) + + shell.push(['one\n', 'two\n', '']) + self.assertRaises(TypeError, f.readlines, 1.5) + self.assertRaises(TypeError, f.readlines, '1') + self.assertRaises(TypeError, f.readlines, 1, 1) + + def test_close(self): + shell = MockShell() + f = run.PseudoInputFile(shell, 'stdin', 'utf-8') + shell.push(['one\n', 'two\n', '']) + self.assertFalse(f.closed) + self.assertEqual(f.readline(), 'one\n') + f.close() + self.assertFalse(f.closed) + self.assertEqual(f.readline(), 'two\n') + self.assertRaises(TypeError, f.close, 1) + + +class PseudeOutputFilesTest(unittest.TestCase): + + def test_misc(self): + shell = MockShell() + f = run.PseudoOutputFile(shell, 'stdout', 'utf-8') + self.assertIsInstance(f, io.TextIOBase) + self.assertEqual(f.encoding, 'utf-8') + self.assertIsNone(f.errors) + self.assertIsNone(f.newlines) + self.assertEqual(f.name, '<stdout>') + self.assertFalse(f.closed) + self.assertTrue(f.isatty()) + self.assertFalse(f.readable()) + self.assertTrue(f.writable()) + self.assertFalse(f.seekable()) + + def test_unsupported(self): + shell = MockShell() + f = run.PseudoOutputFile(shell, 'stdout', 'utf-8') + self.assertRaises(OSError, f.fileno) + self.assertRaises(OSError, f.tell) + self.assertRaises(OSError, f.seek, 0) + self.assertRaises(OSError, f.read, 0) + self.assertRaises(OSError, f.readline, 0) + + def test_write(self): + shell = MockShell() + f = run.PseudoOutputFile(shell, 'stdout', 'utf-8') + f.write('test') + self.assertEqual(shell.written, [('test', 'stdout')]) + shell.reset() + f.write('t\xe8st') + self.assertEqual(shell.written, [('t\xe8st', 'stdout')]) + shell.reset() + + f.write(S('t\xe8st')) + self.assertEqual(shell.written, [('t\xe8st', 'stdout')]) + self.assertEqual(type(shell.written[0][0]), str) + shell.reset() + + self.assertRaises(TypeError, f.write) + self.assertEqual(shell.written, []) + self.assertRaises(TypeError, f.write, b'test') + self.assertRaises(TypeError, f.write, 123) + self.assertEqual(shell.written, []) + self.assertRaises(TypeError, f.write, 'test', 'spam') + self.assertEqual(shell.written, []) + + def test_writelines(self): + shell = MockShell() + f = run.PseudoOutputFile(shell, 'stdout', 'utf-8') + f.writelines([]) + self.assertEqual(shell.written, []) + shell.reset() + f.writelines(['one\n', 'two']) + self.assertEqual(shell.written, + [('one\n', 'stdout'), ('two', 'stdout')]) + shell.reset() + f.writelines(['on\xe8\n', 'tw\xf2']) + self.assertEqual(shell.written, + [('on\xe8\n', 'stdout'), ('tw\xf2', 'stdout')]) + shell.reset() + + f.writelines([S('t\xe8st')]) + self.assertEqual(shell.written, [('t\xe8st', 'stdout')]) + self.assertEqual(type(shell.written[0][0]), str) + shell.reset() + + self.assertRaises(TypeError, f.writelines) + self.assertEqual(shell.written, []) + self.assertRaises(TypeError, f.writelines, 123) + self.assertEqual(shell.written, []) + self.assertRaises(TypeError, f.writelines, [b'test']) + self.assertRaises(TypeError, f.writelines, [123]) + self.assertEqual(shell.written, []) + self.assertRaises(TypeError, f.writelines, [], []) + self.assertEqual(shell.written, []) + + def test_close(self): + shell = MockShell() + f = run.PseudoOutputFile(shell, 'stdout', 'utf-8') + self.assertFalse(f.closed) + f.write('test') + f.close() + self.assertTrue(f.closed) + self.assertRaises(ValueError, f.write, 'x') + self.assertEqual(shell.written, [('test', 'stdout')]) + f.close() + self.assertRaises(TypeError, f.close, 1) + + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_runscript.py b/Lib/idlelib/idle_test/test_runscript.py new file mode 100644 index 00000000000000..5fc60185a663e8 --- /dev/null +++ b/Lib/idlelib/idle_test/test_runscript.py @@ -0,0 +1,33 @@ +"Test runscript, coverage 16%." + +from idlelib import runscript +import unittest +from test.support import requires +from tkinter import Tk +from idlelib.editor import EditorWindow + + +class ScriptBindingTest(unittest.TestCase): + + @classmethod + def setUpClass(cls): + requires('gui') + cls.root = Tk() + cls.root.withdraw() + + @classmethod + def tearDownClass(cls): + cls.root.update_idletasks() + for id in cls.root.tk.call('after', 'info'): + cls.root.after_cancel(id) # Need for EditorWindow. + cls.root.destroy() + del cls.root + + def test_init(self): + ew = EditorWindow(root=self.root) + sb = runscript.ScriptBinding(ew) + ew._close() + + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_scrolledlist.py b/Lib/idlelib/idle_test/test_scrolledlist.py index 56aabfecf4a9ce..2f819fda025ba3 100644 --- a/Lib/idlelib/idle_test/test_scrolledlist.py +++ b/Lib/idlelib/idle_test/test_scrolledlist.py @@ -1,11 +1,9 @@ -''' Test idlelib.scrolledlist. +"Test scrolledlist, coverage 38%." -Coverage: 39% -''' -from idlelib import scrolledlist +from idlelib.scrolledlist import ScrolledList +import unittest from test.support import requires requires('gui') -import unittest from tkinter import Tk @@ -22,7 +20,7 @@ def tearDownClass(cls): def test_init(self): - scrolledlist.ScrolledList(self.root) + ScrolledList(self.root) if __name__ == '__main__': diff --git a/Lib/idlelib/idle_test/test_search.py b/Lib/idlelib/idle_test/test_search.py index 3ab72951efe3fa..de703c195cd229 100644 --- a/Lib/idlelib/idle_test/test_search.py +++ b/Lib/idlelib/idle_test/test_search.py @@ -1,25 +1,23 @@ -"""Test SearchDialog class in idlelib.search.py""" +"Test search, coverage 69%." + +from idlelib import search +import unittest +from test.support import requires +requires('gui') +from tkinter import Tk, Text, BooleanVar +from idlelib import searchengine # Does not currently test the event handler wrappers. # A usage test should simulate clicks and check highlighting. # Tests need to be coordinated with SearchDialogBase tests # to avoid duplication. -from test.support import requires -requires('gui') - -import unittest -import tkinter as tk -from tkinter import BooleanVar -import idlelib.searchengine as se -import idlelib.search as sd - class SearchDialogTest(unittest.TestCase): @classmethod def setUpClass(cls): - cls.root = tk.Tk() + cls.root = Tk() @classmethod def tearDownClass(cls): @@ -27,10 +25,10 @@ def tearDownClass(cls): del cls.root def setUp(self): - self.engine = se.SearchEngine(self.root) - self.dialog = sd.SearchDialog(self.root, self.engine) + self.engine = searchengine.SearchEngine(self.root) + self.dialog = search.SearchDialog(self.root, self.engine) self.dialog.bell = lambda: None - self.text = tk.Text(self.root) + self.text = Text(self.root) self.text.insert('1.0', 'Hello World!') def test_find_again(self): diff --git a/Lib/idlelib/idle_test/test_searchbase.py b/Lib/idlelib/idle_test/test_searchbase.py index 27b02fbe54602c..46c3ad111d1793 100644 --- a/Lib/idlelib/idle_test/test_searchbase.py +++ b/Lib/idlelib/idle_test/test_searchbase.py @@ -1,8 +1,7 @@ -'''tests idlelib.searchbase. +"Test searchbase, coverage 98%." +# The only thing not covered is inconsequential -- +# testing skipping of suite when self.needwrapbutton is false. -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, Frame ##, BooleanVar, StringVar @@ -22,6 +21,7 @@ ## se.BooleanVar = BooleanVar ## se.StringVar = StringVar + class SearchDialogBaseTest(unittest.TestCase): @classmethod diff --git a/Lib/idlelib/idle_test/test_searchengine.py b/Lib/idlelib/idle_test/test_searchengine.py index b3aa8eb81205ee..3d26d62a95a873 100644 --- a/Lib/idlelib/idle_test/test_searchengine.py +++ b/Lib/idlelib/idle_test/test_searchengine.py @@ -1,18 +1,19 @@ -'''Test functions and SearchEngine class in idlelib.searchengine.py.''' +"Test searchengine, coverage 99%." -# With mock replacements, the module does not use any gui widgets. -# The use of tk.Text is avoided (for now, until mock Text is improved) -# by patching instances with an index function returning what is needed. -# This works because mock Text.get does not use .index. - -import re +from idlelib import searchengine as se import unittest # from test.support import requires from tkinter import BooleanVar, StringVar, TclError # ,Tk, Text import tkinter.messagebox as tkMessageBox -from idlelib import searchengine as se from idlelib.idle_test.mock_tk import Var, Mbox from idlelib.idle_test.mock_tk import Text as mockText +import re + +# With mock replacements, the module does not use any gui widgets. +# The use of tk.Text is avoided (for now, until mock Text is improved) +# by patching instances with an index function returning what is needed. +# This works because mock Text.get does not use .index. +# The tkinter imports are used to restore searchengine. def setUpModule(): # Replace s-e module tkinter imports other than non-gui TclError. @@ -326,4 +327,4 @@ def test_search_backward(self): if __name__ == '__main__': - unittest.main(verbosity=2, exit=2) + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_stackviewer.py b/Lib/idlelib/idle_test/test_stackviewer.py new file mode 100644 index 00000000000000..98f53f9537bb25 --- /dev/null +++ b/Lib/idlelib/idle_test/test_stackviewer.py @@ -0,0 +1,47 @@ +"Test stackviewer, coverage 63%." + +from idlelib import stackviewer +import unittest +from test.support import requires +from tkinter import Tk + +from idlelib.tree import TreeNode, ScrolledCanvas +import sys + + +class StackBrowserTest(unittest.TestCase): + + @classmethod + def setUpClass(cls): + svs = stackviewer.sys + try: + abc + except NameError: + svs.last_type, svs.last_value, svs.last_traceback = ( + sys.exc_info()) + + requires('gui') + cls.root = Tk() + cls.root.withdraw() + + @classmethod + def tearDownClass(cls): + svs = stackviewer.sys + del svs.last_traceback, svs.last_type, svs.last_value + + cls.root.update_idletasks() +## for id in cls.root.tk.call('after', 'info'): +## cls.root.after_cancel(id) # Need for EditorWindow. + cls.root.destroy() + del cls.root + + def test_init(self): + sb = stackviewer.StackBrowser(self.root) + isi = self.assertIsInstance + isi(stackviewer.sc, ScrolledCanvas) + isi(stackviewer.item, stackviewer.StackTreeItem) + isi(stackviewer.node, TreeNode) + + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_statusbar.py b/Lib/idlelib/idle_test/test_statusbar.py new file mode 100644 index 00000000000000..203a57db89ca6a --- /dev/null +++ b/Lib/idlelib/idle_test/test_statusbar.py @@ -0,0 +1,41 @@ +"Test statusbar, coverage 100%." + +from idlelib import statusbar +import unittest +from test.support import requires +from tkinter import Tk + + +class Test(unittest.TestCase): + + @classmethod + def setUpClass(cls): + requires('gui') + cls.root = Tk() + cls.root.withdraw() + + @classmethod + def tearDownClass(cls): + cls.root.update_idletasks() + cls.root.destroy() + del cls.root + + def test_init(self): + bar = statusbar.MultiStatusBar(self.root) + self.assertEqual(bar.labels, {}) + + def test_set_label(self): + bar = statusbar.MultiStatusBar(self.root) + bar.set_label('left', text='sometext', width=10) + self.assertIn('left', bar.labels) + left = bar.labels['left'] + self.assertEqual(left['text'], 'sometext') + self.assertEqual(left['width'], 10) + bar.set_label('left', text='revised text') + self.assertEqual(left['text'], 'revised text') + bar.set_label('right', text='correct text') + self.assertEqual(bar.labels['right']['text'], 'correct text') + + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_textview.py b/Lib/idlelib/idle_test/test_textview.py index dfd4063eb08d1e..0d11e41e0fb450 100644 --- a/Lib/idlelib/idle_test/test_textview.py +++ b/Lib/idlelib/idle_test/test_textview.py @@ -1,17 +1,15 @@ -'''Test idlelib.textview. +"""Test textview, coverage 100%. Since all methods and functions create (or destroy) a ViewWindow, which is a widget containing a widget, etcetera, all tests must be gui tests. Using mock Text would not change this. Other mocks are used to retrieve information about calls. - -Coverage: 100%. -''' +""" from idlelib import textview as tv +import unittest from test.support import requires requires('gui') -import unittest import os from tkinter import Tk from tkinter.ttk import Button @@ -109,7 +107,7 @@ def test_view_text(self): view = tv.view_text(root, 'Title', 'test text', modal=False) self.assertIsInstance(view, tv.ViewWindow) self.assertIsInstance(view.viewframe, tv.ViewFrame) - view.ok() + view.viewframe.ok() def test_view_file(self): view = tv.view_file(root, 'Title', __file__, 'ascii', modal=False) diff --git a/Lib/idlelib/idle_test/test_tree.py b/Lib/idlelib/idle_test/test_tree.py index bb597d87ffd104..9be9abee361f08 100644 --- a/Lib/idlelib/idle_test/test_tree.py +++ b/Lib/idlelib/idle_test/test_tree.py @@ -1,11 +1,9 @@ -''' Test idlelib.tree. +"Test tree. coverage 56%." -Coverage: 56% -''' from idlelib import tree +import unittest from test.support import requires requires('gui') -import unittest from tkinter import Tk diff --git a/Lib/idlelib/idle_test/test_undo.py b/Lib/idlelib/idle_test/test_undo.py index e872927a6c6d99..beb5b582039f88 100644 --- a/Lib/idlelib/idle_test/test_undo.py +++ b/Lib/idlelib/idle_test/test_undo.py @@ -1,14 +1,13 @@ -"""Unittest for UndoDelegator in idlelib.undo.py. +"Test undo, coverage 77%." +# Only test UndoDelegator so far. -Coverage about 80% (retest). -""" +from idlelib.undo import UndoDelegator +import unittest from test.support import requires requires('gui') -import unittest from unittest.mock import Mock from tkinter import Text, Tk -from idlelib.undo import UndoDelegator from idlelib.percolator import Percolator @@ -131,5 +130,6 @@ def test_addcmd(self): text.insert('insert', 'foo') self.assertLessEqual(len(self.delegator.undolist), max_undo) + if __name__ == '__main__': unittest.main(verbosity=2, exit=False) diff --git a/Lib/idlelib/idle_test/test_warning.py b/Lib/idlelib/idle_test/test_warning.py index f3269f195af831..221068c5885fcb 100644 --- a/Lib/idlelib/idle_test/test_warning.py +++ b/Lib/idlelib/idle_test/test_warning.py @@ -5,20 +5,18 @@ Revise if output destination changes (http://bugs.python.org/issue18318). Make sure warnings module is left unaltered (http://bugs.python.org/issue18081). ''' - +from idlelib import run +from idlelib import pyshell as shell import unittest from test.support import captured_stderr - import warnings + # Try to capture default showwarning before Idle modules are imported. showwarning = warnings.showwarning # But if we run this file within idle, we are in the middle of the run.main loop # and default showwarnings has already been replaced. running_in_idle = 'idle' in showwarning.__name__ -from idlelib import run -from idlelib import pyshell as shell - # The following was generated from pyshell.idle_formatwarning # and checked as matching expectation. idlemsg = ''' @@ -29,6 +27,7 @@ ''' shellmsg = idlemsg + ">>> " + class RunWarnTest(unittest.TestCase): @unittest.skipIf(running_in_idle, "Does not work when run within Idle.") @@ -46,6 +45,7 @@ def test_run_show(self): # The following uses .splitlines to erase line-ending differences self.assertEqual(idlemsg.splitlines(), f.getvalue().splitlines()) + class ShellWarnTest(unittest.TestCase): @unittest.skipIf(running_in_idle, "Does not work when run within Idle.") @@ -70,4 +70,4 @@ def test_shell_show(self): if __name__ == '__main__': - unittest.main(verbosity=2, exit=False) + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_window.py b/Lib/idlelib/idle_test/test_window.py new file mode 100644 index 00000000000000..5a2645b9cc27dc --- /dev/null +++ b/Lib/idlelib/idle_test/test_window.py @@ -0,0 +1,45 @@ +"Test window, coverage 47%." + +from idlelib import window +import unittest +from test.support import requires +from tkinter import Tk + + +class WindowListTest(unittest.TestCase): + + def test_init(self): + wl = window.WindowList() + self.assertEqual(wl.dict, {}) + self.assertEqual(wl.callbacks, []) + + # Further tests need mock Window. + + +class ListedToplevelTest(unittest.TestCase): + + @classmethod + def setUpClass(cls): + window.registry = set() + requires('gui') + cls.root = Tk() + cls.root.withdraw() + + @classmethod + def tearDownClass(cls): + window.registry = window.WindowList() + cls.root.update_idletasks() +## for id in cls.root.tk.call('after', 'info'): +## cls.root.after_cancel(id) # Need for EditorWindow. + cls.root.destroy() + del cls.root + + def test_init(self): + + win = window.ListedToplevel(self.root) + self.assertIn(win, window.registry) + self.assertEqual(win.focused_widget, win) + + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_zoomheight.py b/Lib/idlelib/idle_test/test_zoomheight.py new file mode 100644 index 00000000000000..bac86ac249f6a5 --- /dev/null +++ b/Lib/idlelib/idle_test/test_zoomheight.py @@ -0,0 +1,39 @@ +"Test zoomheight, coverage 66%." +# Some code is system dependent. + +from idlelib import zoomheight +import unittest +from test.support import requires +from tkinter import Tk, Text +from idlelib.editor import EditorWindow + + +class Test(unittest.TestCase): + + @classmethod + def setUpClass(cls): + requires('gui') + cls.root = Tk() + cls.root.withdraw() + cls.editwin = EditorWindow(root=cls.root) + + @classmethod + def tearDownClass(cls): + cls.editwin._close() + cls.root.update_idletasks() + for id in cls.root.tk.call('after', 'info'): + cls.root.after_cancel(id) # Need for EditorWindow. + cls.root.destroy() + del cls.root + + def test_init(self): + zoom = zoomheight.ZoomHeight(self.editwin) + self.assertIs(zoom.editwin, self.editwin) + + def test_zoom_height_event(self): + zoom = zoomheight.ZoomHeight(self.editwin) + zoom.zoom_height_event() + + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/Lib/idlelib/iomenu.py b/Lib/idlelib/iomenu.py index f9b6907b40cecc..63d107dd9003df 100644 --- a/Lib/idlelib/iomenu.py +++ b/Lib/idlelib/iomenu.py @@ -567,8 +567,8 @@ def savecopy(self, event): IOBinding(editwin) if __name__ == "__main__": - import unittest - unittest.main('idlelib.idle_test.test_iomenu', verbosity=2, exit=False) + from unittest import main + main('idlelib.idle_test.test_iomenu', verbosity=2, exit=False) from idlelib.idle_test.htest import run run(_io_binding) diff --git a/Lib/idlelib/macosx.py b/Lib/idlelib/macosx.py index d85278a0b765ae..d3ae224100cff8 100644 --- a/Lib/idlelib/macosx.py +++ b/Lib/idlelib/macosx.py @@ -128,7 +128,7 @@ def overrideRootMenu(root, flist): # menu. from tkinter import Menu from idlelib import mainmenu - from idlelib import windows + from idlelib import window closeItem = mainmenu.menudefs[0][1][-2] @@ -148,7 +148,7 @@ def overrideRootMenu(root, flist): root.configure(menu=menubar) menudict = {} - menudict['windows'] = menu = Menu(menubar, name='windows', tearoff=0) + menudict['window'] = menu = Menu(menubar, name='window', tearoff=0) menubar.add_cascade(label='Window', menu=menu, underline=0) def postwindowsmenu(menu=menu): @@ -158,8 +158,8 @@ def postwindowsmenu(menu=menu): if end > 0: menu.delete(0, end) - windows.add_windows_to_menu(menu) - windows.register_callback(postwindowsmenu) + window.add_windows_to_menu(menu) + window.register_callback(postwindowsmenu) def about_dialog(event=None): "Handle Help 'About IDLE' event." diff --git a/Lib/idlelib/mainmenu.py b/Lib/idlelib/mainmenu.py index 143570d6b11c41..9fe6b5229446e3 100644 --- a/Lib/idlelib/mainmenu.py +++ b/Lib/idlelib/mainmenu.py @@ -36,7 +36,8 @@ None, ('_Close', '<<close-window>>'), ('E_xit', '<<close-all-windows>>'), - ]), + ]), + ('edit', [ ('_Undo', '<<undo>>'), ('_Redo', '<<redo>>'), @@ -56,9 +57,9 @@ ('E_xpand Word', '<<expand-word>>'), ('Show C_all Tip', '<<force-open-calltip>>'), ('Show Surrounding P_arens', '<<flash-paren>>'), + ]), - ]), -('format', [ + ('format', [ ('_Indent Region', '<<indent-region>>'), ('_Dedent Region', '<<dedent-region>>'), ('Comment _Out Region', '<<comment-region>>'), @@ -70,30 +71,36 @@ ('F_ormat Paragraph', '<<format-paragraph>>'), ('S_trip Trailing Whitespace', '<<do-rstrip>>'), ]), + ('run', [ ('Python Shell', '<<open-python-shell>>'), ('C_heck Module', '<<check-module>>'), ('R_un Module', '<<run-module>>'), ]), + ('shell', [ ('_View Last Restart', '<<view-restart>>'), ('_Restart Shell', '<<restart-shell>>'), None, ('_Interrupt Execution', '<<interrupt-execution>>'), ]), + ('debug', [ ('_Go to File/Line', '<<goto-file-line>>'), ('!_Debugger', '<<toggle-debugger>>'), ('_Stack Viewer', '<<open-stack-viewer>>'), ('!_Auto-open Stack Viewer', '<<toggle-jit-stack-viewer>>'), ]), + ('options', [ ('Configure _IDLE', '<<open-config-dialog>>'), ('_Code Context', '<<toggle-code-context>>'), ]), - ('windows', [ + + ('window', [ ('Zoom Height', '<<zoom-height>>'), ]), + ('help', [ ('_About IDLE', '<<about-idle>>'), None, @@ -106,3 +113,7 @@ menudefs[-1][1].append(('Turtle Demo', '<<open-turtle-demo>>')) default_keydefs = idleConf.GetCurrentKeySet() + +if __name__ == '__main__': + from unittest import main + main('idlelib.idle_test.test_mainmenu', verbosity=2) diff --git a/Lib/idlelib/multicall.py b/Lib/idlelib/multicall.py index b74fed4c0cd13f..dc02001292fc14 100644 --- a/Lib/idlelib/multicall.py +++ b/Lib/idlelib/multicall.py @@ -441,5 +441,8 @@ def handler(event): bindseq("<Leave>") if __name__ == "__main__": + from unittest import main + main('idlelib.idle_test.test_mainmenu', verbosity=2, exit=False) + from idlelib.idle_test.htest import run run(_multi_call) diff --git a/Lib/idlelib/outwin.py b/Lib/idlelib/outwin.py index 6c2a792d86b99a..4af9f1afaed518 100644 --- a/Lib/idlelib/outwin.py +++ b/Lib/idlelib/outwin.py @@ -184,5 +184,5 @@ def setup(self): self.write = self.owin.write if __name__ == '__main__': - import unittest - unittest.main('idlelib.idle_test.test_outwin', verbosity=2, exit=False) + from unittest import main + main('idlelib.idle_test.test_outwin', verbosity=2, exit=False) diff --git a/Lib/idlelib/paragraph.py b/Lib/idlelib/paragraph.py index 1270115a44ce44..81422571fa32f4 100644 --- a/Lib/idlelib/paragraph.py +++ b/Lib/idlelib/paragraph.py @@ -190,6 +190,5 @@ def get_comment_header(line): if __name__ == "__main__": - import unittest - unittest.main('idlelib.idle_test.test_paragraph', - verbosity=2, exit=False) + from unittest import main + main('idlelib.idle_test.test_paragraph', verbosity=2, exit=False) diff --git a/Lib/idlelib/parenmatch.py b/Lib/idlelib/parenmatch.py index 983ca20675af1d..3fd7aadb2aea84 100644 --- a/Lib/idlelib/parenmatch.py +++ b/Lib/idlelib/parenmatch.py @@ -179,5 +179,5 @@ def set_timeout_last(self): if __name__ == '__main__': - import unittest - unittest.main('idlelib.idle_test.test_parenmatch', verbosity=2) + from unittest import main + main('idlelib.idle_test.test_parenmatch', verbosity=2) diff --git a/Lib/idlelib/percolator.py b/Lib/idlelib/percolator.py index d18daf05863c18..db70304f589159 100644 --- a/Lib/idlelib/percolator.py +++ b/Lib/idlelib/percolator.py @@ -96,9 +96,8 @@ def toggle2(): cb2.pack() if __name__ == "__main__": - import unittest - unittest.main('idlelib.idle_test.test_percolator', verbosity=2, - exit=False) + from unittest import main + main('idlelib.idle_test.test_percolator', verbosity=2, exit=False) from idlelib.idle_test.htest import run run(_percolator) diff --git a/Lib/idlelib/pyparse.py b/Lib/idlelib/pyparse.py index 6196c2b7edc9ea..1eeb9154d90610 100644 --- a/Lib/idlelib/pyparse.py +++ b/Lib/idlelib/pyparse.py @@ -594,6 +594,6 @@ def get_last_stmt_bracketing(self): return self.stmt_bracketing -if __name__ == '__main__': #pragma: nocover - import unittest - unittest.main('idlelib.idle_test.test_pyparse', verbosity=2) +if __name__ == '__main__': + from unittest import main + main('idlelib.idle_test.test_pyparse', verbosity=2) diff --git a/Lib/idlelib/pyshell.py b/Lib/idlelib/pyshell.py index ddfb56acdbc44f..52c11e30dbd500 100755 --- a/Lib/idlelib/pyshell.py +++ b/Lib/idlelib/pyshell.py @@ -852,7 +852,7 @@ class PyShell(OutputWindow): ("edit", "_Edit"), ("debug", "_Debug"), ("options", "_Options"), - ("windows", "_Window"), + ("window", "_Window"), ("help", "_Help"), ] @@ -1033,7 +1033,7 @@ def short_title(self): return self.shell_title COPYRIGHT = \ - 'Type "copyright", "credits" or "license()" for more information.' + 'Type "help", "copyright", "credits" or "license()" for more information.' def begin(self): self.text.mark_set("iomark", "insert") diff --git a/Lib/idlelib/query.py b/Lib/idlelib/query.py index 593506383c41ab..15add6d12748d0 100644 --- a/Lib/idlelib/query.py +++ b/Lib/idlelib/query.py @@ -301,8 +301,8 @@ def entry_ok(self): if __name__ == '__main__': - import unittest - unittest.main('idlelib.idle_test.test_query', verbosity=2, exit=False) + from unittest import main + main('idlelib.idle_test.test_query', verbosity=2, exit=False) from idlelib.idle_test.htest import run run(Query, HelpSource) diff --git a/Lib/idlelib/redirector.py b/Lib/idlelib/redirector.py index ec681de38d457f..9ab34c5acfb22c 100644 --- a/Lib/idlelib/redirector.py +++ b/Lib/idlelib/redirector.py @@ -167,9 +167,8 @@ def my_insert(*args): original_insert = redir.register("insert", my_insert) if __name__ == "__main__": - import unittest - unittest.main('idlelib.idle_test.test_redirector', - verbosity=2, exit=False) + from unittest import main + main('idlelib.idle_test.test_redirector', verbosity=2, exit=False) from idlelib.idle_test.htest import run run(_widget_redirector) diff --git a/Lib/idlelib/replace.py b/Lib/idlelib/replace.py index abd9e59f4e5d17..83cf98756bdf81 100644 --- a/Lib/idlelib/replace.py +++ b/Lib/idlelib/replace.py @@ -235,9 +235,8 @@ def show_replace(): button.pack() if __name__ == '__main__': - import unittest - unittest.main('idlelib.idle_test.test_replace', - verbosity=2, exit=False) + from unittest import main + main('idlelib.idle_test.test_replace', verbosity=2, exit=False) from idlelib.idle_test.htest import run run(_replace_dialog) diff --git a/Lib/idlelib/rpc.py b/Lib/idlelib/rpc.py index 8f57edb836dec8..9962477cc56185 100644 --- a/Lib/idlelib/rpc.py +++ b/Lib/idlelib/rpc.py @@ -43,16 +43,20 @@ import types def unpickle_code(ms): + "Return code object from marshal string ms." co = marshal.loads(ms) assert isinstance(co, types.CodeType) return co def pickle_code(co): + "Return unpickle function and tuple with marshalled co code object." assert isinstance(co, types.CodeType) ms = marshal.dumps(co) return unpickle_code, (ms,) def dumps(obj, protocol=None): + "Return pickled (or marshalled) string for obj." + # IDLE passes 'None' to select pickle.DEFAULT_PROTOCOL. f = io.BytesIO() p = CodePickler(f, protocol) p.dump(obj) @@ -625,3 +629,8 @@ def displayhook(value): sys.stdout.write(text) sys.stdout.write("\n") builtins._ = value + + +if __name__ == '__main__': + from unittest import main + main('idlelib.idle_test.test_rpc', verbosity=2,) diff --git a/Lib/idlelib/rstrip.py b/Lib/idlelib/rstrip.py index 18c86f9b2c8896..f93b5e8fc20021 100644 --- a/Lib/idlelib/rstrip.py +++ b/Lib/idlelib/rstrip.py @@ -1,6 +1,6 @@ 'Provides "Strip trailing whitespace" under the "Format" menu.' -class RstripExtension: +class Rstrip: def __init__(self, editwin): self.editwin = editwin @@ -25,5 +25,5 @@ def do_rstrip(self, event=None): undo.undo_block_stop() if __name__ == "__main__": - import unittest - unittest.main('idlelib.idle_test.test_rstrip', verbosity=2, exit=False) + from unittest import main + main('idlelib.idle_test.test_rstrip', verbosity=2,) diff --git a/Lib/idlelib/run.py b/Lib/idlelib/run.py index 176fe3db743bd4..6fa373f2584c27 100644 --- a/Lib/idlelib/run.py +++ b/Lib/idlelib/run.py @@ -11,7 +11,7 @@ import tkinter # Tcl, deletions, messagebox if startup fails from idlelib import autocomplete # AutoComplete, fetch_encodings -from idlelib import calltips # CallTips +from idlelib import calltip # Calltip from idlelib import debugger_r # start_debugger from idlelib import debugobj_r # remote_object_tree_item from idlelib import iomenu # encoding @@ -462,7 +462,7 @@ class Executive(object): def __init__(self, rpchandler): self.rpchandler = rpchandler self.locals = __main__.__dict__ - self.calltip = calltips.CallTips() + self.calltip = calltip.Calltip() self.autocomplete = autocomplete.AutoComplete() def runcode(self, code): diff --git a/Lib/idlelib/runscript.py b/Lib/idlelib/runscript.py index 45bf56345825a1..83433b1cf0a459 100644 --- a/Lib/idlelib/runscript.py +++ b/Lib/idlelib/runscript.py @@ -193,3 +193,8 @@ def errorbox(self, title, message): # XXX This should really be a function of EditorWindow... tkMessageBox.showerror(title, message, parent=self.editwin.text) self.editwin.text.focus_set() + + +if __name__ == "__main__": + from unittest import main + main('idlelib.idle_test.test_runscript', verbosity=2,) diff --git a/Lib/idlelib/scrolledlist.py b/Lib/idlelib/scrolledlist.py index cdf658404ab643..10229b63629293 100644 --- a/Lib/idlelib/scrolledlist.py +++ b/Lib/idlelib/scrolledlist.py @@ -142,6 +142,8 @@ def on_double(self, index): print("double", self.get(index)) scrolled_list.append("Item %02d" % i) if __name__ == '__main__': - # At the moment, test_scrolledlist merely creates instance, like htest. + from unittest import main + main('idlelib.idle_test.test_scrolledlist', verbosity=2,) + from idlelib.idle_test.htest import run run(_scrolled_list) diff --git a/Lib/idlelib/search.py b/Lib/idlelib/search.py index 4b906593082284..6223661c8e080a 100644 --- a/Lib/idlelib/search.py +++ b/Lib/idlelib/search.py @@ -94,9 +94,8 @@ def show_find(): button.pack() if __name__ == '__main__': - import unittest - unittest.main('idlelib.idle_test.test_search', - verbosity=2, exit=False) + from unittest import main + main('idlelib.idle_test.test_search', verbosity=2, exit=False) from idlelib.idle_test.htest import run run(_search_dialog) diff --git a/Lib/idlelib/searchbase.py b/Lib/idlelib/searchbase.py index 5f81785b712c08..9b03ff64c1e1a6 100644 --- a/Lib/idlelib/searchbase.py +++ b/Lib/idlelib/searchbase.py @@ -192,9 +192,10 @@ def __init__(self, parent): def default_command(self, dummy): pass + if __name__ == '__main__': - import unittest - unittest.main('idlelib.idle_test.test_searchbase', verbosity=2, exit=False) + from unittest import main + main('idlelib.idle_test.test_searchbase', verbosity=2, exit=False) from idlelib.idle_test.htest import run run(_searchbase) diff --git a/Lib/idlelib/searchengine.py b/Lib/idlelib/searchengine.py index 253f1b0831a619..911e7d4691cac1 100644 --- a/Lib/idlelib/searchengine.py +++ b/Lib/idlelib/searchengine.py @@ -231,6 +231,7 @@ def get_line_col(index): line, col = map(int, index.split(".")) # Fails on invalid index return line, col + if __name__ == "__main__": - import unittest - unittest.main('idlelib.idle_test.test_searchengine', verbosity=2, exit=False) + from unittest import main + main('idlelib.idle_test.test_searchengine', verbosity=2) diff --git a/Lib/idlelib/stackviewer.py b/Lib/idlelib/stackviewer.py index 400fa632a098cf..94ffb4eff4dd26 100644 --- a/Lib/idlelib/stackviewer.py +++ b/Lib/idlelib/stackviewer.py @@ -8,6 +8,7 @@ from idlelib.tree import TreeNode, TreeItem, ScrolledCanvas def StackBrowser(root, flist=None, tb=None, top=None): + global sc, item, node # For testing. if top is None: top = tk.Toplevel(root) sc = ScrolledCanvas(top, bg="white", highlightthickness=0) @@ -134,7 +135,6 @@ def _stack_viewer(parent): # htest # 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 @@ -148,5 +148,8 @@ def _stack_viewer(parent): # htest # del sys.last_traceback if __name__ == '__main__': + from unittest import main + main('idlelib.idle_test.test_stackviewer', verbosity=2, exit=False) + from idlelib.idle_test.htest import run run(_stack_viewer) diff --git a/Lib/idlelib/statusbar.py b/Lib/idlelib/statusbar.py index 8618528d822130..c071f898b0f744 100644 --- a/Lib/idlelib/statusbar.py +++ b/Lib/idlelib/statusbar.py @@ -42,5 +42,8 @@ def change(): frame.pack() if __name__ == '__main__': + from unittest import main + main('idlelib.idle_test.test_statusbar', verbosity=2, exit=False) + from idlelib.idle_test.htest import run run(_multistatus_bar) diff --git a/Lib/idlelib/textview.py b/Lib/idlelib/textview.py index 66201344061090..d9260e6c7183fc 100644 --- a/Lib/idlelib/textview.py +++ b/Lib/idlelib/textview.py @@ -130,7 +130,8 @@ def view_file(parent, title, filename, encoding, modal=True, _utest=False): if __name__ == '__main__': - import unittest - unittest.main('idlelib.idle_test.test_textview', verbosity=2, exit=False) + from unittest import main + main('idlelib.idle_test.test_textview', verbosity=2, exit=False) + from idlelib.idle_test.htest import run run(ViewWindow) diff --git a/Lib/idlelib/tree.py b/Lib/idlelib/tree.py index 292ce36184c76d..05f864657fb827 100644 --- a/Lib/idlelib/tree.py +++ b/Lib/idlelib/tree.py @@ -462,6 +462,8 @@ def _tree_widget(parent): # htest # node.expand() if __name__ == '__main__': - # test_tree is currently a copy of this + from unittest import main + main('idlelib.idle_test.test_tree', verbosity=2, exit=False) + from idlelib.idle_test.htest import run run(_tree_widget) diff --git a/Lib/idlelib/undo.py b/Lib/idlelib/undo.py index 4332f1099343b4..f048994b7d15c3 100644 --- a/Lib/idlelib/undo.py +++ b/Lib/idlelib/undo.py @@ -359,8 +359,8 @@ def _undo_delegator(parent): # htest # dump.pack(side='left') if __name__ == "__main__": - import unittest - unittest.main('idlelib.idle_test.test_undo', verbosity=2, exit=False) + from unittest import main + main('idlelib.idle_test.test_undo', verbosity=2, exit=False) from idlelib.idle_test.htest import run run(_undo_delegator) diff --git a/Lib/idlelib/windows.py b/Lib/idlelib/window.py similarity index 93% rename from Lib/idlelib/windows.py rename to Lib/idlelib/window.py index a3f858aa73fc48..b2488b28cabe7e 100644 --- a/Lib/idlelib/windows.py +++ b/Lib/idlelib/window.py @@ -87,6 +87,11 @@ def wakeup(self): self.tkraise() self.focused_widget.focus_set() except TclError: - # This can happen when the window menu was torn off. + # This can happen when the Window menu was torn off. # Simply ignore it. pass + + +if __name__ == "__main__": + from unittest import main + main('idlelib.idle_test.test_window', verbosity=2) diff --git a/Lib/idlelib/zoomheight.py b/Lib/idlelib/zoomheight.py index 74fbc888a80d3f..73f1df071bf3bf 100644 --- a/Lib/idlelib/zoomheight.py +++ b/Lib/idlelib/zoomheight.py @@ -11,7 +11,7 @@ class ZoomHeight: def __init__(self, editwin): self.editwin = editwin - def zoom_height_event(self, event): + def zoom_height_event(self, event=None): top = self.editwin.top zoom_height(top) return "break" @@ -46,3 +46,10 @@ def zoom_height(top): else: newgeom = "%dx%d+%d+%d" % (width, newheight, x, newy) top.wm_geometry(newgeom) + + +if __name__ == "__main__": + from unittest import main + main('idlelib.idle_test.test_zoomheight', verbosity=2, exit=False) + + # Add htest? diff --git a/Lib/imp.py b/Lib/imp.py index 866464b245b24c..31f8c766381adc 100644 --- a/Lib/imp.py +++ b/Lib/imp.py @@ -142,17 +142,16 @@ def __init__(self, fullname, path, file=None): def get_data(self, path): """Gross hack to contort loader to deal w/ load_*()'s bad API.""" if self.file and path == self.path: + # The contract of get_data() requires us to return bytes. Reopen the + # file in binary mode if needed. if not self.file.closed: file = self.file - else: - self.file = file = open(self.path, 'r') + if 'b' not in file.mode: + file.close() + if self.file.closed: + self.file = file = open(self.path, 'rb') with file: - # Technically should be returning bytes, but - # SourceLoader.get_code() just passed what is returned to - # compile() which can handle str. And converting to bytes would - # require figuring out the encoding to decode to and - # tokenize.detect_encoding() only accepts bytes. return file.read() else: return super().get_data(path) diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py index 2bdd1929b42f8c..ba5a053d6bfe29 100644 --- a/Lib/importlib/_bootstrap.py +++ b/Lib/importlib/_bootstrap.py @@ -1016,31 +1016,30 @@ def _handle_fromlist(module, fromlist, import_, *, recursive=False): """ # The hell that is fromlist ... # If a package was imported, try to import stuff from fromlist. - if hasattr(module, '__path__'): - for x in fromlist: - if not isinstance(x, str): - if recursive: - where = module.__name__ + '.__all__' - else: - where = "``from list''" - raise TypeError(f"Item in {where} must be str, " - f"not {type(x).__name__}") - elif x == '*': - if not recursive and hasattr(module, '__all__'): - _handle_fromlist(module, module.__all__, import_, - recursive=True) - elif not hasattr(module, x): - from_name = '{}.{}'.format(module.__name__, x) - try: - _call_with_frames_removed(import_, from_name) - except ModuleNotFoundError as exc: - # Backwards-compatibility dictates we ignore failed - # imports triggered by fromlist for modules that don't - # exist. - if (exc.name == from_name and - sys.modules.get(from_name, _NEEDS_LOADING) is not None): - continue - raise + for x in fromlist: + if not isinstance(x, str): + if recursive: + where = module.__name__ + '.__all__' + else: + where = "``from list''" + raise TypeError(f"Item in {where} must be str, " + f"not {type(x).__name__}") + elif x == '*': + if not recursive and hasattr(module, '__all__'): + _handle_fromlist(module, module.__all__, import_, + recursive=True) + elif not hasattr(module, x): + from_name = '{}.{}'.format(module.__name__, x) + try: + _call_with_frames_removed(import_, from_name) + except ModuleNotFoundError as exc: + # Backwards-compatibility dictates we ignore failed + # imports triggered by fromlist for modules that don't + # exist. + if (exc.name == from_name and + sys.modules.get(from_name, _NEEDS_LOADING) is not None): + continue + raise return module @@ -1102,8 +1101,10 @@ def __import__(name, globals=None, locals=None, fromlist=(), level=0): # Slice end needs to be positive to alleviate need to special-case # when ``'.' not in name``. return sys.modules[module.__name__[:len(module.__name__)-cut_off]] - else: + elif hasattr(module, '__path__'): return _handle_fromlist(module, fromlist, _gcd_import) + else: + return module def _builtin_from_name(name): diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index 0a8c78bddf034f..1471004453a5e4 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -102,6 +102,15 @@ def _path_isdir(path): return _path_is_mode_type(path, 0o040000) +def _path_isabs(path): + """Replacement for os.path.isabs. + + Considers a Windows drive-relative path (no drive, but starts with slash) to + still be "absolute". + """ + return path.startswith(path_separators) or path[1:3] in _pathseps_with_colon + + def _write_atomic(path, data, mode=0o666): """Best-effort function to write data to a path atomically. Be prepared to handle a FileExistsError if concurrent writing of the @@ -248,6 +257,8 @@ def _write_atomic(path, data, mode=0o666): # Python 3.7b1 3393 (remove STORE_ANNOTATION opcode #32550) # Python 3.7b5 3394 (restored docstring as the firts stmt in the body; # this might affected the first line number #32911) +# Python 3.8a1 3400 (move frame block handling to compiler #17611) +# Python 3.8a1 3401 (add END_ASYNC_FOR #33041) # # MAGIC must change whenever the bytecode emitted by the compiler may no # longer be understood by older implementations of the eval loop (usually @@ -256,7 +267,7 @@ def _write_atomic(path, data, mode=0o666): # Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array # in PC/launcher.c must also be updated. -MAGIC_NUMBER = (3394).to_bytes(2, 'little') + b'\r\n' +MAGIC_NUMBER = (3401).to_bytes(2, 'little') + b'\r\n' _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c _PYCACHE = '__pycache__' @@ -310,7 +321,33 @@ def cache_from_source(path, debug_override=None, *, optimization=None): if not optimization.isalnum(): raise ValueError('{!r} is not alphanumeric'.format(optimization)) almost_filename = '{}.{}{}'.format(almost_filename, _OPT, optimization) - return _path_join(head, _PYCACHE, almost_filename + BYTECODE_SUFFIXES[0]) + filename = almost_filename + BYTECODE_SUFFIXES[0] + if sys.pycache_prefix is not None: + # We need an absolute path to the py file to avoid the possibility of + # collisions within sys.pycache_prefix, if someone has two different + # `foo/bar.py` on their system and they import both of them using the + # same sys.pycache_prefix. Let's say sys.pycache_prefix is + # `C:\Bytecode`; the idea here is that if we get `Foo\Bar`, we first + # make it absolute (`C:\Somewhere\Foo\Bar`), then make it root-relative + # (`Somewhere\Foo\Bar`), so we end up placing the bytecode file in an + # unambiguous `C:\Bytecode\Somewhere\Foo\Bar\`. + if not _path_isabs(head): + head = _path_join(_os.getcwd(), head) + + # Strip initial drive from a Windows path. We know we have an absolute + # path here, so the second part of the check rules out a POSIX path that + # happens to contain a colon at the second character. + if head[1] == ':' and head[0] not in path_separators: + head = head[2:] + + # Strip initial path separator from `head` to complete the conversion + # back to a root-relative path before joining. + return _path_join( + sys.pycache_prefix, + head.lstrip(path_separators), + filename, + ) + return _path_join(head, _PYCACHE, filename) def source_from_cache(path): @@ -326,23 +363,29 @@ def source_from_cache(path): raise NotImplementedError('sys.implementation.cache_tag is None') path = _os.fspath(path) head, pycache_filename = _path_split(path) - head, pycache = _path_split(head) - if pycache != _PYCACHE: - raise ValueError('{} not bottom-level directory in ' - '{!r}'.format(_PYCACHE, path)) + found_in_pycache_prefix = False + if sys.pycache_prefix is not None: + stripped_path = sys.pycache_prefix.rstrip(path_separators) + if head.startswith(stripped_path + path_sep): + head = head[len(stripped_path):] + found_in_pycache_prefix = True + if not found_in_pycache_prefix: + head, pycache = _path_split(head) + if pycache != _PYCACHE: + raise ValueError(f'{_PYCACHE} not bottom-level directory in ' + f'{path!r}') dot_count = pycache_filename.count('.') if dot_count not in {2, 3}: - raise ValueError('expected only 2 or 3 dots in ' - '{!r}'.format(pycache_filename)) + raise ValueError(f'expected only 2 or 3 dots in {pycache_filename!r}') elif dot_count == 3: optimization = pycache_filename.rsplit('.', 2)[-2] if not optimization.startswith(_OPT): raise ValueError("optimization portion of filename does not start " - "with {!r}".format(_OPT)) + f"with {_OPT!r}") opt_level = optimization[len(_OPT):] if not opt_level.isalnum(): - raise ValueError("optimization level {!r} is not an alphanumeric " - "value".format(optimization)) + raise ValueError(f"optimization level {optimization!r} is not an " + "alphanumeric value") base_filename = pycache_filename.partition('.')[0] return _path_join(head, base_filename + SOURCE_SUFFIXES[0]) @@ -1534,6 +1577,7 @@ def _setup(_bootstrap_module): setattr(self_module, '_os', os_module) setattr(self_module, 'path_sep', path_sep) setattr(self_module, 'path_separators', ''.join(path_separators)) + setattr(self_module, '_pathseps_with_colon', {f':{s}' for s in path_separators}) # Directly load the _thread module (needed during bootstrap). thread_module = _bootstrap._builtin_from_name('_thread') diff --git a/Lib/inspect.py b/Lib/inspect.py index 288bfbbf76bf49..717518614fc6d7 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -110,7 +110,7 @@ def ismethoddescriptor(object): def isdatadescriptor(object): """Return true if the object is a data descriptor. - Data descriptors have both a __get__ and a __set__ attribute. Examples are + Data descriptors have a __set__ or a __delete__ attribute. Examples are properties (defined in Python) and getsets and members (defined in C). Typically, data descriptors will also have __name__ and __doc__ attributes (properties, getsets, and members have both of these attributes), but this @@ -119,7 +119,7 @@ def isdatadescriptor(object): # mutual exclusion return False tp = type(object) - return hasattr(tp, "__set__") and hasattr(tp, "__get__") + return hasattr(tp, "__set__") or hasattr(tp, "__delete__") if hasattr(types, 'MemberDescriptorType'): # CPython and equivalent @@ -993,7 +993,7 @@ def getclasstree(classes, unique=False): for c in classes: if c.__bases__: for parent in c.__bases__: - if not parent in children: + if parent not in children: children[parent] = [] if c not in children[parent]: children[parent].append(c) @@ -1550,7 +1550,7 @@ def _shadowed_dict(klass): except KeyError: pass else: - if not (type(class_dict) is types.GetSetDescriptorType and + if not (isinstance(class_dict, types.GetSetDescriptorType) and class_dict.__name__ == "__dict__" and class_dict.__objclass__ is entry): return class_dict @@ -1572,7 +1572,7 @@ def getattr_static(obj, attr, default=_sentinel): klass = type(obj) dict_attr = _shadowed_dict(klass) if (dict_attr is _sentinel or - type(dict_attr) is types.MemberDescriptorType): + isinstance(dict_attr, types.MemberDescriptorType)): instance_result = _check_instance(obj, attr) else: klass = obj @@ -1987,7 +1987,7 @@ def _signature_fromstr(cls, obj, s, skip_bound_arg=True): def parse_name(node): assert isinstance(node, ast.arg) - if node.annotation != None: + if node.annotation is not None: raise ValueError("Annotations are not currently supported") return node.arg @@ -2407,6 +2407,9 @@ class _ParameterKind(enum.IntEnum): def __str__(self): return self._name_ + @property + def description(self): + return _PARAM_NAME_MAPPING[self] _POSITIONAL_ONLY = _ParameterKind.POSITIONAL_ONLY _POSITIONAL_OR_KEYWORD = _ParameterKind.POSITIONAL_OR_KEYWORD @@ -2422,8 +2425,6 @@ def __str__(self): _VAR_KEYWORD: 'variadic keyword' } -_get_paramkind_descr = _PARAM_NAME_MAPPING.__getitem__ - class Parameter: """Represents a parameter in a function signature. @@ -2465,7 +2466,7 @@ def __init__(self, name, kind, *, default=_empty, annotation=_empty): if default is not _empty: if self._kind in (_VAR_POSITIONAL, _VAR_KEYWORD): msg = '{} parameters cannot have default values' - msg = msg.format(_get_paramkind_descr(self._kind)) + msg = msg.format(self._kind.description) raise ValueError(msg) self._default = default self._annotation = annotation @@ -2487,7 +2488,7 @@ def __init__(self, name, kind, *, default=_empty, annotation=_empty): 'implicit arguments must be passed as ' 'positional or keyword arguments, not {}' ) - msg = msg.format(_get_paramkind_descr(self._kind)) + msg = msg.format(self._kind.description) raise ValueError(msg) self._kind = _POSITIONAL_ONLY name = 'implicit{}'.format(name[1:]) @@ -2763,8 +2764,8 @@ def __init__(self, parameters=None, *, return_annotation=_empty, 'wrong parameter order: {} parameter before {} ' 'parameter' ) - msg = msg.format(_get_paramkind_descr(top_kind), - _get_paramkind_descr(kind)) + msg = msg.format(top_kind.description, + kind.description) raise ValueError(msg) elif kind > top_kind: kind_defaults = False diff --git a/Lib/ipaddress.py b/Lib/ipaddress.py index cc9ae7118d6791..15507d61dec8f9 100644 --- a/Lib/ipaddress.py +++ b/Lib/ipaddress.py @@ -488,7 +488,7 @@ def _prefix_from_prefix_string(cls, prefixlen_str): """ # 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): + if not (prefixlen_str.isascii() and prefixlen_str.isdigit()): cls._report_invalid_netmask(prefixlen_str) try: prefixlen = int(prefixlen_str) @@ -1076,7 +1076,6 @@ class _BaseV4: _version = 4 # Equivalent to 255.255.255.255 or 32 bits of 1's. _ALL_ONES = (2**IPV4LENGTH) - 1 - _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}) @@ -1156,7 +1155,7 @@ def _parse_octet(cls, 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 cls._DECIMAL_DIGITS.issuperset(octet_str): + if not (octet_str.isascii() and octet_str.isdigit()): msg = "Only decimal digits permitted in %r" raise ValueError(msg % octet_str) # We do the length check second, since the invalid character error diff --git a/Lib/json/encoder.py b/Lib/json/encoder.py index fb083ed61bb1f8..2d7b8989c711da 100644 --- a/Lib/json/encoder.py +++ b/Lib/json/encoder.py @@ -350,7 +350,7 @@ def _iterencode_dict(dct, _current_indent_level): item_separator = _item_separator first = True if _sort_keys: - items = sorted(dct.items(), key=lambda kv: kv[0]) + items = sorted(dct.items()) else: items = dct.items() for key, value in items: diff --git a/Lib/lib2to3/pgen2/grammar.py b/Lib/lib2to3/pgen2/grammar.py index 088c58bfa99c1b..c00cb2248d5676 100644 --- a/Lib/lib2to3/pgen2/grammar.py +++ b/Lib/lib2to3/pgen2/grammar.py @@ -86,21 +86,9 @@ def __init__(self): self.start = 256 def dump(self, filename): - """Dump the grammar tables to a pickle file. - - dump() recursively changes all dict to OrderedDict, so the pickled file - is not exactly the same as what was passed in to dump(). load() uses the - pickled file to create the tables, but only changes OrderedDict to dict - at the top level; it does not recursively change OrderedDict to dict. - So, the loaded tables are different from the original tables that were - passed to load() in that some of the OrderedDict (from the pickled file) - are not changed back to dict. For parsing, this has no effect on - performance because OrderedDict uses dict's __getitem__ with nothing in - between. - """ + """Dump the grammar tables to a pickle file.""" with open(filename, "wb") as f: - d = _make_deterministic(self.__dict__) - pickle.dump(d, f, 2) + pickle.dump(self.__dict__, f, pickle.HIGHEST_PROTOCOL) def load(self, filename): """Load the grammar tables from a pickle file.""" @@ -141,17 +129,6 @@ def report(self): print("start", self.start) -def _make_deterministic(top): - if isinstance(top, dict): - return collections.OrderedDict( - sorted(((k, _make_deterministic(v)) for k, v in top.items()))) - if isinstance(top, list): - return [_make_deterministic(e) for e in top] - if isinstance(top, tuple): - return tuple(_make_deterministic(e) for e in top) - return top - - # Map from operator to number (since tokenize doesn't do this) opmap_raw = """ diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py index 46c590687c7dc1..29a7d464decf98 100644 --- a/Lib/logging/__init__.py +++ b/Lib/logging/__init__.py @@ -1397,7 +1397,7 @@ def log(self, level, msg, *args, **kwargs): if self.isEnabledFor(level): self._log(level, msg, args, **kwargs) - def findCaller(self, stack_info=False): + def findCaller(self, stack_info=False, stacklevel=1): """ Find the stack frame of the caller so that we can note the source file name, line number and function name. @@ -1407,6 +1407,12 @@ def findCaller(self, stack_info=False): #IronPython isn't run with -X:Frames. if f is not None: f = f.f_back + orig_f = f + while f and stacklevel > 1: + f = f.f_back + stacklevel -= 1 + if not f: + f = orig_f rv = "(unknown file)", 0, "(unknown function)", None while hasattr(f, "f_code"): co = f.f_code @@ -1442,7 +1448,8 @@ def makeRecord(self, name, level, fn, lno, msg, args, exc_info, rv.__dict__[key] = extra[key] return rv - def _log(self, level, msg, args, exc_info=None, extra=None, stack_info=False): + def _log(self, level, msg, args, exc_info=None, extra=None, stack_info=False, + stacklevel=1): """ Low-level logging routine which creates a LogRecord and then calls all the handlers of this logger to handle the record. @@ -1453,7 +1460,7 @@ def _log(self, level, msg, args, exc_info=None, extra=None, stack_info=False): #exception on some versions of IronPython. We trap it here so that #IronPython can use logging. try: - fn, lno, func, sinfo = self.findCaller(stack_info) + fn, lno, func, sinfo = self.findCaller(stack_info, stacklevel) except ValueError: # pragma: no cover fn, lno, func = "(unknown file)", 0, "(unknown function)" else: # pragma: no cover @@ -1569,6 +1576,9 @@ def isEnabledFor(self, level): """ Is this logger enabled for level 'level'? """ + if self.disabled: + return False + try: return self._cache[level] except KeyError: @@ -1783,7 +1793,8 @@ def basicConfig(**kwargs): Do basic configuration for the logging system. This function does nothing if the root logger already has handlers - configured. It is a convenience method intended for use by simple scripts + configured, unless the keyword argument *force* is set to ``True``. + It is a convenience method intended for use by simple scripts to do one-shot configuration of the logging package. The default behaviour is to create a StreamHandler which writes to @@ -1811,13 +1822,19 @@ def basicConfig(**kwargs): handlers, which will be added to the root handler. Any handler in the list which does not have a formatter assigned will be assigned the formatter created in this function. - + force If this keyword is specified as true, any existing handlers + attached to the root logger are removed and closed, before + carrying out the configuration as specified by the other + arguments. Note that you could specify a stream created using open(filename, mode) rather than passing the filename and mode in. However, it should be remembered that StreamHandler does not close its stream (since it may be using sys.stdout or sys.stderr), whereas FileHandler closes its stream when the handler is closed. + .. versionchanged:: 3.8 + Added the ``force`` parameter. + .. versionchanged:: 3.2 Added the ``style`` parameter. @@ -1832,6 +1849,11 @@ def basicConfig(**kwargs): # basicConfig() from multiple threads _acquireLock() try: + force = kwargs.pop('force', False) + if force: + for h in root.handlers[:]: + root.removeHandler(h) + h.close() if len(root.handlers) == 0: handlers = kwargs.pop("handlers", None) if handlers is None: diff --git a/Lib/logging/config.py b/Lib/logging/config.py index 1b0facaf626985..fa1a398aee2a2b 100644 --- a/Lib/logging/config.py +++ b/Lib/logging/config.py @@ -73,8 +73,8 @@ def fileConfig(fname, defaults=None, disable_existing_loggers=True): # critical section logging._acquireLock() try: - logging._handlers.clear() - del logging._handlerList[:] + _clearExistingHandlers() + # Handlers add themselves to logging._handlers handlers = _install_handlers(cp, formatters) _install_loggers(cp, handlers, disable_existing_loggers) @@ -265,6 +265,14 @@ def _install_loggers(cp, handlers, disable_existing): # logger.disabled = 1 _handle_existing_loggers(existing, child_loggers, disable_existing) + +def _clearExistingHandlers(): + """Clear and close existing handlers""" + logging._handlers.clear() + logging.shutdown(logging._handlerList[:]) + del logging._handlerList[:] + + IDENTIFIER = re.compile('^[a-z_][a-z0-9_]*$', re.I) @@ -524,8 +532,7 @@ def configure(self): else: disable_existing = config.pop('disable_existing_loggers', True) - logging._handlers.clear() - del logging._handlerList[:] + _clearExistingHandlers() # Do formatters first - they don't refer to anything else formatters = config.get('formatters', EMPTY_DICT) diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index c86dd6d13457af..f25872102b8c27 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -113,7 +113,7 @@ def guess_type(self, url, strict=True): Optional `strict' argument when False adds a bunch of commonly found, but non-standard types. """ - scheme, url = urllib.parse.splittype(url) + scheme, url = urllib.parse._splittype(url) if scheme == 'data': # syntax of data URLs: # dataurl := "data:" [ mediatype ] [ ";base64" ] "," data diff --git a/Lib/multiprocessing/connection.py b/Lib/multiprocessing/connection.py index 7a621a55f468b6..1f3ea504fff439 100644 --- a/Lib/multiprocessing/connection.py +++ b/Lib/multiprocessing/connection.py @@ -57,10 +57,10 @@ def _init_timeout(timeout=CONNECTION_TIMEOUT): - return time.time() + timeout + return time.monotonic() + timeout def _check_timeout(t): - return time.time() > t + return time.monotonic() > t # # @@ -914,7 +914,7 @@ def wait(object_list, timeout=None): selector.register(obj, selectors.EVENT_READ) if timeout is not None: - deadline = time.time() + timeout + deadline = time.monotonic() + timeout while True: ready = selector.select(timeout) @@ -922,7 +922,7 @@ def wait(object_list, timeout=None): return [key.fileobj for (key, events) in ready] else: if timeout is not None: - timeout = deadline - time.time() + timeout = deadline - time.monotonic() if timeout < 0: return ready diff --git a/Lib/multiprocessing/heap.py b/Lib/multiprocessing/heap.py index 566173a1b0ae82..6217dfe12689b3 100644 --- a/Lib/multiprocessing/heap.py +++ b/Lib/multiprocessing/heap.py @@ -8,6 +8,7 @@ # import bisect +from collections import defaultdict import mmap import os import sys @@ -28,6 +29,9 @@ import _winapi class Arena(object): + """ + A shared memory area backed by anonymous memory (Windows). + """ _rand = tempfile._RandomNameSequence() @@ -52,6 +56,7 @@ def __getstate__(self): def __setstate__(self, state): self.size, self.name = self._state = state + # Reopen existing mmap self.buffer = mmap.mmap(-1, self.size, tagname=self.name) # XXX Temporarily preventing buildbot failures while determining # XXX the correct long-term fix. See issue 23060 @@ -60,6 +65,10 @@ def __setstate__(self, state): else: class Arena(object): + """ + A shared memory area backed by a temporary file (POSIX). + """ + if sys.platform == 'linux': _dir_candidates = ['/dev/shm'] else: @@ -69,6 +78,8 @@ def __init__(self, size, fd=-1): self.size = size self.fd = fd if fd == -1: + # Arena is created anew (if fd != -1, it means we're coming + # from rebuild_arena() below) self.fd, name = tempfile.mkstemp( prefix='pym-%d-'%os.getpid(), dir=self._choose_dir(size)) @@ -103,37 +114,82 @@ def rebuild_arena(size, dupfd): class Heap(object): + # Minimum malloc() alignment _alignment = 8 + _DISCARD_FREE_SPACE_LARGER_THAN = 4 * 1024 ** 2 # 4 MB + _DOUBLE_ARENA_SIZE_UNTIL = 4 * 1024 ** 2 + def __init__(self, size=mmap.PAGESIZE): self._lastpid = os.getpid() self._lock = threading.Lock() + # Current arena allocation size self._size = size + # A sorted list of available block sizes in arenas self._lengths = [] + + # Free block management: + # - map each block size to a list of `(Arena, start, stop)` blocks self._len_to_seq = {} + # - map `(Arena, start)` tuple to the `(Arena, start, stop)` block + # starting at that offset self._start_to_block = {} + # - map `(Arena, stop)` tuple to the `(Arena, start, stop)` block + # ending at that offset self._stop_to_block = {} - self._allocated_blocks = set() + + # Map arenas to their `(Arena, start, stop)` blocks in use + self._allocated_blocks = defaultdict(set) self._arenas = [] - # list of pending blocks to free - see free() comment below + + # List of pending blocks to free - see comment in free() below self._pending_free_blocks = [] + # Statistics + self._n_mallocs = 0 + self._n_frees = 0 + @staticmethod def _roundup(n, alignment): # alignment must be a power of 2 mask = alignment - 1 return (n + mask) & ~mask + def _new_arena(self, size): + # Create a new arena with at least the given *size* + length = self._roundup(max(self._size, size), mmap.PAGESIZE) + # We carve larger and larger arenas, for efficiency, until we + # reach a large-ish size (roughly L3 cache-sized) + if self._size < self._DOUBLE_ARENA_SIZE_UNTIL: + self._size *= 2 + util.info('allocating a new mmap of length %d', length) + arena = Arena(length) + self._arenas.append(arena) + return (arena, 0, length) + + def _discard_arena(self, arena): + # Possibly delete the given (unused) arena + length = arena.size + # Reusing an existing arena is faster than creating a new one, so + # we only reclaim space if it's large enough. + if length < self._DISCARD_FREE_SPACE_LARGER_THAN: + return + blocks = self._allocated_blocks.pop(arena) + assert not blocks + del self._start_to_block[(arena, 0)] + del self._stop_to_block[(arena, length)] + self._arenas.remove(arena) + seq = self._len_to_seq[length] + seq.remove((arena, 0, length)) + if not seq: + del self._len_to_seq[length] + self._lengths.remove(length) + def _malloc(self, size): # returns a large enough block -- it might be much larger i = bisect.bisect_left(self._lengths, size) if i == len(self._lengths): - length = self._roundup(max(self._size, size), mmap.PAGESIZE) - self._size *= 2 - util.info('allocating a new mmap of length %d', length) - arena = Arena(length) - self._arenas.append(arena) - return (arena, 0, length) + return self._new_arena(size) else: length = self._lengths[i] seq = self._len_to_seq[length] @@ -146,8 +202,8 @@ def _malloc(self, size): del self._stop_to_block[(arena, stop)] return block - def _free(self, block): - # free location and try to merge with neighbours + def _add_free_block(self, block): + # make block available and try to merge with its neighbours in the arena (arena, start, stop) = block try: @@ -191,6 +247,14 @@ def _absorb(self, block): return start, stop + def _remove_allocated_block(self, block): + arena, start, stop = block + blocks = self._allocated_blocks[arena] + blocks.remove((start, stop)) + if not blocks: + # Arena is entirely free, discard it from this process + self._discard_arena(arena) + def _free_pending_blocks(self): # Free all the blocks in the pending list - called with the lock held. while True: @@ -198,8 +262,8 @@ def _free_pending_blocks(self): block = self._pending_free_blocks.pop() except IndexError: break - self._allocated_blocks.remove(block) - self._free(block) + self._add_free_block(block) + self._remove_allocated_block(block) def free(self, block): # free a block returned by malloc() @@ -210,7 +274,7 @@ def free(self, block): # immediately, the block is added to a list of blocks to be freed # synchronously sometimes later from malloc() or free(), by calling # _free_pending_blocks() (appending and retrieving from a list is not - # strictly thread-safe but under cPython it's atomic thanks to the GIL). + # strictly thread-safe but under CPython it's atomic thanks to the GIL). if os.getpid() != self._lastpid: raise ValueError( "My pid ({0:n}) is not last pid {1:n}".format( @@ -222,9 +286,10 @@ def free(self, block): else: # we hold the lock try: + self._n_frees += 1 self._free_pending_blocks() - self._allocated_blocks.remove(block) - self._free(block) + self._add_free_block(block) + self._remove_allocated_block(block) finally: self._lock.release() @@ -237,18 +302,21 @@ def malloc(self, size): if os.getpid() != self._lastpid: self.__init__() # reinitialize after fork with self._lock: + self._n_mallocs += 1 + # allow pending blocks to be marked available self._free_pending_blocks() - size = self._roundup(max(size,1), self._alignment) + size = self._roundup(max(size, 1), self._alignment) (arena, start, stop) = self._malloc(size) - new_stop = start + size - if new_stop < stop: - self._free((arena, new_stop, stop)) - block = (arena, start, new_stop) - self._allocated_blocks.add(block) - return block + real_stop = start + size + if real_stop < stop: + # if the returned block is larger than necessary, mark + # the remainder available + self._add_free_block((arena, real_stop, stop)) + self._allocated_blocks[arena].add((start, real_stop)) + return (arena, start, real_stop) # -# Class representing a chunk of an mmap -- can be inherited by child process +# Class wrapping a block allocated out of a Heap -- can be inherited by child process # class BufferWrapper(object): diff --git a/Lib/multiprocessing/managers.py b/Lib/multiprocessing/managers.py index 04df26bac66187..3f263802bc7cb7 100644 --- a/Lib/multiprocessing/managers.py +++ b/Lib/multiprocessing/managers.py @@ -18,8 +18,8 @@ import threading import array import queue +import time -from time import time as _time from traceback import format_exc from . import connection @@ -1045,13 +1045,13 @@ def wait_for(self, predicate, timeout=None): if result: return result if timeout is not None: - endtime = _time() + timeout + endtime = time.monotonic() + timeout else: endtime = None waittime = None while not result: if endtime is not None: - waittime = endtime - _time() + waittime = endtime - time.monotonic() if waittime <= 0: break self.wait(waittime) diff --git a/Lib/multiprocessing/popen_spawn_win32.py b/Lib/multiprocessing/popen_spawn_win32.py index 3e42e9c3387413..3b92c8a2b4ae7f 100644 --- a/Lib/multiprocessing/popen_spawn_win32.py +++ b/Lib/multiprocessing/popen_spawn_win32.py @@ -18,6 +18,12 @@ WINEXE = (sys.platform == 'win32' and getattr(sys, 'frozen', False)) WINSERVICE = sys.executable.lower().endswith("pythonservice.exe") + +def _close_handles(*handles): + for handle in handles: + _winapi.CloseHandle(handle) + + # # We define a Popen class similar to the one from subprocess, but # whose constructor takes a process object as its argument. @@ -32,8 +38,12 @@ class Popen(object): def __init__(self, process_obj): prep_data = spawn.get_preparation_data(process_obj._name) - # read end of pipe will be "stolen" by the child process + # read end of pipe will be duplicated by the child process # -- see spawn_main() in spawn.py. + # + # bpo-33929: Previously, the read end of pipe was "stolen" by the child + # process, but it leaked a handle if the child process had been + # terminated before it could steal the handle from the parent process. rhandle, whandle = _winapi.CreatePipe(None, 0) wfd = msvcrt.open_osfhandle(whandle, 0) cmd = spawn.get_command_line(parent_pid=os.getpid(), @@ -56,7 +66,8 @@ def __init__(self, process_obj): self.returncode = None self._handle = hp self.sentinel = int(hp) - self.finalizer = util.Finalize(self, _winapi.CloseHandle, (self.sentinel,)) + self.finalizer = util.Finalize(self, _close_handles, + (self.sentinel, int(rhandle))) # send information to child set_spawning_popen(self) diff --git a/Lib/multiprocessing/queues.py b/Lib/multiprocessing/queues.py index 715a9b0e12900e..88f7d267bfd351 100644 --- a/Lib/multiprocessing/queues.py +++ b/Lib/multiprocessing/queues.py @@ -95,12 +95,12 @@ def get(self, block=True, timeout=None): self._sem.release() else: if block: - deadline = time.time() + timeout + deadline = time.monotonic() + timeout if not self._rlock.acquire(block, timeout): raise Empty try: if block: - timeout = deadline - time.time() + timeout = deadline - time.monotonic() if not self._poll(timeout): raise Empty elif not self._poll(): diff --git a/Lib/multiprocessing/reduction.py b/Lib/multiprocessing/reduction.py index deca19ccad7b7f..473fd59df61b69 100644 --- a/Lib/multiprocessing/reduction.py +++ b/Lib/multiprocessing/reduction.py @@ -68,12 +68,16 @@ def dump(obj, file, protocol=None): __all__ += ['DupHandle', 'duplicate', 'steal_handle'] import _winapi - def duplicate(handle, target_process=None, inheritable=False): + def duplicate(handle, target_process=None, inheritable=False, + *, source_process=None): '''Duplicate a handle. (target_process is a handle not a pid!)''' + current_process = _winapi.GetCurrentProcess() + if source_process is None: + source_process = current_process if target_process is None: - target_process = _winapi.GetCurrentProcess() + target_process = current_process return _winapi.DuplicateHandle( - _winapi.GetCurrentProcess(), handle, target_process, + source_process, handle, target_process, 0, inheritable, _winapi.DUPLICATE_SAME_ACCESS) def steal_handle(source_pid, handle): diff --git a/Lib/multiprocessing/resource_sharer.py b/Lib/multiprocessing/resource_sharer.py index 6d99da102ffc61..730b2aa17bdf0b 100644 --- a/Lib/multiprocessing/resource_sharer.py +++ b/Lib/multiprocessing/resource_sharer.py @@ -136,7 +136,7 @@ def _start(self): def _serve(self): if hasattr(signal, 'pthread_sigmask'): - signal.pthread_sigmask(signal.SIG_BLOCK, range(1, signal.NSIG)) + signal.pthread_sigmask(signal.SIG_BLOCK, signal.valid_signals()) while 1: try: with self._listener.accept() as conn: diff --git a/Lib/multiprocessing/spawn.py b/Lib/multiprocessing/spawn.py index 1f4f3f496f51a2..73aa69471f29c3 100644 --- a/Lib/multiprocessing/spawn.py +++ b/Lib/multiprocessing/spawn.py @@ -96,7 +96,19 @@ def spawn_main(pipe_handle, parent_pid=None, tracker_fd=None): assert is_forking(sys.argv), "Not forking" if sys.platform == 'win32': import msvcrt - new_handle = reduction.steal_handle(parent_pid, pipe_handle) + import _winapi + + if parent_pid is not None: + source_process = _winapi.OpenProcess( + _winapi.PROCESS_DUP_HANDLE, False, parent_pid) + else: + source_process = None + try: + new_handle = reduction.duplicate(pipe_handle, + source_process=source_process) + finally: + if source_process is not None: + _winapi.CloseHandle(source_process) fd = msvcrt.open_osfhandle(new_handle, os.O_RDONLY) else: from . import semaphore_tracker diff --git a/Lib/multiprocessing/synchronize.py b/Lib/multiprocessing/synchronize.py index 038f73f6b76551..5137c49c1b6c9b 100644 --- a/Lib/multiprocessing/synchronize.py +++ b/Lib/multiprocessing/synchronize.py @@ -15,8 +15,7 @@ import sys import tempfile import _multiprocessing - -from time import time as _time +import time from . import context from . import process @@ -302,13 +301,13 @@ def wait_for(self, predicate, timeout=None): if result: return result if timeout is not None: - endtime = _time() + timeout + endtime = time.monotonic() + timeout else: endtime = None waittime = None while not result: if endtime is not None: - waittime = endtime - _time() + waittime = endtime - time.monotonic() if waittime <= 0: break self.wait(waittime) diff --git a/Lib/opcode.py b/Lib/opcode.py index 368472d9811625..3fb716b5d96a29 100644 --- a/Lib/opcode.py +++ b/Lib/opcode.py @@ -60,6 +60,7 @@ def jabs_op(name, op): def_op('ROT_THREE', 3) def_op('DUP_TOP', 4) def_op('DUP_TOP_TWO', 5) +def_op('ROT_FOUR', 6) def_op('NOP', 9) def_op('UNARY_POSITIVE', 10) @@ -86,7 +87,8 @@ def jabs_op(name, op): def_op('GET_AITER', 50) def_op('GET_ANEXT', 51) def_op('BEFORE_ASYNC_WITH', 52) - +def_op('BEGIN_FINALLY', 53) +def_op('END_ASYNC_FOR', 54) def_op('INPLACE_ADD', 55) def_op('INPLACE_SUBTRACT', 56) def_op('INPLACE_MULTIPLY', 57) @@ -113,10 +115,8 @@ def jabs_op(name, op): def_op('INPLACE_AND', 77) def_op('INPLACE_XOR', 78) def_op('INPLACE_OR', 79) -def_op('BREAK_LOOP', 80) def_op('WITH_CLEANUP_START', 81) def_op('WITH_CLEANUP_FINISH', 82) - def_op('RETURN_VALUE', 83) def_op('IMPORT_STAR', 84) def_op('SETUP_ANNOTATIONS', 85) @@ -158,10 +158,7 @@ def jabs_op(name, op): name_op('LOAD_GLOBAL', 116) # Index in name list -jabs_op('CONTINUE_LOOP', 119) # Target address -jrel_op('SETUP_LOOP', 120) # Distance to target address -jrel_op('SETUP_EXCEPT', 121) # "" -jrel_op('SETUP_FINALLY', 122) # "" +jrel_op('SETUP_FINALLY', 122) # Distance to target address def_op('LOAD_FAST', 124) # Local variable number haslocal.append(124) @@ -213,5 +210,7 @@ def jabs_op(name, op): name_op('LOAD_METHOD', 160) def_op('CALL_METHOD', 161) +jrel_op('CALL_FINALLY', 162) +def_op('POP_FINALLY', 163) del def_op, name_op, jrel_op, jabs_op diff --git a/Lib/pickle.py b/Lib/pickle.py index b143d0b3e1318e..de745df1e6464f 100644 --- a/Lib/pickle.py +++ b/Lib/pickle.py @@ -57,9 +57,9 @@ HIGHEST_PROTOCOL = 4 # The protocol we write by default. May be less than HIGHEST_PROTOCOL. -# We intentionally write a protocol that Python 2.x cannot read; -# there are too many issues with that. -DEFAULT_PROTOCOL = 3 +# Only bump this if the oldest still supported version of Python already +# includes it. +DEFAULT_PROTOCOL = 4 class PickleError(Exception): """A common base class for the other pickling exceptions.""" @@ -376,8 +376,8 @@ def __init__(self, file, protocol=None, *, fix_imports=True): 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 4. It was introduced in Python 3.4, it is + incompatible with previous versions. Specifying a negative protocol version selects the highest protocol version supported. The higher the protocol used, the diff --git a/Lib/platform.py b/Lib/platform.py index 20f9817f4ffb49..6051f2b590195f 100755 --- a/Lib/platform.py +++ b/Lib/platform.py @@ -132,10 +132,6 @@ # 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)' @@ -249,138 +245,6 @@ def _dist_try_harder(distname, version, id): return distname, version, id -_release_filename = re.compile(r'(\w+)[-_](release|version)', re.ASCII) -_lsb_release_version = re.compile(r'(.+)' - r' release ' - r'([\d.]+)' - r'[^(]*(?:\((.+)\))?', re.ASCII) -_release_version = re.compile(r'([^0-9]+)' - r'(?: release )?' - r'([\d.]+)' - r'[^(]*(?:\((.+)\))?', re.ASCII) - -# See also http://www.novell.com/coolsolutions/feature/11251.html -# and http://linuxmafia.com/faq/Admin/release-files.html -# and http://data.linux-ntfs.org/rpm/whichrpm -# and http://www.die.net/doc/linux/man/man1/lsb_release.1.html - -_supported_dists = ( - 'SuSE', 'debian', 'fedora', 'redhat', 'centos', - 'mandrake', 'mandriva', 'rocks', 'slackware', 'yellowdog', 'gentoo', - 'UnitedLinux', 'turbolinux', 'arch', 'mageia') - -def _parse_release_file(firstline): - - # Default to empty 'version' and 'id' strings. Both defaults are used - # when 'firstline' is empty. 'id' defaults to empty when an id can not - # be deduced. - version = '' - id = '' - - # Parse the first line - m = _lsb_release_version.match(firstline) - if m is not None: - # LSB format: "distro release x.x (codename)" - return tuple(m.groups()) - - # Pre-LSB format: "distro x.x (codename)" - m = _release_version.match(firstline) - if m is not None: - return tuple(m.groups()) - - # Unknown format... take the first two words - l = firstline.strip().split() - if l: - version = l[0] - if len(l) > 1: - id = l[1] - return '', version, id - -def linux_distribution(distname='', version='', id='', - - supported_dists=_supported_dists, - full_distribution_name=1): - import warnings - warnings.warn("dist() and linux_distribution() functions are deprecated " - "in Python 3.5", DeprecationWarning, stacklevel=2) - return _linux_distribution(distname, version, id, supported_dists, - full_distribution_name) - -def _linux_distribution(distname, version, id, supported_dists, - full_distribution_name): - - """ Tries to determine the name of the Linux OS distribution name. - - The function first looks for a distribution release file in - /etc and then reverts to _dist_try_harder() in case no - suitable files are found. - - supported_dists may be given to define the set of Linux - distributions to look for. It defaults to a list of currently - supported Linux distributions identified by their release file - name. - - If full_distribution_name is true (default), the full - 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 - args given as parameters. - - """ - try: - etc = os.listdir(_UNIXCONFDIR) - except OSError: - # Probably not a Unix system - return distname, version, id - etc.sort() - for file in etc: - m = _release_filename.match(file) - if m is not None: - _distname, dummy = m.groups() - if _distname in supported_dists: - distname = _distname - break - else: - return _dist_try_harder(distname, version, id) - - # Read the first line - 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) - - if _distname and full_distribution_name: - distname = _distname - if _version: - version = _version - if _id: - id = _id - return distname, version, id - -# To maintain backwards compatibility: - -def dist(distname='', version='', id='', - - supported_dists=_supported_dists): - - """ Tries to determine the name of the Linux OS distribution name. - - The function first looks for a distribution release file in - /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 - args given as parameters. - - """ - import warnings - warnings.warn("dist() and linux_distribution() functions are deprecated " - "in Python 3.5", DeprecationWarning, stacklevel=2) - return _linux_distribution(distname, version, id, - supported_dists=supported_dists, - full_distribution_name=0) - def popen(cmd, mode='r', bufsize=-1): """ Portable popen() interface. @@ -1338,26 +1202,11 @@ def platform(aliased=0, terse=0): platform = _platform(system, release, version, csd) elif system in ('Linux',): - # Linux based systems - with warnings.catch_warnings(): - # see issue #1322 for more information - warnings.filterwarnings( - 'ignore', - r'dist\(\) and linux_distribution\(\) ' - 'functions are deprecated .*', - DeprecationWarning, - ) - distname, distversion, distid = dist('') - if distname and not terse: - platform = _platform(system, release, machine, processor, - 'with', - 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, - 'with', - libcname+libcversion) + # check for libc vs. glibc + 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() diff --git a/Lib/plistlib.py b/Lib/plistlib.py index 21ebec3f004590..248f5143f4edf7 100644 --- a/Lib/plistlib.py +++ b/Lib/plistlib.py @@ -644,7 +644,6 @@ def _read_object(self, ref): elif tokenH == 0x50: # ascii string s = self._get_size(tokenL) result = self._fp.read(s).decode('ascii') - result = result elif tokenH == 0x60: # unicode string s = self._get_size(tokenL) diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py index 0c736f748f8b2b..1dd040c3ffa275 100644 --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Autogenerated by Sphinx on Tue Jun 12 00:39:48 2018 +# Autogenerated by Sphinx on Tue Jan 30 18:36:07 2018 topics = {'assert': 'The "assert" statement\n' '**********************\n' '\n' @@ -2659,7 +2659,8 @@ 'function.\n' 'The annotation values are available as values of a dictionary ' 'keyed by\n' - 'the parameters’ names in the "__annotations__" attribute of the\n' + 'the parameters\' names in the "__annotations__" attribute of ' + 'the\n' 'function object. If the "annotations" import from "__future__" ' 'is\n' 'used, annotations are preserved as strings at runtime which ' @@ -3933,7 +3934,7 @@ ' breakpoint—which could have its own command list, leading to\n' ' ambiguities about which list to execute.\n' '\n' - ' If you use the ‘silent’ command in the command list, the ' + " 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' @@ -5665,7 +5666,8 @@ 'function.\n' 'The annotation values are available as values of a dictionary ' 'keyed by\n' - 'the parameters’ names in the "__annotations__" attribute of the\n' + 'the parameters\' names in the "__annotations__" attribute of ' + 'the\n' 'function object. If the "annotations" import from "__future__" ' 'is\n' 'used, annotations are preserved as strings at runtime which ' diff --git a/Lib/random.py b/Lib/random.py index 0bc24174e13f14..b2c0d6fcc3b832 100644 --- a/Lib/random.py +++ b/Lib/random.py @@ -38,7 +38,6 @@ """ from warnings import warn as _warn -from types import MethodType as _MethodType, BuiltinMethodType as _BuiltinMethodType from math import log as _log, exp as _exp, pi as _pi, e as _e, ceil as _ceil from math import sqrt as _sqrt, acos as _acos, cos as _cos, sin as _sin from os import urandom as _urandom @@ -94,6 +93,26 @@ def __init__(self, x=None): self.seed(x) self.gauss_next = None + def __init_subclass__(cls, **kwargs): + """Control how subclasses generate random integers. + + The algorithm a subclass can use depends on the random() and/or + getrandbits() implementation available to it and determines + whether it can generate random integers from arbitrarily large + ranges. + """ + + for c in cls.__mro__: + if '_randbelow' in c.__dict__: + # just inherit it + break + if 'getrandbits' in c.__dict__: + cls._randbelow = cls._randbelow_with_getrandbits + break + if 'random' in c.__dict__: + cls._randbelow = cls._randbelow_without_getrandbits + break + def seed(self, a=None, version=2): """Initialize internal state from hashable object. @@ -221,22 +240,23 @@ def randint(self, a, b): return self.randrange(a, b+1) - def _randbelow(self, n, int=int, maxsize=1<<BPF, type=type, - Method=_MethodType, BuiltinMethod=_BuiltinMethodType): + def _randbelow_with_getrandbits(self, n): "Return a random int in the range [0,n). Raises ValueError if n==0." - random = self.random getrandbits = self.getrandbits - # Only call self.getrandbits if the original random() builtin method - # has not been overridden or if a new getrandbits() was supplied. - if type(random) is BuiltinMethod or type(getrandbits) is Method: - k = n.bit_length() # don't use (n-1) here because n can be 1 - r = getrandbits(k) # 0 <= r < 2**k - while r >= n: - r = getrandbits(k) - return r - # There's an overridden random() method but no new getrandbits() method, - # so we can only use random() from here. + k = n.bit_length() # don't use (n-1) here because n can be 1 + r = getrandbits(k) # 0 <= r < 2**k + while r >= n: + r = getrandbits(k) + return r + + def _randbelow_without_getrandbits(self, n, int=int, maxsize=1<<BPF): + """Return a random int in the range [0,n). Raises ValueError if n==0. + + The implementation does not use getrandbits, but only random. + """ + + random = self.random if n >= maxsize: _warn("Underlying random() generator does not supply \n" "enough bits to choose from a population range this large.\n" @@ -251,6 +271,8 @@ def _randbelow(self, n, int=int, maxsize=1<<BPF, type=type, r = random() return int(r*maxsize) % n + _randbelow = _randbelow_with_getrandbits + ## -------------------- sequence methods ------------------- def choice(self, seq): @@ -349,19 +371,21 @@ def choices(self, population, weights=None, *, cum_weights=None, k=1): """ random = self.random + n = len(population) if cum_weights is None: if weights is None: _int = int - total = len(population) - return [population[_int(random() * total)] for i in range(k)] + return [population[_int(random() * n)] for i in range(k)] cum_weights = list(_itertools.accumulate(weights)) elif weights is not None: raise TypeError('Cannot specify both weights and cumulative weights') - if len(cum_weights) != len(population): + if len(cum_weights) != n: raise ValueError('The number of weights does not match the population') bisect = _bisect.bisect total = cum_weights[-1] - return [population[bisect(cum_weights, random() * total)] for i in range(k)] + hi = n - 1 + return [population[bisect(cum_weights, random() * total, 0, hi)] + for i in range(k)] ## -------------------- real-valued distributions ------------------- diff --git a/Lib/shutil.py b/Lib/shutil.py index 3c02776a406551..a4aa0dfdd10b09 100644 --- a/Lib/shutil.py +++ b/Lib/shutil.py @@ -10,6 +10,7 @@ import fnmatch import collections import errno +import io try: import zlib @@ -42,6 +43,17 @@ except ImportError: getgrnam = None +_WINDOWS = os.name == 'nt' +posix = nt = None +if os.name == 'posix': + import posix +elif _WINDOWS: + import nt + +COPY_BUFSIZE = 1024 * 1024 if _WINDOWS else 16 * 1024 +_HAS_SENDFILE = posix and hasattr(os, "sendfile") +_HAS_FCOPYFILE = posix and hasattr(posix, "_fcopyfile") # macOS + __all__ = ["copyfileobj", "copyfile", "copymode", "copystat", "copy", "copy2", "copytree", "move", "rmtree", "Error", "SpecialFileError", "ExecError", "make_archive", "get_archive_formats", @@ -72,14 +84,120 @@ class RegistryError(Exception): """Raised when a registry operation with the archiving and unpacking registries fails""" +class _GiveupOnFastCopy(Exception): + """Raised as a signal to fallback on using raw read()/write() + file copy when fast-copy functions fail to do so. + """ + +def _fastcopy_fcopyfile(fsrc, fdst, flags): + """Copy a regular file content or metadata by using high-performance + fcopyfile(3) syscall (macOS). + """ + try: + infd = fsrc.fileno() + outfd = fdst.fileno() + except Exception as err: + raise _GiveupOnFastCopy(err) # not a regular file + + try: + posix._fcopyfile(infd, outfd, flags) + except OSError as err: + err.filename = fsrc.name + err.filename2 = fdst.name + if err.errno in {errno.EINVAL, errno.ENOTSUP}: + raise _GiveupOnFastCopy(err) + else: + raise err from None + +def _fastcopy_sendfile(fsrc, fdst): + """Copy data from one regular mmap-like fd to another by using + high-performance sendfile(2) syscall. + This should work on Linux >= 2.6.33 and Solaris only. + """ + # Note: copyfileobj() is left alone in order to not introduce any + # unexpected breakage. Possible risks by using zero-copy calls + # in copyfileobj() are: + # - fdst cannot be open in "a"(ppend) mode + # - fsrc and fdst may be open in "t"(ext) mode + # - fsrc may be a BufferedReader (which hides unread data in a buffer), + # GzipFile (which decompresses data), HTTPResponse (which decodes + # chunks). + # - possibly others (e.g. encrypted fs/partition?) + global _HAS_SENDFILE + try: + infd = fsrc.fileno() + outfd = fdst.fileno() + except Exception as err: + raise _GiveupOnFastCopy(err) # not a regular file + + # Hopefully the whole file will be copied in a single call. + # sendfile() is called in a loop 'till EOF is reached (0 return) + # so a bufsize smaller or bigger than the actual file size + # should not make any difference, also in case the file content + # changes while being copied. + try: + blocksize = max(os.fstat(infd).st_size, 2 ** 23) # min 8MB + except Exception: + blocksize = 2 ** 27 # 128MB + + offset = 0 + while True: + try: + sent = os.sendfile(outfd, infd, offset, blocksize) + except OSError as err: + # ...in oder to have a more informative exception. + err.filename = fsrc.name + err.filename2 = fdst.name + + if err.errno == errno.ENOTSOCK: + # sendfile() on this platform (probably Linux < 2.6.33) + # does not support copies between regular files (only + # sockets). + _HAS_SENDFILE = False + raise _GiveupOnFastCopy(err) + + if err.errno == errno.ENOSPC: # filesystem is full + raise err from None + + # Give up on first call and if no data was copied. + if offset == 0 and os.lseek(outfd, 0, os.SEEK_CUR) == 0: + raise _GiveupOnFastCopy(err) + + raise err + else: + if sent == 0: + break # EOF + offset += sent + +def _copyfileobj_readinto(fsrc, fdst, length=COPY_BUFSIZE): + """readinto()/memoryview() based variant of copyfileobj(). + *fsrc* must support readinto() method and both files must be + open in binary mode. + """ + # Localize variable access to minimize overhead. + fsrc_readinto = fsrc.readinto + fdst_write = fdst.write + with memoryview(bytearray(length)) as mv: + while True: + n = fsrc_readinto(mv) + if not n: + break + elif n < length: + with mv[:n] as smv: + fdst.write(smv) + else: + fdst_write(mv) -def copyfileobj(fsrc, fdst, length=16*1024): +def copyfileobj(fsrc, fdst, length=COPY_BUFSIZE): """copy data from file-like object fsrc to file-like object fdst""" - while 1: - buf = fsrc.read(length) + # Localize variable access to minimize overhead. + fsrc_read = fsrc.read + fdst_write = fdst.write + while True: + buf = fsrc_read(length) if not buf: break - fdst.write(buf) + fdst_write(buf) def _samefile(src, dst): # Macintosh, Unix. @@ -94,7 +212,7 @@ def _samefile(src, dst): os.path.normcase(os.path.abspath(dst))) def copyfile(src, dst, *, follow_symlinks=True): - """Copy data from src to dst. + """Copy data from src to dst in the most efficient way possible. If follow_symlinks is not set and src is a symbolic link, a new symlink will be created instead of copying the file it points to. @@ -103,7 +221,8 @@ def copyfile(src, dst, *, follow_symlinks=True): if _samefile(src, dst): raise SameFileError("{!r} and {!r} are the same file".format(src, dst)) - for fn in [src, dst]: + file_size = 0 + for i, fn in enumerate([src, dst]): try: st = os.stat(fn) except OSError: @@ -113,13 +232,35 @@ def copyfile(src, dst, *, follow_symlinks=True): # XXX What about other special files? (sockets, devices...) if stat.S_ISFIFO(st.st_mode): raise SpecialFileError("`%s` is a named pipe" % fn) + if _WINDOWS and i == 0: + file_size = st.st_size if not follow_symlinks and os.path.islink(src): os.symlink(os.readlink(src), dst) else: - with open(src, 'rb') as fsrc: - with open(dst, 'wb') as fdst: - copyfileobj(fsrc, fdst) + with open(src, 'rb') as fsrc, open(dst, 'wb') as fdst: + # macOS + if _HAS_FCOPYFILE: + try: + _fastcopy_fcopyfile(fsrc, fdst, posix._COPYFILE_DATA) + return dst + except _GiveupOnFastCopy: + pass + # Linux / Solaris + elif _HAS_SENDFILE: + try: + _fastcopy_sendfile(fsrc, fdst) + return dst + except _GiveupOnFastCopy: + pass + # Windows, see: + # https://github.com/python/cpython/pull/7160#discussion_r195405230 + elif _WINDOWS and file_size > 0: + _copyfileobj_readinto(fsrc, fdst, min(file_size, COPY_BUFSIZE)) + return dst + + copyfileobj(fsrc, fdst) + return dst def copymode(src, dst, *, follow_symlinks=True): @@ -244,13 +385,12 @@ def copy(src, dst, *, follow_symlinks=True): def copy2(src, dst, *, follow_symlinks=True): """Copy data and all stat info ("cp -p src dst"). Return the file's - destination." + destination. The destination may be a directory. If follow_symlinks is false, symlinks won't be followed. This resembles GNU's "cp -P src dst". - """ if os.path.isdir(dst): dst = os.path.join(dst, os.path.basename(src)) @@ -1013,9 +1153,8 @@ def disk_usage(path): used = (st.f_blocks - st.f_bfree) * st.f_frsize return _ntuple_diskusage(total, used, free) -elif os.name == 'nt': +elif _WINDOWS: - import nt __all__.append('disk_usage') _ntuple_diskusage = collections.namedtuple('usage', 'total used free') diff --git a/Lib/signal.py b/Lib/signal.py index 9f05c9198df717..826b62cf596ccf 100644 --- a/Lib/signal.py +++ b/Lib/signal.py @@ -65,8 +65,7 @@ def pthread_sigmask(how, mask): if 'sigpending' in _globals: @_wraps(_signal.sigpending) def sigpending(): - sigs = _signal.sigpending() - return set(_int_to_enum(x, Signals) for x in sigs) + return {_int_to_enum(x, Signals) for x in _signal.sigpending()} if 'sigwait' in _globals: @@ -76,4 +75,11 @@ def sigwait(sigset): return _int_to_enum(retsig, Signals) sigwait.__doc__ = _signal.sigwait + +if 'valid_signals' in _globals: + @_wraps(_signal.valid_signals) + def valid_signals(): + return {_int_to_enum(x, Signals) for x in _signal.valid_signals()} + + del _globals, _wraps diff --git a/Lib/sqlite3/test/userfunctions.py b/Lib/sqlite3/test/userfunctions.py index 4075045b727e89..9501f535c49999 100644 --- a/Lib/sqlite3/test/userfunctions.py +++ b/Lib/sqlite3/test/userfunctions.py @@ -23,6 +23,7 @@ # 3. This notice may not be removed or altered from any source distribution. import unittest +import unittest.mock import sqlite3 as sqlite def func_returntext(): @@ -275,6 +276,28 @@ def CheckAnyArguments(self): val = cur.fetchone()[0] self.assertEqual(val, 2) + def CheckFuncNonDeterministic(self): + mock = unittest.mock.Mock(return_value=None) + self.con.create_function("deterministic", 0, mock, deterministic=False) + self.con.execute("select deterministic() = deterministic()") + self.assertEqual(mock.call_count, 2) + + @unittest.skipIf(sqlite.sqlite_version_info < (3, 8, 3), "deterministic parameter not supported") + def CheckFuncDeterministic(self): + mock = unittest.mock.Mock(return_value=None) + self.con.create_function("deterministic", 0, mock, deterministic=True) + self.con.execute("select deterministic() = deterministic()") + self.assertEqual(mock.call_count, 1) + + @unittest.skipIf(sqlite.sqlite_version_info >= (3, 8, 3), "SQLite < 3.8.3 needed") + def CheckFuncDeterministicNotSupported(self): + with self.assertRaises(sqlite.NotSupportedError): + self.con.create_function("deterministic", 0, int, deterministic=True) + + def CheckFuncDeterministicKeywordOnly(self): + with self.assertRaises(TypeError): + self.con.create_function("deterministic", 0, int, True) + class AggregateTests(unittest.TestCase): def setUp(self): diff --git a/Lib/sre_parse.py b/Lib/sre_parse.py index a53735b07ded42..7a172ff2fb14d5 100644 --- a/Lib/sre_parse.py +++ b/Lib/sre_parse.py @@ -264,19 +264,19 @@ def getwhile(self, n, charset): result += c self.__next() return result - def getuntil(self, terminator): + def getuntil(self, terminator, name): result = '' while True: c = self.next self.__next() if c is None: if not result: - raise self.error("missing group name") + raise self.error("missing " + name) raise self.error("missing %s, unterminated name" % terminator, len(result)) if c == terminator: if not result: - raise self.error("missing group name", 1) + raise self.error("missing " + name, 1) break result += c return result @@ -322,6 +322,18 @@ def _class_escape(source, escape): c = int(escape[2:], 16) chr(c) # raise ValueError for invalid code return LITERAL, c + elif c == "N" and source.istext: + import unicodedata + # named unicode escape e.g. \N{EM DASH} + if not source.match('{'): + raise source.error("missing {") + charname = source.getuntil('}', 'character name') + try: + c = ord(unicodedata.lookup(charname)) + except KeyError: + raise source.error("undefined character name %r" % charname, + len(charname) + len(r'\N{}')) + return LITERAL, c elif c in OCTDIGITS: # octal escape (up to three digits) escape += source.getwhile(2, OCTDIGITS) @@ -370,6 +382,18 @@ def _escape(source, escape, state): c = int(escape[2:], 16) chr(c) # raise ValueError for invalid code return LITERAL, c + elif c == "N" and source.istext: + import unicodedata + # named unicode escape e.g. \N{EM DASH} + if not source.match('{'): + raise source.error("missing {") + charname = source.getuntil('}', 'character name') + try: + c = ord(unicodedata.lookup(charname)) + except KeyError: + raise source.error("undefined character name %r" % charname, + len(charname) + len(r'\N{}')) + return LITERAL, c elif c == "0": # octal escape escape += source.getwhile(2, OCTDIGITS) @@ -679,13 +703,13 @@ def _parse(source, state, verbose, nested, first=False): # python extensions if sourcematch("<"): # named group: skip forward to end of name - name = source.getuntil(">") + name = source.getuntil(">", "group name") if not name.isidentifier(): msg = "bad character in group name %r" % name raise source.error(msg, len(name) + 1) elif sourcematch("="): # named backreference - name = source.getuntil(")") + name = source.getuntil(")", "group name") if not name.isidentifier(): msg = "bad character in group name %r" % name raise source.error(msg, len(name) + 1) @@ -748,7 +772,7 @@ def _parse(source, state, verbose, nested, first=False): elif char == "(": # conditional backreference group - condname = source.getuntil(")") + condname = source.getuntil(")", "group name") if condname.isidentifier(): condgroup = state.groupdict.get(condname) if condgroup is None: @@ -977,7 +1001,7 @@ def addgroup(index, pos): name = "" if not s.match("<"): raise s.error("missing <") - name = s.getuntil(">") + name = s.getuntil(">", "group name") if name.isidentifier(): try: index = groupindex[name] diff --git a/Lib/subprocess.py b/Lib/subprocess.py index 93635ee61f7e9f..e070011d980e98 100644 --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -135,6 +135,19 @@ def __init__(self, *, dwFlags=0, hStdInput=None, hStdOutput=None, self.hStdError = hStdError self.wShowWindow = wShowWindow self.lpAttributeList = lpAttributeList or {"handle_list": []} + + def copy(self): + attr_list = self.lpAttributeList.copy() + if 'handle_list' in attr_list: + attr_list['handle_list'] = list(attr_list['handle_list']) + + return STARTUPINFO(dwFlags=self.dwFlags, + hStdInput=self.hStdInput, + hStdOutput=self.hStdOutput, + hStdError=self.hStdError, + wShowWindow=self.wShowWindow, + lpAttributeList=attr_list) + else: import _posixsubprocess import select @@ -1102,6 +1115,10 @@ def _execute_child(self, args, executable, preexec_fn, close_fds, # Process startup details if startupinfo is None: startupinfo = STARTUPINFO() + else: + # bpo-34044: Copy STARTUPINFO since it is modified above, + # so the caller can reuse it multiple times. + startupinfo = startupinfo.copy() use_std_handles = -1 not in (p2cread, c2pwrite, errwrite) if use_std_handles: diff --git a/Lib/tarfile.py b/Lib/tarfile.py index 85119a48a48bfa..ba3e95f281dfdc 100755 --- a/Lib/tarfile.py +++ b/Lib/tarfile.py @@ -256,13 +256,6 @@ def copyfileobj(src, dst, length=None, exception=OSError, bufsize=None): dst.write(buf) return -def filemode(mode): - """Deprecated in this location; use stat.filemode.""" - import warnings - warnings.warn("deprecated in favor of stat.filemode", - DeprecationWarning, 2) - return stat.filemode(mode) - def _safe_print(s): encoding = getattr(sys.stdout, 'encoding', None) if encoding is not None: @@ -520,21 +513,10 @@ def seek(self, pos=0): raise StreamError("seeking backwards is not allowed") return self.pos - def read(self, size=None): - """Return the next size number of bytes from the stream. - If size is not defined, return all bytes of the stream - up to EOF. - """ - if size is None: - t = [] - while True: - buf = self._read(self.bufsize) - if not buf: - break - t.append(buf) - buf = "".join(t) - else: - buf = self._read(size) + def read(self, size): + """Return the next size number of bytes from the stream.""" + assert size is not None + buf = self._read(size) self.pos += len(buf) return buf @@ -545,34 +527,41 @@ def _read(self, size): return self.__read(size) c = len(self.dbuf) + t = [self.dbuf] while c < size: - buf = self.__read(self.bufsize) - if not buf: - break + # Skip underlying buffer to avoid unaligned double buffering. + if self.buf: + buf = self.buf + self.buf = b"" + else: + buf = self.fileobj.read(self.bufsize) + if not buf: + break try: buf = self.cmp.decompress(buf) except self.exception: raise ReadError("invalid compressed data") - self.dbuf += buf + t.append(buf) c += len(buf) - buf = self.dbuf[:size] - self.dbuf = self.dbuf[size:] - return buf + t = b"".join(t) + self.dbuf = t[size:] + return t[:size] def __read(self, size): """Return size bytes from stream. If internal buffer is empty, read another block from the stream. """ c = len(self.buf) + t = [self.buf] while c < size: buf = self.fileobj.read(self.bufsize) if not buf: break - self.buf += buf + t.append(buf) c += len(buf) - buf = self.buf[:size] - self.buf = self.buf[size:] - return buf + t = b"".join(t) + self.buf = t[size:] + return t[:size] # class _Stream class _StreamProxy(object): diff --git a/Lib/tempfile.py b/Lib/tempfile.py index 214322416963cc..e6fb3c8e9ad856 100644 --- a/Lib/tempfile.py +++ b/Lib/tempfile.py @@ -519,7 +519,7 @@ def __iter__(self): def NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, - dir=None, delete=True): + dir=None, delete=True, *, errors=None): """Create and return a temporary file. Arguments: 'prefix', 'suffix', 'dir' -- as for mkstemp. @@ -528,6 +528,7 @@ def NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None, 'encoding' -- the encoding argument to io.open (default None) 'newline' -- the newline argument to io.open (default None) 'delete' -- whether the file is deleted on close (default True). + 'errors' -- the errors argument to io.open (default None) The file is created as mkstemp() would do it. Returns an object with a file-like interface; the name of the file @@ -547,7 +548,7 @@ def NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None, (fd, name) = _mkstemp_inner(dir, prefix, suffix, flags, output_type) try: file = _io.open(fd, mode, buffering=buffering, - newline=newline, encoding=encoding) + newline=newline, encoding=encoding, errors=errors) return _TemporaryFileWrapper(file, name, delete) except BaseException: @@ -568,7 +569,7 @@ def NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None, def TemporaryFile(mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, - dir=None): + dir=None, *, errors=None): """Create and return a temporary file. Arguments: 'prefix', 'suffix', 'dir' -- as for mkstemp. @@ -576,6 +577,7 @@ def TemporaryFile(mode='w+b', buffering=-1, encoding=None, 'buffering' -- the buffer size argument to io.open (default -1). 'encoding' -- the encoding argument to io.open (default None) 'newline' -- the newline argument to io.open (default None) + 'errors' -- the errors argument to io.open (default None) The file is created as mkstemp() would do it. Returns an object with a file-like interface. The file has no @@ -609,7 +611,8 @@ def TemporaryFile(mode='w+b', buffering=-1, encoding=None, else: try: return _io.open(fd, mode, buffering=buffering, - newline=newline, encoding=encoding) + newline=newline, encoding=encoding, + errors=errors) except: _os.close(fd) raise @@ -619,7 +622,7 @@ def TemporaryFile(mode='w+b', buffering=-1, encoding=None, try: _os.unlink(name) return _io.open(fd, mode, buffering=buffering, - newline=newline, encoding=encoding) + newline=newline, encoding=encoding, errors=errors) except: _os.close(fd) raise @@ -633,7 +636,7 @@ class SpooledTemporaryFile: def __init__(self, max_size=0, mode='w+b', buffering=-1, encoding=None, newline=None, - suffix=None, prefix=None, dir=None): + suffix=None, prefix=None, dir=None, *, errors=None): if 'b' in mode: self._file = _io.BytesIO() else: @@ -646,7 +649,7 @@ def __init__(self, max_size=0, mode='w+b', buffering=-1, self._TemporaryFileArgs = {'mode': mode, 'buffering': buffering, 'suffix': suffix, 'prefix': prefix, 'encoding': encoding, 'newline': newline, - 'dir': dir} + 'dir': dir, 'errors': errors} def _check(self, file): if self._rolled: return @@ -692,12 +695,11 @@ def closed(self): @property def encoding(self): - try: - return self._file.encoding - except AttributeError: - if 'b' in self._TemporaryFileArgs['mode']: - raise - return self._TemporaryFileArgs['encoding'] + return self._file.encoding + + @property + def errors(self): + return self._file.errors def fileno(self): self.rollover() @@ -725,12 +727,7 @@ def name(self): @property def newlines(self): - try: - return self._file.newlines - except AttributeError: - if 'b' in self._TemporaryFileArgs['mode']: - raise - return self._TemporaryFileArgs['newline'] + return self._file.newlines def read(self, *args): return self._file.read(*args) diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index 4ae5f976a6b5d0..c4810a5ce17e65 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -651,13 +651,17 @@ def check_forkserver_death(self, signum): from multiprocessing.forkserver import _forkserver _forkserver.ensure_running() + # First process sleeps 500 ms + delay = 0.5 + evt = self.Event() - proc = self.Process(target=self._sleep_and_set_event, args=(evt, 1.0)) + proc = self.Process(target=self._sleep_and_set_event, args=(evt, delay)) proc.start() pid = _forkserver._forkserver_pid os.kill(pid, signum) - time.sleep(1.0) # give it time to die + # give time to the fork server to die and time to proc to complete + time.sleep(delay * 2.0) evt2 = self.Event() proc2 = self.Process(target=self._sleep_and_set_event, args=(evt2,)) @@ -1035,9 +1039,9 @@ def test_timeout(self): start = time.time() self.assertRaises(pyqueue.Empty, q.get, True, 0.200) delta = time.time() - start - # Tolerate a delta of 30 ms because of the bad clock resolution on + # Tolerate a delta of 50 ms because of the bad clock resolution on # Windows (usually 15.6 ms) - self.assertGreaterEqual(delta, 0.170) + self.assertGreaterEqual(delta, 0.150) close_queue(q) def test_queue_feeder_donot_stop_onexc(self): @@ -1482,9 +1486,9 @@ def test_wait_result(self): p = self.Process(target=self._test_wait_result, args=(c, pid)) p.start() - self.assertTrue(c.wait(10)) + self.assertTrue(c.wait(60)) if pid is not None: - self.assertRaises(KeyboardInterrupt, c.wait, 10) + self.assertRaises(KeyboardInterrupt, c.wait, 60) p.join() @@ -2351,10 +2355,10 @@ def test_imap_handle_iterable_exception(self): self.assertRaises(SayWhenError, it.__next__) def test_imap_unordered(self): - it = self.pool.imap_unordered(sqr, list(range(1000))) - self.assertEqual(sorted(it), list(map(sqr, list(range(1000))))) + it = self.pool.imap_unordered(sqr, list(range(10))) + self.assertEqual(sorted(it), list(map(sqr, list(range(10))))) - it = self.pool.imap_unordered(sqr, list(range(1000)), chunksize=53) + it = self.pool.imap_unordered(sqr, list(range(1000)), chunksize=100) self.assertEqual(sorted(it), list(map(sqr, list(range(1000))))) def test_imap_unordered_handle_iterable_exception(self): @@ -2666,7 +2670,9 @@ def test_mymanager(self): def test_mymanager_context(self): with MyManager() as manager: self.common(manager) - self.assertEqual(manager._process.exitcode, 0) + # bpo-30356: BaseManager._finalize_manager() sends SIGTERM + # to the manager process if it takes longer than 1 second to stop. + self.assertIn(manager._process.exitcode, (0, -signal.SIGTERM)) def test_mymanager_context_prestarted(self): manager = MyManager() @@ -3372,11 +3378,25 @@ class _TestHeap(BaseTestCase): ALLOWED_TYPES = ('processes',) + def setUp(self): + super().setUp() + # Make pristine heap for these tests + self.old_heap = multiprocessing.heap.BufferWrapper._heap + multiprocessing.heap.BufferWrapper._heap = multiprocessing.heap.Heap() + + def tearDown(self): + multiprocessing.heap.BufferWrapper._heap = self.old_heap + super().tearDown() + def test_heap(self): iterations = 5000 maxblocks = 50 blocks = [] + # get the heap object + heap = multiprocessing.heap.BufferWrapper._heap + heap._DISCARD_FREE_SPACE_LARGER_THAN = 0 + # create and destroy lots of blocks of different sizes for i in range(iterations): size = int(random.lognormvariate(0, 1) * 1000) @@ -3385,31 +3405,52 @@ def test_heap(self): if len(blocks) > maxblocks: i = random.randrange(maxblocks) del blocks[i] - - # get the heap object - heap = multiprocessing.heap.BufferWrapper._heap + del b # verify the state of the heap - all = [] - occupied = 0 - heap._lock.acquire() - self.addCleanup(heap._lock.release) - for L in list(heap._len_to_seq.values()): - for arena, start, stop in L: - all.append((heap._arenas.index(arena), start, stop, - stop-start, 'free')) - for arena, start, stop in heap._allocated_blocks: - all.append((heap._arenas.index(arena), start, stop, - stop-start, 'occupied')) - occupied += (stop-start) - - all.sort() - - for i in range(len(all)-1): - (arena, start, stop) = all[i][:3] - (narena, nstart, nstop) = all[i+1][:3] - self.assertTrue((arena != narena and nstart == 0) or - (stop == nstart)) + with heap._lock: + all = [] + free = 0 + occupied = 0 + for L in list(heap._len_to_seq.values()): + # count all free blocks in arenas + for arena, start, stop in L: + all.append((heap._arenas.index(arena), start, stop, + stop-start, 'free')) + free += (stop-start) + for arena, arena_blocks in heap._allocated_blocks.items(): + # count all allocated blocks in arenas + for start, stop in arena_blocks: + all.append((heap._arenas.index(arena), start, stop, + stop-start, 'occupied')) + occupied += (stop-start) + + self.assertEqual(free + occupied, + sum(arena.size for arena in heap._arenas)) + + all.sort() + + for i in range(len(all)-1): + (arena, start, stop) = all[i][:3] + (narena, nstart, nstop) = all[i+1][:3] + if arena != narena: + # Two different arenas + self.assertEqual(stop, heap._arenas[arena].size) # last block + self.assertEqual(nstart, 0) # first block + else: + # Same arena: two adjacent blocks + self.assertEqual(stop, nstart) + + # test free'ing all blocks + random.shuffle(blocks) + while blocks: + blocks.pop() + + self.assertEqual(heap._n_frees, heap._n_mallocs) + self.assertEqual(len(heap._pending_free_blocks), 0) + self.assertEqual(len(heap._arenas), 0) + self.assertEqual(len(heap._allocated_blocks), 0, heap._allocated_blocks) + self.assertEqual(len(heap._len_to_seq), 0) def test_free_from_gc(self): # Check that freeing of blocks by the garbage collector doesn't deadlock diff --git a/Lib/test/libregrtest/main.py b/Lib/test/libregrtest/main.py index 3429b3726abe90..e262a7a172b931 100644 --- a/Lib/test/libregrtest/main.py +++ b/Lib/test/libregrtest/main.py @@ -462,6 +462,13 @@ def run_tests(self): or self.tests or self.ns.args)): self.display_header() + if self.ns.huntrleaks: + warmup, repetitions, _ = self.ns.huntrleaks + if warmup < 3: + msg = ("WARNING: Running tests with --huntrleaks/-R and less than " + "3 warmup repetitions can give false positives!") + print(msg, file=sys.stdout, flush=True) + if self.ns.randomize: print("Using random seed", self.ns.random_seed) @@ -526,6 +533,15 @@ def main(self, tests=None, **kwargs): def _main(self, tests, kwargs): self.ns = self.parse_args(kwargs) + if self.ns.huntrleaks: + warmup, repetitions, _ = self.ns.huntrleaks + if warmup < 1 or repetitions < 1: + msg = ("Invalid values for the --huntrleaks/-R parameters. The " + "number of warmups and repetitions must be at least 1 " + "each (1:1).") + print(msg, file=sys.stderr, flush=True) + sys.exit(2) + if self.ns.slaveargs is not None: from test.libregrtest.runtest_mp import run_tests_slave run_tests_slave(self.ns.slaveargs) diff --git a/Lib/test/libregrtest/runtest.py b/Lib/test/libregrtest/runtest.py index 12bf422c902dc1..3e1afd41997aad 100644 --- a/Lib/test/libregrtest/runtest.py +++ b/Lib/test/libregrtest/runtest.py @@ -173,9 +173,10 @@ def test_runner(): if loader.errors: raise Exception("errors while loading tests") support.run_unittest(tests) - test_runner() if ns.huntrleaks: refleak = dash_R(the_module, test, test_runner, ns.huntrleaks) + else: + test_runner() test_time = time.time() - start_time post_test_cleanup() except support.ResourceDenied as msg: diff --git a/Lib/test/libregrtest/runtest_mp.py b/Lib/test/libregrtest/runtest_mp.py index f7fa10cf551a4e..907451cf63116c 100644 --- a/Lib/test/libregrtest/runtest_mp.py +++ b/Lib/test/libregrtest/runtest_mp.py @@ -200,7 +200,7 @@ def get_running(workers): if (ok not in (CHILD_ERROR, INTERRUPTED) and test_time >= PROGRESS_MIN_TIME and not regrtest.ns.pgo): - text += ' (%.0f sec)' % test_time + text += ' (%s)' % format_duration(test_time) elif ok == CHILD_ERROR: text = '%s (%s)' % (text, test_time) running = get_running(workers) diff --git a/Lib/test/libregrtest/save_env.py b/Lib/test/libregrtest/save_env.py index 45b365d456336a..2313b71ec893b1 100644 --- a/Lib/test/libregrtest/save_env.py +++ b/Lib/test/libregrtest/save_env.py @@ -1,3 +1,4 @@ +import asyncio import builtins import locale import logging @@ -65,8 +66,14 @@ def __init__(self, testname, verbose=0, quiet=False, *, pgo=False): 'sysconfig._CONFIG_VARS', 'sysconfig._INSTALL_SCHEMES', 'files', 'locale', 'warnings.showwarning', 'shutil_archive_formats', 'shutil_unpack_formats', + 'asyncio.events._event_loop_policy', ) + def get_asyncio_events__event_loop_policy(self): + return support.maybe_get_event_loop_policy() + def restore_asyncio_events__event_loop_policy(self, policy): + asyncio.set_event_loop_policy(policy) + def get_sys_argv(self): return id(sys.argv), sys.argv, sys.argv[:] def restore_sys_argv(self, saved_argv): diff --git a/Lib/test/libregrtest/utils.py b/Lib/test/libregrtest/utils.py index 85049cb06b3649..d36bf9196626db 100644 --- a/Lib/test/libregrtest/utils.py +++ b/Lib/test/libregrtest/utils.py @@ -1,19 +1,28 @@ import os.path +import math import textwrap def format_duration(seconds): - if seconds < 1.0: - return '%.0f ms' % (seconds * 1e3) - if seconds < 60.0: - return '%.0f sec' % seconds + ms = math.ceil(seconds * 1e3) + seconds, ms = divmod(ms, 1000) + minutes, seconds = divmod(seconds, 60) + hours, minutes = divmod(minutes, 60) - minutes, seconds = divmod(seconds, 60.0) - hours, minutes = divmod(minutes, 60.0) + parts = [] if hours: - return '%.0f hour %.0f min' % (hours, minutes) - else: - return '%.0f min %.0f sec' % (minutes, seconds) + parts.append('%s hour' % hours) + if minutes: + parts.append('%s min' % minutes) + if seconds: + parts.append('%s sec' % seconds) + if ms: + parts.append('%s ms' % ms) + if not parts: + return '0 ms' + + parts = parts[:2] + return ' '.join(parts) def removepy(names): diff --git a/Lib/test/pythoninfo.py b/Lib/test/pythoninfo.py index 9242a36bedd68b..f058185c2f8097 100644 --- a/Lib/test/pythoninfo.py +++ b/Lib/test/pythoninfo.py @@ -525,6 +525,15 @@ def collect_cc(info_add): info_add('CC.version', text) +def collect_gdbm(info_add): + try: + from _gdbm import _GDBM_VERSION + except ImportError: + return + + info_add('gdbm.GDBM_VERSION', '.'.join(map(str, _GDBM_VERSION))) + + def collect_info(info): error = False info_add = info.add @@ -552,6 +561,7 @@ def collect_info(info): collect_testcapi, collect_resource, collect_cc, + collect_gdbm, # Collecting from tests should be last as they have side effects. collect_test_socket, diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index ddcd2cc3875922..d8dabd43589564 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -3,6 +3,7 @@ if __name__ != 'test.support': raise ImportError('support must be imported from the test package') +import asyncio.events import collections.abc import contextlib import errno @@ -1082,8 +1083,8 @@ def make_bad_fd(): file.close() unlink(TESTFN) -def check_syntax_error(testcase, statement, *, lineno=None, offset=None): - with testcase.assertRaises(SyntaxError) as cm: +def check_syntax_error(testcase, statement, errtext='', *, lineno=None, offset=None): + with testcase.assertRaisesRegex(SyntaxError, errtext) as cm: compile(statement, '<test string>', 'exec') err = cm.exception testcase.assertIsNotNone(err.lineno) @@ -2822,7 +2823,7 @@ def fd_count(): class SaveSignals: """ - Save an restore signal handlers. + Save and restore signal handlers. This class is only able to save/restore signal handlers registered by the Python signal module: see bpo-13285 for "external" signal @@ -2832,7 +2833,7 @@ class SaveSignals: def __init__(self): import signal self.signal = signal - self.signals = list(range(1, signal.NSIG)) + self.signals = signal.valid_signals() # SIGKILL and SIGSTOP signals cannot be ignored nor caught for signame in ('SIGKILL', 'SIGSTOP'): try: @@ -2880,3 +2881,8 @@ def __fspath__(self): raise self.path else: return self.path + + +def maybe_get_event_loop_policy(): + """Return the global event loop policy if one is set, else return None.""" + return asyncio.events._event_loop_policy diff --git a/Lib/test/test__opcode.py b/Lib/test/test__opcode.py index 1075decc270420..2af1ee35bff0ab 100644 --- a/Lib/test/test__opcode.py +++ b/Lib/test/test__opcode.py @@ -15,6 +15,21 @@ def test_stack_effect(self): self.assertRaises(ValueError, _opcode.stack_effect, 30000) self.assertRaises(ValueError, _opcode.stack_effect, dis.opmap['BUILD_SLICE']) self.assertRaises(ValueError, _opcode.stack_effect, dis.opmap['POP_TOP'], 0) + # All defined opcodes + for name, code in dis.opmap.items(): + with self.subTest(opname=name): + if code < dis.HAVE_ARGUMENT: + _opcode.stack_effect(code) + self.assertRaises(ValueError, _opcode.stack_effect, code, 0) + else: + _opcode.stack_effect(code, 0) + self.assertRaises(ValueError, _opcode.stack_effect, code) + # All not defined opcodes + for code in set(range(256)) - set(dis.opmap.values()): + with self.subTest(opcode=code): + self.assertRaises(ValueError, _opcode.stack_effect, code) + self.assertRaises(ValueError, _opcode.stack_effect, code, 0) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_asyncgen.py b/Lib/test/test_asyncgen.py index 5a36423dc97afa..9d60cb0e7e8f14 100644 --- a/Lib/test/test_asyncgen.py +++ b/Lib/test/test_asyncgen.py @@ -108,6 +108,31 @@ def sync_iterate(g): res.append(str(type(ex))) return res + def async_iterate(g): + res = [] + while True: + an = g.__anext__() + try: + while True: + try: + an.__next__() + except StopIteration as ex: + if ex.args: + res.append(ex.args[0]) + break + else: + res.append('EMPTY StopIteration') + break + except StopAsyncIteration: + raise + except Exception as ex: + res.append(str(type(ex))) + break + except StopAsyncIteration: + res.append('STOP') + break + return res + def async_iterate(g): res = [] while True: @@ -297,6 +322,37 @@ async def gen(): "non-None value .* async generator"): gen().__anext__().send(100) + def test_async_gen_exception_11(self): + def sync_gen(): + yield 10 + yield 20 + + def sync_gen_wrapper(): + yield 1 + sg = sync_gen() + sg.send(None) + try: + sg.throw(GeneratorExit()) + except GeneratorExit: + yield 2 + yield 3 + + async def async_gen(): + yield 10 + yield 20 + + async def async_gen_wrapper(): + yield 1 + asg = async_gen() + await asg.asend(None) + try: + await asg.athrow(GeneratorExit()) + except GeneratorExit: + yield 2 + yield 3 + + self.compare_generators(sync_gen_wrapper(), async_gen_wrapper()) + def test_async_gen_api_01(self): async def gen(): yield 123 @@ -328,6 +384,7 @@ def setUp(self): def tearDown(self): self.loop.close() self.loop = None + asyncio.set_event_loop_policy(None) async def to_list(self, gen): res = [] diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py index 11e9465d392179..bda8cc6e3a8210 100644 --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -24,6 +24,10 @@ PY34 = sys.version_info >= (3, 4) +def tearDownModule(): + asyncio.set_event_loop_policy(None) + + def mock_socket_module(): m_socket = mock.MagicMock(spec=socket) for name in ( @@ -93,11 +97,11 @@ def test_ipaddr_info(self): base_events._ipaddr_info('1.2.3.4', 1, INET6, STREAM, TCP)) self.assertEqual( - (INET6, STREAM, TCP, '', ('::3', 1)), + (INET6, STREAM, TCP, '', ('::3', 1, 0, 0)), base_events._ipaddr_info('::3', 1, INET6, STREAM, TCP)) self.assertEqual( - (INET6, STREAM, TCP, '', ('::3', 1)), + (INET6, STREAM, TCP, '', ('::3', 1, 0, 0)), base_events._ipaddr_info('::3', 1, UNSPEC, STREAM, TCP)) # IPv6 address with family IPv4. @@ -1073,6 +1077,26 @@ def test_create_server_stream_bittype(self): srv.close() self.loop.run_until_complete(srv.wait_closed()) + @unittest.skipUnless(hasattr(socket, 'AF_INET6'), 'no IPv6 support') + def test_create_server_ipv6(self): + async def main(): + srv = await asyncio.start_server( + lambda: None, '::1', 0, loop=self.loop) + try: + self.assertGreater(len(srv.sockets), 0) + finally: + srv.close() + await srv.wait_closed() + + try: + self.loop.run_until_complete(main()) + except OSError as ex: + if (hasattr(errno, 'EADDRNOTAVAIL') and + ex.errno == errno.EADDRNOTAVAIL): + self.skipTest('failed to bind to ::1') + else: + raise + def test_create_datagram_endpoint_wrong_sock(self): sock = socket.socket(socket.AF_INET) with sock: diff --git a/Lib/test/test_asyncio/test_buffered_proto.py b/Lib/test/test_asyncio/test_buffered_proto.py index 89d3df72d98b62..5a5e198b58f746 100644 --- a/Lib/test/test_asyncio/test_buffered_proto.py +++ b/Lib/test/test_asyncio/test_buffered_proto.py @@ -4,6 +4,10 @@ from test.test_asyncio import functional as func_tests +def tearDownModule(): + asyncio.set_event_loop_policy(None) + + class ReceiveStuffProto(asyncio.BufferedProtocol): def __init__(self, cb, con_lost_fut): self.cb = cb diff --git a/Lib/test/test_asyncio/test_context.py b/Lib/test/test_asyncio/test_context.py index 6abddd9f2515e1..c309faa90062e1 100644 --- a/Lib/test/test_asyncio/test_context.py +++ b/Lib/test/test_asyncio/test_context.py @@ -3,6 +3,10 @@ import unittest +def tearDownModule(): + asyncio.set_event_loop_policy(None) + + class DecimalContextTest(unittest.TestCase): def test_asyncio_task_decimal_context(self): diff --git a/Lib/test/test_asyncio/test_events.py b/Lib/test/test_asyncio/test_events.py index 01ed47b3649558..11cd950df1cedb 100644 --- a/Lib/test/test_asyncio/test_events.py +++ b/Lib/test/test_asyncio/test_events.py @@ -37,6 +37,10 @@ from test import support +def tearDownModule(): + asyncio.set_event_loop_policy(None) + + def osx_tiger(): """Return True if the platform is Mac OS 10.4 or older.""" if sys.platform != 'darwin': diff --git a/Lib/test/test_asyncio/test_futures.py b/Lib/test/test_asyncio/test_futures.py index 8c837ad6b620b6..33393562090986 100644 --- a/Lib/test/test_asyncio/test_futures.py +++ b/Lib/test/test_asyncio/test_futures.py @@ -14,6 +14,10 @@ from test import support +def tearDownModule(): + asyncio.set_event_loop_policy(None) + + def _fakefunc(f): return f diff --git a/Lib/test/test_asyncio/test_locks.py b/Lib/test/test_asyncio/test_locks.py index b8d155e1d0340c..63bcb03a5371a9 100644 --- a/Lib/test/test_asyncio/test_locks.py +++ b/Lib/test/test_asyncio/test_locks.py @@ -16,6 +16,10 @@ RGX_REPR = re.compile(STR_RGX_REPR) +def tearDownModule(): + asyncio.set_event_loop_policy(None) + + class LockTests(test_utils.TestCase): def setUp(self): diff --git a/Lib/test/test_asyncio/test_pep492.py b/Lib/test/test_asyncio/test_pep492.py index f2d588f54445a2..5edd36eb4c6b26 100644 --- a/Lib/test/test_asyncio/test_pep492.py +++ b/Lib/test/test_asyncio/test_pep492.py @@ -11,6 +11,10 @@ from test.test_asyncio import utils as test_utils +def tearDownModule(): + asyncio.set_event_loop_policy(None) + + # Test that asyncio.iscoroutine() uses collections.abc.Coroutine class FakeCoro: def send(self, value): diff --git a/Lib/test/test_asyncio/test_proactor_events.py b/Lib/test/test_asyncio/test_proactor_events.py index 557b461750a1d3..ac529413c2756b 100644 --- a/Lib/test/test_asyncio/test_proactor_events.py +++ b/Lib/test/test_asyncio/test_proactor_events.py @@ -16,6 +16,10 @@ from test.test_asyncio import utils as test_utils +def tearDownModule(): + asyncio.set_event_loop_policy(None) + + def close_transport(transport): # Don't call transport.close() because the event loop and the IOCP proactor # are mocked diff --git a/Lib/test/test_asyncio/test_queues.py b/Lib/test/test_asyncio/test_queues.py index efe719ed39a989..eba66e790dcd0b 100644 --- a/Lib/test/test_asyncio/test_queues.py +++ b/Lib/test/test_asyncio/test_queues.py @@ -7,6 +7,10 @@ from test.test_asyncio import utils as test_utils +def tearDownModule(): + asyncio.set_event_loop_policy(None) + + class _QueueTestBase(test_utils.TestCase): def setUp(self): diff --git a/Lib/test/test_asyncio/test_selector_events.py b/Lib/test/test_asyncio/test_selector_events.py index 68b6ee9abbf11a..d380aa4138f8e9 100644 --- a/Lib/test/test_asyncio/test_selector_events.py +++ b/Lib/test/test_asyncio/test_selector_events.py @@ -22,6 +22,10 @@ MOCK_ANY = mock.ANY +def tearDownModule(): + asyncio.set_event_loop_policy(None) + + class TestBaseSelectorEventLoop(BaseSelectorEventLoop): def _make_self_pipe(self): diff --git a/Lib/test/test_asyncio/test_server.py b/Lib/test/test_asyncio/test_server.py index 034293cb3f5961..6de058a1e9bff5 100644 --- a/Lib/test/test_asyncio/test_server.py +++ b/Lib/test/test_asyncio/test_server.py @@ -9,6 +9,10 @@ from test.test_asyncio import functional as func_tests +def tearDownModule(): + asyncio.set_event_loop_policy(None) + + class BaseStartServer(func_tests.FunctionalTestCaseMixin): def new_loop(self): diff --git a/Lib/test/test_asyncio/test_sslproto.py b/Lib/test/test_asyncio/test_sslproto.py index 46a1523ea1ec83..818267138a4cf5 100644 --- a/Lib/test/test_asyncio/test_sslproto.py +++ b/Lib/test/test_asyncio/test_sslproto.py @@ -18,6 +18,10 @@ from test.test_asyncio import functional as func_tests +def tearDownModule(): + asyncio.set_event_loop_policy(None) + + @unittest.skipIf(ssl is None, 'No ssl module') class SslProtoHandshakeTests(test_utils.TestCase): diff --git a/Lib/test/test_asyncio/test_streams.py b/Lib/test/test_asyncio/test_streams.py index 63fa13f79e2871..66d18738b31626 100644 --- a/Lib/test/test_asyncio/test_streams.py +++ b/Lib/test/test_asyncio/test_streams.py @@ -19,6 +19,10 @@ from test.test_asyncio import utils as test_utils +def tearDownModule(): + asyncio.set_event_loop_policy(None) + + class StreamTests(test_utils.TestCase): DATA = b'line1\nline2\nline3\n' diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py index 235813aa977c1e..2be311d97a93cf 100644 --- a/Lib/test/test_asyncio/test_subprocess.py +++ b/Lib/test/test_asyncio/test_subprocess.py @@ -23,6 +23,11 @@ 'data = sys.stdin.buffer.read()', 'sys.stdout.buffer.write(data)'))] + +def tearDownModule(): + asyncio.set_event_loop_policy(None) + + class TestSubprocessTransport(base_subprocess.BaseSubprocessTransport): def _start(self, *args, **kwargs): self._proc = mock.Mock() diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index 67df3c0f48fde5..a5442f5fdfff8f 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -24,6 +24,10 @@ from test.support.script_helper import assert_python_ok +def tearDownModule(): + asyncio.set_event_loop_policy(None) + + @asyncio.coroutine def coroutine_function(): pass diff --git a/Lib/test/test_asyncio/test_unix_events.py b/Lib/test/test_asyncio/test_unix_events.py index 104f995937972e..29b345b142e854 100644 --- a/Lib/test/test_asyncio/test_unix_events.py +++ b/Lib/test/test_asyncio/test_unix_events.py @@ -31,6 +31,10 @@ MOCK_ANY = mock.ANY +def tearDownModule(): + asyncio.set_event_loop_policy(None) + + def close_pipe_transport(transport): # Don't call transport.close() because the event loop and the selector # are mocked @@ -69,6 +73,7 @@ def test_handle_signal_cancelled_handler(self): @mock.patch('asyncio.unix_events.signal') def test_add_signal_handler_setup_error(self, m_signal): m_signal.NSIG = signal.NSIG + m_signal.valid_signals = signal.valid_signals m_signal.set_wakeup_fd.side_effect = ValueError self.assertRaises( @@ -96,6 +101,7 @@ async def simple_coroutine(): @mock.patch('asyncio.unix_events.signal') def test_add_signal_handler(self, m_signal): m_signal.NSIG = signal.NSIG + m_signal.valid_signals = signal.valid_signals cb = lambda: True self.loop.add_signal_handler(signal.SIGHUP, cb) @@ -106,6 +112,7 @@ def test_add_signal_handler(self, m_signal): @mock.patch('asyncio.unix_events.signal') def test_add_signal_handler_install_error(self, m_signal): m_signal.NSIG = signal.NSIG + m_signal.valid_signals = signal.valid_signals def set_wakeup_fd(fd): if fd == -1: @@ -125,6 +132,7 @@ class Err(OSError): @mock.patch('asyncio.base_events.logger') def test_add_signal_handler_install_error2(self, m_logging, m_signal): m_signal.NSIG = signal.NSIG + m_signal.valid_signals = signal.valid_signals class Err(OSError): errno = errno.EINVAL @@ -145,6 +153,7 @@ class Err(OSError): errno = errno.EINVAL m_signal.signal.side_effect = Err m_signal.NSIG = signal.NSIG + m_signal.valid_signals = signal.valid_signals self.assertRaises( RuntimeError, @@ -156,6 +165,7 @@ class Err(OSError): @mock.patch('asyncio.unix_events.signal') def test_remove_signal_handler(self, m_signal): m_signal.NSIG = signal.NSIG + m_signal.valid_signals = signal.valid_signals self.loop.add_signal_handler(signal.SIGHUP, lambda: True) @@ -170,6 +180,7 @@ def test_remove_signal_handler(self, m_signal): def test_remove_signal_handler_2(self, m_signal): m_signal.NSIG = signal.NSIG m_signal.SIGINT = signal.SIGINT + m_signal.valid_signals = signal.valid_signals self.loop.add_signal_handler(signal.SIGINT, lambda: True) self.loop._signal_handlers[signal.SIGHUP] = object() @@ -187,6 +198,7 @@ def test_remove_signal_handler_2(self, m_signal): @mock.patch('asyncio.base_events.logger') def test_remove_signal_handler_cleanup_error(self, m_logging, m_signal): m_signal.NSIG = signal.NSIG + m_signal.valid_signals = signal.valid_signals self.loop.add_signal_handler(signal.SIGHUP, lambda: True) m_signal.set_wakeup_fd.side_effect = ValueError @@ -197,6 +209,7 @@ def test_remove_signal_handler_cleanup_error(self, m_logging, m_signal): @mock.patch('asyncio.unix_events.signal') def test_remove_signal_handler_error(self, m_signal): m_signal.NSIG = signal.NSIG + m_signal.valid_signals = signal.valid_signals self.loop.add_signal_handler(signal.SIGHUP, lambda: True) m_signal.signal.side_effect = OSError @@ -207,6 +220,7 @@ def test_remove_signal_handler_error(self, m_signal): @mock.patch('asyncio.unix_events.signal') def test_remove_signal_handler_error2(self, m_signal): m_signal.NSIG = signal.NSIG + m_signal.valid_signals = signal.valid_signals self.loop.add_signal_handler(signal.SIGHUP, lambda: True) class Err(OSError): @@ -219,6 +233,7 @@ class Err(OSError): @mock.patch('asyncio.unix_events.signal') def test_close(self, m_signal): m_signal.NSIG = signal.NSIG + m_signal.valid_signals = signal.valid_signals self.loop.add_signal_handler(signal.SIGHUP, lambda: True) self.loop.add_signal_handler(signal.SIGCHLD, lambda: True) @@ -236,6 +251,7 @@ def test_close(self, m_signal): @mock.patch('asyncio.unix_events.signal') def test_close_on_finalizing(self, m_signal, m_sys): m_signal.NSIG = signal.NSIG + m_signal.valid_signals = signal.valid_signals self.loop.add_signal_handler(signal.SIGHUP, lambda: True) self.assertEqual(len(self.loop._signal_handlers), 1) diff --git a/Lib/test/test_asyncio/test_windows_events.py b/Lib/test/test_asyncio/test_windows_events.py index 15d933da21be1c..8f4c50e2c92b45 100644 --- a/Lib/test/test_asyncio/test_windows_events.py +++ b/Lib/test/test_asyncio/test_windows_events.py @@ -15,6 +15,10 @@ from test.test_asyncio import utils as test_utils +def tearDownModule(): + asyncio.set_event_loop_policy(None) + + class UpperProto(asyncio.Protocol): def __init__(self): self.buf = [] diff --git a/Lib/test/test_asyncio/test_windows_utils.py b/Lib/test/test_asyncio/test_windows_utils.py index 9fc38586ab0023..45c09bb4a2d3a0 100644 --- a/Lib/test/test_asyncio/test_windows_utils.py +++ b/Lib/test/test_asyncio/test_windows_utils.py @@ -10,10 +10,15 @@ import _overlapped import _winapi +import asyncio from asyncio import windows_utils from test import support +def tearDownModule(): + asyncio.set_event_loop_policy(None) + + class PipeTests(unittest.TestCase): def test_pipe_overlapped(self): diff --git a/Lib/test/test_binascii.py b/Lib/test/test_binascii.py index 7418a9ce984879..c5fcc1ac164730 100644 --- a/Lib/test/test_binascii.py +++ b/Lib/test/test_binascii.py @@ -226,6 +226,11 @@ def test_hex(self): self.assertEqual(s, u) self.assertRaises(binascii.Error, binascii.a2b_hex, t[:-1]) self.assertRaises(binascii.Error, binascii.a2b_hex, t[:-1] + b'q') + self.assertRaises(binascii.Error, binascii.a2b_hex, bytes([255, 255])) + self.assertRaises(binascii.Error, binascii.a2b_hex, b'0G') + self.assertRaises(binascii.Error, binascii.a2b_hex, b'0g') + self.assertRaises(binascii.Error, binascii.a2b_hex, b'G0') + self.assertRaises(binascii.Error, binascii.a2b_hex, b'g0') # Confirm that b2a_hex == hexlify and a2b_hex == unhexlify self.assertEqual(binascii.hexlify(self.type2test(s)), t) diff --git a/Lib/test/test_buffer.py b/Lib/test/test_buffer.py index f302da415d33f3..a3f3ef098a6137 100644 --- a/Lib/test/test_buffer.py +++ b/Lib/test/test_buffer.py @@ -924,23 +924,30 @@ def verify(self, result, obj=-1, except BufferError: # re-exporter does not provide full information return ex = result.obj if isinstance(result, memoryview) else result - self.assertIs(m.obj, ex) - self.assertEqual(m.nbytes, expected_len) - self.assertEqual(m.itemsize, itemsize) - self.assertEqual(m.format, fmt) - self.assertEqual(m.readonly, readonly) - self.assertEqual(m.ndim, ndim) - self.assertEqual(m.shape, tuple(shape)) - if not (sliced and suboffsets): - self.assertEqual(m.strides, tuple(strides)) - self.assertEqual(m.suboffsets, tuple(suboffsets)) - - n = 1 if ndim == 0 else len(lst) - self.assertEqual(len(m), n) - rep = result.tolist() if fmt else result.tobytes() - self.assertEqual(rep, lst) - self.assertEqual(m, result) + def check_memoryview(m, expected_readonly=readonly): + self.assertIs(m.obj, ex) + self.assertEqual(m.nbytes, expected_len) + self.assertEqual(m.itemsize, itemsize) + self.assertEqual(m.format, fmt) + self.assertEqual(m.readonly, expected_readonly) + self.assertEqual(m.ndim, ndim) + self.assertEqual(m.shape, tuple(shape)) + if not (sliced and suboffsets): + self.assertEqual(m.strides, tuple(strides)) + self.assertEqual(m.suboffsets, tuple(suboffsets)) + + n = 1 if ndim == 0 else len(lst) + self.assertEqual(len(m), n) + + rep = result.tolist() if fmt else result.tobytes() + self.assertEqual(rep, lst) + self.assertEqual(m, result) + + check_memoryview(m) + with m.toreadonly() as mm: + check_memoryview(mm, expected_readonly=True) + m.tobytes() # Releasing mm didn't release m def verify_getbuf(self, orig_ex, ex, req, sliced=False): def simple_fmt(ex): diff --git a/Lib/test/test_cgi.py b/Lib/test/test_cgi.py index 4f2bba14a1bdc4..b284a0d0980586 100644 --- a/Lib/test/test_cgi.py +++ b/Lib/test/test_cgi.py @@ -4,7 +4,6 @@ import sys import tempfile import unittest -import warnings from collections import namedtuple from io import StringIO, BytesIO from test import support @@ -163,15 +162,6 @@ def test_fieldstorage_invalid(self): 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(): - warnings.filterwarnings('ignore', r'cgi\.escape', - DeprecationWarning) - self.assertEqual("test & string", cgi.escape("test & string")) - self.assertEqual("<test string>", cgi.escape("<test string>")) - self.assertEqual(""test string"", cgi.escape('"test string"', True)) - def test_strict(self): for orig, expect in parse_strict_test_cases: # Test basic parsing @@ -449,20 +439,6 @@ def testQSAndFormDataFile(self): v = gen_result(data, environ) self.assertEqual(result, v) - def test_deprecated_parse_qs(self): - # this func is moved to urllib.parse, this is just a sanity check - with check_warnings(('cgi.parse_qs is deprecated, use urllib.parse.' - 'parse_qs instead', DeprecationWarning)): - self.assertEqual({'a': ['A1'], 'B': ['B3'], 'b': ['B2']}, - cgi.parse_qs('a=A1&b=B2&B=B3')) - - def test_deprecated_parse_qsl(self): - # this func is moved to urllib.parse, this is just a sanity check - with check_warnings(('cgi.parse_qsl is deprecated, use urllib.parse.' - 'parse_qsl instead', DeprecationWarning)): - self.assertEqual([('a', 'A1'), ('b', 'B2'), ('B', 'B3')], - cgi.parse_qsl('a=A1&b=B2&B=B3')) - def test_parse_header(self): self.assertEqual( cgi.parse_header("text/plain"), diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index d8a96c49ce9699..ce14a96c1407f3 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -519,6 +519,32 @@ def test_sys_flags_set(self): with self.subTest(envar_value=value): assert_python_ok('-c', code, **env_vars) + def test_set_pycache_prefix(self): + # sys.pycache_prefix can be set from either -X pycache_prefix or + # PYTHONPYCACHEPREFIX env var, with the former taking precedence. + NO_VALUE = object() # `-X pycache_prefix` with no `=PATH` + cases = [ + # (PYTHONPYCACHEPREFIX, -X pycache_prefix, sys.pycache_prefix) + (None, None, None), + ('foo', None, 'foo'), + (None, 'bar', 'bar'), + ('foo', 'bar', 'bar'), + ('foo', '', None), + ('foo', NO_VALUE, None), + ] + for envval, opt, expected in cases: + exp_clause = "is None" if expected is None else f'== "{expected}"' + code = f"import sys; sys.exit(not sys.pycache_prefix {exp_clause})" + args = ['-c', code] + env = {} if envval is None else {'PYTHONPYCACHEPREFIX': envval} + if opt is NO_VALUE: + args[:0] = ['-X', 'pycache_prefix'] + elif opt is not None: + args[:0] = ['-X', f'pycache_prefix={opt}'] + with self.subTest(envval=envval, opt=opt): + with support.temp_cwd(): + assert_python_ok(*args, **env) + def run_xdev(self, *args, check_exitcode=True, xdev=True): env = dict(os.environ) env.pop('PYTHONWARNINGS', None) diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index acebdbdc463613..6b45a24334381c 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -856,7 +856,7 @@ def test_for_break_continue_inside_try_finally_block(self): """ self.check_stack_size(snippet) - def test_for_break_inside_finally_block(self): + def test_for_break_continue_inside_finally_block(self): snippet = """ for x in y: try: @@ -864,6 +864,8 @@ def test_for_break_inside_finally_block(self): finally: if z: break + elif u: + continue else: a else: diff --git a/Lib/test/test_concurrent_futures.py b/Lib/test/test_concurrent_futures.py index b258a0eafde6d4..01125c79ba575e 100644 --- a/Lib/test/test_concurrent_futures.py +++ b/Lib/test/test_concurrent_futures.py @@ -109,7 +109,7 @@ class ExecutorMixin: def setUp(self): super().setUp() - self.t1 = time.time() + self.t1 = time.monotonic() if hasattr(self, "ctx"): self.executor = self.executor_type( max_workers=self.worker_count, @@ -125,10 +125,10 @@ def tearDown(self): self.executor.shutdown(wait=True) self.executor = None - dt = time.time() - self.t1 + dt = time.monotonic() - self.t1 if test.support.verbose: print("%.2fs" % dt, end=' ') - self.assertLess(dt, 60, "synchronization issue: test lasted too long") + self.assertLess(dt, 300, "synchronization issue: test lasted too long") super().tearDown() @@ -240,9 +240,9 @@ def test_initializer(self): with self.assertRaises(BrokenExecutor): future.result() # At some point, the executor should break - t1 = time.time() + t1 = time.monotonic() while not self.executor._broken: - if time.time() - t1 > 5: + if time.monotonic() - t1 > 5: self.fail("executor not broken after 5 s.") time.sleep(0.01) # ... and from this point submit() is guaranteed to fail @@ -1206,6 +1206,34 @@ def notification(): self.assertTrue(isinstance(f1.exception(timeout=5), OSError)) t.join() + def test_multiple_set_result(self): + f = create_future(state=PENDING) + f.set_result(1) + + with self.assertRaisesRegex( + futures.InvalidStateError, + 'FINISHED: <Future at 0x[0-9a-f]+ ' + 'state=finished returned int>' + ): + f.set_result(2) + + self.assertTrue(f.done()) + self.assertEqual(f.result(), 1) + + def test_multiple_set_exception(self): + f = create_future(state=PENDING) + e = ValueError() + f.set_exception(e) + + with self.assertRaisesRegex( + futures.InvalidStateError, + 'FINISHED: <Future at 0x[0-9a-f]+ ' + 'state=finished raised ValueError>' + ): + f.set_exception(Exception()) + + self.assertEqual(f.exception(), e) + @test.support.reap_threads def test_main(): diff --git a/Lib/test/test_configparser.py b/Lib/test/test_configparser.py index 4d07203b9dac28..f16da116a745f3 100644 --- a/Lib/test/test_configparser.py +++ b/Lib/test/test_configparser.py @@ -850,12 +850,18 @@ def test_setitem(self): self.assertEqual(set(cf['section3'].keys()), {'named'}) self.assertNotIn('name3', cf['section3']) self.assertEqual(cf.sections(), ['section1', 'section2', 'section3']) + # For bpo-32108, assigning default_section to itself. + cf[self.default_section] = cf[self.default_section] + self.assertNotEqual(set(cf[self.default_section].keys()), set()) cf[self.default_section] = {} self.assertEqual(set(cf[self.default_section].keys()), set()) self.assertEqual(set(cf['section1'].keys()), {'name1'}) self.assertEqual(set(cf['section2'].keys()), {'name22'}) self.assertEqual(set(cf['section3'].keys()), set()) self.assertEqual(cf.sections(), ['section1', 'section2', 'section3']) + # For bpo-32108, assigning section to itself. + cf['section2'] = cf['section2'] + self.assertEqual(set(cf['section2'].keys()), {'name22'}) def test_invalid_multiline_value(self): if self.allow_no_value: @@ -915,8 +921,7 @@ def test_items(self): self.check_items_config([('default', '<default>'), ('getdefault', '|<default>|'), ('key', '|value|'), - ('name', 'value'), - ('value', 'value')]) + ('name', 'value')]) def test_safe_interpolation(self): # See http://www.python.org/sf/511737 @@ -1093,8 +1098,7 @@ def test_items(self): self.check_items_config([('default', '<default>'), ('getdefault', '|%(default)s|'), ('key', '|%(name)s|'), - ('name', '%(value)s'), - ('value', 'value')]) + ('name', '%(value)s')]) def test_set_nonstring_types(self): cf = self.newconfig() @@ -1111,7 +1115,7 @@ def test_set_nonstring_types(self): self.assertEqual(cf.get(123, 'this is sick'), True) if cf._dict is configparser._default_dict: # would not work for SortedDict; only checking for the most common - # default dictionary (OrderedDict) + # default dictionary (dict) cf.optionxform = lambda x: x cf.set('non-string', 1, 1) self.assertEqual(cf.get('non-string', 1), 1) diff --git a/Lib/test/test_context.py b/Lib/test/test_context.py index 74d05fc5c412cd..efd7319a23ae02 100644 --- a/Lib/test/test_context.py +++ b/Lib/test/test_context.py @@ -30,8 +30,13 @@ def test_context_var_new_1(self): with self.assertRaisesRegex(TypeError, 'must be a str'): contextvars.ContextVar(1) - c = contextvars.ContextVar('a') - self.assertNotEqual(hash(c), hash('a')) + c = contextvars.ContextVar('aaa') + self.assertEqual(c.name, 'aaa') + + with self.assertRaises(AttributeError): + c.name = 'bbb' + + self.assertNotEqual(hash(c), hash('aaa')) def test_context_var_new_2(self): self.assertIsNone(contextvars.ContextVar[int]) diff --git a/Lib/test/test_contextlib_async.py b/Lib/test/test_contextlib_async.py index 879ddbe0e11853..39dcd9b364e589 100644 --- a/Lib/test/test_contextlib_async.py +++ b/Lib/test/test_contextlib_async.py @@ -18,7 +18,7 @@ def wrapper(*args, **kwargs): return loop.run_until_complete(coro) finally: loop.close() - asyncio.set_event_loop(None) + asyncio.set_event_loop_policy(None) return wrapper @@ -36,6 +36,28 @@ async def __aexit__(self, *args): async with manager as context: self.assertIs(manager, context) + @_async_test + async def test_async_gen_propagates_generator_exit(self): + # A regression test for https://bugs.python.org/issue33786. + + @asynccontextmanager + async def ctx(): + yield + + async def gen(): + async with ctx(): + yield 11 + + ret = [] + exc = ValueError(22) + with self.assertRaises(ValueError): + async with ctx(): + async for val in gen(): + ret.append(val) + raise exc + + self.assertEqual(ret, [11]) + def test_exit_is_abstract(self): class MissingAexit(AbstractAsyncContextManager): pass @@ -295,6 +317,7 @@ def setUp(self): self.loop = asyncio.new_event_loop() asyncio.set_event_loop(self.loop) self.addCleanup(self.loop.close) + self.addCleanup(asyncio.set_event_loop_policy, None) @_async_test async def test_async_callback(self): diff --git a/Lib/test/test_coroutines.py b/Lib/test/test_coroutines.py index ac24f39767385f..091b6626dcc8be 100644 --- a/Lib/test/test_coroutines.py +++ b/Lib/test/test_coroutines.py @@ -2039,6 +2039,71 @@ async def func(): pass support.gc_collect() self.assertIn("was never awaited", stderr.getvalue()) + def test_for_assign_raising_stop_async_iteration(self): + class BadTarget: + def __setitem__(self, key, value): + raise StopAsyncIteration(42) + tgt = BadTarget() + async def source(): + yield 10 + + async def run_for(): + with self.assertRaises(StopAsyncIteration) as cm: + async for tgt[0] in source(): + pass + self.assertEqual(cm.exception.args, (42,)) + return 'end' + self.assertEqual(run_async(run_for()), ([], 'end')) + + async def run_list(): + with self.assertRaises(StopAsyncIteration) as cm: + return [0 async for tgt[0] in source()] + self.assertEqual(cm.exception.args, (42,)) + return 'end' + self.assertEqual(run_async(run_list()), ([], 'end')) + + async def run_gen(): + gen = (0 async for tgt[0] in source()) + a = gen.asend(None) + with self.assertRaises(RuntimeError) as cm: + await a + self.assertIsInstance(cm.exception.__cause__, StopAsyncIteration) + self.assertEqual(cm.exception.__cause__.args, (42,)) + return 'end' + self.assertEqual(run_async(run_gen()), ([], 'end')) + + def test_for_assign_raising_stop_async_iteration_2(self): + class BadIterable: + def __iter__(self): + raise StopAsyncIteration(42) + async def badpairs(): + yield BadIterable() + + async def run_for(): + with self.assertRaises(StopAsyncIteration) as cm: + async for i, j in badpairs(): + pass + self.assertEqual(cm.exception.args, (42,)) + return 'end' + self.assertEqual(run_async(run_for()), ([], 'end')) + + async def run_list(): + with self.assertRaises(StopAsyncIteration) as cm: + return [0 async for i, j in badpairs()] + self.assertEqual(cm.exception.args, (42,)) + return 'end' + self.assertEqual(run_async(run_list()), ([], 'end')) + + async def run_gen(): + gen = (0 async for i, j in badpairs()) + a = gen.asend(None) + with self.assertRaises(RuntimeError) as cm: + await a + self.assertIsInstance(cm.exception.__cause__, StopAsyncIteration) + self.assertEqual(cm.exception.__cause__.args, (42,)) + return 'end' + self.assertEqual(run_async(run_gen()), ([], 'end')) + class CoroAsyncIOCompatTest(unittest.TestCase): @@ -2077,7 +2142,7 @@ async def f(): pass finally: loop.close() - asyncio.set_event_loop(None) + asyncio.set_event_loop_policy(None) self.assertEqual(buffer, [1, 2, 'MyException']) diff --git a/Lib/test/test_cprofile.py b/Lib/test/test_cprofile.py index 1430d22504854e..2fd67ee75688fe 100644 --- a/Lib/test/test_cprofile.py +++ b/Lib/test/test_cprofile.py @@ -49,6 +49,33 @@ def test_module_path_option(self): # Test successful run assert_python_ok('-m', 'cProfile', '-m', 'timeit', '-n', '1') + def test_profile_enable_disable(self): + prof = self.profilerclass() + # Make sure we clean ourselves up if the test fails for some reason. + self.addCleanup(prof.disable) + + prof.enable() + self.assertIs(sys.getprofile(), prof) + + prof.disable() + self.assertIs(sys.getprofile(), None) + + def test_profile_as_context_manager(self): + prof = self.profilerclass() + # Make sure we clean ourselves up if the test fails for some reason. + self.addCleanup(prof.disable) + + with prof as __enter__return_value: + # profile.__enter__ should return itself. + self.assertIs(prof, __enter__return_value) + + # profile should be set as the global profiler inside the + # with-block + self.assertIs(sys.getprofile(), prof) + + # profile shouldn't be set once we leave the with-block. + self.assertIs(sys.getprofile(), None) + def test_main(): run_unittest(CProfileTest) diff --git a/Lib/test/test_dataclasses.py b/Lib/test/test_dataclasses.py index 929793119d72b6..d9556c7ff9cecc 100755 --- a/Lib/test/test_dataclasses.py +++ b/Lib/test/test_dataclasses.py @@ -3024,6 +3024,22 @@ class C: replace(c, x=5) + def test_initvar_is_specified(self): + @dataclass + class C: + x: int + y: InitVar[int] + + def __post_init__(self, y): + self.x *= y + + c = C(1, 10) + self.assertEqual(c.x, 10) + with self.assertRaisesRegex(ValueError, r"InitVar 'y' must be " + "specified with replace()"): + replace(c, x=3) + c = replace(c, x=3, y=5) + self.assertEqual(c.x, 15) ## def test_initvar(self): ## @dataclass ## class C: diff --git a/Lib/test/test_dbm.py b/Lib/test/test_dbm.py index 1884b5c683efda..1db3bef6f41367 100644 --- a/Lib/test/test_dbm.py +++ b/Lib/test/test_dbm.py @@ -160,7 +160,7 @@ def test_whichdb(self): # and test that we can find it self.assertIn(b"1", f) # and read it - self.assertTrue(f[b"1"] == b"1") + self.assertEqual(f[b"1"], b"1") f.close() self.assertEqual(name, self.dbm.whichdb(_fname)) diff --git a/Lib/test/test_dbm_dumb.py b/Lib/test/test_dbm_dumb.py index 7f5c09f2fe553a..58b9d174656895 100644 --- a/Lib/test/test_dbm_dumb.py +++ b/Lib/test/test_dbm_dumb.py @@ -82,14 +82,14 @@ def test_dumbdbm_read(self): self.init_db() f = dumbdbm.open(_fname, 'r') self.read_helper(f) - with self.assertWarnsRegex(DeprecationWarning, + with self.assertRaisesRegex(ValueError, 'The database is opened for reading only'): f[b'g'] = b'x' - with self.assertWarnsRegex(DeprecationWarning, + with self.assertRaisesRegex(ValueError, 'The database is opened for reading only'): del f[b'a'] # get() works as in the dict interface - self.assertEqual(f.get(b'b'), self._dict[b'b']) + self.assertEqual(f.get(b'a'), self._dict[b'a']) self.assertEqual(f.get(b'xxx', b'foo'), b'foo') self.assertIsNone(f.get(b'xxx')) with self.assertRaises(KeyError): @@ -250,37 +250,30 @@ def test_eval(self): pass self.assertEqual(stdout.getvalue(), '') - def test_warn_on_ignored_flags(self): + def test_missing_data(self): for value in ('r', 'w'): _delete_files() - with self.assertWarnsRegex(DeprecationWarning, - "The database file is missing, the " - "semantics of the 'c' flag will " - "be used."): - f = dumbdbm.open(_fname, value) - f.close() + with self.assertRaises(FileNotFoundError): + dumbdbm.open(_fname, value) + self.assertFalse(os.path.exists(_fname + '.dir')) + self.assertFalse(os.path.exists(_fname + '.bak')) def test_missing_index(self): with dumbdbm.open(_fname, 'n') as f: pass os.unlink(_fname + '.dir') for value in ('r', 'w'): - with self.assertWarnsRegex(DeprecationWarning, - "The index file is missing, the " - "semantics of the 'c' flag will " - "be used."): - f = dumbdbm.open(_fname, value) - f.close() - self.assertEqual(os.path.exists(_fname + '.dir'), value == 'w') + with self.assertRaises(FileNotFoundError): + dumbdbm.open(_fname, value) + self.assertFalse(os.path.exists(_fname + '.dir')) self.assertFalse(os.path.exists(_fname + '.bak')) def test_invalid_flag(self): for flag in ('x', 'rf', None): - with self.assertWarnsRegex(DeprecationWarning, - "Flag must be one of " - "'r', 'w', 'c', or 'n'"): - f = dumbdbm.open(_fname, flag) - f.close() + with self.assertRaisesRegex(ValueError, + "Flag must be one of " + "'r', 'w', 'c', or 'n'"): + dumbdbm.open(_fname, flag) @unittest.skipUnless(hasattr(os, 'chmod'), 'test needs os.chmod()') def test_readonly_files(self): diff --git a/Lib/test/test_dbm_gnu.py b/Lib/test/test_dbm_gnu.py index 463d343411558c..c96eff5a319e64 100644 --- a/Lib/test/test_dbm_gnu.py +++ b/Lib/test/test_dbm_gnu.py @@ -8,6 +8,16 @@ filename = TESTFN class TestGdbm(unittest.TestCase): + @staticmethod + def setUpClass(): + if support.verbose: + try: + from _gdbm import _GDBM_VERSION as version + except ImportError: + pass + else: + print(f"gdbm version: {version}") + def setUp(self): self.g = None @@ -72,9 +82,13 @@ def test_reorganize(self): self.g = gdbm.open(filename, 'c') size0 = os.path.getsize(filename) - self.g['x'] = 'x' * 10000 + # bpo-33901: on macOS with gdbm 1.15, an empty database uses 16 MiB + # and adding an entry of 10,000 B has no effect on the file size. + # Add size0 bytes to make sure that the file size changes. + value_size = max(size0, 10000) + self.g['x'] = 'x' * value_size size1 = os.path.getsize(filename) - self.assertTrue(size0 < size1) + self.assertGreater(size1, size0) del self.g['x'] # 'size' is supposed to be the same even after deleting an entry. @@ -82,7 +96,8 @@ def test_reorganize(self): self.g.reorganize() size2 = os.path.getsize(filename) - self.assertTrue(size1 > size2 >= size0) + self.assertLess(size2, size1) + self.assertGreaterEqual(size2, size0) def test_context_manager(self): with gdbm.open(filename, 'c') as db: diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index ba8c6b940b0458..c86f61f236bd0e 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -120,20 +120,18 @@ def bug708901(): pass dis_bug708901 = """\ -%3d 0 SETUP_LOOP 18 (to 20) - 2 LOAD_GLOBAL 0 (range) - 4 LOAD_CONST 1 (1) - -%3d 6 LOAD_CONST 2 (10) - 8 CALL_FUNCTION 2 - 10 GET_ITER - >> 12 FOR_ITER 4 (to 18) - 14 STORE_FAST 0 (res) - -%3d 16 JUMP_ABSOLUTE 12 - >> 18 POP_BLOCK - >> 20 LOAD_CONST 0 (None) - 22 RETURN_VALUE +%3d 0 LOAD_GLOBAL 0 (range) + 2 LOAD_CONST 1 (1) + +%3d 4 LOAD_CONST 2 (10) + 6 CALL_FUNCTION 2 + 8 GET_ITER + >> 10 FOR_ITER 4 (to 16) + 12 STORE_FAST 0 (res) + +%3d 14 JUMP_ABSOLUTE 10 + >> 16 LOAD_CONST 0 (None) + 18 RETURN_VALUE """ % (bug708901.__code__.co_firstlineno + 1, bug708901.__code__.co_firstlineno + 2, bug708901.__code__.co_firstlineno + 3) @@ -259,20 +257,17 @@ def bug1333982(x=[]): 1 0 LOAD_CONST 0 (0) 2 STORE_NAME 0 (x) - 2 4 SETUP_LOOP 12 (to 18) - - 3 >> 6 LOAD_NAME 0 (x) - 8 LOAD_CONST 1 (1) - 10 INPLACE_ADD - 12 STORE_NAME 0 (x) - 14 JUMP_ABSOLUTE 6 - 16 POP_BLOCK - >> 18 LOAD_CONST 2 (None) - 20 RETURN_VALUE + 3 >> 4 LOAD_NAME 0 (x) + 6 LOAD_CONST 1 (1) + 8 INPLACE_ADD + 10 STORE_NAME 0 (x) + 12 JUMP_ABSOLUTE 4 + 14 LOAD_CONST 2 (None) + 16 RETURN_VALUE """ dis_traceback = """\ -%3d 0 SETUP_EXCEPT 12 (to 14) +%3d 0 SETUP_FINALLY 12 (to 14) %3d 2 LOAD_CONST 1 (1) 4 LOAD_CONST 2 (0) @@ -294,7 +289,7 @@ def bug1333982(x=[]): 32 LOAD_ATTR 1 (__traceback__) 34 STORE_FAST 1 (tb) 36 POP_BLOCK - 38 LOAD_CONST 0 (None) + 38 BEGIN_FINALLY >> 40 LOAD_CONST 0 (None) 42 STORE_FAST 0 (e) 44 DELETE_FAST 0 (e) @@ -353,7 +348,7 @@ def foo(x): 2 BUILD_TUPLE 1 4 LOAD_CONST 1 (<code object foo at 0x..., file "%s", line %d>) 6 LOAD_CONST 2 ('_h.<locals>.foo') - 8 MAKE_FUNCTION 8 + 8 MAKE_FUNCTION 8 (closure) 10 STORE_FAST 1 (foo) %3d 12 LOAD_FAST 1 (foo) @@ -370,7 +365,7 @@ def foo(x): 2 BUILD_TUPLE 1 4 LOAD_CONST 1 (<code object <listcomp> at 0x..., file "%s", line %d>) 6 LOAD_CONST 2 ('_h.<locals>.foo.<locals>.<listcomp>') - 8 MAKE_FUNCTION 8 + 8 MAKE_FUNCTION 8 (closure) 10 LOAD_DEREF 1 (y) 12 GET_ITER 14 CALL_FUNCTION 1 @@ -749,7 +744,13 @@ async def async_def(): Flags: OPTIMIZED, NEWLOCALS, NOFREE, COROUTINE Constants: 0: None - 1: 1""" + 1: 1 +Names: + 0: b + 1: c +Variable names: + 0: a + 1: d""" class CodeInfoTests(unittest.TestCase): test_pairs = [ @@ -860,7 +861,7 @@ def jumpy(): Instruction(opname='BUILD_TUPLE', opcode=102, arg=2, argval=2, argrepr='', offset=6, starts_line=None, is_jump_target=False), Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=code_object_f, argrepr=repr(code_object_f), offset=8, starts_line=None, is_jump_target=False), Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='outer.<locals>.f', argrepr="'outer.<locals>.f'", offset=10, starts_line=None, is_jump_target=False), - Instruction(opname='MAKE_FUNCTION', opcode=132, arg=9, argval=9, argrepr='', offset=12, starts_line=None, is_jump_target=False), + Instruction(opname='MAKE_FUNCTION', opcode=132, arg=9, argval=9, argrepr='defaults, closure', offset=12, starts_line=None, is_jump_target=False), Instruction(opname='STORE_FAST', opcode=125, arg=2, argval='f', argrepr='f', offset=14, starts_line=None, is_jump_target=False), Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='print', argrepr='print', offset=16, starts_line=7, is_jump_target=False), Instruction(opname='LOAD_DEREF', opcode=136, arg=0, argval='a', argrepr='a', offset=18, starts_line=None, is_jump_target=False), @@ -885,7 +886,7 @@ def jumpy(): Instruction(opname='BUILD_TUPLE', opcode=102, arg=4, argval=4, argrepr='', offset=10, starts_line=None, is_jump_target=False), Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=code_object_inner, argrepr=repr(code_object_inner), offset=12, starts_line=None, is_jump_target=False), Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='outer.<locals>.f.<locals>.inner', argrepr="'outer.<locals>.f.<locals>.inner'", offset=14, starts_line=None, is_jump_target=False), - Instruction(opname='MAKE_FUNCTION', opcode=132, arg=9, argval=9, argrepr='', offset=16, starts_line=None, is_jump_target=False), + Instruction(opname='MAKE_FUNCTION', opcode=132, arg=9, argval=9, argrepr='defaults, closure', offset=16, starts_line=None, is_jump_target=False), Instruction(opname='STORE_FAST', opcode=125, arg=2, argval='inner', argrepr='inner', offset=18, starts_line=None, is_jump_target=False), Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='print', argrepr='print', offset=20, starts_line=5, is_jump_target=False), Instruction(opname='LOAD_DEREF', opcode=136, arg=2, argval='a', argrepr='a', offset=22, starts_line=None, is_jump_target=False), @@ -913,103 +914,100 @@ def jumpy(): ] expected_opinfo_jumpy = [ - Instruction(opname='SETUP_LOOP', opcode=120, arg=52, argval=54, argrepr='to 54', offset=0, starts_line=3, is_jump_target=False), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='range', argrepr='range', offset=2, starts_line=None, is_jump_target=False), - Instruction(opname='LOAD_CONST', opcode=100, arg=1, argval=10, argrepr='10', offset=4, starts_line=None, is_jump_target=False), - Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=6, starts_line=None, is_jump_target=False), - Instruction(opname='GET_ITER', opcode=68, arg=None, argval=None, argrepr='', offset=8, starts_line=None, is_jump_target=False), - Instruction(opname='FOR_ITER', opcode=93, arg=32, argval=44, argrepr='to 44', offset=10, starts_line=None, is_jump_target=True), - Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=12, starts_line=None, is_jump_target=False), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=14, starts_line=4, is_jump_target=False), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=16, starts_line=None, is_jump_target=False), - Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=18, starts_line=None, is_jump_target=False), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=20, starts_line=None, is_jump_target=False), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=22, starts_line=5, is_jump_target=False), - Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=24, starts_line=None, is_jump_target=False), - Instruction(opname='COMPARE_OP', opcode=107, arg=0, argval='<', argrepr='<', offset=26, starts_line=None, is_jump_target=False), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=32, argval=32, argrepr='', offset=28, starts_line=None, is_jump_target=False), - Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=10, argval=10, argrepr='', offset=30, starts_line=6, is_jump_target=False), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=32, starts_line=7, is_jump_target=True), - Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=34, starts_line=None, is_jump_target=False), - Instruction(opname='COMPARE_OP', opcode=107, arg=4, argval='>', argrepr='>', offset=36, starts_line=None, is_jump_target=False), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=10, argval=10, argrepr='', offset=38, starts_line=None, is_jump_target=False), - Instruction(opname='BREAK_LOOP', opcode=80, arg=None, argval=None, argrepr='', offset=40, starts_line=8, is_jump_target=False), - Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=10, argval=10, argrepr='', offset=42, starts_line=None, is_jump_target=False), - Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=44, starts_line=None, is_jump_target=True), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=46, 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=48, starts_line=None, is_jump_target=False), - Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=50, starts_line=None, is_jump_target=False), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=52, starts_line=None, is_jump_target=False), - Instruction(opname='SETUP_LOOP', opcode=120, arg=52, argval=108, argrepr='to 108', offset=54, starts_line=11, is_jump_target=True), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=56, starts_line=None, is_jump_target=True), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=98, argval=98, argrepr='', offset=58, starts_line=None, is_jump_target=False), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=60, starts_line=12, is_jump_target=False), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=62, starts_line=None, is_jump_target=False), - Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=64, starts_line=None, is_jump_target=False), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=66, starts_line=None, is_jump_target=False), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=68, starts_line=13, is_jump_target=False), - Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=70, starts_line=None, is_jump_target=False), - Instruction(opname='INPLACE_SUBTRACT', opcode=56, arg=None, argval=None, argrepr='', offset=72, starts_line=None, is_jump_target=False), - Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=74, starts_line=None, is_jump_target=False), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=76, starts_line=14, is_jump_target=False), - Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=78, starts_line=None, is_jump_target=False), - Instruction(opname='COMPARE_OP', opcode=107, arg=4, argval='>', argrepr='>', offset=80, starts_line=None, is_jump_target=False), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=86, argval=86, argrepr='', offset=82, starts_line=None, is_jump_target=False), - Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=56, argval=56, argrepr='', offset=84, starts_line=15, is_jump_target=False), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=86, starts_line=16, is_jump_target=True), - Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=88, starts_line=None, is_jump_target=False), - Instruction(opname='COMPARE_OP', opcode=107, arg=0, argval='<', argrepr='<', offset=90, starts_line=None, is_jump_target=False), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=56, argval=56, argrepr='', offset=92, starts_line=None, is_jump_target=False), - Instruction(opname='BREAK_LOOP', opcode=80, arg=None, argval=None, argrepr='', offset=94, starts_line=17, is_jump_target=False), - Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=56, argval=56, argrepr='', offset=96, starts_line=None, is_jump_target=False), - Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=98, starts_line=None, is_jump_target=True), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=100, 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=102, starts_line=None, is_jump_target=False), - Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=104, starts_line=None, is_jump_target=False), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=106, starts_line=None, is_jump_target=False), - Instruction(opname='SETUP_FINALLY', opcode=122, arg=70, argval=180, argrepr='to 180', offset=108, starts_line=20, is_jump_target=True), - Instruction(opname='SETUP_EXCEPT', opcode=121, arg=12, argval=124, argrepr='to 124', offset=110, starts_line=None, is_jump_target=False), - Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=112, starts_line=21, is_jump_target=False), - Instruction(opname='LOAD_CONST', opcode=100, arg=7, argval=0, argrepr='0', offset=114, starts_line=None, is_jump_target=False), - Instruction(opname='BINARY_TRUE_DIVIDE', opcode=27, arg=None, argval=None, argrepr='', offset=116, starts_line=None, is_jump_target=False), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=118, starts_line=None, is_jump_target=False), - Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=120, starts_line=None, is_jump_target=False), - Instruction(opname='JUMP_FORWARD', opcode=110, arg=28, argval=152, argrepr='to 152', offset=122, starts_line=None, is_jump_target=False), - Instruction(opname='DUP_TOP', opcode=4, arg=None, argval=None, argrepr='', offset=124, starts_line=22, is_jump_target=True), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=2, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=126, starts_line=None, is_jump_target=False), - Instruction(opname='COMPARE_OP', opcode=107, arg=10, argval='exception match', argrepr='exception match', offset=128, starts_line=None, is_jump_target=False), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=150, argval=150, argrepr='', offset=130, starts_line=None, is_jump_target=False), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=132, starts_line=None, is_jump_target=False), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=134, starts_line=None, is_jump_target=False), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=136, starts_line=None, is_jump_target=False), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=138, 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=140, starts_line=None, is_jump_target=False), - Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=142, starts_line=None, is_jump_target=False), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=144, starts_line=None, is_jump_target=False), - Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=146, starts_line=None, is_jump_target=False), - Instruction(opname='JUMP_FORWARD', opcode=110, arg=26, argval=176, argrepr='to 176', offset=148, starts_line=None, is_jump_target=False), - Instruction(opname='END_FINALLY', opcode=88, arg=None, argval=None, argrepr='', offset=150, starts_line=None, is_jump_target=True), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=152, starts_line=25, is_jump_target=True), - Instruction(opname='SETUP_WITH', opcode=143, arg=14, argval=170, argrepr='to 170', offset=154, starts_line=None, is_jump_target=False), - Instruction(opname='STORE_FAST', opcode=125, arg=1, argval='dodgy', argrepr='dodgy', offset=156, starts_line=None, is_jump_target=False), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=158, starts_line=26, is_jump_target=False), - Instruction(opname='LOAD_CONST', opcode=100, arg=9, argval='Never reach this', argrepr="'Never reach this'", offset=160, starts_line=None, is_jump_target=False), - Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=162, starts_line=None, is_jump_target=False), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=164, starts_line=None, is_jump_target=False), - Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=166, starts_line=None, is_jump_target=False), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=168, starts_line=None, is_jump_target=False), - Instruction(opname='WITH_CLEANUP_START', opcode=81, arg=None, argval=None, argrepr='', offset=170, starts_line=None, is_jump_target=True), - Instruction(opname='WITH_CLEANUP_FINISH', opcode=82, arg=None, argval=None, argrepr='', offset=172, starts_line=None, is_jump_target=False), - Instruction(opname='END_FINALLY', opcode=88, arg=None, argval=None, argrepr='', offset=174, starts_line=None, is_jump_target=False), - Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=176, starts_line=None, is_jump_target=True), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=178, starts_line=None, is_jump_target=False), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=180, 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=182, starts_line=None, is_jump_target=False), - Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=184, starts_line=None, is_jump_target=False), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=186, starts_line=None, is_jump_target=False), - Instruction(opname='END_FINALLY', opcode=88, arg=None, argval=None, argrepr='', offset=188, starts_line=None, is_jump_target=False), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=190, starts_line=None, is_jump_target=False), - Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=192, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='range', argrepr='range', offset=0, starts_line=3, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=1, argval=10, argrepr='10', offset=2, starts_line=None, is_jump_target=False), + Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=4, starts_line=None, is_jump_target=False), + Instruction(opname='GET_ITER', opcode=68, arg=None, argval=None, argrepr='', offset=6, starts_line=None, is_jump_target=False), + Instruction(opname='FOR_ITER', opcode=93, arg=34, argval=44, argrepr='to 44', offset=8, starts_line=None, is_jump_target=True), + Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=10, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=12, starts_line=4, is_jump_target=False), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=14, starts_line=None, is_jump_target=False), + Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=16, starts_line=None, is_jump_target=False), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=18, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=20, starts_line=5, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=22, starts_line=None, is_jump_target=False), + Instruction(opname='COMPARE_OP', opcode=107, arg=0, argval='<', argrepr='<', offset=24, starts_line=None, is_jump_target=False), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=30, argval=30, argrepr='', offset=26, starts_line=None, is_jump_target=False), + Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=8, argval=8, argrepr='', offset=28, starts_line=6, is_jump_target=False), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=30, starts_line=7, is_jump_target=True), + Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=32, starts_line=None, is_jump_target=False), + Instruction(opname='COMPARE_OP', opcode=107, arg=4, argval='>', argrepr='>', offset=34, starts_line=None, is_jump_target=False), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=8, argval=8, argrepr='', offset=36, starts_line=None, is_jump_target=False), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=38, starts_line=8, is_jump_target=False), + Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=52, argval=52, argrepr='', offset=40, starts_line=None, is_jump_target=False), + Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=8, argval=8, argrepr='', offset=42, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=44, starts_line=10, is_jump_target=True), + Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=46, starts_line=None, is_jump_target=False), + Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=48, starts_line=None, is_jump_target=False), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=50, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=52, starts_line=11, is_jump_target=True), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=94, argval=94, argrepr='', offset=54, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=56, starts_line=12, is_jump_target=False), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=58, starts_line=None, is_jump_target=False), + Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=60, starts_line=None, is_jump_target=False), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=62, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=64, starts_line=13, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=66, starts_line=None, is_jump_target=False), + Instruction(opname='INPLACE_SUBTRACT', opcode=56, arg=None, argval=None, argrepr='', offset=68, starts_line=None, is_jump_target=False), + Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=70, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=72, starts_line=14, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=74, starts_line=None, is_jump_target=False), + Instruction(opname='COMPARE_OP', opcode=107, arg=4, argval='>', argrepr='>', offset=76, starts_line=None, is_jump_target=False), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=82, argval=82, argrepr='', offset=78, starts_line=None, is_jump_target=False), + Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=52, argval=52, argrepr='', offset=80, starts_line=15, is_jump_target=False), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=82, starts_line=16, is_jump_target=True), + Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=84, starts_line=None, is_jump_target=False), + Instruction(opname='COMPARE_OP', opcode=107, arg=0, argval='<', argrepr='<', offset=86, starts_line=None, is_jump_target=False), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=52, argval=52, argrepr='', offset=88, starts_line=None, is_jump_target=False), + Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=102, argval=102, argrepr='', offset=90, starts_line=17, is_jump_target=False), + Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=52, argval=52, argrepr='', offset=92, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=94, starts_line=19, is_jump_target=True), + 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=96, starts_line=None, is_jump_target=False), + Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=98, starts_line=None, is_jump_target=False), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=100, starts_line=None, is_jump_target=False), + Instruction(opname='SETUP_FINALLY', opcode=122, arg=70, argval=174, argrepr='to 174', offset=102, starts_line=20, is_jump_target=True), + Instruction(opname='SETUP_FINALLY', opcode=122, arg=12, argval=118, argrepr='to 118', offset=104, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=106, starts_line=21, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=7, argval=0, argrepr='0', offset=108, starts_line=None, is_jump_target=False), + Instruction(opname='BINARY_TRUE_DIVIDE', opcode=27, arg=None, argval=None, argrepr='', offset=110, starts_line=None, is_jump_target=False), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=112, starts_line=None, is_jump_target=False), + Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=114, starts_line=None, is_jump_target=False), + Instruction(opname='JUMP_FORWARD', opcode=110, arg=28, argval=146, argrepr='to 146', offset=116, starts_line=None, is_jump_target=False), + Instruction(opname='DUP_TOP', opcode=4, arg=None, argval=None, argrepr='', offset=118, starts_line=22, is_jump_target=True), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=2, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=120, starts_line=None, is_jump_target=False), + Instruction(opname='COMPARE_OP', opcode=107, arg=10, argval='exception match', argrepr='exception match', offset=122, starts_line=None, is_jump_target=False), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=144, argval=144, argrepr='', offset=124, starts_line=None, is_jump_target=False), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=126, starts_line=None, is_jump_target=False), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=128, starts_line=None, is_jump_target=False), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=130, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=132, 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=134, starts_line=None, is_jump_target=False), + Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=136, starts_line=None, is_jump_target=False), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=138, starts_line=None, is_jump_target=False), + Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=140, starts_line=None, is_jump_target=False), + Instruction(opname='JUMP_FORWARD', opcode=110, arg=26, argval=170, argrepr='to 170', offset=142, starts_line=None, is_jump_target=False), + Instruction(opname='END_FINALLY', opcode=88, arg=None, argval=None, argrepr='', offset=144, starts_line=None, is_jump_target=True), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=146, starts_line=25, is_jump_target=True), + Instruction(opname='SETUP_WITH', opcode=143, arg=14, argval=164, argrepr='to 164', offset=148, starts_line=None, is_jump_target=False), + Instruction(opname='STORE_FAST', opcode=125, arg=1, argval='dodgy', argrepr='dodgy', offset=150, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=152, starts_line=26, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=9, argval='Never reach this', argrepr="'Never reach this'", offset=154, starts_line=None, is_jump_target=False), + Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=156, starts_line=None, is_jump_target=False), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=158, starts_line=None, is_jump_target=False), + Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=160, starts_line=None, is_jump_target=False), + Instruction(opname='BEGIN_FINALLY', opcode=53, arg=None, argval=None, argrepr='', offset=162, starts_line=None, is_jump_target=False), + Instruction(opname='WITH_CLEANUP_START', opcode=81, arg=None, argval=None, argrepr='', offset=164, starts_line=None, is_jump_target=True), + Instruction(opname='WITH_CLEANUP_FINISH', opcode=82, arg=None, argval=None, argrepr='', offset=166, starts_line=None, is_jump_target=False), + Instruction(opname='END_FINALLY', opcode=88, arg=None, argval=None, argrepr='', offset=168, starts_line=None, is_jump_target=False), + Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=170, starts_line=None, is_jump_target=True), + Instruction(opname='BEGIN_FINALLY', opcode=53, 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=174, 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=176, starts_line=None, is_jump_target=False), + Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=178, starts_line=None, is_jump_target=False), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=180, starts_line=None, is_jump_target=False), + Instruction(opname='END_FINALLY', opcode=88, arg=None, argval=None, argrepr='', offset=182, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=184, starts_line=None, is_jump_target=False), + Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=186, starts_line=None, is_jump_target=False), ] # One last piece of inspect fodder to check the default line number handling diff --git a/Lib/test/test_email/test__encoded_words.py b/Lib/test/test_email/test__encoded_words.py index 900e1d0e64d434..5a59aebba89be4 100644 --- a/Lib/test/test_email/test__encoded_words.py +++ b/Lib/test/test_email/test__encoded_words.py @@ -33,7 +33,10 @@ def test_simple(self): self._test(b'Zm9v', b'foo') def test_missing_padding(self): + # 1 missing padding character self._test(b'dmk', b'vi', [errors.InvalidBase64PaddingDefect]) + # 2 missing padding characters + self._test(b'dg', b'v', [errors.InvalidBase64PaddingDefect]) def test_invalid_character(self): self._test(b'dm\x01k===', b'vi', [errors.InvalidBase64CharactersDefect]) @@ -42,6 +45,9 @@ def test_invalid_character_and_bad_padding(self): self._test(b'dm\x01k', b'vi', [errors.InvalidBase64CharactersDefect, errors.InvalidBase64PaddingDefect]) + def test_invalid_length(self): + self._test(b'abcde', b'abcde', [errors.InvalidBase64LengthDefect]) + class TestDecode(TestEmailBase): diff --git a/Lib/test/test_email/test__header_value_parser.py b/Lib/test/test_email/test__header_value_parser.py index 5cdc4bcecad447..5036de2ca0c358 100644 --- a/Lib/test/test_email/test__header_value_parser.py +++ b/Lib/test/test_email/test__header_value_parser.py @@ -347,6 +347,15 @@ def test_get_unstructured_invalid_base64_character_and_bad_padding(self): errors.InvalidBase64PaddingDefect], '') + def test_get_unstructured_invalid_base64_length(self): + # bpo-27397: Return the encoded string since there's no way to decode. + self._test_get_x(self._get_unst, + '=?utf-8?b?abcde?=', + 'abcde', + 'abcde', + [errors.InvalidBase64LengthDefect], + '') + def test_get_unstructured_no_whitespace_between_ews(self): self._test_get_x(self._get_unst, '=?utf-8?q?foo?==?utf-8?q?bar?=', diff --git a/Lib/test/test_email/test_defect_handling.py b/Lib/test/test_email/test_defect_handling.py index f36b907573995d..781f657418220c 100644 --- a/Lib/test/test_email/test_defect_handling.py +++ b/Lib/test/test_email/test_defect_handling.py @@ -254,6 +254,23 @@ def test_invalid_chars_in_base64_payload(self): self.assertDefectsEqual(self.get_defects(msg), [errors.InvalidBase64CharactersDefect]) + def test_invalid_length_of_base64_payload(self): + source = textwrap.dedent("""\ + Subject: test + MIME-Version: 1.0 + Content-Type: text/plain; charset="utf-8" + Content-Transfer-Encoding: base64 + + abcde + """) + msg = self._str_msg(source) + with self._raise_point(errors.InvalidBase64LengthDefect): + payload = msg.get_payload(decode=True) + if self.raise_expected: return + self.assertEqual(payload, b'abcde') + self.assertDefectsEqual(self.get_defects(msg), + [errors.InvalidBase64LengthDefect]) + def test_missing_ending_boundary(self): source = textwrap.dedent("""\ To: 1@harrydomain4.com diff --git a/Lib/test/test_epoll.py b/Lib/test/test_epoll.py index 549e0f712168be..efb54f42deb39e 100644 --- a/Lib/test/test_epoll.py +++ b/Lib/test/test_epoll.py @@ -74,11 +74,11 @@ def test_create(self): ep.close() self.assertTrue(ep.closed) self.assertRaises(ValueError, ep.fileno) + if hasattr(select, "EPOLL_CLOEXEC"): - select.epoll(select.EPOLL_CLOEXEC).close() + select.epoll(-1, select.EPOLL_CLOEXEC).close() select.epoll(flags=select.EPOLL_CLOEXEC).close() select.epoll(flags=0).close() - self.assertRaises(OSError, select.epoll, flags=12356) def test_badcreate(self): self.assertRaises(TypeError, select.epoll, 1, 2, 3) @@ -88,6 +88,13 @@ def test_badcreate(self): self.assertRaises(TypeError, select.epoll, ['foo']) self.assertRaises(TypeError, select.epoll, {}) + self.assertRaises(ValueError, select.epoll, 0) + self.assertRaises(ValueError, select.epoll, -2) + self.assertRaises(ValueError, select.epoll, sizehint=-2) + + if hasattr(select, "EPOLL_CLOEXEC"): + self.assertRaises(OSError, select.epoll, flags=12356) + def test_context_manager(self): with select.epoll(16) as ep: self.assertGreater(ep.fileno(), 0) @@ -117,19 +124,19 @@ def test_add(self): try: # TypeError: argument must be an int, or have a fileno() method. self.assertRaises(TypeError, ep.register, object(), - select.EPOLLIN | select.EPOLLOUT) + select.EPOLLIN | select.EPOLLOUT) self.assertRaises(TypeError, ep.register, None, - select.EPOLLIN | select.EPOLLOUT) + select.EPOLLIN | select.EPOLLOUT) # ValueError: file descriptor cannot be a negative integer (-1) self.assertRaises(ValueError, ep.register, -1, - select.EPOLLIN | select.EPOLLOUT) + select.EPOLLIN | select.EPOLLOUT) # OSError: [Errno 9] Bad file descriptor self.assertRaises(OSError, ep.register, 10000, - select.EPOLLIN | select.EPOLLOUT) + select.EPOLLIN | select.EPOLLOUT) # registering twice also raises an exception ep.register(server, select.EPOLLIN | select.EPOLLOUT) self.assertRaises(OSError, ep.register, server, - select.EPOLLIN | select.EPOLLOUT) + select.EPOLLIN | select.EPOLLOUT) finally: ep.close() @@ -160,9 +167,9 @@ def test_control_and_wait(self): ep = select.epoll(16) ep.register(server.fileno(), - select.EPOLLIN | select.EPOLLOUT | select.EPOLLET) + select.EPOLLIN | select.EPOLLOUT | select.EPOLLET) ep.register(client.fileno(), - select.EPOLLIN | select.EPOLLOUT | select.EPOLLET) + select.EPOLLIN | select.EPOLLOUT | select.EPOLLET) now = time.monotonic() events = ep.poll(1, 4) diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index 9d10df5f9425ee..2a9ec706467f3e 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -138,15 +138,6 @@ def ckmsg(src, msg): else: self.fail("failed to get expected SyntaxError") - s = '''while 1: - try: - pass - finally: - continue''' - - if not sys.platform.startswith('java'): - ckmsg(s, "'continue' not supported inside 'finally' clause") - s = '''if 1: try: continue diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py index 2245b974339786..7ffe000af04d2f 100644 --- a/Lib/test/test_functools.py +++ b/Lib/test/test_functools.py @@ -2147,6 +2147,124 @@ def __eq__(self, other): return self.arg == other self.assertEqual(i("str"), "str") + def test_method_register(self): + class A: + @functools.singledispatchmethod + def t(self, arg): + self.arg = "base" + @t.register(int) + def _(self, arg): + self.arg = "int" + @t.register(str) + def _(self, arg): + self.arg = "str" + a = A() + + a.t(0) + self.assertEqual(a.arg, "int") + aa = A() + self.assertFalse(hasattr(aa, 'arg')) + a.t('') + self.assertEqual(a.arg, "str") + aa = A() + self.assertFalse(hasattr(aa, 'arg')) + a.t(0.0) + self.assertEqual(a.arg, "base") + aa = A() + self.assertFalse(hasattr(aa, 'arg')) + + def test_staticmethod_register(self): + class A: + @functools.singledispatchmethod + @staticmethod + def t(arg): + return arg + @t.register(int) + @staticmethod + def _(arg): + return isinstance(arg, int) + @t.register(str) + @staticmethod + def _(arg): + return isinstance(arg, str) + a = A() + + self.assertTrue(A.t(0)) + self.assertTrue(A.t('')) + self.assertEqual(A.t(0.0), 0.0) + + def test_classmethod_register(self): + class A: + def __init__(self, arg): + self.arg = arg + + @functools.singledispatchmethod + @classmethod + def t(cls, arg): + return cls("base") + @t.register(int) + @classmethod + def _(cls, arg): + return cls("int") + @t.register(str) + @classmethod + def _(cls, arg): + return cls("str") + + self.assertEqual(A.t(0).arg, "int") + self.assertEqual(A.t('').arg, "str") + self.assertEqual(A.t(0.0).arg, "base") + + def test_callable_register(self): + class A: + def __init__(self, arg): + self.arg = arg + + @functools.singledispatchmethod + @classmethod + def t(cls, arg): + return cls("base") + + @A.t.register(int) + @classmethod + def _(cls, arg): + return cls("int") + @A.t.register(str) + @classmethod + def _(cls, arg): + return cls("str") + + self.assertEqual(A.t(0).arg, "int") + self.assertEqual(A.t('').arg, "str") + self.assertEqual(A.t(0.0).arg, "base") + + def test_abstractmethod_register(self): + class Abstract(abc.ABCMeta): + + @functools.singledispatchmethod + @abc.abstractmethod + def add(self, x, y): + pass + + self.assertTrue(Abstract.add.__isabstractmethod__) + + def test_type_ann_register(self): + class A: + @functools.singledispatchmethod + def t(self, arg): + return "base" + @t.register + def _(self, arg: int): + return "int" + @t.register + def _(self, arg: str): + return "str" + a = A() + + self.assertEqual(a.t(0), "int") + self.assertEqual(a.t(''), "str") + self.assertEqual(a.t(0.0), "base") + def test_invalid_registrations(self): msg_prefix = "Invalid first argument to `register()`: " msg_suffix = ( diff --git a/Lib/test/test_gc.py b/Lib/test/test_gc.py index 904fc7d88c0318..8d806db3ba57a1 100644 --- a/Lib/test/test_gc.py +++ b/Lib/test/test_gc.py @@ -1,7 +1,7 @@ import unittest from test.support import (verbose, refcount_test, run_unittest, strip_python_stderr, cpython_only, start_threads, - temp_dir, requires_type_collecting) + temp_dir, requires_type_collecting, TESTFN, unlink) from test.support.script_helper import assert_python_ok, make_script import sys @@ -708,6 +708,21 @@ def __del__(self): rc, out, err = assert_python_ok('-c', code) self.assertEqual(out.strip(), b'__del__ called') + @requires_type_collecting + def test_global_del_SystemExit(self): + code = """if 1: + class ClassWithDel: + def __del__(self): + print('__del__ called') + a = ClassWithDel() + a.link = a + raise SystemExit(0)""" + self.addCleanup(unlink, TESTFN) + with open(TESTFN, 'w') as script: + script.write(code) + rc, out, err = assert_python_ok(TESTFN) + self.assertEqual(out.strip(), b'__del__ called') + def test_get_stats(self): stats = gc.get_stats() self.assertEqual(len(stats), 3) diff --git a/Lib/test/test_genericpath.py b/Lib/test/test_genericpath.py index 9ed53902dc12bd..8b291cda689ce1 100644 --- a/Lib/test/test_genericpath.py +++ b/Lib/test/test_genericpath.py @@ -127,17 +127,20 @@ def test_filetime(self): def test_exists(self): filename = support.TESTFN + bfilename = os.fsencode(filename) self.addCleanup(support.unlink, filename) self.assertIs(self.pathmodule.exists(filename), False) + self.assertIs(self.pathmodule.exists(bfilename), False) - with open(filename, "xb") as f: - f.write(b"foo") + create_file(filename) self.assertIs(self.pathmodule.exists(filename), True) + self.assertIs(self.pathmodule.exists(bfilename), True) - if not self.pathmodule == genericpath: + if self.pathmodule is not genericpath: self.assertIs(self.pathmodule.lexists(filename), True) + self.assertIs(self.pathmodule.lexists(bfilename), True) @unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()") def test_exists_fd(self): @@ -149,37 +152,45 @@ def test_exists_fd(self): os.close(w) self.assertFalse(self.pathmodule.exists(r)) - def test_isdir_file(self): + def test_isdir(self): filename = support.TESTFN - self.addCleanup(support.unlink, filename) - self.assertIs(self.pathmodule.isdir(filename), False) - - create_file(filename) + bfilename = os.fsencode(filename) self.assertIs(self.pathmodule.isdir(filename), False) + self.assertIs(self.pathmodule.isdir(bfilename), False) - def test_isdir_dir(self): - filename = support.TESTFN - self.addCleanup(support.rmdir, filename) - self.assertIs(self.pathmodule.isdir(filename), False) + try: + create_file(filename) + self.assertIs(self.pathmodule.isdir(filename), False) + self.assertIs(self.pathmodule.isdir(bfilename), False) + finally: + support.unlink(filename) - os.mkdir(filename) - self.assertIs(self.pathmodule.isdir(filename), True) + try: + os.mkdir(filename) + self.assertIs(self.pathmodule.isdir(filename), True) + self.assertIs(self.pathmodule.isdir(bfilename), True) + finally: + support.rmdir(filename) - def test_isfile_file(self): + def test_isfile(self): filename = support.TESTFN - self.addCleanup(support.unlink, filename) + bfilename = os.fsencode(filename) self.assertIs(self.pathmodule.isfile(filename), False) + self.assertIs(self.pathmodule.isfile(bfilename), False) - create_file(filename) - self.assertIs(self.pathmodule.isfile(filename), True) - - def test_isfile_dir(self): - filename = support.TESTFN - self.addCleanup(support.rmdir, filename) - self.assertIs(self.pathmodule.isfile(filename), False) + try: + create_file(filename) + self.assertIs(self.pathmodule.isfile(filename), True) + self.assertIs(self.pathmodule.isfile(bfilename), True) + finally: + support.unlink(filename) - os.mkdir(filename) - self.assertIs(self.pathmodule.isfile(filename), False) + try: + os.mkdir(filename) + self.assertIs(self.pathmodule.isfile(filename), False) + self.assertIs(self.pathmodule.isfile(bfilename), False) + finally: + support.rmdir(filename) def test_samefile(self): file1 = support.TESTFN @@ -280,15 +291,25 @@ class TestGenericTest(GenericTest, unittest.TestCase): # and is only meant to be inherited by others. pathmodule = genericpath - def test_null_bytes(self): + def test_invalid_paths(self): for attr in GenericTest.common_attributes: # os.path.commonprefix doesn't raise ValueError if attr == 'commonprefix': continue + func = getattr(self.pathmodule, attr) with self.subTest(attr=attr): - with self.assertRaises(ValueError) as cm: - getattr(self.pathmodule, attr)('/tmp\x00abcds') - self.assertIn('embedded null', str(cm.exception)) + try: + func('/tmp\udfffabcds') + except (OSError, UnicodeEncodeError): + pass + try: + func(b'/tmp\xffabcds') + except (OSError, UnicodeDecodeError): + pass + with self.assertRaisesRegex(ValueError, 'embedded null'): + func('/tmp\x00abcds') + with self.assertRaisesRegex(ValueError, 'embedded null'): + func(b'/tmp\x00abcds') # Following TestCase is not supposed to be run from test_genericpath. # It is inherited by other test modules (macpath, ntpath, posixpath). @@ -529,5 +550,5 @@ def test_path_samefile(self): self.assertTrue(os.path.samefile(self.file_path, self.file_name)) -if __name__=="__main__": +if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py index 88c22b89d444a3..ee4136286ba1bd 100644 --- a/Lib/test/test_grammar.py +++ b/Lib/test/test_grammar.py @@ -251,6 +251,8 @@ def __getitem__(self, item): class GrammarTests(unittest.TestCase): + check_syntax_error = check_syntax_error + # single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE # XXX can't test in a script -- this rule is only used when interactive @@ -857,6 +859,59 @@ def test_break_in_finally(self): break self.assertEqual(count, 0) + def test_continue_in_finally(self): + count = 0 + while count < 2: + count += 1 + try: + pass + finally: + continue + break + self.assertEqual(count, 2) + + count = 0 + while count < 2: + count += 1 + try: + break + finally: + continue + self.assertEqual(count, 2) + + count = 0 + while count < 2: + count += 1 + try: + 1/0 + finally: + continue + break + self.assertEqual(count, 2) + + for count in [0, 1]: + try: + pass + finally: + continue + break + self.assertEqual(count, 1) + + for count in [0, 1]: + try: + break + finally: + continue + self.assertEqual(count, 1) + + for count in [0, 1]: + try: + 1/0 + finally: + continue + break + self.assertEqual(count, 1) + def test_return_in_finally(self): def g1(): try: @@ -920,15 +975,7 @@ def test_yield_in_comprehensions(self): def g(): [x for x in [(yield 1)]] def g(): [x for x in [(yield from ())]] - def check(code, warntext): - with self.assertWarnsRegex(DeprecationWarning, warntext): - compile(code, '<test string>', 'exec') - import warnings - with warnings.catch_warnings(): - warnings.filterwarnings('error', category=DeprecationWarning) - with self.assertRaisesRegex(SyntaxError, warntext): - compile(code, '<test string>', 'exec') - + check = self.check_syntax_error check("def g(): [(yield x) for x in ()]", "'yield' inside list comprehension") check("def g(): [x for x in () if not (yield x)]", diff --git a/Lib/test/test_http_cookies.py b/Lib/test/test_http_cookies.py index c1caad332d617a..6072c7e15e92be 100644 --- a/Lib/test/test_http_cookies.py +++ b/Lib/test/test_http_cookies.py @@ -121,6 +121,19 @@ def test_set_secure_httponly_attrs(self): self.assertEqual(C.output(), 'Set-Cookie: Customer="WILE_E_COYOTE"; HttpOnly; Secure') + def test_samesite_attrs(self): + samesite_values = ['Strict', 'Lax', 'strict', 'lax'] + for val in samesite_values: + with self.subTest(val=val): + C = cookies.SimpleCookie('Customer="WILE_E_COYOTE"') + C['Customer']['samesite'] = val + self.assertEqual(C.output(), + 'Set-Cookie: Customer="WILE_E_COYOTE"; SameSite=%s' % val) + + C = cookies.SimpleCookie() + C.load('Customer="WILL_E_COYOTE"; SameSite=%s' % val) + self.assertEqual(C['Customer']['samesite'], val) + def test_secure_httponly_false_if_not_present(self): C = cookies.SimpleCookie() C.load('eggs=scrambled; Path=/bacon') diff --git a/Lib/test/test_httplib.py b/Lib/test/test_httplib.py index a3f8194dc44fcf..f816eac83b682d 100644 --- a/Lib/test/test_httplib.py +++ b/Lib/test/test_httplib.py @@ -344,6 +344,21 @@ def test_invalid_headers(self): with self.assertRaisesRegex(ValueError, 'Invalid header'): conn.putheader(name, value) + def test_headers_debuglevel(self): + body = ( + b'HTTP/1.1 200 OK\r\n' + b'First: val\r\n' + b'Second: val\r\n' + ) + sock = FakeSocket(body) + resp = client.HTTPResponse(sock, debuglevel=1) + with support.captured_stdout() as output: + resp.begin() + lines = output.getvalue().splitlines() + self.assertEqual(lines[0], "reply: 'HTTP/1.1 200 OK\\r\\n'") + self.assertEqual(lines[1], "header: First: val") + self.assertEqual(lines[2], "header: Second: val") + class TransferEncodingTest(TestCase): expected_body = b"It's just a flesh wound" diff --git a/Lib/test/test_imp.py b/Lib/test/test_imp.py index a115e60d4e4f08..bb0144b12d4107 100644 --- a/Lib/test/test_imp.py +++ b/Lib/test/test_imp.py @@ -2,6 +2,7 @@ import importlib.util import os import os.path +import py_compile import sys from test import support from test.support import script_helper @@ -350,6 +351,20 @@ def test_pyc_invalidation_mode_from_cmdline(self): res = script_helper.assert_python_ok(*args) self.assertEqual(res.out.strip().decode('utf-8'), expected) + def test_find_and_load_checked_pyc(self): + # issue 34056 + with support.temp_cwd(): + with open('mymod.py', 'wb') as fp: + fp.write(b'x = 42\n') + py_compile.compile( + 'mymod.py', + doraise=True, + invalidation_mode=py_compile.PycInvalidationMode.CHECKED_HASH, + ) + file, path, description = imp.find_module('mymod', path=['.']) + mod = imp.load_module('mymod', file, path, description) + self.assertEqual(mod.x, 42) + class ReloadTests(unittest.TestCase): diff --git a/Lib/test/test_import/__init__.py b/Lib/test/test_import/__init__.py index 1fc4de11e17896..fb9453ad0b3920 100644 --- a/Lib/test/test_import/__init__.py +++ b/Lib/test/test_import/__init__.py @@ -112,6 +112,27 @@ def test_from_import_missing_attr_path_is_canonical(self): self.assertIn(cm.exception.name, {'posixpath', 'ntpath'}) self.assertIsNotNone(cm.exception) + def test_from_import_star_invalid_type(self): + import re + with _ready_to_import() as (name, path): + with open(path, 'w') as f: + f.write("__all__ = [b'invalid_type']") + globals = {} + with self.assertRaisesRegex( + TypeError, f"{re.escape(name)}\\.__all__ must be str" + ): + exec(f"from {name} import *", globals) + self.assertNotIn(b"invalid_type", globals) + with _ready_to_import() as (name, path): + with open(path, 'w') as f: + f.write("globals()[b'invalid_type'] = object()") + globals = {} + with self.assertRaisesRegex( + TypeError, f"{re.escape(name)}\\.__dict__ must be str" + ): + exec(f"from {name} import *", globals) + self.assertNotIn(b"invalid_type", globals) + def test_case_sensitivity(self): # Brief digression to test that import is case-sensitive: if we got # this far, we know for sure that "random" exists. diff --git a/Lib/test/test_importlib/test_util.py b/Lib/test/test_importlib/test_util.py index bcbc99ff361d79..d134e3c3b04dfc 100644 --- a/Lib/test/test_importlib/test_util.py +++ b/Lib/test/test_importlib/test_util.py @@ -1,9 +1,10 @@ -from . import 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 contextlib import importlib.util import os import pathlib @@ -12,6 +13,7 @@ from test import support import types import unittest +import unittest.mock import warnings @@ -557,8 +559,8 @@ class PEP3147Tests: tag = sys.implementation.cache_tag - @unittest.skipUnless(sys.implementation.cache_tag is not None, - 'requires sys.implementation.cache_tag not be None') + @unittest.skipIf(sys.implementation.cache_tag is None, + 'requires sys.implementation.cache_tag not be None') def test_cache_from_source(self): # Given the path to a .py file, return the path to its PEP 3147 # defined .pyc file (i.e. under __pycache__). @@ -678,8 +680,8 @@ def test_sep_altsep_and_sep_cache_from_source(self): self.util.cache_from_source('\\foo\\bar\\baz/qux.py', optimization=''), '\\foo\\bar\\baz\\__pycache__\\qux.{}.pyc'.format(self.tag)) - @unittest.skipUnless(sys.implementation.cache_tag is not None, - 'requires sys.implementation.cache_tag not be None') + @unittest.skipIf(sys.implementation.cache_tag is None, + 'requires sys.implementation.cache_tag not be None') def test_source_from_cache_path_like_arg(self): path = pathlib.PurePath('foo', 'bar', 'baz', 'qux.py') expect = os.path.join('foo', 'bar', 'baz', '__pycache__', @@ -687,9 +689,8 @@ def test_source_from_cache_path_like_arg(self): self.assertEqual(self.util.cache_from_source(path, optimization=''), expect) - @unittest.skipUnless(sys.implementation.cache_tag is not None, - 'requires sys.implementation.cache_tag to not be ' - 'None') + @unittest.skipIf(sys.implementation.cache_tag is None, + 'requires sys.implementation.cache_tag to not be None') def test_source_from_cache(self): # Given the path to a PEP 3147 defined .pyc file, return the path to # its source. This tests the good path. @@ -749,15 +750,87 @@ def test_source_from_cache_missing_optimization(self): with self.assertRaises(ValueError): self.util.source_from_cache(path) - @unittest.skipUnless(sys.implementation.cache_tag is not None, - 'requires sys.implementation.cache_tag to not be ' - 'None') + @unittest.skipIf(sys.implementation.cache_tag is None, + 'requires sys.implementation.cache_tag to not be None') def test_source_from_cache_path_like_arg(self): path = pathlib.PurePath('foo', 'bar', 'baz', '__pycache__', 'qux.{}.pyc'.format(self.tag)) expect = os.path.join('foo', 'bar', 'baz', 'qux.py') self.assertEqual(self.util.source_from_cache(path), expect) + @unittest.skipIf(sys.implementation.cache_tag is None, + 'requires sys.implementation.cache_tag to not be None') + def test_cache_from_source_respects_pycache_prefix(self): + # If pycache_prefix is set, cache_from_source will return a bytecode + # path inside that directory (in a subdirectory mirroring the .py file's + # path) rather than in a __pycache__ dir next to the py file. + pycache_prefixes = [ + os.path.join(os.path.sep, 'tmp', 'bytecode'), + os.path.join(os.path.sep, 'tmp', '\u2603'), # non-ASCII in path! + os.path.join(os.path.sep, 'tmp', 'trailing-slash') + os.path.sep, + ] + drive = '' + if os.name == 'nt': + drive = 'C:' + pycache_prefixes = [ + f'{drive}{prefix}' for prefix in pycache_prefixes] + pycache_prefixes += [r'\\?\C:\foo', r'\\localhost\c$\bar'] + for pycache_prefix in pycache_prefixes: + with self.subTest(path=pycache_prefix): + path = drive + os.path.join( + os.path.sep, 'foo', 'bar', 'baz', 'qux.py') + expect = os.path.join( + pycache_prefix, 'foo', 'bar', 'baz', + 'qux.{}.pyc'.format(self.tag)) + with util.temporary_pycache_prefix(pycache_prefix): + self.assertEqual( + self.util.cache_from_source(path, optimization=''), + expect) + + @unittest.skipIf(sys.implementation.cache_tag is None, + 'requires sys.implementation.cache_tag to not be None') + def test_cache_from_source_respects_pycache_prefix_relative(self): + # If the .py path we are given is relative, we will resolve to an + # absolute path before prefixing with pycache_prefix, to avoid any + # possible ambiguity. + pycache_prefix = os.path.join(os.path.sep, 'tmp', 'bytecode') + path = os.path.join('foo', 'bar', 'baz', 'qux.py') + root = os.path.splitdrive(os.getcwd())[0] + os.path.sep + expect = os.path.join( + pycache_prefix, + os.path.relpath(os.getcwd(), root), + 'foo', 'bar', 'baz', f'qux.{self.tag}.pyc') + with util.temporary_pycache_prefix(pycache_prefix): + self.assertEqual( + self.util.cache_from_source(path, optimization=''), + expect) + + @unittest.skipIf(sys.implementation.cache_tag is None, + 'requires sys.implementation.cache_tag to not be None') + def test_source_from_cache_inside_pycache_prefix(self): + # If pycache_prefix is set and the cache path we get is inside it, + # we return an absolute path to the py file based on the remainder of + # the path within pycache_prefix. + pycache_prefix = os.path.join(os.path.sep, 'tmp', 'bytecode') + path = os.path.join(pycache_prefix, 'foo', 'bar', 'baz', + f'qux.{self.tag}.pyc') + expect = os.path.join(os.path.sep, 'foo', 'bar', 'baz', 'qux.py') + with util.temporary_pycache_prefix(pycache_prefix): + self.assertEqual(self.util.source_from_cache(path), expect) + + @unittest.skipIf(sys.implementation.cache_tag is None, + 'requires sys.implementation.cache_tag to not be None') + def test_source_from_cache_outside_pycache_prefix(self): + # If pycache_prefix is set but the cache path we get is not inside + # it, just ignore it and handle the cache path according to the default + # behavior. + pycache_prefix = os.path.join(os.path.sep, 'tmp', 'bytecode') + path = os.path.join('foo', 'bar', 'baz', '__pycache__', + f'qux.{self.tag}.pyc') + expect = os.path.join('foo', 'bar', 'baz', 'qux.py') + with util.temporary_pycache_prefix(pycache_prefix): + self.assertEqual(self.util.source_from_cache(path), expect) + (Frozen_PEP3147Tests, Source_PEP3147Tests @@ -789,7 +862,7 @@ def test_magic_number(self): in advance. Such exceptional releases will then require an adjustment to this test case. """ - EXPECTED_MAGIC_NUMBER = 3394 + EXPECTED_MAGIC_NUMBER = 3400 actual = int.from_bytes(importlib.util.MAGIC_NUMBER[:2], 'little') msg = ( diff --git a/Lib/test/test_importlib/util.py b/Lib/test/test_importlib/util.py index b0badebc2b8c00..196ea1c9d4dda5 100644 --- a/Lib/test/test_importlib/util.py +++ b/Lib/test/test_importlib/util.py @@ -319,6 +319,17 @@ def ensure_bytecode_path(bytecode_path): raise +@contextlib.contextmanager +def temporary_pycache_prefix(prefix): + """Adjust and restore sys.pycache_prefix.""" + _orig_prefix = sys.pycache_prefix + sys.pycache_prefix = prefix + try: + yield + finally: + sys.pycache_prefix = _orig_prefix + + @contextlib.contextmanager def create_modules(*names): """Temporarily create each named module with an attribute (named 'attr') diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py index 8b701614962b45..cda8d5cf73ef11 100644 --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -1136,6 +1136,61 @@ class C(metaclass=M): attrs = [a[0] for a in inspect.getmembers(C)] self.assertNotIn('missing', attrs) +class TestIsDataDescriptor(unittest.TestCase): + + def test_custom_descriptors(self): + class NonDataDescriptor: + def __get__(self, value, type=None): pass + class DataDescriptor0: + def __set__(self, name, value): pass + class DataDescriptor1: + def __delete__(self, name): pass + class DataDescriptor2: + __set__ = None + self.assertFalse(inspect.isdatadescriptor(NonDataDescriptor()), + 'class with only __get__ not a data descriptor') + self.assertTrue(inspect.isdatadescriptor(DataDescriptor0()), + 'class with __set__ is a data descriptor') + self.assertTrue(inspect.isdatadescriptor(DataDescriptor1()), + 'class with __delete__ is a data descriptor') + self.assertTrue(inspect.isdatadescriptor(DataDescriptor2()), + 'class with __set__ = None is a data descriptor') + + def test_slot(self): + class Slotted: + __slots__ = 'foo', + self.assertTrue(inspect.isdatadescriptor(Slotted.foo), + 'a slot is a data descriptor') + + def test_property(self): + class Propertied: + @property + def a_property(self): + pass + self.assertTrue(inspect.isdatadescriptor(Propertied.a_property), + 'a property is a data descriptor') + + def test_functions(self): + class Test(object): + def instance_method(self): pass + @classmethod + def class_method(cls): pass + @staticmethod + def static_method(): pass + def function(): + pass + a_lambda = lambda: None + self.assertFalse(inspect.isdatadescriptor(Test().instance_method), + 'a instance method is not a data descriptor') + self.assertFalse(inspect.isdatadescriptor(Test().class_method), + 'a class method is not a data descriptor') + self.assertFalse(inspect.isdatadescriptor(Test().static_method), + 'a static method is not a data descriptor') + self.assertFalse(inspect.isdatadescriptor(function), + 'a function is not a data descriptor') + self.assertFalse(inspect.isdatadescriptor(a_lambda), + 'a lambda is not a data descriptor') + _global_ref = object() class TestGetClosureVars(unittest.TestCase): @@ -3813,7 +3868,7 @@ def test_main(): TestGetcallargsUnboundMethods, TestGetattrStatic, TestGetGeneratorState, TestNoEOL, TestSignatureObject, TestSignatureBind, TestParameterObject, TestBoundArguments, TestSignaturePrivateHelpers, - TestSignatureDefinitions, + TestSignatureDefinitions, TestIsDataDescriptor, TestGetClosureVars, TestUnwrap, TestMain, TestReload, TestGetCoroutineState ) diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index 286ae760e17fcb..a03a7f78109c23 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -3549,6 +3549,17 @@ def test_reconfigure_newline(self): expected = 'linesep' + os.linesep + 'LF\nLF\nCR\rCRLF\r\n' self.assertEqual(txt.detach().getvalue().decode('ascii'), expected) + def test_issue25862(self): + # Assertion failures occurred in tell() after read() and write(). + t = self.TextIOWrapper(self.BytesIO(b'test'), encoding='ascii') + t.read(1) + t.read() + t.tell() + t = self.TextIOWrapper(self.BytesIO(b'test'), encoding='ascii') + t.read(1) + t.write('x') + t.tell() + class MemviewBytesIO(io.BytesIO): '''A BytesIO object whose read method returns memoryviews diff --git a/Lib/test/test_json/test_speedups.py b/Lib/test/test_json/test_speedups.py index 5dad6920870421..fbfee1a582095b 100644 --- a/Lib/test/test_json/test_speedups.py +++ b/Lib/test/test_json/test_speedups.py @@ -31,6 +31,8 @@ def test(value): class TestEncode(CTest): def test_make_encoder(self): + # bpo-6986: The interpreter shouldn't crash in case c_make_encoder() + # receives invalid arguments. self.assertRaises(TypeError, self.json.encoder.c_make_encoder, (True, False), b"\xCD\x7D\x3D\x4E\x12\x4C\xF9\x79\xD7\x52\xBA\x82\xF2\x27\x4A\x7D\xA0\xCA\x75", diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index 0fa3892e57a316..a3731fa4793917 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -1089,6 +1089,7 @@ class ConfigFileTest(BaseTest): """Reading logging config from a .ini-style config file.""" + check_no_resource_warning = support.check_no_resource_warning expected_log_pat = r"^(\w+) \+\+ (\w+)$" # config0 is a standard configuration. @@ -1297,6 +1298,27 @@ class ConfigFileTest(BaseTest): datefmt= """ + # config 8, check for resource warning + config8 = r""" + [loggers] + keys=root + + [handlers] + keys=file + + [formatters] + keys= + + [logger_root] + level=DEBUG + handlers=file + + [handler_file] + class=FileHandler + level=DEBUG + args=("{tempfile}",) + """ + disable_test = """ [loggers] keys=root @@ -1442,6 +1464,29 @@ def test_config7_ok(self): # Original logger output is empty. self.assert_log_lines([]) + def test_config8_ok(self): + + def cleanup(h1, fn): + h1.close() + os.remove(fn) + + with self.check_no_resource_warning(): + fd, fn = tempfile.mkstemp(".log", "test_logging-X-") + os.close(fd) + + # Replace single backslash with double backslash in windows + # to avoid unicode error during string formatting + if os.name == "nt": + fn = fn.replace("\\", "\\\\") + + config8 = self.config8.format(tempfile=fn) + + self.apply_config(config8) + self.apply_config(config8) + + handler = logging.root.handlers[0] + self.addCleanup(cleanup, handler, fn) + def test_logger_disabling(self): self.apply_config(self.disable_test) logger = logging.getLogger('some_pristine_logger') @@ -2022,6 +2067,7 @@ class ConfigDictTest(BaseTest): """Reading logging config from a dictionary.""" + check_no_resource_warning = support.check_no_resource_warning expected_log_pat = r"^(\w+) \+\+ (\w+)$" # config0 is a standard configuration. @@ -2896,6 +2942,35 @@ def test_config14_ok(self): logging.warning('Exclamation') self.assertTrue(output.getvalue().endswith('Exclamation!\n')) + def test_config15_ok(self): + + def cleanup(h1, fn): + h1.close() + os.remove(fn) + + with self.check_no_resource_warning(): + fd, fn = tempfile.mkstemp(".log", "test_logging-X-") + os.close(fd) + + config = { + "version": 1, + "handlers": { + "file": { + "class": "logging.FileHandler", + "filename": fn + } + }, + "root": { + "handlers": ["file"] + } + } + + self.apply_config(config) + self.apply_config(config) + + handler = logging.root.handlers[0] + self.addCleanup(cleanup, handler, fn) + def setup_via_listener(self, text, verify=None): text = text.encode("utf-8") # Ask for a randomly assigned port (by using port 0) @@ -3901,6 +3976,27 @@ def test_handlers(self): self.assertIs(handlers[2].formatter, f) self.assertIs(handlers[0].formatter, handlers[1].formatter) + def test_force(self): + old_string_io = io.StringIO() + new_string_io = io.StringIO() + old_handlers = [logging.StreamHandler(old_string_io)] + new_handlers = [logging.StreamHandler(new_string_io)] + logging.basicConfig(level=logging.WARNING, handlers=old_handlers) + logging.warning('warn') + logging.info('info') + logging.debug('debug') + self.assertEqual(len(logging.root.handlers), 1) + logging.basicConfig(level=logging.INFO, handlers=new_handlers, + force=True) + logging.warning('warn') + logging.info('info') + logging.debug('debug') + self.assertEqual(len(logging.root.handlers), 1) + self.assertEqual(old_string_io.getvalue().strip(), + 'WARNING:root:warn') + self.assertEqual(new_string_io.getvalue().strip(), + 'WARNING:root:warn\nINFO:root:info') + def _test_log(self, method, level=None): # logging.root has no handlers so basicConfig should be called called = [] @@ -4100,6 +4196,37 @@ def test_find_caller_with_stack_info(self): self.assertEqual(len(called), 1) self.assertEqual('Stack (most recent call last):\n', called[0]) + def test_find_caller_with_stacklevel(self): + the_level = 1 + + def innermost(): + self.logger.warning('test', stacklevel=the_level) + + def inner(): + innermost() + + def outer(): + inner() + + records = self.recording.records + outer() + self.assertEqual(records[-1].funcName, 'innermost') + lineno = records[-1].lineno + the_level += 1 + outer() + self.assertEqual(records[-1].funcName, 'inner') + self.assertGreater(records[-1].lineno, lineno) + lineno = records[-1].lineno + the_level += 1 + outer() + self.assertEqual(records[-1].funcName, 'outer') + self.assertGreater(records[-1].lineno, lineno) + lineno = records[-1].lineno + the_level += 1 + outer() + self.assertEqual(records[-1].funcName, 'test_find_caller_with_stacklevel') + self.assertGreater(records[-1].lineno, lineno) + def test_make_record_with_extra_overwrite(self): name = 'my record' level = 13 @@ -4140,6 +4267,18 @@ def test_is_enabled_for(self): self.addCleanup(setattr, self.logger.manager, 'disable', old_disable) self.assertFalse(self.logger.isEnabledFor(22)) + def test_is_enabled_for_disabled_logger(self): + old_disabled = self.logger.disabled + old_disable = self.logger.manager.disable + + self.logger.disabled = True + self.logger.manager.disable = 21 + + self.addCleanup(setattr, self.logger, 'disabled', old_disabled) + self.addCleanup(setattr, self.logger.manager, 'disable', old_disable) + + self.assertFalse(self.logger.isEnabledFor(22)) + def test_root_logger_aliases(self): root = logging.getLogger() self.assertIs(root, logging.root) diff --git a/Lib/test/test_marshal.py b/Lib/test/test_marshal.py index a8a43d22bc3651..a3bd350c77b95b 100644 --- a/Lib/test/test_marshal.py +++ b/Lib/test/test_marshal.py @@ -192,8 +192,8 @@ def test_bug_5888452(self): marshal.dumps([128] * 1000) def test_patch_873224(self): - self.assertRaises(Exception, marshal.loads, '0') - self.assertRaises(Exception, marshal.loads, 'f') + self.assertRaises(Exception, marshal.loads, b'0') + self.assertRaises(Exception, marshal.loads, b'f') self.assertRaises(Exception, marshal.loads, marshal.dumps(2**65)[:-1]) def test_version_argument(self): @@ -204,19 +204,31 @@ def test_version_argument(self): def test_fuzz(self): # simple test that it's at least not *totally* trivial to # crash from bad marshal data - for c in [chr(i) for i in range(256)]: + for i in range(256): + c = bytes([i]) try: marshal.loads(c) except Exception: pass - def test_loads_2x_code(self): - s = b'c' + (b'X' * 4*4) + b'{' * 2**20 - self.assertRaises(ValueError, marshal.loads, s) - def test_loads_recursion(self): - s = b'c' + (b'X' * 4*5) + b'{' * 2**20 - self.assertRaises(ValueError, marshal.loads, s) + def run_tests(N, check): + # (((...None...),),) + check(b')\x01' * N + b'N') + check(b'(\x01\x00\x00\x00' * N + b'N') + # [[[...None...]]] + check(b'[\x01\x00\x00\x00' * N + b'N') + # {None: {None: {None: ...None...}}} + check(b'{N' * N + b'N' + b'0' * N) + # frozenset([frozenset([frozenset([...None...])])]) + check(b'>\x01\x00\x00\x00' * N + b'N') + # Check that the generated marshal data is valid and marshal.loads() + # works for moderately deep nesting + run_tests(100, marshal.loads) + # Very deeply nested structure shouldn't blow the stack + def check(s): + self.assertRaises(ValueError, marshal.loads, s) + run_tests(2**20, check) def test_recursion_limit(self): # Create a deeply nested structure. @@ -307,7 +319,7 @@ def readinto(self, buf): self.assertRaises(ValueError, marshal.load, BadReader(marshal.dumps(value))) - def _test_eof(self): + def test_eof(self): data = marshal.dumps(("hello", "dolly", None)) for i in range(len(data)): self.assertRaises(EOFError, marshal.loads, data[0: i]) diff --git a/Lib/test/test_memoryview.py b/Lib/test/test_memoryview.py index ddd5b9a8e2f250..ca307d8342f31f 100644 --- a/Lib/test/test_memoryview.py +++ b/Lib/test/test_memoryview.py @@ -362,6 +362,17 @@ def test_reversed(self): self.assertEqual(list(reversed(m)), aslist) self.assertEqual(list(reversed(m)), list(m[::-1])) + def test_toreadonly(self): + for tp in self._types: + b = tp(self._source) + m = self._view(b) + mm = m.toreadonly() + self.assertTrue(mm.readonly) + self.assertTrue(memoryview(mm).readonly) + self.assertEqual(mm.tolist(), m.tolist()) + mm.release() + m.tolist() + def test_issue22668(self): a = array.array('H', [256, 256, 256, 256]) x = memoryview(a) diff --git a/Lib/test/test_minidom.py b/Lib/test/test_minidom.py index a2cc8828461d3e..e91cdba1eb2eff 100644 --- a/Lib/test/test_minidom.py +++ b/Lib/test/test_minidom.py @@ -325,7 +325,7 @@ def testRemoveAttributeNode(self): node = child.getAttributeNode("spam") self.assertRaises(xml.dom.NotFoundErr, child.removeAttributeNode, None) - child.removeAttributeNode(node) + self.assertIs(node, child.removeAttributeNode(node)) self.confirm(len(child.attributes) == 0 and child.getAttributeNode("spam") is None) dom2 = Document() diff --git a/Lib/test/test_multiprocessing_main_handling.py b/Lib/test/test_multiprocessing_main_handling.py index fd93184914aea7..9fd5c9fcd91fa6 100644 --- a/Lib/test/test_multiprocessing_main_handling.py +++ b/Lib/test/test_multiprocessing_main_handling.py @@ -57,11 +57,13 @@ def f(x): p = Pool(5) results = [] p.map_async(f, [1, 2, 3], callback=results.extend) - deadline = time.time() + 60 # up to 60 s to report the results + start_time = time.monotonic() while not results: time.sleep(0.05) - if time.time() > deadline: - raise RuntimeError("Timed out waiting for results") + # up to 1 min to report the results + dt = time.monotonic() - start_time + if dt > 60.0: + raise RuntimeError("Timed out waiting for results (%.1f sec)" % dt) results.sort() print(start_method, "->", results) """ @@ -85,11 +87,13 @@ def f(x): 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 +start_time = time.monotonic() while not results: time.sleep(0.05) - if time.time() > deadline: - raise RuntimeError("Timed out waiting for results") + # up to 1 min to report the results + dt = time.monotonic() - start_time + if dt > 60.0: + raise RuntimeError("Timed out waiting for results (%.1f sec)" % dt) results.sort() print(start_method, "->", results) """ diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 9aa38e08dd6e6c..4f9d28afd3b5b4 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -745,6 +745,7 @@ def test_pdb_next_command_for_coroutine(): ... loop = asyncio.new_event_loop() ... loop.run_until_complete(test_main()) ... loop.close() + ... asyncio.set_event_loop_policy(None) ... print("finished") >>> with PdbTestInput(['step', @@ -804,6 +805,7 @@ def test_pdb_next_command_for_asyncgen(): ... loop = asyncio.new_event_loop() ... loop.run_until_complete(test_main()) ... loop.close() + ... asyncio.set_event_loop_policy(None) ... print("finished") >>> with PdbTestInput(['step', @@ -915,6 +917,7 @@ def test_pdb_return_command_for_coroutine(): ... loop = asyncio.new_event_loop() ... loop.run_until_complete(test_main()) ... loop.close() + ... asyncio.set_event_loop_policy(None) ... print("finished") >>> with PdbTestInput(['step', @@ -1005,6 +1008,7 @@ def test_pdb_until_command_for_coroutine(): ... loop = asyncio.new_event_loop() ... loop.run_until_complete(test_main()) ... loop.close() + ... asyncio.set_event_loop_policy(None) ... print("finished") >>> with PdbTestInput(['step', diff --git a/Lib/test/test_peepholer.py b/Lib/test/test_peepholer.py index 0cc1e92907b52b..794d104d5919bd 100644 --- a/Lib/test/test_peepholer.py +++ b/Lib/test/test_peepholer.py @@ -3,6 +3,19 @@ from test.bytecode_helper import BytecodeTestCase +def count_instr_recursively(f, opname): + count = 0 + for instr in dis.get_instructions(f): + if instr.opname == opname: + count += 1 + if hasattr(f, '__code__'): + f = f.__code__ + for c in f.co_consts: + if hasattr(c, 'co_code'): + count += count_instr_recursively(c, opname) + return count + + class TestTranforms(BytecodeTestCase): def test_unot(self): @@ -268,7 +281,7 @@ def f(cond1, cond2): self.assertNotInBytecode(f, 'JUMP_ABSOLUTE') returns = [instr for instr in dis.get_instructions(f) if instr.opname == 'RETURN_VALUE'] - self.assertEqual(len(returns), 6) + self.assertLessEqual(len(returns), 6) def test_elim_jump_after_return2(self): # Eliminate dead code: jumps immediately after returns can't be reached @@ -282,7 +295,7 @@ def f(cond1, cond2): self.assertEqual(len(returns), 1) returns = [instr for instr in dis.get_instructions(f) if instr.opname == 'RETURN_VALUE'] - self.assertEqual(len(returns), 2) + self.assertLessEqual(len(returns), 2) def test_make_function_doesnt_bail(self): def f(): @@ -311,6 +324,17 @@ def test_constant_folding(self): self.assertFalse(instr.opname.startswith('BINARY_')) self.assertFalse(instr.opname.startswith('BUILD_')) + def test_in_literal_list(self): + def containtest(): + return x in [a, b] + self.assertEqual(count_instr_recursively(containtest, 'BUILD_LIST'), 0) + + def test_iterate_literal_list(self): + def forloop(): + for x in [a, b]: + pass + self.assertEqual(count_instr_recursively(forloop, 'BUILD_LIST'), 0) + class TestBuglets(unittest.TestCase): diff --git a/Lib/test/test_platform.py b/Lib/test/test_platform.py index 5f1e28a5d950bb..7e3e40114b476b 100644 --- a/Lib/test/test_platform.py +++ b/Lib/test/test_platform.py @@ -259,16 +259,6 @@ def test_mac_ver_with_fork(self): self.assertEqual(cpid, pid) self.assertEqual(sts, 0) - def test_dist(self): - with warnings.catch_warnings(): - warnings.filterwarnings( - 'ignore', - r'dist\(\) and linux_distribution\(\) ' - 'functions are deprecated .*', - PendingDeprecationWarning, - ) - res = platform.dist() - def test_libc_ver(self): import os if os.path.isdir(sys.executable) and \ @@ -279,23 +269,6 @@ def test_libc_ver(self): executable = sys.executable res = platform.libc_ver(executable) - def test_parse_release_file(self): - - for input, output in ( - # Examples of release file contents: - ('SuSE Linux 9.3 (x86-64)', ('SuSE Linux ', '9.3', 'x86-64')), - ('SUSE LINUX 10.1 (X86-64)', ('SUSE LINUX ', '10.1', 'X86-64')), - ('SUSE LINUX 10.1 (i586)', ('SUSE LINUX ', '10.1', 'i586')), - ('Fedora Core release 5 (Bordeaux)', ('Fedora Core', '5', 'Bordeaux')), - ('Red Hat Linux release 8.0 (Psyche)', ('Red Hat Linux', '8.0', 'Psyche')), - ('Red Hat Linux release 9 (Shrike)', ('Red Hat Linux', '9', 'Shrike')), - ('Red Hat Enterprise Linux release 4 (Nahant)', ('Red Hat Enterprise Linux', '4', 'Nahant')), - ('CentOS release 4', ('CentOS', '4', None)), - ('Rocks release 4.2.1 (Cydonia)', ('Rocks', '4.2.1', 'Cydonia')), - ('', ('', '', '')), # If there's nothing there. - ): - self.assertEqual(platform._parse_release_file(input), output) - def test_popen(self): mswindows = (sys.platform == "win32") @@ -328,43 +301,5 @@ 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): - with warnings.catch_warnings(): - warnings.filterwarnings( - 'ignore', - r'dist\(\) and linux_distribution\(\) ' - 'functions are deprecated .*', - PendingDeprecationWarning, - ) - distname, version, distid = platform.linux_distribution() - - self.assertEqual(distname, 'Fedora') - self.assertEqual(version, '19') - self.assertEqual(distid, 'Schr\xf6dinger\u2019s Cat') - - -class DeprecationTest(unittest.TestCase): - - def test_dist_deprecation(self): - with self.assertWarns(DeprecationWarning) as cm: - platform.dist() - self.assertEqual(str(cm.warning), - 'dist() and linux_distribution() functions are ' - 'deprecated in Python 3.5') - - def test_linux_distribution_deprecation(self): - with self.assertWarns(DeprecationWarning) as cm: - platform.linux_distribution() - self.assertEqual(str(cm.warning), - 'dist() and linux_distribution() functions are ' - 'deprecated in Python 3.5') - if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index 7dea1beab2c28b..4f6abc6f7d6fd9 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -615,11 +615,6 @@ def test_makedev(self): self.assertRaises(TypeError, posix.minor) self.assertRaises((ValueError, OverflowError), posix.minor, -1) - # FIXME: reenable these tests on FreeBSD with the kernel fix - if sys.platform.startswith('freebsd') and dev >= 0x1_0000_0000: - self.skipTest("bpo-31044: on FreeBSD CURRENT, minor() truncates " - "64-bit dev to 32-bit") - self.assertEqual(posix.makedev(major, minor), dev) self.assertRaises(TypeError, posix.makedev, float(major), minor) self.assertRaises(TypeError, posix.makedev, major, float(minor)) @@ -1426,9 +1421,168 @@ def test_setgroups(self): posix.setgroups(groups) self.assertListEqual(groups, posix.getgroups()) + +@unittest.skipUnless(hasattr(os, 'posix_spawn'), "test needs os.posix_spawn") +class TestPosixSpawn(unittest.TestCase): + def test_returns_pid(self): + pidfile = support.TESTFN + self.addCleanup(support.unlink, pidfile) + script = f"""if 1: + import os + with open({pidfile!r}, "w") as pidfile: + pidfile.write(str(os.getpid())) + """ + pid = posix.posix_spawn(sys.executable, + [sys.executable, '-c', script], + os.environ) + self.assertEqual(os.waitpid(pid, 0), (pid, 0)) + with open(pidfile) as f: + self.assertEqual(f.read(), str(pid)) + + def test_no_such_executable(self): + no_such_executable = 'no_such_executable' + try: + pid = posix.posix_spawn(no_such_executable, + [no_such_executable], + os.environ) + except FileNotFoundError as exc: + self.assertEqual(exc.filename, no_such_executable) + else: + pid2, status = os.waitpid(pid, 0) + self.assertEqual(pid2, pid) + self.assertNotEqual(status, 0) + + def test_specify_environment(self): + envfile = support.TESTFN + self.addCleanup(support.unlink, envfile) + script = f"""if 1: + import os + with open({envfile!r}, "w") as envfile: + envfile.write(os.environ['foo']) + """ + pid = posix.posix_spawn(sys.executable, + [sys.executable, '-c', script], + {**os.environ, 'foo': 'bar'}) + self.assertEqual(os.waitpid(pid, 0), (pid, 0)) + with open(envfile) as f: + self.assertEqual(f.read(), 'bar') + + def test_empty_file_actions(self): + pid = posix.posix_spawn( + sys.executable, + [sys.executable, '-c', 'pass'], + os.environ, + [] + ) + self.assertEqual(os.waitpid(pid, 0), (pid, 0)) + + def test_multiple_file_actions(self): + file_actions = [ + (os.POSIX_SPAWN_OPEN, 3, os.path.realpath(__file__), os.O_RDONLY, 0), + (os.POSIX_SPAWN_CLOSE, 0), + (os.POSIX_SPAWN_DUP2, 1, 4), + ] + pid = posix.posix_spawn(sys.executable, + [sys.executable, "-c", "pass"], + os.environ, file_actions) + self.assertEqual(os.waitpid(pid, 0), (pid, 0)) + + def test_bad_file_actions(self): + with self.assertRaises(TypeError): + posix.posix_spawn(sys.executable, + [sys.executable, "-c", "pass"], + os.environ, [None]) + with self.assertRaises(TypeError): + posix.posix_spawn(sys.executable, + [sys.executable, "-c", "pass"], + os.environ, [()]) + with self.assertRaises(TypeError): + posix.posix_spawn(sys.executable, + [sys.executable, "-c", "pass"], + os.environ, [(None,)]) + with self.assertRaises(TypeError): + posix.posix_spawn(sys.executable, + [sys.executable, "-c", "pass"], + os.environ, [(12345,)]) + with self.assertRaises(TypeError): + posix.posix_spawn(sys.executable, + [sys.executable, "-c", "pass"], + os.environ, [(os.POSIX_SPAWN_CLOSE,)]) + with self.assertRaises(TypeError): + posix.posix_spawn(sys.executable, + [sys.executable, "-c", "pass"], + os.environ, [(os.POSIX_SPAWN_CLOSE, 1, 2)]) + with self.assertRaises(TypeError): + posix.posix_spawn(sys.executable, + [sys.executable, "-c", "pass"], + os.environ, [(os.POSIX_SPAWN_CLOSE, None)]) + with self.assertRaises(ValueError): + posix.posix_spawn(sys.executable, + [sys.executable, "-c", "pass"], + os.environ, + [(os.POSIX_SPAWN_OPEN, 3, __file__ + '\0', + os.O_RDONLY, 0)]) + + def test_open_file(self): + outfile = support.TESTFN + self.addCleanup(support.unlink, outfile) + script = """if 1: + import sys + sys.stdout.write("hello") + """ + file_actions = [ + (os.POSIX_SPAWN_OPEN, 1, outfile, + os.O_WRONLY | os.O_CREAT | os.O_TRUNC, + stat.S_IRUSR | stat.S_IWUSR), + ] + pid = posix.posix_spawn(sys.executable, + [sys.executable, '-c', script], + os.environ, file_actions) + self.assertEqual(os.waitpid(pid, 0), (pid, 0)) + with open(outfile) as f: + self.assertEqual(f.read(), 'hello') + + def test_close_file(self): + closefile = support.TESTFN + self.addCleanup(support.unlink, closefile) + script = f"""if 1: + import os + try: + os.fstat(0) + except OSError as e: + with open({closefile!r}, 'w') as closefile: + closefile.write('is closed %d' % e.errno) + """ + pid = posix.posix_spawn(sys.executable, + [sys.executable, '-c', script], + os.environ, + [(os.POSIX_SPAWN_CLOSE, 0),]) + self.assertEqual(os.waitpid(pid, 0), (pid, 0)) + with open(closefile) as f: + self.assertEqual(f.read(), 'is closed %d' % errno.EBADF) + + def test_dup2(self): + dupfile = support.TESTFN + self.addCleanup(support.unlink, dupfile) + script = """if 1: + import sys + sys.stdout.write("hello") + """ + with open(dupfile, "wb") as childfile: + file_actions = [ + (os.POSIX_SPAWN_DUP2, childfile.fileno(), 1), + ] + pid = posix.posix_spawn(sys.executable, + [sys.executable, '-c', script], + os.environ, file_actions) + self.assertEqual(os.waitpid(pid, 0), (pid, 0)) + with open(dupfile) as f: + self.assertEqual(f.read(), 'hello') + + def test_main(): try: - support.run_unittest(PosixTester, PosixGroupsTester) + support.run_unittest(PosixTester, PosixGroupsTester, TestPosixSpawn) finally: support.reap_children() diff --git a/Lib/test/test_posixpath.py b/Lib/test/test_posixpath.py index 96b267cd45fd9a..9476ede5319397 100644 --- a/Lib/test/test_posixpath.py +++ b/Lib/test/test_posixpath.py @@ -153,27 +153,20 @@ def test_dirname(self): def test_islink(self): self.assertIs(posixpath.islink(support.TESTFN + "1"), False) self.assertIs(posixpath.lexists(support.TESTFN + "2"), False) - f = open(support.TESTFN + "1", "wb") - try: + with open(support.TESTFN + "1", "wb") as f: f.write(b"foo") - f.close() - self.assertIs(posixpath.islink(support.TESTFN + "1"), False) - if support.can_symlink(): - os.symlink(support.TESTFN + "1", support.TESTFN + "2") - self.assertIs(posixpath.islink(support.TESTFN + "2"), True) - os.remove(support.TESTFN + "1") - self.assertIs(posixpath.islink(support.TESTFN + "2"), True) - self.assertIs(posixpath.exists(support.TESTFN + "2"), False) - self.assertIs(posixpath.lexists(support.TESTFN + "2"), True) - finally: - if not f.close(): - f.close() + self.assertIs(posixpath.islink(support.TESTFN + "1"), False) + if support.can_symlink(): + os.symlink(support.TESTFN + "1", support.TESTFN + "2") + self.assertIs(posixpath.islink(support.TESTFN + "2"), True) + os.remove(support.TESTFN + "1") + self.assertIs(posixpath.islink(support.TESTFN + "2"), True) + self.assertIs(posixpath.exists(support.TESTFN + "2"), False) + self.assertIs(posixpath.lexists(support.TESTFN + "2"), True) def test_ismount(self): self.assertIs(posixpath.ismount("/"), True) - with warnings.catch_warnings(): - warnings.simplefilter("ignore", DeprecationWarning) - self.assertIs(posixpath.ismount(b"/"), True) + self.assertIs(posixpath.ismount(b"/"), True) def test_ismount_non_existent(self): # Non-existent mountpoint. diff --git a/Lib/test/test_random.py b/Lib/test/test_random.py index eee245df48a161..38fd8a9105ea15 100644 --- a/Lib/test/test_random.py +++ b/Lib/test/test_random.py @@ -227,6 +227,14 @@ def test_choices(self): with self.assertRaises(IndexError): choices([], cum_weights=[], k=5) + def test_choices_subnormal(self): + # Subnormal weights would occassionally trigger an IndexError + # in choices() when the value returned by random() was large + # enough to make `random() * total` round up to the total. + # See https://bugs.python.org/msg275594 for more detail. + choices = self.gen.choices + choices(population=[1, 2], weights=[1e-323, 1e-323], k=5000) + def test_gauss(self): # Ensure that the seed() method initializes all the hidden state. In # particular, through 2.2.1 it failed to reset a piece of state used @@ -619,6 +627,16 @@ def test_genrandbits(self): self.assertRaises(ValueError, self.gen.getrandbits, 0) self.assertRaises(ValueError, self.gen.getrandbits, -1) + def test_randrange_uses_getrandbits(self): + # Verify use of getrandbits by randrange + # Use same seed as in the cross-platform repeatability test + # in test_genrandbits above. + self.gen.seed(1234567) + # If randrange uses getrandbits, it should pick getrandbits(100) + # when called with a 100-bits stop argument. + self.assertEqual(self.gen.randrange(2**99), + 97904845777343510404718956115) + def test_randbelow_logic(self, _log=log, int=int): # check bitcount transition points: 2**i and 2**(i+1)-1 # show that: k = int(1.001 + _log(n, 2)) @@ -640,21 +658,22 @@ def test_randbelow_logic(self, _log=log, int=int): self.assertEqual(k, numbits) # note the stronger assertion self.assertTrue(2**k > n > 2**(k-1)) # note the stronger assertion - @unittest.mock.patch('random.Random.random') - def test_randbelow_overridden_random(self, random_mock): + def test_randbelow_without_getrandbits(self): # Random._randbelow() can only use random() when the built-in one # has been overridden but no new getrandbits() method was supplied. - random_mock.side_effect = random.SystemRandom().random maxsize = 1<<random.BPF with warnings.catch_warnings(): warnings.simplefilter("ignore", UserWarning) # Population range too large (n >= maxsize) - self.gen._randbelow(maxsize+1, maxsize = maxsize) - self.gen._randbelow(5640, maxsize = maxsize) + self.gen._randbelow_without_getrandbits( + maxsize+1, maxsize=maxsize + ) + self.gen._randbelow_without_getrandbits(5640, maxsize=maxsize) # issue 33203: test that _randbelow raises ValueError on # n == 0 also in its getrandbits-independent branch. with self.assertRaises(ValueError): - self.gen._randbelow(0, maxsize=maxsize) + self.gen._randbelow_without_getrandbits(0, maxsize=maxsize) + # This might be going too far to test a single line, but because of our # noble aim of achieving 100% test coverage we need to write a case in # which the following line in Random._randbelow() gets executed: @@ -672,8 +691,10 @@ def test_randbelow_overridden_random(self, random_mock): n = 42 epsilon = 0.01 limit = (maxsize - (maxsize % n)) / maxsize - random_mock.side_effect = [limit + epsilon, limit - epsilon] - self.gen._randbelow(n, maxsize = maxsize) + with unittest.mock.patch.object(random.Random, 'random') as random_mock: + random_mock.side_effect = [limit + epsilon, limit - epsilon] + self.gen._randbelow_without_getrandbits(n, maxsize=maxsize) + self.assertEqual(random_mock.call_count, 2) def test_randrange_bug_1590891(self): start = 1000000000000 @@ -926,6 +947,100 @@ def test_betavariate_return_zero(self, gammavariate_mock): gammavariate_mock.return_value = 0.0 self.assertEqual(0.0, random.betavariate(2.71828, 3.14159)) + +class TestRandomSubclassing(unittest.TestCase): + def test_random_subclass_with_kwargs(self): + # SF bug #1486663 -- this used to erroneously raise a TypeError + class Subclass(random.Random): + def __init__(self, newarg=None): + random.Random.__init__(self) + Subclass(newarg=1) + + def test_subclasses_overriding_methods(self): + # Subclasses with an overridden random, but only the original + # getrandbits method should not rely on getrandbits in for randrange, + # but should use a getrandbits-independent implementation instead. + + # subclass providing its own random **and** getrandbits methods + # like random.SystemRandom does => keep relying on getrandbits for + # randrange + class SubClass1(random.Random): + def random(self): + called.add('SubClass1.random') + return random.Random.random(self) + + def getrandbits(self, n): + called.add('SubClass1.getrandbits') + return random.Random.getrandbits(self, n) + called = set() + SubClass1().randrange(42) + self.assertEqual(called, {'SubClass1.getrandbits'}) + + # subclass providing only random => can only use random for randrange + class SubClass2(random.Random): + def random(self): + called.add('SubClass2.random') + return random.Random.random(self) + called = set() + SubClass2().randrange(42) + self.assertEqual(called, {'SubClass2.random'}) + + # subclass defining getrandbits to complement its inherited random + # => can now rely on getrandbits for randrange again + class SubClass3(SubClass2): + def getrandbits(self, n): + called.add('SubClass3.getrandbits') + return random.Random.getrandbits(self, n) + called = set() + SubClass3().randrange(42) + self.assertEqual(called, {'SubClass3.getrandbits'}) + + # subclass providing only random and inherited getrandbits + # => random takes precedence + class SubClass4(SubClass3): + def random(self): + called.add('SubClass4.random') + return random.Random.random(self) + called = set() + SubClass4().randrange(42) + self.assertEqual(called, {'SubClass4.random'}) + + # Following subclasses don't define random or getrandbits directly, + # but inherit them from classes which are not subclasses of Random + class Mixin1: + def random(self): + called.add('Mixin1.random') + return random.Random.random(self) + class Mixin2: + def getrandbits(self, n): + called.add('Mixin2.getrandbits') + return random.Random.getrandbits(self, n) + + class SubClass5(Mixin1, random.Random): + pass + called = set() + SubClass5().randrange(42) + self.assertEqual(called, {'Mixin1.random'}) + + class SubClass6(Mixin2, random.Random): + pass + called = set() + SubClass6().randrange(42) + self.assertEqual(called, {'Mixin2.getrandbits'}) + + class SubClass7(Mixin1, Mixin2, random.Random): + pass + called = set() + SubClass7().randrange(42) + self.assertEqual(called, {'Mixin1.random'}) + + class SubClass8(Mixin2, Mixin1, random.Random): + pass + called = set() + SubClass8().randrange(42) + self.assertEqual(called, {'Mixin2.getrandbits'}) + + class TestModule(unittest.TestCase): def testMagicConstants(self): self.assertAlmostEqual(random.NV_MAGICCONST, 1.71552776992141) @@ -937,13 +1052,6 @@ def test__all__(self): # tests validity but not completeness of the __all__ list self.assertTrue(set(random.__all__) <= set(dir(random))) - def test_random_subclass_with_kwargs(self): - # SF bug #1486663 -- this used to erroneously raise a TypeError - class Subclass(random.Random): - def __init__(self, newarg=None): - random.Random.__init__(self) - Subclass(newarg=1) - @unittest.skipUnless(hasattr(os, "fork"), "fork() required") def test_after_fork(self): # Test the global Random instance gets reseeded in child diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index 9fed4bef8809fc..ab1d985d59f878 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -694,6 +694,42 @@ def test_other_escapes(self): with self.subTest(c): self.assertRaises(re.error, re.compile, '[\\%c]' % c) + def test_named_unicode_escapes(self): + # test individual Unicode named escapes + self.assertTrue(re.match(r'\N{LESS-THAN SIGN}', '<')) + self.assertTrue(re.match(r'\N{less-than sign}', '<')) + self.assertIsNone(re.match(r'\N{LESS-THAN SIGN}', '>')) + self.assertTrue(re.match(r'\N{SNAKE}', '\U0001f40d')) + self.assertTrue(re.match(r'\N{ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH ' + r'HAMZA ABOVE WITH ALEF MAKSURA ISOLATED FORM}', + '\ufbf9')) + self.assertTrue(re.match(r'[\N{LESS-THAN SIGN}-\N{GREATER-THAN SIGN}]', + '=')) + self.assertIsNone(re.match(r'[\N{LESS-THAN SIGN}-\N{GREATER-THAN SIGN}]', + ';')) + + # test errors in \N{name} handling - only valid names should pass + self.checkPatternError(r'\N', 'missing {', 2) + self.checkPatternError(r'[\N]', 'missing {', 3) + self.checkPatternError(r'\N{', 'missing character name', 3) + self.checkPatternError(r'[\N{', 'missing character name', 4) + self.checkPatternError(r'\N{}', 'missing character name', 3) + self.checkPatternError(r'[\N{}]', 'missing character name', 4) + self.checkPatternError(r'\NSNAKE}', 'missing {', 2) + self.checkPatternError(r'[\NSNAKE}]', 'missing {', 3) + self.checkPatternError(r'\N{SNAKE', + 'missing }, unterminated name', 3) + self.checkPatternError(r'[\N{SNAKE]', + 'missing }, unterminated name', 4) + self.checkPatternError(r'[\N{SNAKE]}', + "undefined character name 'SNAKE]'", 1) + self.checkPatternError(r'\N{SPAM}', + "undefined character name 'SPAM'", 0) + self.checkPatternError(r'[\N{SPAM}]', + "undefined character name 'SPAM'", 1) + self.checkPatternError(br'\N{LESS-THAN SIGN}', r'bad escape \N', 0) + self.checkPatternError(br'[\N{LESS-THAN SIGN}]', r'bad escape \N', 1) + def test_string_boundaries(self): # See http://bugs.python.org/issue10713 self.assertEqual(re.search(r"\b(abc)\b", "abc").group(1), diff --git a/Lib/test/test_regrtest.py b/Lib/test/test_regrtest.py index 10411522dffb02..af332ad15d922a 100644 --- a/Lib/test/test_regrtest.py +++ b/Lib/test/test_regrtest.py @@ -19,6 +19,7 @@ import unittest from test import libregrtest from test import support +from test.libregrtest import utils Py_DEBUG = hasattr(sys, 'getobjects') @@ -980,5 +981,29 @@ def test_bug(self): failed=testname, rerun=testname) +class TestUtils(unittest.TestCase): + def test_format_duration(self): + self.assertEqual(utils.format_duration(0), + '0 ms') + self.assertEqual(utils.format_duration(1e-9), + '1 ms') + self.assertEqual(utils.format_duration(10e-3), + '10 ms') + self.assertEqual(utils.format_duration(1.5), + '1 sec 500 ms') + self.assertEqual(utils.format_duration(1), + '1 sec') + self.assertEqual(utils.format_duration(2 * 60), + '2 min') + self.assertEqual(utils.format_duration(2 * 60 + 1), + '2 min 1 sec') + self.assertEqual(utils.format_duration(3 * 3600), + '3 hour') + self.assertEqual(utils.format_duration(3 * 3600 + 2 * 60 + 1), + '3 hour 2 min') + self.assertEqual(utils.format_duration(3 * 3600 + 1), + '3 hour 1 sec') + + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_robotparser.py b/Lib/test/test_robotparser.py index 140636590aa860..84a267ad9567ee 100644 --- a/Lib/test/test_robotparser.py +++ b/Lib/test/test_robotparser.py @@ -12,6 +12,7 @@ class BaseRobotTest: agent = 'test_robotparser' good = [] bad = [] + site_maps = None def setUp(self): lines = io.StringIO(self.robots_txt).readlines() @@ -36,6 +37,9 @@ def test_bad_urls(self): with self.subTest(url=url, agent=agent): self.assertFalse(self.parser.can_fetch(agent, url)) + def test_site_maps(self): + self.assertEqual(self.parser.site_maps(), self.site_maps) + class UserAgentWildcardTest(BaseRobotTest, unittest.TestCase): robots_txt = """\ @@ -65,6 +69,23 @@ class CrawlDelayAndCustomAgentTest(BaseRobotTest, unittest.TestCase): bad = ['/cyberworld/map/index.html'] +class SitemapTest(BaseRobotTest, unittest.TestCase): + robots_txt = """\ +# robots.txt for http://www.example.com/ + +User-agent: * +Sitemap: http://www.gstatic.com/s2/sitemaps/profiles-sitemap.xml +Sitemap: http://www.google.com/hostednews/sitemap_index.xml +Request-rate: 3/15 +Disallow: /cyberworld/map/ # This is an infinite virtual URL space + + """ + good = ['/', '/test.html'] + bad = ['/cyberworld/map/index.html'] + site_maps = ['http://www.gstatic.com/s2/sitemaps/profiles-sitemap.xml', + 'http://www.google.com/hostednews/sitemap_index.xml'] + + class RejectAllRobotsTest(BaseRobotTest, unittest.TestCase): robots_txt = """\ # go away @@ -265,8 +286,7 @@ class StringFormattingTest(BaseRobotTest, unittest.TestCase): User-agent: * Crawl-delay: 1 Request-rate: 3/15 -Disallow: /cyberworld/map/ - +Disallow: /cyberworld/map/\ """ def test_string_formatting(self): diff --git a/Lib/test/test_script_helper.py b/Lib/test/test_script_helper.py index a7680f886a8d74..4ade2cbc0d4b18 100644 --- a/Lib/test/test_script_helper.py +++ b/Lib/test/test_script_helper.py @@ -2,6 +2,7 @@ import subprocess import sys +import os from test.support import script_helper import unittest from unittest import mock @@ -73,7 +74,7 @@ class TestScriptHelperEnvironment(unittest.TestCase): def setUp(self): self.assertTrue( - hasattr(script_helper, '__cached_interp_requires_environment')) + hasattr(script_helper, '__cached_interp_requires_environment')) # Reset the private cached state. script_helper.__dict__['__cached_interp_requires_environment'] = None @@ -83,27 +84,41 @@ def tearDown(self): @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) + with mock.patch.dict(os.environ): + os.environ.pop('PYTHONHOME', None) + 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) + with mock.patch.dict(os.environ): + os.environ.pop('PYTHONHOME', None) + # 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) + with mock.patch.dict(os.environ): + os.environ.pop('PYTHONHOME', None) + 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) + + @mock.patch('subprocess.check_call') + def test_interpreter_requires_environment_with_pythonhome(self, mock_check_call): + with mock.patch.dict(os.environ): + os.environ['PYTHONHOME'] = 'MockedHome' + self.assertTrue(script_helper.interpreter_requires_environment()) + self.assertTrue(script_helper.interpreter_requires_environment()) + self.assertEqual(0, mock_check_call.call_count) if __name__ == '__main__': diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py index 2cb2f14643e1b3..7e0a3292e0f8a4 100644 --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -12,20 +12,28 @@ import functools import pathlib import subprocess +import random +import string +import contextlib +import io from shutil import (make_archive, register_archive_format, unregister_archive_format, get_archive_formats, Error, unpack_archive, register_unpack_format, RegistryError, unregister_unpack_format, get_unpack_formats, - SameFileError) + SameFileError, _GiveupOnFastCopy) import tarfile import zipfile +try: + import posix +except ImportError: + posix = None from test import support from test.support import TESTFN, FakePath TESTFN2 = TESTFN + "2" - +MACOS = sys.platform.startswith("darwin") try: import grp import pwd @@ -60,6 +68,24 @@ def write_file(path, content, binary=False): with open(path, 'wb' if binary else 'w') as fp: fp.write(content) +def write_test_file(path, size): + """Create a test file with an arbitrary size and random text content.""" + def chunks(total, step): + assert total >= step + while total > step: + yield step + total -= step + if total: + yield total + + bufsize = min(size, 8192) + chunk = b"".join([random.choice(string.ascii_letters).encode() + for i in range(bufsize)]) + with open(path, 'wb') as f: + for csize in chunks(size, bufsize): + f.write(chunk) + assert os.path.getsize(path) == size + def read_file(path, binary=False): """Return contents from a file located at *path*. @@ -84,6 +110,37 @@ def rlistdir(path): res.append(name) return res +def supports_file2file_sendfile(): + # ...apparently Linux and Solaris are the only ones + if not hasattr(os, "sendfile"): + return False + srcname = None + dstname = None + try: + with tempfile.NamedTemporaryFile("wb", delete=False) as f: + srcname = f.name + f.write(b"0123456789") + + with open(srcname, "rb") as src: + with tempfile.NamedTemporaryFile("wb", delete=False) as dst: + dstname = f.name + infd = src.fileno() + outfd = dst.fileno() + try: + os.sendfile(outfd, infd, 0, 2) + except OSError: + return False + else: + return True + finally: + if srcname is not None: + support.unlink(srcname) + if dstname is not None: + support.unlink(dstname) + + +SUPPORTS_SENDFILE = supports_file2file_sendfile() + class TestShutil(unittest.TestCase): @@ -1401,6 +1458,8 @@ def test_copyfile_same_file(self): self.assertRaises(SameFileError, shutil.copyfile, src_file, src_file) # But Error should work too, to stay backward compatible. self.assertRaises(Error, shutil.copyfile, src_file, src_file) + # Make sure file is not corrupted. + self.assertEqual(read_file(src_file), 'foo') def test_copytree_return_value(self): # copytree returns its destination path. @@ -1749,6 +1808,7 @@ def _open(filename, mode='r'): self.assertRaises(OSError, shutil.copyfile, 'srcfile', 'destfile') + @unittest.skipIf(MACOS, "skipped on macOS") def test_w_dest_open_fails(self): srcfile = self.Faux() @@ -1768,6 +1828,7 @@ def _open(filename, mode='r'): self.assertEqual(srcfile._exited_with[1].args, ('Cannot open "destfile"',)) + @unittest.skipIf(MACOS, "skipped on macOS") def test_w_dest_close_fails(self): srcfile = self.Faux() @@ -1790,6 +1851,7 @@ def _open(filename, mode='r'): self.assertEqual(srcfile._exited_with[1].args, ('Cannot close',)) + @unittest.skipIf(MACOS, "skipped on macOS") def test_w_source_close_fails(self): srcfile = self.Faux(True) @@ -1829,6 +1891,308 @@ def test_move_dir_caseinsensitive(self): finally: os.rmdir(dst_dir) + +class TestCopyFileObj(unittest.TestCase): + FILESIZE = 2 * 1024 * 1024 + + @classmethod + def setUpClass(cls): + write_test_file(TESTFN, cls.FILESIZE) + + @classmethod + def tearDownClass(cls): + support.unlink(TESTFN) + support.unlink(TESTFN2) + + def tearDown(self): + support.unlink(TESTFN2) + + @contextlib.contextmanager + def get_files(self): + with open(TESTFN, "rb") as src: + with open(TESTFN2, "wb") as dst: + yield (src, dst) + + def assert_files_eq(self, src, dst): + with open(src, 'rb') as fsrc: + with open(dst, 'rb') as fdst: + self.assertEqual(fsrc.read(), fdst.read()) + + def test_content(self): + with self.get_files() as (src, dst): + shutil.copyfileobj(src, dst) + self.assert_files_eq(TESTFN, TESTFN2) + + def test_file_not_closed(self): + with self.get_files() as (src, dst): + shutil.copyfileobj(src, dst) + assert not src.closed + assert not dst.closed + + def test_file_offset(self): + with self.get_files() as (src, dst): + shutil.copyfileobj(src, dst) + self.assertEqual(src.tell(), self.FILESIZE) + self.assertEqual(dst.tell(), self.FILESIZE) + + @unittest.skipIf(os.name != 'nt', "Windows only") + def test_win_impl(self): + # Make sure alternate Windows implementation is called. + with unittest.mock.patch("shutil._copyfileobj_readinto") as m: + shutil.copyfile(TESTFN, TESTFN2) + assert m.called + + # File size is 2 MiB but max buf size should be 1 MiB. + self.assertEqual(m.call_args[0][2], 1 * 1024 * 1024) + + # If file size < 1 MiB memoryview() length must be equal to + # the actual file size. + with tempfile.NamedTemporaryFile(delete=False) as f: + f.write(b'foo') + fname = f.name + self.addCleanup(support.unlink, fname) + with unittest.mock.patch("shutil._copyfileobj_readinto") as m: + shutil.copyfile(fname, TESTFN2) + self.assertEqual(m.call_args[0][2], 3) + + # Empty files should not rely on readinto() variant. + with tempfile.NamedTemporaryFile(delete=False) as f: + pass + fname = f.name + self.addCleanup(support.unlink, fname) + with unittest.mock.patch("shutil._copyfileobj_readinto") as m: + shutil.copyfile(fname, TESTFN2) + assert not m.called + self.assert_files_eq(fname, TESTFN2) + + +class _ZeroCopyFileTest(object): + """Tests common to all zero-copy APIs.""" + FILESIZE = (10 * 1024 * 1024) # 10 MiB + FILEDATA = b"" + PATCHPOINT = "" + + @classmethod + def setUpClass(cls): + write_test_file(TESTFN, cls.FILESIZE) + with open(TESTFN, 'rb') as f: + cls.FILEDATA = f.read() + assert len(cls.FILEDATA) == cls.FILESIZE + + @classmethod + def tearDownClass(cls): + support.unlink(TESTFN) + + def tearDown(self): + support.unlink(TESTFN2) + + @contextlib.contextmanager + def get_files(self): + with open(TESTFN, "rb") as src: + with open(TESTFN2, "wb") as dst: + yield (src, dst) + + def zerocopy_fun(self, *args, **kwargs): + raise NotImplementedError("must be implemented in subclass") + + def reset(self): + self.tearDown() + self.tearDownClass() + self.setUpClass() + self.setUp() + + # --- + + def test_regular_copy(self): + with self.get_files() as (src, dst): + self.zerocopy_fun(src, dst) + self.assertEqual(read_file(TESTFN2, binary=True), self.FILEDATA) + # Make sure the fallback function is not called. + with self.get_files() as (src, dst): + with unittest.mock.patch('shutil.copyfileobj') as m: + shutil.copyfile(TESTFN, TESTFN2) + assert not m.called + + def test_same_file(self): + self.addCleanup(self.reset) + with self.get_files() as (src, dst): + with self.assertRaises(Exception): + self.zerocopy_fun(src, src) + # Make sure src file is not corrupted. + self.assertEqual(read_file(TESTFN, binary=True), self.FILEDATA) + + def test_non_existent_src(self): + name = tempfile.mktemp() + with self.assertRaises(FileNotFoundError) as cm: + shutil.copyfile(name, "new") + self.assertEqual(cm.exception.filename, name) + + def test_empty_file(self): + srcname = TESTFN + 'src' + dstname = TESTFN + 'dst' + self.addCleanup(lambda: support.unlink(srcname)) + self.addCleanup(lambda: support.unlink(dstname)) + with open(srcname, "wb"): + pass + + with open(srcname, "rb") as src: + with open(dstname, "wb") as dst: + self.zerocopy_fun(src, dst) + + self.assertEqual(read_file(dstname, binary=True), b"") + + def test_unhandled_exception(self): + with unittest.mock.patch(self.PATCHPOINT, + side_effect=ZeroDivisionError): + self.assertRaises(ZeroDivisionError, + shutil.copyfile, TESTFN, TESTFN2) + + def test_exception_on_first_call(self): + # Emulate a case where the first call to the zero-copy + # function raises an exception in which case the function is + # supposed to give up immediately. + with unittest.mock.patch(self.PATCHPOINT, + side_effect=OSError(errno.EINVAL, "yo")): + with self.get_files() as (src, dst): + with self.assertRaises(_GiveupOnFastCopy): + self.zerocopy_fun(src, dst) + + def test_filesystem_full(self): + # Emulate a case where filesystem is full and sendfile() fails + # on first call. + with unittest.mock.patch(self.PATCHPOINT, + side_effect=OSError(errno.ENOSPC, "yo")): + with self.get_files() as (src, dst): + self.assertRaises(OSError, self.zerocopy_fun, src, dst) + + +@unittest.skipIf(not SUPPORTS_SENDFILE, 'os.sendfile() not supported') +class TestZeroCopySendfile(_ZeroCopyFileTest, unittest.TestCase): + PATCHPOINT = "os.sendfile" + + def zerocopy_fun(self, fsrc, fdst): + return shutil._fastcopy_sendfile(fsrc, fdst) + + def test_non_regular_file_src(self): + with io.BytesIO(self.FILEDATA) as src: + with open(TESTFN2, "wb") as dst: + with self.assertRaises(_GiveupOnFastCopy): + self.zerocopy_fun(src, dst) + shutil.copyfileobj(src, dst) + + self.assertEqual(read_file(TESTFN2, binary=True), self.FILEDATA) + + def test_non_regular_file_dst(self): + with open(TESTFN, "rb") as src: + with io.BytesIO() as dst: + with self.assertRaises(_GiveupOnFastCopy): + self.zerocopy_fun(src, dst) + shutil.copyfileobj(src, dst) + dst.seek(0) + self.assertEqual(dst.read(), self.FILEDATA) + + def test_exception_on_second_call(self): + def sendfile(*args, **kwargs): + if not flag: + flag.append(None) + return orig_sendfile(*args, **kwargs) + else: + raise OSError(errno.EBADF, "yo") + + flag = [] + orig_sendfile = os.sendfile + with unittest.mock.patch('os.sendfile', create=True, + side_effect=sendfile): + with self.get_files() as (src, dst): + with self.assertRaises(OSError) as cm: + shutil._fastcopy_sendfile(src, dst) + assert flag + self.assertEqual(cm.exception.errno, errno.EBADF) + + def test_cant_get_size(self): + # Emulate a case where src file size cannot be determined. + # Internally bufsize will be set to a small value and + # sendfile() will be called repeatedly. + with unittest.mock.patch('os.fstat', side_effect=OSError) as m: + with self.get_files() as (src, dst): + shutil._fastcopy_sendfile(src, dst) + assert m.called + self.assertEqual(read_file(TESTFN2, binary=True), self.FILEDATA) + + def test_small_chunks(self): + # Force internal file size detection to be smaller than the + # actual file size. We want to force sendfile() to be called + # multiple times, also in order to emulate a src fd which gets + # bigger while it is being copied. + mock = unittest.mock.Mock() + mock.st_size = 65536 + 1 + with unittest.mock.patch('os.fstat', return_value=mock) as m: + with self.get_files() as (src, dst): + shutil._fastcopy_sendfile(src, dst) + assert m.called + self.assertEqual(read_file(TESTFN2, binary=True), self.FILEDATA) + + def test_big_chunk(self): + # Force internal file size detection to be +100MB bigger than + # the actual file size. Make sure sendfile() does not rely on + # file size value except for (maybe) a better throughput / + # performance. + mock = unittest.mock.Mock() + mock.st_size = self.FILESIZE + (100 * 1024 * 1024) + with unittest.mock.patch('os.fstat', return_value=mock) as m: + with self.get_files() as (src, dst): + shutil._fastcopy_sendfile(src, dst) + assert m.called + self.assertEqual(read_file(TESTFN2, binary=True), self.FILEDATA) + + def test_blocksize_arg(self): + with unittest.mock.patch('os.sendfile', + side_effect=ZeroDivisionError) as m: + self.assertRaises(ZeroDivisionError, + shutil.copyfile, TESTFN, TESTFN2) + blocksize = m.call_args[0][3] + # Make sure file size and the block size arg passed to + # sendfile() are the same. + self.assertEqual(blocksize, os.path.getsize(TESTFN)) + # ...unless we're dealing with a small file. + support.unlink(TESTFN2) + write_file(TESTFN2, b"hello", binary=True) + self.addCleanup(support.unlink, TESTFN2 + '3') + self.assertRaises(ZeroDivisionError, + shutil.copyfile, TESTFN2, TESTFN2 + '3') + blocksize = m.call_args[0][3] + self.assertEqual(blocksize, 2 ** 23) + + def test_file2file_not_supported(self): + # Emulate a case where sendfile() only support file->socket + # fds. In such a case copyfile() is supposed to skip the + # fast-copy attempt from then on. + assert shutil._HAS_SENDFILE + try: + with unittest.mock.patch( + self.PATCHPOINT, + side_effect=OSError(errno.ENOTSOCK, "yo")) as m: + with self.get_files() as (src, dst): + with self.assertRaises(_GiveupOnFastCopy): + shutil._fastcopy_sendfile(src, dst) + assert m.called + assert not shutil._HAS_SENDFILE + + with unittest.mock.patch(self.PATCHPOINT) as m: + shutil.copyfile(TESTFN, TESTFN2) + assert not m.called + finally: + shutil._HAS_SENDFILE = True + + +@unittest.skipIf(not MACOS, 'macOS only') +class TestZeroCopyMACOS(_ZeroCopyFileTest, unittest.TestCase): + PATCHPOINT = "posix._fcopyfile" + + def zerocopy_fun(self, src, dst): + return shutil._fastcopy_fcopyfile(src, dst, posix._COPYFILE_DATA) + + class TermsizeTests(unittest.TestCase): def test_does_not_crash(self): """Check if get_terminal_size() returns a meaningful value. diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py index 48b7a392e50b34..354c3fde168c32 100644 --- a/Lib/test/test_signal.py +++ b/Lib/test/test_signal.py @@ -43,6 +43,8 @@ def test_out_of_range_signal_number_raises_error(self): self.assertRaises(ValueError, signal.signal, 4242, self.trivial_signal_handler) + self.assertRaises(ValueError, signal.strsignal, 4242) + def test_setting_signal_handler_to_none_raises_error(self): self.assertRaises(TypeError, signal.signal, signal.SIGUSR1, None) @@ -55,15 +57,38 @@ def test_getsignal(self): signal.signal(signal.SIGHUP, hup) self.assertEqual(signal.getsignal(signal.SIGHUP), hup) + def test_strsignal(self): + self.assertIn("Interrupt", signal.strsignal(signal.SIGINT)) + self.assertIn("Terminated", signal.strsignal(signal.SIGTERM)) + # Issue 3864, unknown if this affects earlier versions of freebsd also def test_interprocess_signal(self): dirname = os.path.dirname(__file__) script = os.path.join(dirname, 'signalinterproctester.py') assert_python_ok(script) + def test_valid_signals(self): + s = signal.valid_signals() + self.assertIsInstance(s, set) + self.assertIn(signal.Signals.SIGINT, s) + self.assertIn(signal.Signals.SIGALRM, s) + self.assertNotIn(0, s) + self.assertNotIn(signal.NSIG, s) + self.assertLess(len(s), signal.NSIG) + @unittest.skipUnless(sys.platform == "win32", "Windows specific") class WindowsSignalTests(unittest.TestCase): + + def test_valid_signals(self): + s = signal.valid_signals() + self.assertIsInstance(s, set) + self.assertGreaterEqual(len(s), 6) + self.assertIn(signal.Signals.SIGINT, s) + self.assertNotIn(0, s) + self.assertNotIn(signal.NSIG, s) + self.assertLess(len(s), signal.NSIG) + def test_issue9324(self): # Updated for issue #10003, adding SIGBREAK handler = lambda x, y: None @@ -916,6 +941,21 @@ def test_pthread_sigmask_arguments(self): self.assertRaises(TypeError, signal.pthread_sigmask, 1) self.assertRaises(TypeError, signal.pthread_sigmask, 1, 2, 3) self.assertRaises(OSError, signal.pthread_sigmask, 1700, []) + with self.assertRaises(ValueError): + signal.pthread_sigmask(signal.SIG_BLOCK, [signal.NSIG]) + with self.assertRaises(ValueError): + signal.pthread_sigmask(signal.SIG_BLOCK, [0]) + with self.assertRaises(ValueError): + signal.pthread_sigmask(signal.SIG_BLOCK, [1<<1000]) + + @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'), + 'need signal.pthread_sigmask()') + def test_pthread_sigmask_valid_signals(self): + s = signal.pthread_sigmask(signal.SIG_BLOCK, signal.valid_signals()) + self.addCleanup(signal.pthread_sigmask, signal.SIG_SETMASK, s) + # Get current blocked set + s = signal.pthread_sigmask(signal.SIG_UNBLOCK, signal.valid_signals()) + self.assertLessEqual(s, signal.valid_signals()) @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'), 'need signal.pthread_sigmask()') diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index 7bbaa9f1e8eb9b..73d3e3bbcdaeb8 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -181,22 +181,6 @@ def asn1time(cert_time): return cert_time -# Issue #9415: Ubuntu hijacks their OpenSSL and forcefully disables SSLv2 -def skip_if_broken_ubuntu_ssl(func): - if hasattr(ssl, 'PROTOCOL_SSLv2'): - @functools.wraps(func) - def f(*args, **kwargs): - try: - ssl.SSLContext(ssl.PROTOCOL_SSLv2) - except ssl.SSLError: - if (ssl.OPENSSL_VERSION_INFO == (0, 9, 8, 15, 15) and - platform.linux_distribution() == ('debian', 'squeeze/sid', '')): - raise unittest.SkipTest("Patched Ubuntu OpenSSL breaks behaviour") - return func(*args, **kwargs) - return f - else: - return func - needs_sni = unittest.skipUnless(ssl.HAS_SNI, "SNI support needed for this test") @@ -975,7 +959,6 @@ def test_connect_ex_error(self): class ContextTests(unittest.TestCase): - @skip_if_broken_ubuntu_ssl def test_constructor(self): for protocol in PROTOCOLS: ssl.SSLContext(protocol) @@ -984,7 +967,6 @@ def test_constructor(self): self.assertRaises(ValueError, ssl.SSLContext, -1) self.assertRaises(ValueError, ssl.SSLContext, 42) - @skip_if_broken_ubuntu_ssl def test_protocol(self): for proto in PROTOCOLS: ctx = ssl.SSLContext(proto) @@ -1018,7 +1000,6 @@ def test_get_ciphers(self): self.assertIn('AES256-GCM-SHA384', names) self.assertIn('AES128-GCM-SHA256', names) - @skip_if_broken_ubuntu_ssl def test_options(self): ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) # OP_ALL | OP_NO_SSLv2 | OP_NO_SSLv3 is the default value @@ -1333,7 +1314,6 @@ def test_load_dh_params(self): with self.assertRaises(ssl.SSLError) as cm: ctx.load_dh_params(CERTFILE) - @skip_if_broken_ubuntu_ssl def test_session_stats(self): for proto in PROTOCOLS: ctx = ssl.SSLContext(proto) @@ -2577,7 +2557,6 @@ def try_protocol_combo(server_protocol, client_protocol, expect_success, class ThreadedTests(unittest.TestCase): - @skip_if_broken_ubuntu_ssl def test_echo(self): """Basic test of an SSL client connecting to a server""" if support.verbose: @@ -2970,7 +2949,6 @@ def test_ssl_cert_verify_error(self): self.assertIn(msg, repr(e)) self.assertIn('certificate verify failed', repr(e)) - @skip_if_broken_ubuntu_ssl @unittest.skipUnless(hasattr(ssl, 'PROTOCOL_SSLv2'), "OpenSSL is compiled without SSLv2 support") def test_protocol_sslv2(self): @@ -2994,7 +2972,6 @@ def test_protocol_sslv2(self): try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLS, False, client_options=ssl.OP_NO_TLSv1) - @skip_if_broken_ubuntu_ssl def test_PROTOCOL_TLS(self): """Connecting to an SSLv23 server with various client options""" if support.verbose: @@ -3034,7 +3011,6 @@ def test_PROTOCOL_TLS(self): server_options=ssl.OP_NO_TLSv1) - @skip_if_broken_ubuntu_ssl @unittest.skipUnless(hasattr(ssl, 'PROTOCOL_SSLv3'), "OpenSSL is compiled without SSLv3 support") def test_protocol_sslv3(self): @@ -3054,7 +3030,6 @@ def test_protocol_sslv3(self): try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLS, False, client_options=ssl.OP_NO_SSLv2) - @skip_if_broken_ubuntu_ssl def test_protocol_tlsv1(self): """Connecting to a TLSv1 server with various client options""" if support.verbose: @@ -3069,7 +3044,6 @@ def test_protocol_tlsv1(self): try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLS, False, client_options=ssl.OP_NO_TLSv1) - @skip_if_broken_ubuntu_ssl @unittest.skipUnless(hasattr(ssl, "PROTOCOL_TLSv1_1"), "TLS version 1.1 not supported.") def test_protocol_tlsv1_1(self): @@ -3089,7 +3063,6 @@ def test_protocol_tlsv1_1(self): try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1, False) try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1_1, False) - @skip_if_broken_ubuntu_ssl @unittest.skipUnless(hasattr(ssl, "PROTOCOL_TLSv1_2"), "TLS version 1.2 not supported.") def test_protocol_tlsv1_2(self): @@ -4136,24 +4109,16 @@ def test_main(verbose=False): if support.verbose: import warnings plats = { - 'Linux': platform.linux_distribution, 'Mac': platform.mac_ver, 'Windows': platform.win32_ver, } - with warnings.catch_warnings(): - warnings.filterwarnings( - 'ignore', - r'dist\(\) and linux_distribution\(\) ' - 'functions are deprecated .*', - PendingDeprecationWarning, - ) - for name, func in plats.items(): - plat = func() - if plat and plat[0]: - plat = '%s %r' % (name, plat) - break - else: - plat = repr(platform.platform()) + for name, func in plats.items(): + plat = func() + if plat and plat[0]: + plat = '%s %r' % (name, plat) + break + else: + plat = repr(platform.platform()) print("test_ssl: testing with %r %r" % (ssl.OPENSSL_VERSION, ssl.OPENSSL_VERSION_INFO)) print(" under %s" % plat) diff --git a/Lib/test/test_struct.py b/Lib/test/test_struct.py index 8fd56c91cb7a4d..454082e66d3f86 100644 --- a/Lib/test/test_struct.py +++ b/Lib/test/test_struct.py @@ -579,14 +579,22 @@ def test__sizeof__(self): self.check_sizeof('0c', 0) def test_boundary_error_message(self): - regex = ( + regex1 = ( r'pack_into requires a buffer of at least 6 ' r'bytes for packing 1 bytes at offset 5 ' r'\(actual buffer size is 1\)' ) - with self.assertRaisesRegex(struct.error, regex): + with self.assertRaisesRegex(struct.error, regex1): struct.pack_into('b', bytearray(1), 5, 1) + regex2 = ( + r'unpack_from requires a buffer of at least 6 ' + r'bytes for unpacking 1 bytes at offset 5 ' + r'\(actual buffer size is 1\)' + ) + with self.assertRaisesRegex(struct.error, regex2): + struct.unpack_from('b', bytearray(1), 5) + def test_boundary_error_message_with_negative_offset(self): byte_list = bytearray(10) with self.assertRaisesRegex( @@ -599,16 +607,34 @@ def test_boundary_error_message_with_negative_offset(self): 'offset -11 out of range for 10-byte buffer'): struct.pack_into('<B', byte_list, -11, 123) + with self.assertRaisesRegex( + struct.error, + r'not enough data to unpack 4 bytes at offset -2'): + struct.unpack_from('<I', byte_list, -2) + + with self.assertRaisesRegex( + struct.error, + "offset -11 out of range for 10-byte buffer"): + struct.unpack_from('<B', byte_list, -11) + def test_boundary_error_message_with_large_offset(self): # Test overflows cause by large offset and value size (issue 30245) - regex = ( + regex1 = ( r'pack_into requires a buffer of at least ' + str(sys.maxsize + 4) + r' bytes for packing 4 bytes at offset ' + str(sys.maxsize) + r' \(actual buffer size is 10\)' ) - with self.assertRaisesRegex(struct.error, regex): + with self.assertRaisesRegex(struct.error, regex1): struct.pack_into('<I', bytearray(10), sys.maxsize, 1) + regex2 = ( + r'unpack_from requires a buffer of at least ' + str(sys.maxsize + 4) + + r' bytes for unpacking 4 bytes at offset ' + str(sys.maxsize) + + r' \(actual buffer size is 10\)' + ) + with self.assertRaisesRegex(struct.error, regex2): + struct.unpack_from('<I', bytearray(10), sys.maxsize) + def test_issue29802(self): # When the second argument of struct.unpack() was of wrong type # the Struct object was decrefed twice and the reference to diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py index 4b089f525c152a..73b57b21db2cec 100644 --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -2822,6 +2822,33 @@ def test_startupinfo_keywords(self): subprocess.call([sys.executable, "-c", "import sys; sys.exit(0)"], startupinfo=startupinfo) + def test_startupinfo_copy(self): + # bpo-34044: Popen must not modify input STARTUPINFO structure + startupinfo = subprocess.STARTUPINFO() + startupinfo.dwFlags = subprocess.STARTF_USESHOWWINDOW + startupinfo.wShowWindow = subprocess.SW_HIDE + + # Call Popen() twice with the same startupinfo object to make sure + # that it's not modified + for _ in range(2): + cmd = [sys.executable, "-c", "pass"] + with open(os.devnull, 'w') as null: + proc = subprocess.Popen(cmd, + stdout=null, + stderr=subprocess.STDOUT, + startupinfo=startupinfo) + with proc: + proc.communicate() + self.assertEqual(proc.returncode, 0) + + self.assertEqual(startupinfo.dwFlags, + subprocess.STARTF_USESHOWWINDOW) + self.assertIsNone(startupinfo.hStdInput) + self.assertIsNone(startupinfo.hStdOutput) + self.assertIsNone(startupinfo.hStdError) + self.assertEqual(startupinfo.wShowWindow, subprocess.SW_HIDE) + self.assertEqual(startupinfo.lpAttributeList, {"handle_list": []}) + def test_creationflags(self): # creationflags argument CREATE_NEW_CONSOLE = 16 diff --git a/Lib/test/test_sundry.py b/Lib/test/test_sundry.py index 4025c2354a6cdb..6e36a6123daa0e 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 = ('encodings', 'formatter', 'tabnanny') + untested = ('encodings', 'formatter') with support.check_warnings(quiet=True): for name in untested: try: diff --git a/Lib/test/test_super.py b/Lib/test/test_super.py index cb2d7c32236b4c..5d94372bf6ec7f 100644 --- a/Lib/test/test_super.py +++ b/Lib/test/test_super.py @@ -1,8 +1,6 @@ """Unit tests for zero-argument super() & related machinery.""" import unittest -import warnings -from test.support import check_warnings class A: @@ -173,14 +171,10 @@ def __new__(cls, name, bases, namespace): test_namespace = namespace return None - # This case shouldn't trigger the __classcell__ deprecation warning - with check_warnings() as w: - warnings.simplefilter("always", DeprecationWarning) - class A(metaclass=Meta): - @staticmethod - def f(): - return __class__ - self.assertEqual(w.warnings, []) + class A(metaclass=Meta): + @staticmethod + def f(): + return __class__ self.assertIs(A, None) @@ -244,37 +238,19 @@ def __new__(cls, name, bases, namespace): namespace.pop('__classcell__', None) return super().__new__(cls, name, bases, namespace) - # The default case should continue to work without any warnings - with check_warnings() as w: - warnings.simplefilter("always", DeprecationWarning) - class WithoutClassRef(metaclass=Meta): - pass - self.assertEqual(w.warnings, []) + # The default case should continue to work without any errors + class WithoutClassRef(metaclass=Meta): + pass # With zero-arg super() or an explicit __class__ reference, we expect - # __build_class__ to emit a DeprecationWarning complaining that + # __build_class__ to raise a RuntimeError complaining that # __class__ was not set, and asking if __classcell__ was propagated # to type.__new__. - # In Python 3.7, that warning will become a RuntimeError. - expected_warning = ( - '__class__ not set.*__classcell__ propagated', - DeprecationWarning - ) - with check_warnings(expected_warning): - warnings.simplefilter("always", DeprecationWarning) + expected_error = '__class__ not set.*__classcell__ propagated' + with self.assertRaisesRegex(RuntimeError, expected_error): class WithClassRef(metaclass=Meta): def f(self): return __class__ - # Check __class__ still gets set despite the warning - self.assertIs(WithClassRef().f(), WithClassRef) - - # Check the warning is turned into an error as expected - with warnings.catch_warnings(): - warnings.simplefilter("error", DeprecationWarning) - with self.assertRaises(DeprecationWarning): - class WithClassRef(metaclass=Meta): - def f(self): - return __class__ def test___classcell___overwrite(self): # See issue #23722 diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index 2b96a94401a87d..fa1e7aa5d4f27d 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -298,7 +298,7 @@ >>> test() 9 -Start simple, a continue in a finally should not be allowed. +continue in a finally should be ok. >>> def test(): ... for abc in range(10): @@ -306,11 +306,9 @@ ... pass ... finally: ... continue - Traceback (most recent call last): - ... - SyntaxError: 'continue' not supported inside 'finally' clause - -This is essentially a continue in a finally which should not be allowed. + ... print(abc) + >>> test() + 9 >>> def test(): ... for abc in range(10): @@ -321,9 +319,24 @@ ... continue ... except: ... pass - Traceback (most recent call last): - ... - SyntaxError: 'continue' not supported inside 'finally' clause + ... print(abc) + >>> test() + 9 + + >>> def test(): + ... for abc in range(10): + ... try: + ... pass + ... finally: + ... try: + ... pass + ... except: + ... continue + ... print(abc) + >>> test() + 9 + +A continue outside loop should not be allowed. >>> def foo(): ... try: @@ -332,42 +345,7 @@ ... continue Traceback (most recent call last): ... - SyntaxError: 'continue' not supported inside 'finally' clause - - >>> def foo(): - ... for a in (): - ... try: - ... pass - ... finally: - ... continue - Traceback (most recent call last): - ... - SyntaxError: 'continue' not supported inside 'finally' clause - - >>> def foo(): - ... for a in (): - ... try: - ... pass - ... finally: - ... try: - ... continue - ... finally: - ... pass - Traceback (most recent call last): - ... - SyntaxError: 'continue' not supported inside 'finally' clause - - >>> def foo(): - ... for a in (): - ... try: pass - ... finally: - ... try: - ... pass - ... except: - ... continue - Traceback (most recent call last): - ... - SyntaxError: 'continue' not supported inside 'finally' clause + SyntaxError: 'continue' not properly in loop There is one test for a break that is not in a loop. The compiler uses a single data structure to keep track of try-finally and loops, diff --git a/Lib/test/test_sys_settrace.py b/Lib/test/test_sys_settrace.py index 2cf55eb97e4b21..112ea877205abc 100644 --- a/Lib/test/test_sys_settrace.py +++ b/Lib/test/test_sys_settrace.py @@ -207,7 +207,6 @@ def tightloop_example(): (1, 'line'), (2, 'line'), (3, 'line'), - (4, 'line'), (5, 'line'), (5, 'line'), (5, 'line'), @@ -668,6 +667,7 @@ def run_async_test(self, func, jumpFrom, jumpTo, expected, error=None, with self.assertRaisesRegex(*error): asyncio.run(func(output)) sys.settrace(None) + asyncio.set_event_loop_policy(None) self.compare_jump_output(expected, output) def jump_test(jumpFrom, jumpTo, expected, error=None, event='line'): @@ -793,6 +793,21 @@ def test_jump_in_nested_finally_3(output): output.append(11) output.append(12) + @jump_test(5, 11, [2, 4, 12]) + def test_jump_over_return_try_finally_in_finally_block(output): + try: + output.append(2) + finally: + output.append(4) + output.append(5) + return + try: + output.append(8) + finally: + output.append(10) + pass + output.append(12) + @jump_test(3, 4, [1, 4]) def test_jump_infinite_while_loop(output): output.append(1) @@ -800,6 +815,22 @@ def test_jump_infinite_while_loop(output): output.append(3) output.append(4) + @jump_test(2, 4, [4, 4]) + def test_jump_forwards_into_while_block(output): + i = 1 + output.append(2) + while i <= 2: + output.append(4) + i += 1 + + @jump_test(5, 3, [3, 3, 3, 5]) + def test_jump_backwards_into_while_block(output): + i = 1 + while i <= 2: + output.append(3) + i += 1 + output.append(5) + @jump_test(2, 3, [1, 3]) def test_jump_forwards_out_of_with_block(output): with tracecontext(output, 1): @@ -1101,22 +1132,6 @@ async def test_no_jump_backwards_into_async_for_block(output): output.append(2) output.append(3) - @jump_test(2, 4, [], (ValueError, 'into')) - def test_no_jump_forwards_into_while_block(output): - i = 1 - output.append(2) - while i <= 2: - output.append(4) - i += 1 - - @jump_test(5, 3, [3, 3], (ValueError, 'into')) - def test_no_jump_backwards_into_while_block(output): - i = 1 - while i <= 2: - output.append(3) - i += 1 - output.append(5) - @jump_test(1, 3, [], (ValueError, 'into')) def test_no_jump_forwards_into_with_block(output): output.append(1) @@ -1187,8 +1202,16 @@ def test_no_jump_between_except_blocks_2(output): output.append(7) output.append(8) - @jump_test(3, 6, [2, 5, 6], (ValueError, 'finally')) + @jump_test(1, 5, [], (ValueError, "into a 'finally'")) def test_no_jump_into_finally_block(output): + output.append(1) + try: + output.append(3) + finally: + output.append(5) + + @jump_test(3, 6, [2, 5, 6], (ValueError, "into a 'finally'")) + def test_no_jump_into_finally_block_from_try_block(output): try: output.append(2) output.append(3) @@ -1197,22 +1220,72 @@ def test_no_jump_into_finally_block(output): output.append(6) output.append(7) - @jump_test(1, 5, [], (ValueError, 'finally')) - def test_no_jump_into_finally_block_2(output): + @jump_test(5, 1, [1, 3], (ValueError, "out of a 'finally'")) + def test_no_jump_out_of_finally_block(output): output.append(1) try: output.append(3) finally: output.append(5) - @jump_test(5, 1, [1, 3], (ValueError, 'finally')) - def test_no_jump_out_of_finally_block(output): + @jump_test(1, 5, [], (ValueError, "into an 'except'")) + def test_no_jump_into_bare_except_block(output): output.append(1) try: output.append(3) - finally: + except: + output.append(5) + + @jump_test(1, 5, [], (ValueError, "into an 'except'")) + def test_no_jump_into_qualified_except_block(output): + output.append(1) + try: + output.append(3) + except Exception: output.append(5) + @jump_test(3, 6, [2, 5, 6], (ValueError, "into an 'except'")) + def test_no_jump_into_bare_except_block_from_try_block(output): + try: + output.append(2) + output.append(3) + except: # executed if the jump is failed + output.append(5) + output.append(6) + raise + output.append(8) + + @jump_test(3, 6, [2], (ValueError, "into an 'except'")) + def test_no_jump_into_qualified_except_block_from_try_block(output): + try: + output.append(2) + output.append(3) + except ZeroDivisionError: + output.append(5) + output.append(6) + raise + output.append(8) + + @jump_test(7, 1, [1, 3, 6], (ValueError, "out of an 'except'")) + def test_no_jump_out_of_bare_except_block(output): + output.append(1) + try: + output.append(3) + 1/0 + except: + output.append(6) + output.append(7) + + @jump_test(7, 1, [1, 3, 6], (ValueError, "out of an 'except'")) + def test_no_jump_out_of_qualified_except_block(output): + output.append(1) + try: + output.append(3) + 1/0 + except Exception: + output.append(6) + output.append(7) + @jump_test(3, 5, [1, 2, -2], (ValueError, 'into')) def test_no_jump_between_with_blocks(output): output.append(1) @@ -1229,6 +1302,16 @@ async def test_no_jump_between_async_with_blocks(output): async with asynctracecontext(output, 4): output.append(5) + @jump_test(5, 7, [2, 4], (ValueError, 'finally')) + def test_no_jump_over_return_out_of_finally_block(output): + try: + output.append(2) + finally: + output.append(4) + output.append(5) + return + output.append(7) + @jump_test(7, 4, [1, 6], (ValueError, 'into')) def test_no_jump_into_for_block_before_else(output): output.append(1) diff --git a/Lib/test/test_tabnanny.py b/Lib/test/test_tabnanny.py new file mode 100644 index 00000000000000..ec887361730b96 --- /dev/null +++ b/Lib/test/test_tabnanny.py @@ -0,0 +1,343 @@ +"""Testing `tabnanny` module. + +Glossary: + * errored : Whitespace related problems present in file. +""" +from unittest import TestCase, mock +from unittest import mock +import tabnanny +import tokenize +import tempfile +import textwrap +from test.support import (captured_stderr, captured_stdout, script_helper, + findfile, unlink) + + +SOURCE_CODES = { + "incomplete_expression": ( + 'fruits = [\n' + ' "Apple",\n' + ' "Orange",\n' + ' "Banana",\n' + '\n' + 'print(fruits)\n' + ), + "wrong_indented": ( + 'if True:\n' + ' print("hello")\n' + ' print("world")\n' + 'else:\n' + ' print("else called")\n' + ), + "nannynag_errored": ( + 'if True:\n' + ' \tprint("hello")\n' + '\tprint("world")\n' + 'else:\n' + ' print("else called")\n' + ), + "error_free": ( + 'if True:\n' + ' print("hello")\n' + ' print("world")\n' + 'else:\n' + ' print("else called")\n' + ), + "tab_space_errored_1": ( + 'def my_func():\n' + '\t print("hello world")\n' + '\t if True:\n' + '\t\tprint("If called")' + ), + "tab_space_errored_2": ( + 'def my_func():\n' + '\t\tprint("Hello world")\n' + '\t\tif True:\n' + '\t print("If called")' + ) +} + + +class TemporaryPyFile: + """Create a temporary python source code file.""" + + def __init__(self, source_code='', directory=None): + self.source_code = source_code + self.dir = directory + + def __enter__(self): + with tempfile.NamedTemporaryFile( + mode='w', dir=self.dir, suffix=".py", delete=False + ) as f: + f.write(self.source_code) + self.file_path = f.name + return self.file_path + + def __exit__(self, exc_type, exc_value, exc_traceback): + unlink(self.file_path) + + +class TestFormatWitnesses(TestCase): + """Testing `tabnanny.format_witnesses()`.""" + + def test_format_witnesses(self): + """Asserting formatter result by giving various input samples.""" + tests = [ + ('Test', 'at tab sizes T, e, s, t'), + ('', 'at tab size '), + ('t', 'at tab size t'), + (' t ', 'at tab sizes , , t, , '), + ] + + for words, expected in tests: + with self.subTest(words=words, expected=expected): + self.assertEqual(tabnanny.format_witnesses(words), expected) + + +class TestErrPrint(TestCase): + """Testing `tabnanny.errprint()`.""" + + def test_errprint(self): + """Asserting result of `tabnanny.errprint()` by giving sample inputs.""" + tests = [ + (['first', 'second'], 'first second\n'), + (['first'], 'first\n'), + ([1, 2, 3], '1 2 3\n'), + ([], '\n') + ] + + for args, expected in tests: + with self.subTest(arguments=args, expected=expected): + with captured_stderr() as stderr: + tabnanny.errprint(*args) + self.assertEqual(stderr.getvalue() , expected) + + +class TestNannyNag(TestCase): + def test_all_methods(self): + """Asserting behaviour of `tabnanny.NannyNag` exception.""" + tests = [ + ( + tabnanny.NannyNag(0, "foo", "bar"), + {'lineno': 0, 'msg': 'foo', 'line': 'bar'} + ), + ( + tabnanny.NannyNag(5, "testmsg", "testline"), + {'lineno': 5, 'msg': 'testmsg', 'line': 'testline'} + ) + ] + for nanny, expected in tests: + line_number = nanny.get_lineno() + msg = nanny.get_msg() + line = nanny.get_line() + with self.subTest( + line_number=line_number, expected=expected['lineno'] + ): + self.assertEqual(expected['lineno'], line_number) + with self.subTest(msg=msg, expected=expected['msg']): + self.assertEqual(expected['msg'], msg) + with self.subTest(line=line, expected=expected['line']): + self.assertEqual(expected['line'], line) + + +class TestCheck(TestCase): + """Testing tabnanny.check().""" + + def setUp(self): + self.addCleanup(setattr, tabnanny, 'verbose', tabnanny.verbose) + tabnanny.verbose = 0 # Forcefully deactivating verbose mode. + + def verify_tabnanny_check(self, dir_or_file, out="", err=""): + """Common verification for tabnanny.check(). + + Use this method to assert expected values of `stdout` and `stderr` after + running tabnanny.check() on given `dir` or `file` path. Because + tabnanny.check() captures exceptions and writes to `stdout` and + `stderr`, asserting standard outputs is the only way. + """ + with captured_stdout() as stdout, captured_stderr() as stderr: + tabnanny.check(dir_or_file) + self.assertEqual(stdout.getvalue(), out) + self.assertEqual(stderr.getvalue(), err) + + def test_correct_file(self): + """A python source code file without any errors.""" + with TemporaryPyFile(SOURCE_CODES["error_free"]) as file_path: + self.verify_tabnanny_check(file_path) + + def test_correct_directory_verbose(self): + """Directory containing few error free python source code files. + + Because order of files returned by `os.lsdir()` is not fixed, verify the + existence of each output lines at `stdout` using `in` operator. + `verbose` mode of `tabnanny.verbose` asserts `stdout`. + """ + with tempfile.TemporaryDirectory() as tmp_dir: + lines = [f"{tmp_dir!r}: listing directory\n",] + file1 = TemporaryPyFile(SOURCE_CODES["error_free"], directory=tmp_dir) + file2 = TemporaryPyFile(SOURCE_CODES["error_free"], directory=tmp_dir) + with file1 as file1_path, file2 as file2_path: + for file_path in (file1_path, file2_path): + lines.append(f"{file_path!r}: Clean bill of health.\n") + + tabnanny.verbose = 1 + with captured_stdout() as stdout, captured_stderr() as stderr: + tabnanny.check(tmp_dir) + stdout = stdout.getvalue() + for line in lines: + with self.subTest(line=line): + self.assertIn(line, stdout) + self.assertEqual(stderr.getvalue(), "") + + def test_correct_directory(self): + """Directory which contains few error free python source code files.""" + with tempfile.TemporaryDirectory() as tmp_dir: + with TemporaryPyFile(SOURCE_CODES["error_free"], directory=tmp_dir): + self.verify_tabnanny_check(tmp_dir) + + def test_when_wrong_indented(self): + """A python source code file eligible for raising `IndentationError`.""" + with TemporaryPyFile(SOURCE_CODES["wrong_indented"]) as file_path: + err = ('unindent does not match any outer indentation level' + ' (<tokenize>, line 3)\n') + err = f"{file_path!r}: Indentation Error: {err}" + self.verify_tabnanny_check(file_path, err=err) + + def test_when_tokenize_tokenerror(self): + """A python source code file eligible for raising 'tokenize.TokenError'.""" + with TemporaryPyFile(SOURCE_CODES["incomplete_expression"]) as file_path: + err = "('EOF in multi-line statement', (7, 0))\n" + err = f"{file_path!r}: Token Error: {err}" + self.verify_tabnanny_check(file_path, err=err) + + def test_when_nannynag_error_verbose(self): + """A python source code file eligible for raising `tabnanny.NannyNag`. + + Tests will assert `stdout` after activating `tabnanny.verbose` mode. + """ + with TemporaryPyFile(SOURCE_CODES["nannynag_errored"]) as file_path: + out = f"{file_path!r}: *** Line 3: trouble in tab city! ***\n" + out += "offending line: '\\tprint(\"world\")\\n'\n" + out += "indent not equal e.g. at tab size 1\n" + + tabnanny.verbose = 1 + self.verify_tabnanny_check(file_path, out=out) + + def test_when_nannynag_error(self): + """A python source code file eligible for raising `tabnanny.NannyNag`.""" + with TemporaryPyFile(SOURCE_CODES["nannynag_errored"]) as file_path: + out = f"{file_path} 3 '\\tprint(\"world\")\\n'\n" + self.verify_tabnanny_check(file_path, out=out) + + def test_when_no_file(self): + """A python file which does not exist actually in system.""" + path = 'no_file.py' + err = f"{path!r}: I/O Error: [Errno 2] No such file or directory: {path!r}\n" + self.verify_tabnanny_check(path, err=err) + + def test_errored_directory(self): + """Directory containing wrongly indented python source code files.""" + with tempfile.TemporaryDirectory() as tmp_dir: + error_file = TemporaryPyFile( + SOURCE_CODES["wrong_indented"], directory=tmp_dir + ) + code_file = TemporaryPyFile( + SOURCE_CODES["error_free"], directory=tmp_dir + ) + with error_file as e_file, code_file as c_file: + err = ('unindent does not match any outer indentation level' + ' (<tokenize>, line 3)\n') + err = f"{e_file!r}: Indentation Error: {err}" + self.verify_tabnanny_check(tmp_dir, err=err) + + +class TestProcessTokens(TestCase): + """Testing `tabnanny.process_tokens()`.""" + + @mock.patch('tabnanny.NannyNag') + def test_with_correct_code(self, MockNannyNag): + """A python source code without any whitespace related problems.""" + + with TemporaryPyFile(SOURCE_CODES["error_free"]) as file_path: + with open(file_path) as f: + tabnanny.process_tokens(tokenize.generate_tokens(f.readline)) + self.assertFalse(MockNannyNag.called) + + def test_with_errored_codes_samples(self): + """A python source code with whitespace related sampled problems.""" + + # "tab_space_errored_1": executes block under type == tokenize.INDENT + # at `tabnanny.process_tokens()`. + # "tab space_errored_2": executes block under + # `check_equal and type not in JUNK` condition at + # `tabnanny.process_tokens()`. + + for key in ["tab_space_errored_1", "tab_space_errored_2"]: + with self.subTest(key=key): + with TemporaryPyFile(SOURCE_CODES[key]) as file_path: + with open(file_path) as f: + tokens = tokenize.generate_tokens(f.readline) + with self.assertRaises(tabnanny.NannyNag): + tabnanny.process_tokens(tokens) + + +class TestCommandLine(TestCase): + """Tests command line interface of `tabnanny`.""" + + def validate_cmd(self, *args, stdout="", stderr="", partial=False): + """Common function to assert the behaviour of command line interface.""" + _, out, err = script_helper.assert_python_ok('-m', 'tabnanny', *args) + # Note: The `splitlines()` will solve the problem of CRLF(\r) added + # by OS Windows. + out = out.decode('ascii') + err = err.decode('ascii') + if partial: + for std, output in ((stdout, out), (stderr, err)): + _output = output.splitlines() + for _std in std.splitlines(): + with self.subTest(std=_std, output=_output): + self.assertIn(_std, _output) + else: + self.assertListEqual(out.splitlines(), stdout.splitlines()) + self.assertListEqual(err.splitlines(), stderr.splitlines()) + + def test_with_errored_file(self): + """Should displays error when errored python file is given.""" + with TemporaryPyFile(SOURCE_CODES["wrong_indented"]) as file_path: + stderr = f"{file_path!r}: Indentation Error: " + stderr += ('unindent does not match any outer indentation level' + ' (<tokenize>, line 3)') + self.validate_cmd(file_path, stderr=stderr) + + def test_with_error_free_file(self): + """Should not display anything if python file is correctly indented.""" + with TemporaryPyFile(SOURCE_CODES["error_free"]) as file_path: + self.validate_cmd(file_path) + + def test_command_usage(self): + """Should display usage on no arguments.""" + path = findfile('tabnanny.py') + stderr = f"Usage: {path} [-v] file_or_directory ..." + self.validate_cmd(stderr=stderr) + + def test_quiet_flag(self): + """Should display less when quite mode is on.""" + with TemporaryPyFile(SOURCE_CODES["nannynag_errored"]) as file_path: + stdout = f"{file_path}\n" + self.validate_cmd("-q", file_path, stdout=stdout) + + def test_verbose_mode(self): + """Should display more error information if verbose mode is on.""" + with TemporaryPyFile(SOURCE_CODES["nannynag_errored"]) as path: + stdout = textwrap.dedent( + "offending line: '\\tprint(\"world\")\\n'" + ).strip() + self.validate_cmd("-v", path, stdout=stdout, partial=True) + + def test_double_verbose_mode(self): + """Should display detailed error information if double verbose is on.""" + with TemporaryPyFile(SOURCE_CODES["nannynag_errored"]) as path: + stdout = textwrap.dedent( + "offending line: '\\tprint(\"world\")\\n'" + ).strip() + self.validate_cmd("-vv", path, stdout=stdout, partial=True) diff --git a/Lib/test/test_tcl.py b/Lib/test/test_tcl.py index db99b75eec6458..80f1668bcecab8 100644 --- a/Lib/test/test_tcl.py +++ b/Lib/test/test_tcl.py @@ -649,6 +649,43 @@ def test_splitdict(self): expected = {'a': (1, 2, 3), 'something': 'foo', 'status': ''} self.assertEqual(splitdict(tcl, arg), expected) + def test_join(self): + join = tkinter._join + tcl = self.interp.tk + def unpack(s): + return tcl.call('lindex', s, 0) + def check(value): + self.assertEqual(unpack(join([value])), value) + self.assertEqual(unpack(join([value, 0])), value) + self.assertEqual(unpack(unpack(join([[value]]))), value) + self.assertEqual(unpack(unpack(join([[value, 0]]))), value) + self.assertEqual(unpack(unpack(join([[value], 0]))), value) + self.assertEqual(unpack(unpack(join([[value, 0], 0]))), value) + check('') + check('spam') + check('sp am') + check('sp\tam') + check('sp\nam') + check(' \t\n') + check('{spam}') + check('{sp am}') + check('"spam"') + check('"sp am"') + check('{"spam"}') + check('"{spam}"') + check('sp\\am') + check('"sp\\am"') + check('"{}" "{}"') + check('"\\') + check('"{') + check('"}') + check('\n\\') + check('\n{') + check('\n}') + check('\\\n') + check('{\n') + check('}\n') + def test_new_tcl_obj(self): self.assertRaises(TypeError, _tkinter.Tcl_Obj) diff --git a/Lib/test/test_tempfile.py b/Lib/test/test_tempfile.py index 710756bde64c04..e5098d2eea6be1 100644 --- a/Lib/test/test_tempfile.py +++ b/Lib/test/test_tempfile.py @@ -1094,6 +1094,8 @@ def test_properties(self): f.newlines with self.assertRaises(AttributeError): f.encoding + with self.assertRaises(AttributeError): + f.errors f.write(b'x') self.assertTrue(f._rolled) @@ -1103,6 +1105,8 @@ def test_properties(self): f.newlines with self.assertRaises(AttributeError): f.encoding + with self.assertRaises(AttributeError): + f.errors def test_text_mode(self): # Creating a SpooledTemporaryFile with a text mode should produce @@ -1119,6 +1123,7 @@ def test_text_mode(self): self.assertIsNone(f.name) self.assertIsNone(f.newlines) self.assertIsNone(f.encoding) + self.assertIsNone(f.errors) f.write("xyzzy\n") f.seek(0) @@ -1132,10 +1137,12 @@ def test_text_mode(self): self.assertIsNotNone(f.name) self.assertEqual(f.newlines, os.linesep) self.assertIsNotNone(f.encoding) + self.assertIsNotNone(f.errors) def test_text_newline_and_encoding(self): f = tempfile.SpooledTemporaryFile(mode='w+', max_size=10, - newline='', encoding='utf-8') + newline='', encoding='utf-8', + errors='ignore') f.write("\u039B\r\n") f.seek(0) self.assertEqual(f.read(), "\u039B\r\n") @@ -1144,6 +1151,7 @@ def test_text_newline_and_encoding(self): self.assertIsNone(f.name) self.assertIsNone(f.newlines) self.assertIsNone(f.encoding) + self.assertIsNone(f.errors) f.write("\u039B" * 20 + "\r\n") f.seek(0) @@ -1153,6 +1161,7 @@ def test_text_newline_and_encoding(self): self.assertIsNotNone(f.name) self.assertIsNotNone(f.newlines) self.assertEqual(f.encoding, 'utf-8') + self.assertEqual(f.errors, 'ignore') def test_context_manager_before_rollover(self): # A SpooledTemporaryFile can be used as a context manager diff --git a/Lib/test/test_tokenize.py b/Lib/test/test_tokenize.py index 3520a67bd42b11..f68580ccfb7c63 100644 --- a/Lib/test/test_tokenize.py +++ b/Lib/test/test_tokenize.py @@ -1,8 +1,9 @@ from test import support from tokenize import (tokenize, _tokenize, untokenize, NUMBER, NAME, OP, STRING, ENDMARKER, ENCODING, tok_name, detect_encoding, - open as tokenize_open, Untokenizer) -from io import BytesIO + open as tokenize_open, Untokenizer, generate_tokens, + NEWLINE) +from io import BytesIO, StringIO import unittest from unittest import TestCase, mock from test.test_grammar import (VALID_UNDERSCORE_LITERALS, @@ -11,27 +12,51 @@ import token +# Converts a source string into a list of textual representation +# of the tokens such as: +# ` NAME 'if' (1, 0) (1, 2)` +# to make writing tests easier. +def stringify_tokens_from_source(token_generator, source_string): + result = [] + num_lines = len(source_string.splitlines()) + missing_trailing_nl = source_string[-1] not in '\r\n' + + for type, token, start, end, line in token_generator: + if type == ENDMARKER: + break + # Ignore the new line on the last line if the input lacks one + if missing_trailing_nl and type == NEWLINE and end[0] == num_lines: + continue + type = tok_name[type] + result.append(f" {type:10} {token!r:13} {start} {end}") + + return result + class TokenizeTest(TestCase): # 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 ENDMARKER is omitted for - # brevity. + # code, print out a table with tokens. The ENDMARKER, ENCODING and + # final NEWLINE are omitted for brevity. def check_tokenize(self, s, expected): # Format the tokens in s in a table format. - # The ENDMARKER is omitted. - result = [] + # The ENDMARKER and final NEWLINE are omitted. f = BytesIO(s.encode('utf-8')) - for type, token, start, end, line in tokenize(f.readline): - if type == ENDMARKER: - break - type = tok_name[type] - result.append(f" {type:10} {token!r:13} {start} {end}") + result = stringify_tokens_from_source(tokenize(f.readline), s) + self.assertEqual(result, [" ENCODING 'utf-8' (0, 0) (0, 0)"] + expected.rstrip().splitlines()) + def test_implicit_newline(self): + # Make sure that the tokenizer puts in an implicit NEWLINE + # when the input lacks a trailing new line. + f = BytesIO("x".encode('utf-8')) + tokens = list(tokenize(f.readline)) + self.assertEqual(tokens[-2].type, NEWLINE) + self.assertEqual(tokens[-1].type, ENDMARKER) + def test_basic(self): self.check_tokenize("1 + 1", """\ NUMBER '1' (1, 0) (1, 1) @@ -919,6 +944,14 @@ async def bar(): pass DEDENT '' (7, 0) (7, 0) """) +class GenerateTokensTest(TokenizeTest): + def check_tokenize(self, s, expected): + # Format the tokens in s in a table format. + # The ENDMARKER and final NEWLINE are omitted. + f = StringIO(s) + result = stringify_tokens_from_source(generate_tokens(f.readline), s) + self.assertEqual(result, expected.rstrip().splitlines()) + def decistmt(s): result = [] @@ -1009,8 +1042,8 @@ def readline(): else: return b'' - # skip the initial encoding token and the end token - tokens = list(_tokenize(readline, encoding='utf-8'))[1:-1] + # skip the initial encoding token and the end tokens + tokens = list(_tokenize(readline, encoding='utf-8'))[1:-2] expected_tokens = [(3, '"ЉЊЈЁЂ"', (1, 0), (1, 7), '"ЉЊЈЁЂ"')] self.assertEqual(tokens, expected_tokens, "bytes not decoded with encoding") @@ -1026,8 +1059,8 @@ def readline(): else: return b'' - # skip the end token - tokens = list(_tokenize(readline, encoding=None))[:-1] + # skip the end tokens + tokens = list(_tokenize(readline, encoding=None))[:-2] expected_tokens = [(3, '"ЉЊЈЁЂ"', (1, 0), (1, 7), '"ЉЊЈЁЂ"')] self.assertEqual(tokens, expected_tokens, "string not tokenized when encoding is None") @@ -1338,18 +1371,21 @@ def test_oneline_defs(self): # Test that 500 consequent, one-line defs is OK toks = list(tokenize(BytesIO(buf.encode('utf-8')).readline)) - self.assertEqual(toks[-2].string, 'OK') # [-1] is always ENDMARKER + self.assertEqual(toks[-3].string, 'OK') # [-1] is always ENDMARKER + # [-2] is always NEWLINE def assertExactTypeEqual(self, opstr, *optypes): tokens = list(tokenize(BytesIO(opstr.encode('utf-8')).readline)) num_optypes = len(optypes) - self.assertEqual(len(tokens), 2 + num_optypes) + self.assertEqual(len(tokens), 3 + num_optypes) self.assertEqual(tok_name[tokens[0].exact_type], tok_name[ENCODING]) for i in range(num_optypes): self.assertEqual(tok_name[tokens[i + 1].exact_type], tok_name[optypes[i]]) self.assertEqual(tok_name[tokens[1 + num_optypes].exact_type], + tok_name[token.NEWLINE]) + self.assertEqual(tok_name[tokens[2 + num_optypes].exact_type], tok_name[token.ENDMARKER]) def test_exact_type(self): @@ -1502,7 +1538,7 @@ def test_roundtrip(self): self.check_roundtrip("if x == 1:\n" " print(x)\n") self.check_roundtrip("# This is a comment\n" - "# This also") + "# This also\n") # Some people use different formatting conventions, which makes # untokenize a little trickier. Note that this test involves trailing diff --git a/Lib/test/test_unicodedata.py b/Lib/test/test_unicodedata.py index 99dd0dec9d11d6..170778fa977db1 100644 --- a/Lib/test/test_unicodedata.py +++ b/Lib/test/test_unicodedata.py @@ -208,6 +208,19 @@ def test_issue10254(self): b = 'C\u0338' * 20 + '\xC7' self.assertEqual(self.db.normalize('NFC', a), b) + def test_issue29456(self): + # Fix #29456 + u1176_str_a = '\u1100\u1176\u11a8' + u1176_str_b = '\u1100\u1176\u11a8' + u11a7_str_a = '\u1100\u1175\u11a7' + u11a7_str_b = '\uae30\u11a7' + u11c3_str_a = '\u1100\u1175\u11c3' + u11c3_str_b = '\uae30\u11c3' + self.assertEqual(self.db.normalize('NFC', u1176_str_a), u1176_str_b) + self.assertEqual(self.db.normalize('NFC', u11a7_str_a), u11a7_str_b) + self.assertEqual(self.db.normalize('NFC', u11c3_str_a), u11c3_str_b) + + def test_east_asian_width(self): eaw = self.db.east_asian_width self.assertRaises(TypeError, eaw, b'a') diff --git a/Lib/test/test_urlparse.py b/Lib/test/test_urlparse.py index ddee1c38d8b4f0..cd3eabb5606b22 100644 --- a/Lib/test/test_urlparse.py +++ b/Lib/test/test_urlparse.py @@ -1,5 +1,6 @@ import unittest import urllib.parse +import warnings RFC1808_BASE = "http://a/b/c/d;p?q#f" RFC2396_BASE = "http://a/b/c/d;p?q" @@ -936,6 +937,16 @@ def test_issue14072(self): self.assertEqual(p2.scheme, 'tel') self.assertEqual(p2.path, '+31641044153') + def test_port_casting_failure_message(self): + message = "Port could not be cast to integer value as 'oracle'" + p1 = urllib.parse.urlparse('http://Server=sde; Service=sde:oracle') + with self.assertRaisesRegex(ValueError, message): + p1.port + + p2 = urllib.parse.urlsplit('http://Server=sde; Service=sde:oracle') + with self.assertRaisesRegex(ValueError, message): + p2.port + def test_telurl_params(self): p1 = urllib.parse.urlparse('tel:123-4;phone-context=+1-650-516') self.assertEqual(p1.scheme, 'tel') @@ -983,7 +994,7 @@ class Utility_Tests(unittest.TestCase): # In Python 2 this test class was in test_urllib. def test_splittype(self): - splittype = urllib.parse.splittype + splittype = urllib.parse._splittype self.assertEqual(splittype('type:opaquestring'), ('type', 'opaquestring')) self.assertEqual(splittype('opaquestring'), (None, 'opaquestring')) self.assertEqual(splittype(':opaquestring'), (None, ':opaquestring')) @@ -991,7 +1002,7 @@ def test_splittype(self): self.assertEqual(splittype('type:opaque:string'), ('type', 'opaque:string')) def test_splithost(self): - splithost = urllib.parse.splithost + splithost = urllib.parse._splithost self.assertEqual(splithost('//www.example.org:80/foo/bar/baz.html'), ('www.example.org:80', '/foo/bar/baz.html')) self.assertEqual(splithost('//www.example.org:80'), @@ -1020,7 +1031,7 @@ def test_splithost(self): ('example.net', '/file#')) def test_splituser(self): - splituser = urllib.parse.splituser + splituser = urllib.parse._splituser self.assertEqual(splituser('User:Pass@www.python.org:080'), ('User:Pass', 'www.python.org:080')) self.assertEqual(splituser('@www.python.org:080'), @@ -1035,7 +1046,7 @@ def test_splituser(self): def test_splitpasswd(self): # Some of the password examples are not sensible, but it is added to # confirming to RFC2617 and addressing issue4675. - splitpasswd = urllib.parse.splitpasswd + splitpasswd = urllib.parse._splitpasswd self.assertEqual(splitpasswd('user:ab'), ('user', 'ab')) self.assertEqual(splitpasswd('user:a\nb'), ('user', 'a\nb')) self.assertEqual(splitpasswd('user:a\tb'), ('user', 'a\tb')) @@ -1051,7 +1062,7 @@ def test_splitpasswd(self): self.assertEqual(splitpasswd(':ab'), ('', 'ab')) def test_splitport(self): - splitport = urllib.parse.splitport + splitport = urllib.parse._splitport self.assertEqual(splitport('parrot:88'), ('parrot', '88')) self.assertEqual(splitport('parrot'), ('parrot', None)) self.assertEqual(splitport('parrot:'), ('parrot', None)) @@ -1062,7 +1073,7 @@ def test_splitport(self): self.assertEqual(splitport(':88'), ('', '88')) def test_splitnport(self): - splitnport = urllib.parse.splitnport + splitnport = urllib.parse._splitnport self.assertEqual(splitnport('parrot:88'), ('parrot', 88)) self.assertEqual(splitnport('parrot'), ('parrot', -1)) self.assertEqual(splitnport('parrot', 55), ('parrot', 55)) @@ -1076,7 +1087,7 @@ def test_splitnport(self): def test_splitquery(self): # Normal cases are exercised by other tests; ensure that we also # catch cases with no port specified (testcase ensuring coverage) - splitquery = urllib.parse.splitquery + splitquery = urllib.parse._splitquery self.assertEqual(splitquery('http://python.org/fake?foo=bar'), ('http://python.org/fake', 'foo=bar')) self.assertEqual(splitquery('http://python.org/fake?foo=bar?'), @@ -1086,7 +1097,7 @@ def test_splitquery(self): self.assertEqual(splitquery('?foo=bar'), ('', 'foo=bar')) def test_splittag(self): - splittag = urllib.parse.splittag + splittag = urllib.parse._splittag self.assertEqual(splittag('http://example.com?foo=bar#baz'), ('http://example.com?foo=bar', 'baz')) self.assertEqual(splittag('http://example.com?foo=bar#'), @@ -1098,7 +1109,7 @@ def test_splittag(self): ('http://example.com?foo=bar#baz', 'boo')) def test_splitattr(self): - splitattr = urllib.parse.splitattr + splitattr = urllib.parse._splitattr self.assertEqual(splitattr('/path;attr1=value1;attr2=value2'), ('/path', ['attr1=value1', 'attr2=value2'])) self.assertEqual(splitattr('/path;'), ('/path', [''])) @@ -1109,7 +1120,7 @@ def test_splitattr(self): def test_splitvalue(self): # Normal cases are exercised by other tests; test pathological cases # with no key/value pairs. (testcase ensuring coverage) - splitvalue = urllib.parse.splitvalue + splitvalue = urllib.parse._splitvalue self.assertEqual(splitvalue('foo=bar'), ('foo', 'bar')) self.assertEqual(splitvalue('foo='), ('foo', '')) self.assertEqual(splitvalue('=bar'), ('', 'bar')) @@ -1117,15 +1128,100 @@ def test_splitvalue(self): self.assertEqual(splitvalue('foo=bar=baz'), ('foo', 'bar=baz')) def test_to_bytes(self): - result = urllib.parse.to_bytes('http://www.python.org') + result = urllib.parse._to_bytes('http://www.python.org') self.assertEqual(result, 'http://www.python.org') - self.assertRaises(UnicodeError, urllib.parse.to_bytes, + self.assertRaises(UnicodeError, urllib.parse._to_bytes, 'http://www.python.org/medi\u00e6val') def test_unwrap(self): - url = urllib.parse.unwrap('<URL:type://host/path>') + url = urllib.parse._unwrap('<URL:type://host/path>') self.assertEqual(url, 'type://host/path') +class DeprecationTest(unittest.TestCase): + + def test_splittype_deprecation(self): + with self.assertWarns(DeprecationWarning) as cm: + urllib.parse.splittype('') + self.assertEqual(str(cm.warning), + 'urllib.parse.splittype() is deprecated as of 3.8, ' + 'use urllib.parse.urlparse() instead') + + def test_splithost_deprecation(self): + with self.assertWarns(DeprecationWarning) as cm: + urllib.parse.splithost('') + self.assertEqual(str(cm.warning), + 'urllib.parse.splithost() is deprecated as of 3.8, ' + 'use urllib.parse.urlparse() instead') + + def test_splituser_deprecation(self): + with self.assertWarns(DeprecationWarning) as cm: + urllib.parse.splituser('') + self.assertEqual(str(cm.warning), + 'urllib.parse.splituser() is deprecated as of 3.8, ' + 'use urllib.parse.urlparse() instead') + + def test_splitpasswd_deprecation(self): + with self.assertWarns(DeprecationWarning) as cm: + urllib.parse.splitpasswd('') + self.assertEqual(str(cm.warning), + 'urllib.parse.splitpasswd() is deprecated as of 3.8, ' + 'use urllib.parse.urlparse() instead') + + def test_splitport_deprecation(self): + with self.assertWarns(DeprecationWarning) as cm: + urllib.parse.splitport('') + self.assertEqual(str(cm.warning), + 'urllib.parse.splitport() is deprecated as of 3.8, ' + 'use urllib.parse.urlparse() instead') + + def test_splitnport_deprecation(self): + with self.assertWarns(DeprecationWarning) as cm: + urllib.parse.splitnport('') + self.assertEqual(str(cm.warning), + 'urllib.parse.splitnport() is deprecated as of 3.8, ' + 'use urllib.parse.urlparse() instead') + + def test_splitquery_deprecation(self): + with self.assertWarns(DeprecationWarning) as cm: + urllib.parse.splitquery('') + self.assertEqual(str(cm.warning), + 'urllib.parse.splitquery() is deprecated as of 3.8, ' + 'use urllib.parse.urlparse() instead') + + def test_splittag_deprecation(self): + with self.assertWarns(DeprecationWarning) as cm: + urllib.parse.splittag('') + self.assertEqual(str(cm.warning), + 'urllib.parse.splittag() is deprecated as of 3.8, ' + 'use urllib.parse.urlparse() instead') + + def test_splitattr_deprecation(self): + with self.assertWarns(DeprecationWarning) as cm: + urllib.parse.splitattr('') + self.assertEqual(str(cm.warning), + 'urllib.parse.splitattr() is deprecated as of 3.8, ' + 'use urllib.parse.urlparse() instead') + + def test_splitvalue_deprecation(self): + with self.assertWarns(DeprecationWarning) as cm: + urllib.parse.splitvalue('') + self.assertEqual(str(cm.warning), + 'urllib.parse.splitvalue() is deprecated as of 3.8, ' + 'use urllib.parse.parse_qsl() instead') + + def test_to_bytes_deprecation(self): + with self.assertWarns(DeprecationWarning) as cm: + urllib.parse.to_bytes('') + self.assertEqual(str(cm.warning), + 'urllib.parse.to_bytes() is deprecated as of 3.8') + + def test_unwrap(self): + with self.assertWarns(DeprecationWarning) as cm: + urllib.parse.unwrap('') + self.assertEqual(str(cm.warning), + 'urllib.parse.unwrap() is deprecated as of 3.8') + + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_warnings/__init__.py b/Lib/test/test_warnings/__init__.py index b48debd31fa841..87f929f3147885 100644 --- a/Lib/test/test_warnings/__init__.py +++ b/Lib/test/test_warnings/__init__.py @@ -441,78 +441,15 @@ def test_stacklevel_import(self): self.assertEqual(len(w), 1) self.assertEqual(w[0].filename, __file__) - def test_missing_filename_not_main(self): - # If __file__ is not specified and __main__ is not the module name, - # then __file__ should be set to the module name. - filename = warning_tests.__file__ - try: - del warning_tests.__file__ - with warnings_state(self.module): - with original_warnings.catch_warnings(record=True, - module=self.module) as w: - warning_tests.inner("spam8", stacklevel=1) - self.assertEqual(w[-1].filename, warning_tests.__name__) - finally: - warning_tests.__file__ = filename - - @unittest.skipUnless(hasattr(sys, 'argv'), 'test needs sys.argv') - def test_missing_filename_main_with_argv(self): - # If __file__ is not specified and the caller is __main__ and sys.argv - # exists, then use sys.argv[0] as the file. - filename = warning_tests.__file__ - module_name = warning_tests.__name__ - try: - del warning_tests.__file__ - warning_tests.__name__ = '__main__' - with warnings_state(self.module): - with original_warnings.catch_warnings(record=True, - module=self.module) as w: - warning_tests.inner('spam9', stacklevel=1) - self.assertEqual(w[-1].filename, sys.argv[0]) - finally: - warning_tests.__file__ = filename - warning_tests.__name__ = module_name - - def test_missing_filename_main_without_argv(self): - # If __file__ is not specified, the caller is __main__, and sys.argv - # is not set, then '__main__' is the file name. - filename = warning_tests.__file__ - module_name = warning_tests.__name__ - argv = sys.argv - try: - del warning_tests.__file__ - warning_tests.__name__ = '__main__' - del sys.argv - with warnings_state(self.module): - with original_warnings.catch_warnings(record=True, - module=self.module) as w: - warning_tests.inner('spam10', stacklevel=1) - self.assertEqual(w[-1].filename, '__main__') - finally: - warning_tests.__file__ = filename - warning_tests.__name__ = module_name - sys.argv = argv - - def test_missing_filename_main_with_argv_empty_string(self): - # If __file__ is not specified, the caller is __main__, and sys.argv[0] - # is the empty string, then '__main__ is the file name. - # Tests issue 2743. - file_name = warning_tests.__file__ - module_name = warning_tests.__name__ - argv = sys.argv - try: - del warning_tests.__file__ - warning_tests.__name__ = '__main__' - sys.argv = [''] - with warnings_state(self.module): - with original_warnings.catch_warnings(record=True, - module=self.module) as w: - warning_tests.inner('spam11', stacklevel=1) - self.assertEqual(w[-1].filename, '__main__') - finally: - warning_tests.__file__ = file_name - warning_tests.__name__ = module_name - sys.argv = argv + def test_exec_filename(self): + filename = "<warnings-test>" + codeobj = compile(("import warnings\n" + "warnings.warn('hello', UserWarning)"), + filename, "exec") + with original_warnings.catch_warnings(record=True) as w: + self.module.simplefilter("always", category=UserWarning) + exec(codeobj) + self.assertEqual(w[0].filename, filename) def test_warn_explicit_non_ascii_filename(self): with original_warnings.catch_warnings(record=True, @@ -1245,9 +1182,7 @@ def __del__(self): a=A() """ rc, out, err = assert_python_ok("-c", code) - # note: "__main__" filename is not correct, it should be the name - # of the script - self.assertEqual(err.decode(), '__main__:7: UserWarning: test') + self.assertEqual(err.decode(), '<string>:7: UserWarning: test') def test_late_resource_warning(self): # Issue #21925: Emitting a ResourceWarning late during the Python diff --git a/Lib/test/test_webbrowser.py b/Lib/test/test_webbrowser.py index 0820b9123125a3..71f2e27467eef0 100644 --- a/Lib/test/test_webbrowser.py +++ b/Lib/test/test_webbrowser.py @@ -1,5 +1,7 @@ import webbrowser import unittest +import os +import sys import subprocess from unittest import mock from test import support @@ -170,23 +172,23 @@ class OperaCommandTest(CommandTestMixin, unittest.TestCase): def test_open(self): self._test('open', - options=['-remote'], - arguments=['openURL({})'.format(URL)]) + options=[], + arguments=[URL]) def test_open_with_autoraise_false(self): self._test('open', kw=dict(autoraise=False), - options=['-remote', '-noraise'], - arguments=['openURL({})'.format(URL)]) + options=[], + arguments=[URL]) def test_open_new(self): self._test('open_new', - options=['-remote'], - arguments=['openURL({},new-window)'.format(URL)]) + options=['--new-window'], + arguments=[URL]) def test_open_new_tab(self): self._test('open_new_tab', - options=['-remote'], - arguments=['openURL({},new-page)'.format(URL)]) + options=[], + arguments=[URL]) class ELinksCommandTest(CommandTestMixin, unittest.TestCase): @@ -290,6 +292,23 @@ def test_get(self): webbrowser.get('fakebrowser') self.assertIsNotNone(webbrowser._tryorder) + def test_synthesize(self): + webbrowser = support.import_fresh_module('webbrowser') + name = os.path.basename(sys.executable).lower() + webbrowser.register(name, None, webbrowser.GenericBrowser(name)) + webbrowser.get(sys.executable) + + def test_environment(self): + webbrowser = support.import_fresh_module('webbrowser') + try: + browser = webbrowser.get().name + except (webbrowser.Error, AttributeError) as err: + self.skipTest(str(err)) + with support.EnvironmentVarGuard() as env: + env["BROWSER"] = browser + webbrowser = support.import_fresh_module('webbrowser') + webbrowser.get() + if __name__=='__main__': unittest.main() diff --git a/Lib/test/test_zlib.py b/Lib/test/test_zlib.py index 99aa89bdc8c92b..4871d60d756c03 100644 --- a/Lib/test/test_zlib.py +++ b/Lib/test/test_zlib.py @@ -1,6 +1,7 @@ import unittest from test import support import binascii +import copy import pickle import random import sys @@ -626,23 +627,24 @@ def test_compresscopy(self): # Test copying a compression object data0 = HAMLET_SCENE data1 = bytes(str(HAMLET_SCENE, "ascii").swapcase(), "ascii") - c0 = zlib.compressobj(zlib.Z_BEST_COMPRESSION) - bufs0 = [] - bufs0.append(c0.compress(data0)) + for func in lambda c: c.copy(), copy.copy, copy.deepcopy: + c0 = zlib.compressobj(zlib.Z_BEST_COMPRESSION) + bufs0 = [] + bufs0.append(c0.compress(data0)) - c1 = c0.copy() - bufs1 = bufs0[:] + c1 = func(c0) + bufs1 = bufs0[:] - bufs0.append(c0.compress(data0)) - bufs0.append(c0.flush()) - s0 = b''.join(bufs0) + bufs0.append(c0.compress(data0)) + bufs0.append(c0.flush()) + s0 = b''.join(bufs0) - bufs1.append(c1.compress(data1)) - bufs1.append(c1.flush()) - s1 = b''.join(bufs1) + bufs1.append(c1.compress(data1)) + bufs1.append(c1.flush()) + s1 = b''.join(bufs1) - self.assertEqual(zlib.decompress(s0),data0+data0) - self.assertEqual(zlib.decompress(s1),data0+data1) + self.assertEqual(zlib.decompress(s0),data0+data0) + self.assertEqual(zlib.decompress(s1),data0+data1) @requires_Compress_copy def test_badcompresscopy(self): @@ -651,6 +653,8 @@ def test_badcompresscopy(self): c.compress(HAMLET_SCENE) c.flush() self.assertRaises(ValueError, c.copy) + self.assertRaises(ValueError, copy.copy, c) + self.assertRaises(ValueError, copy.deepcopy, c) @requires_Decompress_copy def test_decompresscopy(self): @@ -660,21 +664,22 @@ def test_decompresscopy(self): # Test type of return value self.assertIsInstance(comp, bytes) - d0 = zlib.decompressobj() - bufs0 = [] - bufs0.append(d0.decompress(comp[:32])) + for func in lambda c: c.copy(), copy.copy, copy.deepcopy: + d0 = zlib.decompressobj() + bufs0 = [] + bufs0.append(d0.decompress(comp[:32])) - d1 = d0.copy() - bufs1 = bufs0[:] + d1 = func(d0) + bufs1 = bufs0[:] - bufs0.append(d0.decompress(comp[32:])) - s0 = b''.join(bufs0) + bufs0.append(d0.decompress(comp[32:])) + s0 = b''.join(bufs0) - bufs1.append(d1.decompress(comp[32:])) - s1 = b''.join(bufs1) + bufs1.append(d1.decompress(comp[32:])) + s1 = b''.join(bufs1) - self.assertEqual(s0,s1) - self.assertEqual(s0,data) + self.assertEqual(s0,s1) + self.assertEqual(s0,data) @requires_Decompress_copy def test_baddecompresscopy(self): @@ -684,6 +689,8 @@ def test_baddecompresscopy(self): d.decompress(data) d.flush() self.assertRaises(ValueError, d.copy) + self.assertRaises(ValueError, copy.copy, d) + self.assertRaises(ValueError, copy.deepcopy, d) def test_compresspickle(self): for proto in range(pickle.HIGHEST_PROTOCOL + 1): diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index b78191e2777f45..ff85f837d1d594 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -61,7 +61,7 @@ def _stringify(value): if isinstance(value, (list, tuple)): if len(value) == 1: value = _stringify(value[0]) - if value[0] == '{': + if _magic_re.search(value): value = '{%s}' % value else: value = '{%s}' % _join(value) @@ -72,7 +72,10 @@ def _stringify(value): elif _magic_re.search(value): # add '\' before special characters and spaces value = _magic_re.sub(r'\\\1', value) + value = value.replace('\n', r'\n') value = _space_re.sub(r'\\\1', value) + if value[0] == '"': + value = '\\' + value elif value[0] == '"' or _space_re.search(value): value = '{%s}' % value return value diff --git a/Lib/tkinter/test/test_ttk/test_widgets.py b/Lib/tkinter/test/test_ttk/test_widgets.py index 06e3dfe70d5dc3..5b0e29cdccaf4f 100644 --- a/Lib/tkinter/test/test_ttk/test_widgets.py +++ b/Lib/tkinter/test/test_ttk/test_widgets.py @@ -1742,27 +1742,6 @@ def test_selection(self): self.tv.selection_toggle((c1, c3)) self.assertEqual(self.tv.selection(), (c3, item2)) - if sys.version_info >= (3, 8): - import warnings - warnings.warn( - 'Deprecated API of Treeview.selection() should be removed') - self.tv.selection_set() - self.assertEqual(self.tv.selection(), ()) - with self.assertWarns(DeprecationWarning): - self.tv.selection('set', (c1, item2)) - self.assertEqual(self.tv.selection(), (c1, item2)) - with self.assertWarns(DeprecationWarning): - self.tv.selection('add', (c1, item1)) - self.assertEqual(self.tv.selection(), (item1, c1, item2)) - with self.assertWarns(DeprecationWarning): - self.tv.selection('remove', (item1, c3)) - self.assertEqual(self.tv.selection(), (c1, item2)) - with self.assertWarns(DeprecationWarning): - self.tv.selection('toggle', (c1, c3)) - self.assertEqual(self.tv.selection(), (c3, item2)) - with self.assertWarns(DeprecationWarning): - selection = self.tv.selection(None) - self.assertEqual(selection, (c3, item2)) def test_set(self): self.tv['columns'] = ['A', 'B'] diff --git a/Lib/tkinter/ttk.py b/Lib/tkinter/ttk.py index 12f4ac0bd9086b..573544dd84a390 100644 --- a/Lib/tkinter/ttk.py +++ b/Lib/tkinter/ttk.py @@ -28,8 +28,6 @@ import tkinter from tkinter import _flatten, _join, _stringify, _splitdict -_sentinel = object() - # Verify if Tk is new enough to not need the Tile package _REQUIRE_TILE = True if tkinter.TkVersion < 8.5 else False @@ -1423,26 +1421,9 @@ def see(self, item): self.tk.call(self._w, "see", item) - def selection(self, selop=_sentinel, items=None): + def selection(self): """Returns the tuple of selected items.""" - if selop is _sentinel: - selop = None - elif selop is None: - import warnings - warnings.warn( - "The selop=None argument of selection() is deprecated " - "and will be removed in Python 3.8", - DeprecationWarning, 3) - elif selop in ('set', 'add', 'remove', 'toggle'): - import warnings - warnings.warn( - "The selop argument of selection() is deprecated " - "and will be removed in Python 3.8, " - "use selection_%s() instead" % (selop,), - DeprecationWarning, 3) - else: - raise TypeError('Unsupported operation') - return self.tk.splitlist(self.tk.call(self._w, "selection", selop, items)) + return self.tk.splitlist(self.tk.call(self._w, "selection")) def _selection(self, selop, items): diff --git a/Lib/tokenize.py b/Lib/tokenize.py index 6528b900612863..fce010bc5e7aa7 100644 --- a/Lib/tokenize.py +++ b/Lib/tokenize.py @@ -28,7 +28,6 @@ from codecs import lookup, BOM_UTF8 import collections from io import TextIOWrapper -from itertools import chain import itertools as _itertools import re import sys @@ -38,7 +37,7 @@ blank_re = re.compile(br'^[ \t\f]*(?:[#\r\n]|$)', re.ASCII) import token -__all__ = token.__all__ + ["tokenize", "detect_encoding", +__all__ = token.__all__ + ["tokenize", "generate_tokens", "detect_encoding", "untokenize", "TokenInfo"] del token @@ -278,7 +277,7 @@ def compat(self, token, iterable): startline = token[0] in (NEWLINE, NL) prevstring = False - for tok in chain([token], iterable): + for tok in _itertools.chain([token], iterable): toknum, tokval = tok[:2] if toknum == ENCODING: self.encoding = tokval @@ -475,13 +474,10 @@ def tokenize(readline): The first token sequence will always be an ENCODING token which tells you which encoding was used to decode the bytes stream. """ - # This import is here to avoid problems when the itertools module is not - # built yet and tokenize is imported. - from itertools import chain, repeat encoding, consumed = detect_encoding(readline) - rl_gen = iter(readline, b"") - empty = repeat(b"") - return _tokenize(chain(consumed, rl_gen, empty).__next__, encoding) + empty = _itertools.repeat(b"") + rl_gen = _itertools.chain(consumed, iter(readline, b""), empty) + return _tokenize(rl_gen.__next__, encoding) def _tokenize(readline, encoding): @@ -496,8 +492,15 @@ def _tokenize(readline, encoding): # BOM will already have been stripped. encoding = "utf-8" yield TokenInfo(ENCODING, encoding, (0, 0), (0, 0), '') - while True: # loop over lines in stream + last_line = b'' + line = b'' + while True: # loop over lines in stream try: + # We capture the value of the line variable here because + # readline uses the empty string '' to signal end of input, + # hence `line` itself will always be overwritten at the end + # of this loop. + last_line = line line = readline() except StopIteration: line = b'' @@ -581,7 +584,7 @@ def _tokenize(readline, encoding): continue token, initial = line[start:end], line[start] - if (initial in numchars or # ordinary number + if (initial in numchars or # ordinary number (initial == '.' and token != '.' and token != '...')): yield TokenInfo(NUMBER, token, spos, epos, line) elif initial in '\r\n': @@ -652,14 +655,20 @@ def _tokenize(readline, encoding): (lnum, pos), (lnum, pos+1), line) pos += 1 + # Add an implicit NEWLINE if the input doesn't end in one + if last_line and last_line[-1] not in '\r\n': + yield TokenInfo(NEWLINE, '', (lnum - 1, len(last_line)), (lnum - 1, len(last_line) + 1), '') for indent in indents[1:]: # pop remaining indent levels yield TokenInfo(DEDENT, '', (lnum, 0), (lnum, 0), '') yield TokenInfo(ENDMARKER, '', (lnum, 0), (lnum, 0), '') -# An undocumented, backwards compatible, API for all the places in the standard -# library that expect to be able to use tokenize with strings def generate_tokens(readline): + """Tokenize a source reading Python code as unicode strings. + + This has the same API as tokenize(), except that it expects the *readline* + callable to return str objects instead of bytes. + """ return _tokenize(readline, None) def main(): @@ -667,7 +676,8 @@ def main(): # Helper error handling routines def perror(message): - print(message, file=sys.stderr) + sys.stderr.write(message) + sys.stderr.write('\n') def error(message, filename=None, location=None): if location: diff --git a/Lib/turtledemo/penrose.py b/Lib/turtledemo/penrose.py index b2a5813938abfb..e118d6a75e99e4 100755 --- a/Lib/turtledemo/penrose.py +++ b/Lib/turtledemo/penrose.py @@ -144,9 +144,6 @@ def test(l=200, n=4, fun=sun, startpos=(0,0), th=2): draw(l, n, th) tracer(1) c = clock() - print("Calculation: %7.4f s" % (b - a)) - print("Drawing: %7.4f s" % (c - b)) - print("Together: %7.4f s" % (c - a)) nk = len([x for x in tiledict if tiledict[x]]) nd = len([x for x in tiledict if not tiledict[x]]) print("%d kites and %d darts = %d pieces." % (nk, nd, nk+nd)) diff --git a/Lib/turtledemo/wikipedia.py b/Lib/turtledemo/rosette.py similarity index 100% rename from Lib/turtledemo/wikipedia.py rename to Lib/turtledemo/rosette.py diff --git a/Lib/turtledemo/tree.py b/Lib/turtledemo/tree.py index 9998fa839ce1ce..98a20da7f15c11 100755 --- a/Lib/turtledemo/tree.py +++ b/Lib/turtledemo/tree.py @@ -49,7 +49,6 @@ def maketree(): t = tree([p], 200, 65, 0.6375) for x in t: pass - print(len(p.getscreen().turtles())) def main(): a=clock() diff --git a/Lib/typing.py b/Lib/typing.py index a95eb2e184a0f4..48992633ac349d 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -509,7 +509,7 @@ def longest(x: A, y: A) -> A: At runtime, isinstance(x, T) and issubclass(C, T) will raise TypeError. Type variables defined with covariant=True or contravariant=True - can be used do declare covariant or contravariant generic types. + can be used to declare covariant or contravariant generic types. See PEP 484 for more details. By default generic types are invariant in all type variables. diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index 382696d6c7e9c6..19dabddc7dfcc4 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -1709,7 +1709,7 @@ def _patch_stopall(): # because there is no idivmod "divmod rdivmod neg pos abs invert " "complex int float index " - "trunc floor ceil " + "round trunc floor ceil " "bool next " ) diff --git a/Lib/unittest/test/test_break.py b/Lib/unittest/test/test_break.py index aa2c69eea01ac6..eebd2b610ce11f 100644 --- a/Lib/unittest/test/test_break.py +++ b/Lib/unittest/test/test_break.py @@ -39,16 +39,13 @@ def testInstallHandler(self): def testRegisterResult(self): result = unittest.TestResult() - unittest.registerResult(result) - - for ref in unittest.signals._results: - if ref is result: - break - elif ref is not result: - self.fail("odd object in result set") - else: - self.fail("result not found") + self.assertNotIn(result, unittest.signals._results) + unittest.registerResult(result) + try: + self.assertIn(result, unittest.signals._results) + finally: + unittest.removeResult(result) def testInterruptCaught(self): default_handler = signal.getsignal(signal.SIGINT) diff --git a/Lib/unittest/test/testmock/testmagicmethods.py b/Lib/unittest/test/testmock/testmagicmethods.py index 37623dcebc6c3a..5ab95978f60db2 100644 --- a/Lib/unittest/test/testmock/testmagicmethods.py +++ b/Lib/unittest/test/testmock/testmagicmethods.py @@ -1,3 +1,4 @@ +import math import unittest import sys from unittest.mock import Mock, MagicMock, _magics @@ -280,6 +281,10 @@ def test_magicmock_defaults(self): self.assertEqual(hash(mock), object.__hash__(mock)) self.assertEqual(str(mock), object.__str__(mock)) self.assertTrue(bool(mock)) + self.assertEqual(round(mock), mock.__round__()) + self.assertEqual(math.trunc(mock), mock.__trunc__()) + self.assertEqual(math.floor(mock), mock.__floor__()) + self.assertEqual(math.ceil(mock), mock.__ceil__()) # in Python 3 oct and hex use __index__ # so these tests are for __index__ in py3k diff --git a/Lib/urllib/parse.py b/Lib/urllib/parse.py index 58460f9234fb96..f21b8eb49cca22 100644 --- a/Lib/urllib/parse.py +++ b/Lib/urllib/parse.py @@ -30,6 +30,7 @@ import re import sys import collections +import warnings __all__ = ["urlparse", "urlunparse", "urljoin", "urldefrag", "urlsplit", "urlunsplit", "urlencode", "parse_qs", @@ -166,7 +167,11 @@ def hostname(self): def port(self): port = self._hostinfo[1] if port is not None: - port = int(port, 10) + try: + port = int(port, 10) + except ValueError: + message = f'Port could not be cast to integer value as {port!r}' + raise ValueError(message) from None if not ( 0 <= port <= 65535): raise ValueError("Port out of range 0-65535") return port @@ -284,7 +289,7 @@ def _hostinfo(self): """ _ParseResultBase.__doc__ = """ -ParseResult(scheme, netloc, path, params, query, fragment) +ParseResult(scheme, netloc, path, params, query, fragment) A 6-tuple that contains components of a parsed URL. """ @@ -909,7 +914,14 @@ def urlencode(query, doseq=False, safe='', encoding=None, errors=None, l.append(k + '=' + elt) return '&'.join(l) + def to_bytes(url): + warnings.warn("urllib.parse.to_bytes() is deprecated as of 3.8", + DeprecationWarning, stacklevel=2) + return _to_bytes(url) + + +def _to_bytes(url): """to_bytes(u"URL") --> 'URL'.""" # Most URL schemes require ASCII. If that changes, the conversion # can be relaxed. @@ -922,7 +934,14 @@ def to_bytes(url): " contains non-ASCII characters") return url + def unwrap(url): + warnings.warn("urllib.parse.unwrap() is deprecated as of 3.8", + DeprecationWarning, stacklevel=2) + return _unwrap(url) + + +def _unwrap(url): """unwrap('<URL:type://host/path>') --> 'type://host/path'.""" url = str(url).strip() if url[:1] == '<' and url[-1:] == '>': @@ -930,8 +949,16 @@ def unwrap(url): if url[:4] == 'URL:': url = url[4:].strip() return url -_typeprog = None + def splittype(url): + warnings.warn("urllib.parse.splittype() is deprecated as of 3.8, " + "use urllib.parse.urlparse() instead", + DeprecationWarning, stacklevel=2) + return _splittype(url) + + +_typeprog = None +def _splittype(url): """splittype('type:opaquestring') --> 'type', 'opaquestring'.""" global _typeprog if _typeprog is None: @@ -943,8 +970,16 @@ def splittype(url): return scheme.lower(), data return None, url -_hostprog = None + def splithost(url): + warnings.warn("urllib.parse.splithost() is deprecated as of 3.8, " + "use urllib.parse.urlparse() instead", + DeprecationWarning, stacklevel=2) + return _splithost(url) + + +_hostprog = None +def _splithost(url): """splithost('//host[:port]/path') --> 'host[:port]', '/path'.""" global _hostprog if _hostprog is None: @@ -958,19 +993,43 @@ def splithost(url): return host_port, path return None, url + def splituser(host): + warnings.warn("urllib.parse.splituser() is deprecated as of 3.8, " + "use urllib.parse.urlparse() instead", + DeprecationWarning, stacklevel=2) + return _splituser(host) + + +def _splituser(host): """splituser('user[:passwd]@host[:port]') --> 'user[:passwd]', 'host[:port]'.""" user, delim, host = host.rpartition('@') return (user if delim else None), host + def splitpasswd(user): + warnings.warn("urllib.parse.splitpasswd() is deprecated as of 3.8, " + "use urllib.parse.urlparse() instead", + DeprecationWarning, stacklevel=2) + return _splitpasswd(user) + + +def _splitpasswd(user): """splitpasswd('user:passwd') -> 'user', 'passwd'.""" user, delim, passwd = user.partition(':') return user, (passwd if delim else None) + +def splitport(host): + warnings.warn("urllib.parse.splitport() is deprecated as of 3.8, " + "use urllib.parse.urlparse() instead", + DeprecationWarning, stacklevel=2) + return _splitport(host) + + # splittag('/path#tag') --> '/path', 'tag' _portprog = None -def splitport(host): +def _splitport(host): """splitport('host:port') --> 'host', 'port'.""" global _portprog if _portprog is None: @@ -983,7 +1042,15 @@ def splitport(host): return host, port return host, None + def splitnport(host, defport=-1): + warnings.warn("urllib.parse.splitnport() is deprecated as of 3.8, " + "use urllib.parse.urlparse() instead", + DeprecationWarning, stacklevel=2) + return _splitnport(host, defport) + + +def _splitnport(host, defport=-1): """Split host and port, returning numeric port. Return given default port if no ':' found; defaults to -1. Return numerical port if a valid number are found after ':'. @@ -999,27 +1066,59 @@ def splitnport(host, defport=-1): return host, nport return host, defport + def splitquery(url): + warnings.warn("urllib.parse.splitquery() is deprecated as of 3.8, " + "use urllib.parse.urlparse() instead", + DeprecationWarning, stacklevel=2) + return _splitquery(url) + + +def _splitquery(url): """splitquery('/path?query') --> '/path', 'query'.""" path, delim, query = url.rpartition('?') if delim: return path, query return url, None + def splittag(url): + warnings.warn("urllib.parse.splittag() is deprecated as of 3.8, " + "use urllib.parse.urlparse() instead", + DeprecationWarning, stacklevel=2) + return _splittag(url) + + +def _splittag(url): """splittag('/path#tag') --> '/path', 'tag'.""" path, delim, tag = url.rpartition('#') if delim: return path, tag return url, None + def splitattr(url): + warnings.warn("urllib.parse.splitattr() is deprecated as of 3.8, " + "use urllib.parse.urlparse() instead", + DeprecationWarning, stacklevel=2) + return _splitattr(url) + + +def _splitattr(url): """splitattr('/path;attr1=value1;attr2=value2;...') -> '/path', ['attr1=value1', 'attr2=value2', ...].""" words = url.split(';') return words[0], words[1:] + def splitvalue(attr): + warnings.warn("urllib.parse.splitvalue() is deprecated as of 3.8, " + "use urllib.parse.parse_qsl() instead", + DeprecationWarning, stacklevel=2) + return _splitvalue(attr) + + +def _splitvalue(attr): """splitvalue('attr=value') --> 'attr', 'value'.""" attr, delim, value = attr.partition('=') return attr, (value if delim else None) diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py index 27993386102696..8b745bb15275a5 100644 --- a/Lib/urllib/request.py +++ b/Lib/urllib/request.py @@ -101,9 +101,9 @@ from urllib.error import URLError, HTTPError, ContentTooShortError from urllib.parse import ( - urlparse, urlsplit, urljoin, unwrap, quote, unquote, - splittype, splithost, splitport, splituser, splitpasswd, - splitattr, splitquery, splitvalue, splittag, to_bytes, + urlparse, urlsplit, urljoin, _unwrap, quote, unquote, + _splittype, _splithost, _splitport, _splituser, _splitpasswd, + _splitattr, _splitquery, _splitvalue, _splittag, _to_bytes, unquote_to_bytes, urlunparse) from urllib.response import addinfourl, addclosehook @@ -242,7 +242,7 @@ def urlretrieve(url, filename=None, reporthook=None, data=None): Returns a tuple containing the path to the newly created data file as well as the resulting HTTPMessage object. """ - url_type, path = splittype(url) + url_type, path = _splittype(url) with contextlib.closing(urlopen(url, data)) as fp: headers = fp.info() @@ -349,8 +349,8 @@ def full_url(self): @full_url.setter def full_url(self, url): # unwrap('<URL:type://host/path>') --> 'type://host/path' - self._full_url = unwrap(url) - self._full_url, self.fragment = splittag(self._full_url) + self._full_url = _unwrap(url) + self._full_url, self.fragment = _splittag(self._full_url) self._parse() @full_url.deleter @@ -378,10 +378,10 @@ def data(self): self.data = None def _parse(self): - self.type, rest = splittype(self._full_url) + self.type, rest = _splittype(self._full_url) if self.type is None: raise ValueError("unknown url type: %r" % self.full_url) - self.host, self.selector = splithost(rest) + self.host, self.selector = _splithost(rest) if self.host: self.host = unquote(self.host) @@ -769,7 +769,7 @@ def _parse_proxy(proxy): According to RFC 3986, having an authority component means the URL must have two slashes after the scheme. """ - scheme, r_scheme = splittype(proxy) + scheme, r_scheme = _splittype(proxy) if not r_scheme.startswith("/"): # authority scheme = None @@ -784,9 +784,9 @@ def _parse_proxy(proxy): if end == -1: end = None authority = r_scheme[2:end] - userinfo, hostport = splituser(authority) + userinfo, hostport = _splituser(authority) if userinfo is not None: - user, password = splitpasswd(userinfo) + user, password = _splitpasswd(userinfo) else: user = password = None return scheme, user, password, hostport @@ -873,7 +873,7 @@ def reduce_uri(self, uri, default_port=True): scheme = None authority = uri path = '/' - host, port = splitport(authority) + host, port = _splitport(authority) if default_port and port is None and scheme is not None: dport = {"http": 80, "https": 443, @@ -1262,8 +1262,8 @@ def do_request_(self, request): sel_host = host if request.has_proxy(): - scheme, sel = splittype(request.selector) - sel_host, sel_path = splithost(sel) + scheme, sel = _splittype(request.selector) + sel_host, sel_path = _splithost(sel) if not request.has_header('Host'): request.add_unredirected_header('Host', sel_host) for name, value in self.parent.addheaders: @@ -1479,7 +1479,7 @@ def open_local_file(self, req): 'Content-type: %s\nContent-length: %d\nLast-modified: %s\n' % (mtype or 'text/plain', size, modified)) if host: - host, port = splitport(host) + host, port = _splitport(host) if not host or \ (not port and _safe_gethostbyname(host) in self.get_names()): if host: @@ -1504,16 +1504,16 @@ def ftp_open(self, req): host = req.host if not host: raise URLError('ftp error: no host given') - host, port = splitport(host) + host, port = _splitport(host) if port is None: port = ftplib.FTP_PORT else: port = int(port) # username/password handling - user, host = splituser(host) + user, host = _splituser(host) if user: - user, passwd = splitpasswd(user) + user, passwd = _splitpasswd(user) else: passwd = None host = unquote(host) @@ -1524,7 +1524,7 @@ def ftp_open(self, req): host = socket.gethostbyname(host) except OSError as msg: raise URLError(msg) - path, attrs = splitattr(req.selector) + path, attrs = _splitattr(req.selector) dirs = path.split('/') dirs = list(map(unquote, dirs)) dirs, file = dirs[:-1], dirs[-1] @@ -1534,7 +1534,7 @@ def ftp_open(self, req): fw = self.connect_ftp(user, passwd, host, port, dirs, req.timeout) type = file and 'I' or 'D' for attr in attrs: - attr, value = splitvalue(attr) + attr, value = _splitvalue(attr) if attr.lower() == 'type' and \ value in ('a', 'A', 'i', 'I', 'd', 'D'): type = value.upper() @@ -1728,19 +1728,19 @@ def addheader(self, *args): # External interface def open(self, fullurl, data=None): """Use URLopener().open(file) instead of open(file, 'r').""" - fullurl = unwrap(to_bytes(fullurl)) + fullurl = _unwrap(_to_bytes(fullurl)) fullurl = quote(fullurl, safe="%/:=&?~#+!$,;'@()*[]|") if self.tempcache and fullurl in self.tempcache: filename, headers = self.tempcache[fullurl] fp = open(filename, 'rb') return addinfourl(fp, headers, fullurl) - urltype, url = splittype(fullurl) + urltype, url = _splittype(fullurl) if not urltype: urltype = 'file' if urltype in self.proxies: proxy = self.proxies[urltype] - urltype, proxyhost = splittype(proxy) - host, selector = splithost(proxyhost) + urltype, proxyhost = _splittype(proxy) + host, selector = _splithost(proxyhost) url = (host, fullurl) # Signal special case to open_*() else: proxy = None @@ -1764,22 +1764,22 @@ def open(self, fullurl, data=None): def open_unknown(self, fullurl, data=None): """Overridable interface to open unknown URL type.""" - type, url = splittype(fullurl) + type, url = _splittype(fullurl) raise OSError('url error', 'unknown url type', type) def open_unknown_proxy(self, proxy, fullurl, data=None): """Overridable interface to open unknown URL type.""" - type, url = splittype(fullurl) + type, url = _splittype(fullurl) raise OSError('url error', 'invalid proxy for %s' % type, proxy) # External interface def retrieve(self, url, filename=None, reporthook=None, data=None): """retrieve(url) returns (filename, headers) for a local object or (tempfilename, headers) for a remote object.""" - url = unwrap(to_bytes(url)) + url = _unwrap(_to_bytes(url)) if self.tempcache and url in self.tempcache: return self.tempcache[url] - type, url1 = splittype(url) + type, url1 = _splittype(url) if filename is None and (not type or type == 'file'): try: fp = self.open_local_file(url1) @@ -1854,25 +1854,25 @@ def _open_generic_http(self, connection_factory, url, data): user_passwd = None proxy_passwd= None if isinstance(url, str): - host, selector = splithost(url) + host, selector = _splithost(url) if host: - user_passwd, host = splituser(host) + user_passwd, host = _splituser(host) host = unquote(host) realhost = host else: host, selector = url # check whether the proxy contains authorization information - proxy_passwd, host = splituser(host) + proxy_passwd, host = _splituser(host) # now we proceed with the url we want to obtain - urltype, rest = splittype(selector) + urltype, rest = _splittype(selector) url = rest user_passwd = None if urltype.lower() != 'http': realhost = None else: - realhost, rest = splithost(rest) + realhost, rest = _splithost(rest) if realhost: - user_passwd, realhost = splituser(realhost) + user_passwd, realhost = _splituser(realhost) if user_passwd: selector = "%s://%s%s" % (urltype, realhost, rest) if proxy_bypass(realhost): @@ -1978,7 +1978,7 @@ def open_local_file(self, url): """Use local file.""" import email.utils import mimetypes - host, file = splithost(url) + host, file = _splithost(url) localname = url2pathname(file) try: stats = os.stat(localname) @@ -1995,7 +1995,7 @@ def open_local_file(self, url): if file[:1] == '/': urlfile = 'file://' + file return addinfourl(open(localname, 'rb'), headers, urlfile) - host, port = splitport(host) + host, port = _splitport(host) if (not port and socket.gethostbyname(host) in ((localhost(),) + thishost())): urlfile = file @@ -2011,11 +2011,11 @@ def open_ftp(self, url): if not isinstance(url, str): raise URLError('ftp error: proxy support for ftp protocol currently not implemented') import mimetypes - host, path = splithost(url) + host, path = _splithost(url) if not host: raise URLError('ftp error: no host given') - host, port = splitport(host) - user, host = splituser(host) - if user: user, passwd = splitpasswd(user) + host, port = _splitport(host) + user, host = _splituser(host) + if user: user, passwd = _splitpasswd(user) else: passwd = None host = unquote(host) user = unquote(user or '') @@ -2026,7 +2026,7 @@ def open_ftp(self, url): port = ftplib.FTP_PORT else: port = int(port) - path, attrs = splitattr(path) + path, attrs = _splitattr(path) path = unquote(path) dirs = path.split('/') dirs, file = dirs[:-1], dirs[-1] @@ -2048,7 +2048,7 @@ def open_ftp(self, url): if not file: type = 'D' else: type = 'I' for attr in attrs: - attr, value = splitvalue(attr) + attr, value = _splitvalue(attr) if attr.lower() == 'type' and \ value in ('a', 'A', 'i', 'I', 'd', 'D'): type = value.upper() @@ -2231,11 +2231,11 @@ def http_error_407(self, url, fp, errcode, errmsg, headers, data=None, return getattr(self,name)(url, realm, data) def retry_proxy_http_basic_auth(self, url, realm, data=None): - host, selector = splithost(url) + host, selector = _splithost(url) newurl = 'http://' + host + selector proxy = self.proxies['http'] - urltype, proxyhost = splittype(proxy) - proxyhost, proxyselector = splithost(proxyhost) + urltype, proxyhost = _splittype(proxy) + proxyhost, proxyselector = _splithost(proxyhost) i = proxyhost.find('@') + 1 proxyhost = proxyhost[i:] user, passwd = self.get_user_passwd(proxyhost, realm, i) @@ -2249,11 +2249,11 @@ def retry_proxy_http_basic_auth(self, url, realm, data=None): return self.open(newurl, data) def retry_proxy_https_basic_auth(self, url, realm, data=None): - host, selector = splithost(url) + host, selector = _splithost(url) newurl = 'https://' + host + selector proxy = self.proxies['https'] - urltype, proxyhost = splittype(proxy) - proxyhost, proxyselector = splithost(proxyhost) + urltype, proxyhost = _splittype(proxy) + proxyhost, proxyselector = _splithost(proxyhost) i = proxyhost.find('@') + 1 proxyhost = proxyhost[i:] user, passwd = self.get_user_passwd(proxyhost, realm, i) @@ -2267,7 +2267,7 @@ def retry_proxy_https_basic_auth(self, url, realm, data=None): return self.open(newurl, data) def retry_http_basic_auth(self, url, realm, data=None): - host, selector = splithost(url) + host, selector = _splithost(url) i = host.find('@') + 1 host = host[i:] user, passwd = self.get_user_passwd(host, realm, i) @@ -2281,7 +2281,7 @@ def retry_http_basic_auth(self, url, realm, data=None): return self.open(newurl, data) def retry_https_basic_auth(self, url, realm, data=None): - host, selector = splithost(url) + host, selector = _splithost(url) i = host.find('@') + 1 host = host[i:] user, passwd = self.get_user_passwd(host, realm, i) @@ -2503,7 +2503,7 @@ def proxy_bypass_environment(host, proxies=None): if no_proxy == '*': return 1 # strip port off host - hostonly, port = splitport(host) + hostonly, port = _splitport(host) # check if the host ends with any of the DNS suffixes no_proxy_list = [proxy.strip() for proxy in no_proxy.split(',')] for name in no_proxy_list: @@ -2534,7 +2534,7 @@ def _proxy_bypass_macosx_sysconf(host, proxy_settings): """ from fnmatch import fnmatch - hostonly, port = splitport(host) + hostonly, port = _splitport(host) def ip2num(ipAddr): parts = ipAddr.split('.') @@ -2688,7 +2688,7 @@ def proxy_bypass_registry(host): if not proxyEnable or not proxyOverride: return 0 # try to make a host list from name and IP address. - rawHost, port = splitport(host) + rawHost, port = _splitport(host) host = [rawHost] try: addr = socket.gethostbyname(rawHost) diff --git a/Lib/urllib/robotparser.py b/Lib/urllib/robotparser.py index 883ef249210ebc..7089916a4f81cc 100644 --- a/Lib/urllib/robotparser.py +++ b/Lib/urllib/robotparser.py @@ -27,6 +27,7 @@ class RobotFileParser: def __init__(self, url=''): self.entries = [] + self.sitemaps = [] self.default_entry = None self.disallow_all = False self.allow_all = False @@ -141,6 +142,12 @@ def parse(self, lines): and numbers[1].strip().isdigit()): entry.req_rate = RequestRate(int(numbers[0]), int(numbers[1])) state = 2 + elif line[0] == "sitemap": + # According to http://www.sitemaps.org/protocol.html + # "This directive is independent of the user-agent line, + # so it doesn't matter where you place it in your file." + # Therefore we do not change the state of the parser. + self.sitemaps.append(line[1]) if state == 2: self._add_entry(entry) @@ -189,11 +196,16 @@ def request_rate(self, useragent): return entry.req_rate return self.default_entry.req_rate + def site_maps(self): + if not self.sitemaps: + return None + return self.sitemaps + def __str__(self): entries = self.entries if self.default_entry is not None: entries = entries + [self.default_entry] - return '\n'.join(map(str, entries)) + '\n' + return '\n\n'.join(map(str, entries)) class RuleLine: @@ -232,7 +244,6 @@ def __str__(self): rate = self.req_rate ret.append(f"Request-rate: {rate.requests}/{rate.seconds}") ret.extend(map(str, self.rulelines)) - ret.append('') # for compatibility return '\n'.join(ret) def applies_to(self, useragent): diff --git a/Lib/warnings.py b/Lib/warnings.py index 81f98647786d2c..6830b602de9ab2 100644 --- a/Lib/warnings.py +++ b/Lib/warnings.py @@ -303,28 +303,16 @@ def warn(message, category=None, stacklevel=1, source=None): raise ValueError except ValueError: globals = sys.__dict__ + filename = "sys" lineno = 1 else: globals = frame.f_globals + filename = frame.f_code.co_filename lineno = frame.f_lineno if '__name__' in globals: module = globals['__name__'] else: module = "<string>" - filename = globals.get('__file__') - if filename: - fnl = filename.lower() - if fnl.endswith(".pyc"): - filename = filename[:-1] - else: - if module == "__main__": - try: - filename = sys.argv[0] - except AttributeError: - # embedded interpreters don't have sys.argv, see bug #839151 - filename = '__main__' - if not filename: - filename = module registry = globals.setdefault("__warningregistry__", {}) warn_explicit(message, category, filename, lineno, module, registry, globals, source) diff --git a/Lib/webbrowser.py b/Lib/webbrowser.py index 2a5729b446f0cc..1e27c83fd947f0 100755 --- a/Lib/webbrowser.py +++ b/Lib/webbrowser.py @@ -86,7 +86,7 @@ def open_new_tab(url): return open(url, 2) -def _synthesize(browser, update_tryorder=1): +def _synthesize(browser, *, preferred=True): """Attempt to synthesize a controller base on existing controllers. This is useful to create a controller when a user specifies a path to @@ -113,7 +113,7 @@ def _synthesize(browser, update_tryorder=1): controller = copy.copy(controller) controller.name = browser controller.basename = os.path.basename(browser) - register(browser, None, controller, update_tryorder) + register(browser, None, instance=controller, preferred=preferred) return [None, controller] return [None, None] @@ -308,11 +308,10 @@ class Chrome(UnixBrowser): class Opera(UnixBrowser): "Launcher class for Opera browser." - raise_opts = ["-noraise", ""] - remote_args = ['-remote', 'openURL(%s%action)'] + remote_args = ['%action', '%s'] remote_action = "" - remote_action_newwin = ",new-window" - remote_action_newtab = ",new-page" + remote_action_newwin = "--new-window" + remote_action_newtab = "" background = True @@ -564,7 +563,7 @@ def register_standard_browsers(): # and prepend to _tryorder for cmdline in userchoices: if cmdline != '': - cmd = _synthesize(cmdline, -1) + cmd = _synthesize(cmdline, preferred=False) if cmd[1] is None: register(cmdline, None, GenericBrowser(cmdline), preferred=True) diff --git a/Lib/xml/dom/minidom.py b/Lib/xml/dom/minidom.py index a5d813f932ace3..e44e04a069ecb4 100644 --- a/Lib/xml/dom/minidom.py +++ b/Lib/xml/dom/minidom.py @@ -823,6 +823,7 @@ def removeAttributeNode(self, node): # Restore this since the node is still useful and otherwise # unlinked node.ownerDocument = self.ownerDocument + return node removeAttributeNodeNS = removeAttributeNode diff --git a/Lib/xmlrpc/client.py b/Lib/xmlrpc/client.py index 1e8bb5f1bb965d..ddab76ffbe8309 100644 --- a/Lib/xmlrpc/client.py +++ b/Lib/xmlrpc/client.py @@ -1214,7 +1214,7 @@ def get_host_info(self, host): if isinstance(host, tuple): host, x509 = host - auth, host = urllib.parse.splituser(host) + auth, host = urllib.parse._splituser(host) if auth: auth = urllib.parse.unquote_to_bytes(auth) @@ -1413,10 +1413,10 @@ def __init__(self, uri, transport=None, encoding=None, verbose=False, # establish a "logical" server connection # get the url - type, uri = urllib.parse.splittype(uri) + type, uri = urllib.parse._splittype(uri) if type not in ("http", "https"): raise OSError("unsupported XML-RPC protocol") - self.__host, self.__handler = urllib.parse.splithost(uri) + self.__host, self.__handler = urllib.parse._splithost(uri) if not self.__handler: self.__handler = "/RPC2" diff --git a/Mac/Makefile.in b/Mac/Makefile.in index 95fd4a2722d51a..0b32673323a0dc 100644 --- a/Mac/Makefile.in +++ b/Mac/Makefile.in @@ -67,7 +67,6 @@ installunixtools: pydoc3 \ python3 \ python3-config \ - pyvenv \ ; \ do \ rm -f $${fn} ; \ @@ -118,7 +117,6 @@ altinstallunixtools: pydoc$(VERSION) \ python$(VERSION) \ python$(LDVERSION)-config \ - pyvenv-$(VERSION) \ ; \ do \ rm -f $${fn} ;\ diff --git a/Makefile.pre.in b/Makefile.pre.in index 221f28d93fb3d4..b247651f46fc66 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -1231,8 +1231,6 @@ bininstall: altbininstall (cd $(DESTDIR)$(BINDIR); $(LN) -s pydoc$(VERSION) pydoc3) -rm -f $(DESTDIR)$(BINDIR)/2to3 (cd $(DESTDIR)$(BINDIR); $(LN) -s 2to3-$(VERSION) 2to3) - -rm -f $(DESTDIR)$(BINDIR)/pyvenv - (cd $(DESTDIR)$(BINDIR); $(LN) -s pyvenv-$(VERSION) pyvenv) if test "x$(LIPO_32BIT_FLAGS)" != "x" ; then \ rm -f $(DESTDIR)$(BINDIR)/python3-32$(EXE); \ (cd $(DESTDIR)$(BINDIR); $(LN) -s python$(VERSION)-32$(EXE) python3-32$(EXE)) \ diff --git a/Misc/ACKS b/Misc/ACKS index 7234c0a766fdaa..8e1b6f73d706cd 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -109,6 +109,7 @@ Anthony Baxter Mike Bayer Samuel L. Bayer Bo Bayles +Christopher Beacham AKA Lady Red Tommy Beadle Donald Beaudry David Beazley @@ -183,6 +184,7 @@ Thierry Bousch Sebastian Boving Michal Bozon Jeff Bradberry +Chris Bradbury Aaron Brancotti Monty Brandenberg Georg Brandl @@ -449,6 +451,7 @@ Andy Eskilsson André Espaze Stefan Esser Nicolas Estibals +Jonathan Eunice Carey Evans Stephen D Evans Tim Everett @@ -466,6 +469,7 @@ Michael Farrell Troy J. Farrell Jim Fasarakis-Hilliard Mark Favas +Sergey Fedoseev Boris Feld Thomas Fenzl Niels Ferguson @@ -599,6 +603,7 @@ Peter Haight Václav Haisman Zbigniew Halas Walker Hale IV +Aaron Christopher Hall Bob Halley Jesse Hallio Jun Hamano @@ -1310,6 +1315,7 @@ Marc Recht John Redford Terry J. Reedy Gareth Rees +John Reese Steve Reeves Lennart Regebro John Regehr @@ -1466,6 +1472,7 @@ Varun Sharma Daniel Shaulov Vlad Shcherbina Justin Sheehy +Akash Shende Charlie Shepherd Bruce Sherwood Alexander Shigin @@ -1504,6 +1511,7 @@ Václav Šmilauer Allen W. Smith Christopher Smith Eric V. Smith +Ethan H. Smith Gregory P. Smith Mark Smith Nathaniel J. Smith @@ -1759,6 +1767,7 @@ Dik Winter Blake Winton Jean-Claude Wippler Stéphane Wirtel +Peter Wirtz Lars Wirzenius John Wiseman Chris Withers @@ -1775,6 +1784,7 @@ Gordon Worley Darren Worrall Thomas Wouters Daniel Wozniak +Marcin Niemira Wei Wu Heiko Wundram Doug Wyatt @@ -1791,6 +1801,7 @@ Jason Yeo EungJun Yi Bob Yodlowski Danny Yoo +Wonsup Yoon Rory Yorke George Yoshida Kazuhiro Yoshida diff --git a/Misc/NEWS.d/3.6.6rc1.rst b/Misc/NEWS.d/3.6.6rc1.rst index bc21a34b1fd6de..85428d8245e1c6 100644 --- a/Misc/NEWS.d/3.6.6rc1.rst +++ b/Misc/NEWS.d/3.6.6rc1.rst @@ -175,7 +175,7 @@ handshake to hang or fail. .. -.. bpo: 31467 +.. bpo: 31647 .. date: 2018-05-28-18-40-26 .. nonce: s4Fad3 .. section: Library diff --git a/Misc/NEWS.d/3.7.0b5.rst b/Misc/NEWS.d/3.7.0b5.rst index 202e50b4e035c2..b420496cedd2e3 100644 --- a/Misc/NEWS.d/3.7.0b5.rst +++ b/Misc/NEWS.d/3.7.0b5.rst @@ -132,7 +132,7 @@ handshake to hang or fail. .. -.. bpo: 31467 +.. bpo: 31647 .. date: 2018-05-28-18-40-26 .. nonce: s4Fad3 .. section: Library diff --git a/Misc/NEWS.d/next/Build/2018-02-21-12-46-00.bpo-32898.M15bZh.rst b/Misc/NEWS.d/next/Build/2018-02-21-12-46-00.bpo-32898.M15bZh.rst new file mode 100644 index 00000000000000..4c75466bfd0f59 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2018-02-21-12-46-00.bpo-32898.M15bZh.rst @@ -0,0 +1 @@ +Fix the python debug build when using COUNT_ALLOCS. diff --git a/Misc/NEWS.d/next/Build/2018-03-08-20-25-29.bpo-33012.k9Fe1q.rst b/Misc/NEWS.d/next/Build/2018-03-08-20-25-29.bpo-33012.k9Fe1q.rst new file mode 100644 index 00000000000000..474053348fcc9a --- /dev/null +++ b/Misc/NEWS.d/next/Build/2018-03-08-20-25-29.bpo-33012.k9Fe1q.rst @@ -0,0 +1,5 @@ +gcc 8 has added a new warning heuristic to detect invalid function casts and +a stock python build seems to hit that warning quite often. The most common +is the cast of a METH_NOARGS function (that uses just one argument) to a +PyCFunction. Fix this by adding a dummy argument to all functions that +implement METH_NOARGS. diff --git a/Misc/NEWS.d/next/Build/2018-03-28-04-15-03.bpo-33163.hfpWuU.rst b/Misc/NEWS.d/next/Build/2018-03-28-04-15-03.bpo-33163.hfpWuU.rst new file mode 100644 index 00000000000000..b3f04e3f800c03 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2018-03-28-04-15-03.bpo-33163.hfpWuU.rst @@ -0,0 +1 @@ +Upgrade pip to 9.0.3 and setuptools to v39.0.1. diff --git a/Misc/NEWS.d/next/Build/2018-03-30-14-55-48.bpo-33182.CePczb.rst b/Misc/NEWS.d/next/Build/2018-03-30-14-55-48.bpo-33182.CePczb.rst new file mode 100644 index 00000000000000..6310e5d5b55729 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2018-03-30-14-55-48.bpo-33182.CePczb.rst @@ -0,0 +1 @@ +The embedding tests can once again be built with clang 6.0 diff --git a/Misc/NEWS.d/next/Build/2018-04-17-00-38-19.bpo-32232.o7G_UO.rst b/Misc/NEWS.d/next/Build/2018-04-17-00-38-19.bpo-32232.o7G_UO.rst new file mode 100644 index 00000000000000..fea0b60fcedd9b --- /dev/null +++ b/Misc/NEWS.d/next/Build/2018-04-17-00-38-19.bpo-32232.o7G_UO.rst @@ -0,0 +1,3 @@ +By default, modules configured in `Modules/Setup` are no longer built with +`-DPy_BUILD_CORE`. Instead, modules that specifically need that preprocessor +definition include it in their individual entries. diff --git a/Misc/NEWS.d/next/Build/2018-04-30-16-53-00.bpo-33377.QBh6vP.rst b/Misc/NEWS.d/next/Build/2018-04-30-16-53-00.bpo-33377.QBh6vP.rst new file mode 100644 index 00000000000000..f5dbd23c7c35db --- /dev/null +++ b/Misc/NEWS.d/next/Build/2018-04-30-16-53-00.bpo-33377.QBh6vP.rst @@ -0,0 +1,2 @@ +Add new triplets for mips r6 and riscv variants (used in extension +suffixes). diff --git a/Misc/NEWS.d/next/Build/2018-04-30-17-19-37.bpo-33393.HkVCqI.rst b/Misc/NEWS.d/next/Build/2018-04-30-17-19-37.bpo-33393.HkVCqI.rst new file mode 100644 index 00000000000000..f3317e7e68f3fe --- /dev/null +++ b/Misc/NEWS.d/next/Build/2018-04-30-17-19-37.bpo-33393.HkVCqI.rst @@ -0,0 +1 @@ +Update config.guess and config.sub files. diff --git a/Misc/NEWS.d/next/Build/2018-04-30-17-36-46.bpo-33394._Vdi4t.rst b/Misc/NEWS.d/next/Build/2018-04-30-17-36-46.bpo-33394._Vdi4t.rst new file mode 100644 index 00000000000000..b25fbb02c4065c --- /dev/null +++ b/Misc/NEWS.d/next/Build/2018-04-30-17-36-46.bpo-33394._Vdi4t.rst @@ -0,0 +1,2 @@ +Enable the verbose build for extension modules, when GNU make is passed +macros on the command line. diff --git a/Misc/NEWS.d/next/Build/2018-05-13-17-21-54.bpo-33483.WOs-en.rst b/Misc/NEWS.d/next/Build/2018-05-13-17-21-54.bpo-33483.WOs-en.rst new file mode 100644 index 00000000000000..9808711e14ea45 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2018-05-13-17-21-54.bpo-33483.WOs-en.rst @@ -0,0 +1,2 @@ +C compiler is now correctly detected from the standard environment +variables. --without-gcc and --with-icc options have been removed. diff --git a/Misc/NEWS.d/next/Build/2018-05-15-02-07-49.bpo-33512.X4Fy1Q.rst b/Misc/NEWS.d/next/Build/2018-05-15-02-07-49.bpo-33512.X4Fy1Q.rst new file mode 100644 index 00000000000000..6b74551f1ba447 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2018-05-15-02-07-49.bpo-33512.X4Fy1Q.rst @@ -0,0 +1 @@ +configure's check for "long double" has been simplified diff --git a/Misc/NEWS.d/next/Build/2018-05-15-12-44-50.bpo-33522.mJoNcA.rst b/Misc/NEWS.d/next/Build/2018-05-15-12-44-50.bpo-33522.mJoNcA.rst new file mode 100644 index 00000000000000..f44862f0c454fd --- /dev/null +++ b/Misc/NEWS.d/next/Build/2018-05-15-12-44-50.bpo-33522.mJoNcA.rst @@ -0,0 +1,2 @@ +Enable CI builds on Visual Studio Team Services at +https://python.visualstudio.com/cpython diff --git a/Misc/NEWS.d/next/Build/2018-05-28-11-40-22.bpo-33614.28e0sE.rst b/Misc/NEWS.d/next/Build/2018-05-28-11-40-22.bpo-33614.28e0sE.rst new file mode 100644 index 00000000000000..9091c282ad0a91 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2018-05-28-11-40-22.bpo-33614.28e0sE.rst @@ -0,0 +1,2 @@ +Ensures module definition files for the stable ABI on Windows are correctly +regenerated. diff --git a/Misc/NEWS.d/next/Build/2018-06-04-21-34-34.bpo-5755.65GmCj.rst b/Misc/NEWS.d/next/Build/2018-06-04-21-34-34.bpo-5755.65GmCj.rst new file mode 100644 index 00000000000000..8bcad4418bafc6 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2018-06-04-21-34-34.bpo-5755.65GmCj.rst @@ -0,0 +1,3 @@ +Move ``-Wstrict-prototypes`` option to ``CFLAGS_NODIST`` from ``OPT``. This +option emitted annoying warnings when building extension modules written in +C++. diff --git a/Misc/NEWS.d/next/Build/2018-06-15-18-18-16.bpo-30345.j-xRE1.rst b/Misc/NEWS.d/next/Build/2018-06-15-18-18-16.bpo-30345.j-xRE1.rst new file mode 100644 index 00000000000000..f8db09bdbc6684 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2018-06-15-18-18-16.bpo-30345.j-xRE1.rst @@ -0,0 +1 @@ +Add -g to LDFLAGS when compiling with LTO to get debug symbols. diff --git a/Misc/NEWS.d/next/C API/2018-01-09-17-03-54.bpo-32374.SwwLoz.rst b/Misc/NEWS.d/next/C API/2018-01-09-17-03-54.bpo-32374.SwwLoz.rst new file mode 100644 index 00000000000000..f9cf6d6b99ce9d --- /dev/null +++ b/Misc/NEWS.d/next/C API/2018-01-09-17-03-54.bpo-32374.SwwLoz.rst @@ -0,0 +1,2 @@ +Document that m_traverse for multi-phase initialized modules can be called +with m_state=NULL, and add a sanity check diff --git a/Misc/NEWS.d/next/C API/2018-03-20-21-43-09.bpo-33042.FPFp64.rst b/Misc/NEWS.d/next/C API/2018-03-20-21-43-09.bpo-33042.FPFp64.rst new file mode 100644 index 00000000000000..f840b55869cc36 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2018-03-20-21-43-09.bpo-33042.FPFp64.rst @@ -0,0 +1,2 @@ +Embedding applications may once again call PySys_ResetWarnOptions, +PySys_AddWarnOption, and PySys_AddXOption prior to calling Py_Initialize. \ No newline at end of file diff --git a/Misc/NEWS.d/next/C API/2018-06-10-09-42-31.bpo-33818.50nlf3.rst b/Misc/NEWS.d/next/C API/2018-06-10-09-42-31.bpo-33818.50nlf3.rst new file mode 100644 index 00000000000000..0f30a6e380ef91 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2018-06-10-09-42-31.bpo-33818.50nlf3.rst @@ -0,0 +1,2 @@ +:c:func:`PyExceptionClass_Name` will now return ``const char *`` instead of +``char *``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-10-02-21-02-14.bpo-21983.UoC319.rst b/Misc/NEWS.d/next/Core and Builtins/2017-10-02-21-02-14.bpo-21983.UoC319.rst new file mode 100644 index 00000000000000..88a03685073c0d --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2017-10-02-21-02-14.bpo-21983.UoC319.rst @@ -0,0 +1,2 @@ +Fix a crash in `ctypes.cast()` in case the type argument is a ctypes +structured data type. Patch by Eryk Sun and Oren Milman. diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-10-07-10-13-15.bpo-25862.FPYBA5.rst b/Misc/NEWS.d/next/Core and Builtins/2017-10-07-10-13-15.bpo-25862.FPYBA5.rst new file mode 100644 index 00000000000000..787163643ad8d5 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2017-10-07-10-13-15.bpo-25862.FPYBA5.rst @@ -0,0 +1,2 @@ +Fix assertion failures in the ``tell()`` method of ``io.TextIOWrapper``. +Patch by Zackery Spytz. diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-11-26-00-59-22.bpo-10544.fHOM3V.rst b/Misc/NEWS.d/next/Core and Builtins/2017-11-26-00-59-22.bpo-10544.fHOM3V.rst new file mode 100644 index 00000000000000..404f12cbbb31de --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2017-11-26-00-59-22.bpo-10544.fHOM3V.rst @@ -0,0 +1,2 @@ +Yield expressions are now disallowed in comprehensions and generator +expressions except the expression for the outermost iterable. diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-12-24-19-48-59.bpo-17611.P85kWL.rst b/Misc/NEWS.d/next/Core and Builtins/2017-12-24-19-48-59.bpo-17611.P85kWL.rst new file mode 100644 index 00000000000000..52949e6018af72 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2017-12-24-19-48-59.bpo-17611.P85kWL.rst @@ -0,0 +1,10 @@ +Simplified the interpreter loop by moving the logic of unrolling the stack +of blocks into the compiler. The compiler emits now explicit instructions +for adjusting the stack of values and calling the cleaning up code for +:keyword:`break`, :keyword:`continue` and :keyword:`return`. + +Removed opcodes :opcode:`BREAK_LOOP`, :opcode:`CONTINUE_LOOP`, +:opcode:`SETUP_LOOP` and :opcode:`SETUP_EXCEPT`. Added new opcodes +:opcode:`ROT_FOUR`, :opcode:`BEGIN_FINALLY` and :opcode:`CALL_FINALLY` and +:opcode:`POP_FINALLY`. Changed the behavior of :opcode:`END_FINALLY` and +:opcode:`WITH_CLEANUP_START`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-01-03-23-12-43.bpo-32489.SDEPHB.rst b/Misc/NEWS.d/next/Core and Builtins/2018-01-03-23-12-43.bpo-32489.SDEPHB.rst new file mode 100644 index 00000000000000..68babebdad3cbb --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-01-03-23-12-43.bpo-32489.SDEPHB.rst @@ -0,0 +1,2 @@ +A :keyword:`continue` statement is now allowed in the :keyword:`finally` +clause. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-01-26-21-20-21.bpo-32583.Fh3fau.rst b/Misc/NEWS.d/next/Core and Builtins/2018-01-26-21-20-21.bpo-32583.Fh3fau.rst new file mode 100644 index 00000000000000..45f1d043f9d6fe --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-01-26-21-20-21.bpo-32583.Fh3fau.rst @@ -0,0 +1,2 @@ +Fix possible crashing in builtin Unicode decoders caused by write +out-of-bound errors when using customized decode error handlers. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-01-29-14-36-37.bpo-32711.8hQFJP.rst b/Misc/NEWS.d/next/Core and Builtins/2018-01-29-14-36-37.bpo-32711.8hQFJP.rst new file mode 100644 index 00000000000000..4d55b894ce100c --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-01-29-14-36-37.bpo-32711.8hQFJP.rst @@ -0,0 +1 @@ +Fix the warning messages for Python/ast_unparse.c. Patch by Stéphane Wirtel diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-02-01-10-16-28.bpo-32303.VsvhSl.rst b/Misc/NEWS.d/next/Core and Builtins/2018-02-01-10-16-28.bpo-32303.VsvhSl.rst new file mode 100644 index 00000000000000..b84448fb25a12a --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-02-01-10-16-28.bpo-32303.VsvhSl.rst @@ -0,0 +1 @@ +Make sure ``__spec__.loader`` matches ``__loader__`` for namespace packages. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-02-01-10-56-41.bpo-32305.dkU9Qa.rst b/Misc/NEWS.d/next/Core and Builtins/2018-02-01-10-56-41.bpo-32305.dkU9Qa.rst new file mode 100644 index 00000000000000..204d74a49754e3 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-02-01-10-56-41.bpo-32305.dkU9Qa.rst @@ -0,0 +1,2 @@ +For namespace packages, ensure that both ``__file__`` and +``__spec__.origin`` are set to None. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-02-02-08-50-46.bpo-31356.MNwUOQ.rst b/Misc/NEWS.d/next/Core and Builtins/2018-02-02-08-50-46.bpo-31356.MNwUOQ.rst new file mode 100644 index 00000000000000..5022a1370609ca --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-02-02-08-50-46.bpo-31356.MNwUOQ.rst @@ -0,0 +1,2 @@ +Remove the new API added in bpo-31356 (gc.ensure_disabled() context +manager). diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-02-14-12-35-47.bpo-32836.bThJnx.rst b/Misc/NEWS.d/next/Core and Builtins/2018-02-14-12-35-47.bpo-32836.bThJnx.rst new file mode 100644 index 00000000000000..4eeb9aa2e52c44 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-02-14-12-35-47.bpo-32836.bThJnx.rst @@ -0,0 +1 @@ +Don't use temporary variables in cases of list/dict/set comprehensions diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-02-20-21-53-48.bpo-32889.J6eWy5.rst b/Misc/NEWS.d/next/Core and Builtins/2018-02-20-21-53-48.bpo-32889.J6eWy5.rst new file mode 100644 index 00000000000000..99128ccc1826f7 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-02-20-21-53-48.bpo-32889.J6eWy5.rst @@ -0,0 +1,2 @@ +Update Valgrind suppression list to account for the rename of +``Py_ADDRESS_IN_RANG`` to ``address_in_range``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-02-24-00-07-05.bpo-32925.e-7Ufh.rst b/Misc/NEWS.d/next/Core and Builtins/2018-02-24-00-07-05.bpo-32925.e-7Ufh.rst new file mode 100644 index 00000000000000..e9443e69e2a20b --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-02-24-00-07-05.bpo-32925.e-7Ufh.rst @@ -0,0 +1,3 @@ +Optimized iterating and containing test for literal lists consisting of +non-constants: ``x in [a, b]`` and ``for x in [a, b]``. The case of all +constant elements already was optimized. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-02-24-21-51-42.bpo-32932.2cz31L.rst b/Misc/NEWS.d/next/Core and Builtins/2018-02-24-21-51-42.bpo-32932.2cz31L.rst new file mode 100644 index 00000000000000..51e3d9b613d5ee --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-02-24-21-51-42.bpo-32932.2cz31L.rst @@ -0,0 +1 @@ +Make error message more revealing when there are non-str objects in ``__all__``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-02-25-10-52-40.bpo-32946.Lo09rG.rst b/Misc/NEWS.d/next/Core and Builtins/2018-02-25-10-52-40.bpo-32946.Lo09rG.rst new file mode 100644 index 00000000000000..cb1d2a7fb13c28 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-02-25-10-52-40.bpo-32946.Lo09rG.rst @@ -0,0 +1,2 @@ +Importing names from already imported module with "from ... import ..." is +now 30% faster if the module is not a package. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-02-27-13-36-21.bpo-17288.Gdj24S.rst b/Misc/NEWS.d/next/Core and Builtins/2018-02-27-13-36-21.bpo-17288.Gdj24S.rst new file mode 100644 index 00000000000000..ce9e84c403135e --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-02-27-13-36-21.bpo-17288.Gdj24S.rst @@ -0,0 +1 @@ +Prevent jumps from 'return' and 'exception' trace events. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-02-27-20-57-00.bpo-32911.cmKfco.rst b/Misc/NEWS.d/next/Core and Builtins/2018-02-27-20-57-00.bpo-32911.cmKfco.rst new file mode 100644 index 00000000000000..0c2ae756b65cf9 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-02-27-20-57-00.bpo-32911.cmKfco.rst @@ -0,0 +1,5 @@ +Due to unexpected compatibility issues discovered during downstream beta +testing, reverted :issue:`29463`. ``docstring`` field is removed from Module, +ClassDef, FunctionDef, and AsyncFunctionDef ast nodes which was added in +3.7a1. Docstring expression is restored as a first statement in their body. +Based on patch by Inada Naoki. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-03-06-12-19-19.bpo-33005.LP-V2U.rst b/Misc/NEWS.d/next/Core and Builtins/2018-03-06-12-19-19.bpo-33005.LP-V2U.rst new file mode 100644 index 00000000000000..6c8b99cbb89721 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-03-06-12-19-19.bpo-33005.LP-V2U.rst @@ -0,0 +1,4 @@ +Fix a crash on fork when using a custom memory allocator (ex: using +PYTHONMALLOC env var). _PyGILState_Reinit() and _PyInterpreterState_Enable() +now use the default RAW memory allocator to allocate a new interpreters mutex +on fork. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-03-08-09-48-38.bpo-33026.QZA3Ba.rst b/Misc/NEWS.d/next/Core and Builtins/2018-03-08-09-48-38.bpo-33026.QZA3Ba.rst new file mode 100644 index 00000000000000..dc166d1e577136 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-03-08-09-48-38.bpo-33026.QZA3Ba.rst @@ -0,0 +1 @@ +Fixed jumping out of "with" block by setting f_lineno. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-03-10-15-16-40.bpo-33041.-ak5Fk.rst b/Misc/NEWS.d/next/Core and Builtins/2018-03-10-15-16-40.bpo-33041.-ak5Fk.rst new file mode 100644 index 00000000000000..af9ccfd89f5d32 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-03-10-15-16-40.bpo-33041.-ak5Fk.rst @@ -0,0 +1,3 @@ +Fixed bytecode generation for "async for" with a complex target. A +StopAsyncIteration raised on assigning or unpacking will be now propagated +instead of stopping the iteration. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-03-18-13-56-14.bpo-33041.XwPhI2.rst b/Misc/NEWS.d/next/Core and Builtins/2018-03-18-13-56-14.bpo-33041.XwPhI2.rst new file mode 100644 index 00000000000000..34bf6c9b0f1c40 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-03-18-13-56-14.bpo-33041.XwPhI2.rst @@ -0,0 +1,6 @@ +Added new opcode :opcode:`END_ASYNC_FOR` and fixes the following issues: + +* Setting global :exc:`StopAsyncIteration` no longer breaks ``async for`` + loops. +* Jumping into an ``async for`` loop is now disabled. +* Jumping out of an ``async for`` loop no longer corrupts the stack. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-03-22-23-09-06.bpo-33018.0ncEJV.rst b/Misc/NEWS.d/next/Core and Builtins/2018-03-22-23-09-06.bpo-33018.0ncEJV.rst new file mode 100644 index 00000000000000..e799e9834aa111 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-03-22-23-09-06.bpo-33018.0ncEJV.rst @@ -0,0 +1,3 @@ +Improve consistency of errors raised by ``issubclass()`` when called with a +non-class and an abstract base class as the first and second arguments, +respectively. Patch by Josh Bronson. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-03-25-19-49-06.bpo-33053.V3xlsH.rst b/Misc/NEWS.d/next/Core and Builtins/2018-03-25-19-49-06.bpo-33053.V3xlsH.rst new file mode 100644 index 00000000000000..fd32ac150e4cbe --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-03-25-19-49-06.bpo-33053.V3xlsH.rst @@ -0,0 +1,4 @@ +When using the -m switch, sys.path[0] is now explicitly expanded as the +*starting* working directory, rather than being left as the empty path +(which allows imports from the current working directory at the time of the +import) diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-04-02-09-32-40.bpo-33199.TPnxQu.rst b/Misc/NEWS.d/next/Core and Builtins/2018-04-02-09-32-40.bpo-33199.TPnxQu.rst new file mode 100644 index 00000000000000..22abf8d000112a --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-04-02-09-32-40.bpo-33199.TPnxQu.rst @@ -0,0 +1,2 @@ +Fix ``ma_version_tag`` in dict implementation is uninitialized when copying +from key-sharing dict. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-04-03-00-30-25.bpo-29922.CdLuMl.rst b/Misc/NEWS.d/next/Core and Builtins/2018-04-03-00-30-25.bpo-29922.CdLuMl.rst new file mode 100644 index 00000000000000..d8c144e59d6ce7 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-04-03-00-30-25.bpo-29922.CdLuMl.rst @@ -0,0 +1,2 @@ +Improved error messages in 'async with' when ``__aenter__()`` or +``__aexit__()`` return non-awaitable object. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-04-03-00-58-41.bpo-33205.lk2F3r.rst b/Misc/NEWS.d/next/Core and Builtins/2018-04-03-00-58-41.bpo-33205.lk2F3r.rst new file mode 100644 index 00000000000000..44511865abfa16 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-04-03-00-58-41.bpo-33205.lk2F3r.rst @@ -0,0 +1,3 @@ +Change dict growth function from ``round_up_to_power_2(used*2+hashtable_size/2)`` to +``round_up_to_power_2(used*3)``. Previously, dict is shrinked only when ``used == 0``. +Now dict has more chance to be shrinked. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-04-05-22-20-44.bpo-33231.3Jmo0q.rst b/Misc/NEWS.d/next/Core and Builtins/2018-04-05-22-20-44.bpo-33231.3Jmo0q.rst new file mode 100644 index 00000000000000..de54fbb52671a1 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-04-05-22-20-44.bpo-33231.3Jmo0q.rst @@ -0,0 +1 @@ +Fix potential memory leak in ``normalizestring()``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-04-13-22-31-09.bpo-33176.PB9com.rst b/Misc/NEWS.d/next/Core and Builtins/2018-04-13-22-31-09.bpo-33176.PB9com.rst new file mode 100644 index 00000000000000..68785b3cb6a1d0 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-04-13-22-31-09.bpo-33176.PB9com.rst @@ -0,0 +1 @@ +Add a ``toreadonly()`` method to memoryviews. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-04-14-13-12-50.bpo-33270.UmVV6i.rst b/Misc/NEWS.d/next/Core and Builtins/2018-04-14-13-12-50.bpo-33270.UmVV6i.rst new file mode 100644 index 00000000000000..4dbc4a3062b07c --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-04-14-13-12-50.bpo-33270.UmVV6i.rst @@ -0,0 +1 @@ +Intern the names for all anonymous code objects. Patch by Zackery Spytz. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-04-19-08-30-07.bpo-33312.mDe2iL.rst b/Misc/NEWS.d/next/Core and Builtins/2018-04-19-08-30-07.bpo-33312.mDe2iL.rst new file mode 100644 index 00000000000000..40b51b902c9f70 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-04-19-08-30-07.bpo-33312.mDe2iL.rst @@ -0,0 +1,3 @@ +Fixed clang ubsan (undefined behavior sanitizer) warnings in dictobject.c by +adjusting how the internal struct _dictkeysobject shared keys structure is +declared. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-04-24-22-31-04.bpo-33128.g2yLuf.rst b/Misc/NEWS.d/next/Core and Builtins/2018-04-24-22-31-04.bpo-33128.g2yLuf.rst new file mode 100644 index 00000000000000..66b98cdf51cfcf --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-04-24-22-31-04.bpo-33128.g2yLuf.rst @@ -0,0 +1,2 @@ +Fix a bug that causes PathFinder to appear twice on sys.meta_path. Patch by +Pablo Galindo Salgado. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-04-25-20-44-42.bpo-28055.f49kfC.rst b/Misc/NEWS.d/next/Core and Builtins/2018-04-25-20-44-42.bpo-28055.f49kfC.rst new file mode 100644 index 00000000000000..c7d849906fc95f --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-04-25-20-44-42.bpo-28055.f49kfC.rst @@ -0,0 +1 @@ +Fix unaligned accesses in siphash24(). Patch by Rolf Eike Beer. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-04-26-22-48-28.bpo-33363.8RCnN2.rst b/Misc/NEWS.d/next/Core and Builtins/2018-04-26-22-48-28.bpo-33363.8RCnN2.rst new file mode 100644 index 00000000000000..ad8d24895343b5 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-04-26-22-48-28.bpo-33363.8RCnN2.rst @@ -0,0 +1,2 @@ +Raise a SyntaxError for ``async with`` and ``async for`` statements outside +of async functions. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-05-02-08-36-03.bpo-33391.z4a7rb.rst b/Misc/NEWS.d/next/Core and Builtins/2018-05-02-08-36-03.bpo-33391.z4a7rb.rst new file mode 100644 index 00000000000000..ab17aa408c06fe --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-05-02-08-36-03.bpo-33391.z4a7rb.rst @@ -0,0 +1 @@ +Fix a leak in set_symmetric_difference(). diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-05-13-01-26-18.bpo-33475.rI0y1U.rst b/Misc/NEWS.d/next/Core and Builtins/2018-05-13-01-26-18.bpo-33475.rI0y1U.rst new file mode 100644 index 00000000000000..cd714b9d1e89cc --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-05-13-01-26-18.bpo-33475.rI0y1U.rst @@ -0,0 +1,2 @@ +Fixed miscellaneous bugs in converting annotations to strings and optimized +parentheses in the string representation. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-05-14-11-00-00.bpo-31849.EmHaH4.rst b/Misc/NEWS.d/next/Core and Builtins/2018-05-14-11-00-00.bpo-31849.EmHaH4.rst new file mode 100644 index 00000000000000..876a3cf0aa1313 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-05-14-11-00-00.bpo-31849.EmHaH4.rst @@ -0,0 +1 @@ +Fix signed/unsigned comparison warning in pyhash.c. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-05-14-17-31-02.bpo-33509.pIUfTd.rst b/Misc/NEWS.d/next/Core and Builtins/2018-05-14-17-31-02.bpo-33509.pIUfTd.rst new file mode 100644 index 00000000000000..3d80a8c7f3eb93 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-05-14-17-31-02.bpo-33509.pIUfTd.rst @@ -0,0 +1,2 @@ +Fix module_globals parameter of warnings.warn_explicit(): don't crash if +module_globals is not a dict. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-05-15-10-48-47.bpo-33499.uBEc06.rst b/Misc/NEWS.d/next/Core and Builtins/2018-05-15-10-48-47.bpo-33499.uBEc06.rst new file mode 100644 index 00000000000000..f25a8d099aac47 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-05-15-10-48-47.bpo-33499.uBEc06.rst @@ -0,0 +1,3 @@ +Add :envvar:`PYTHONPYCACHEPREFIX` environment variable and :option:`-X` +``pycache_prefix`` command-line option to set an alternate root directory for +writing module bytecode cache files. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-05-17-13-06-36.bpo-23722.xisqZk.rst b/Misc/NEWS.d/next/Core and Builtins/2018-05-17-13-06-36.bpo-23722.xisqZk.rst new file mode 100644 index 00000000000000..dfd1e79786abec --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-05-17-13-06-36.bpo-23722.xisqZk.rst @@ -0,0 +1,4 @@ +A :exc:`RuntimeError` is now raised when the custom metaclass doesn't +provide the ``__classcell__`` entry in the namespace passed to +``type.__new__``. A :exc:`DeprecationWarning` was emitted in Python +3.6--3.7. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-05-23-20-46-14.bpo-33622.xPucO9.rst b/Misc/NEWS.d/next/Core and Builtins/2018-05-23-20-46-14.bpo-33622.xPucO9.rst new file mode 100644 index 00000000000000..e589b45032293f --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-05-23-20-46-14.bpo-33622.xPucO9.rst @@ -0,0 +1,4 @@ +Fixed a leak when the garbage collector fails to add an object with the +``__del__`` method or referenced by it into the :data:`gc.garbage` list. +:c:func:`PyGC_Collect` can now be called when an exception is set and +preserves it. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-05-28-12-28-53.bpo-30654.9fDJye.rst b/Misc/NEWS.d/next/Core and Builtins/2018-05-28-12-28-53.bpo-30654.9fDJye.rst new file mode 100644 index 00000000000000..01c27daa8f88cf --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-05-28-12-28-53.bpo-30654.9fDJye.rst @@ -0,0 +1,2 @@ +Fixed reset of the SIGINT handler to SIG_DFL on interpreter shutdown even +when there was a custom handler set previously. Patch by Philipp Kerling. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-05-31-14-50-04.bpo-33706.ztlH04.rst b/Misc/NEWS.d/next/Core and Builtins/2018-05-31-14-50-04.bpo-33706.ztlH04.rst new file mode 100644 index 00000000000000..d3b8477b21977e --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-05-31-14-50-04.bpo-33706.ztlH04.rst @@ -0,0 +1,2 @@ +Fix a crash in Python initialization when parsing the command line options. +Thanks Christoph Gohlke for the bug report and the fix! diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-06-06-23-24-40.bpo-33786.lBvT8z.rst b/Misc/NEWS.d/next/Core and Builtins/2018-06-06-23-24-40.bpo-33786.lBvT8z.rst new file mode 100644 index 00000000000000..57deefe339b5c8 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-06-06-23-24-40.bpo-33786.lBvT8z.rst @@ -0,0 +1 @@ +Fix asynchronous generators to handle GeneratorExit in athrow() correctly diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-06-07-18-34-19.bpo-33738.ODZS7a.rst b/Misc/NEWS.d/next/Core and Builtins/2018-06-07-18-34-19.bpo-33738.ODZS7a.rst new file mode 100644 index 00000000000000..2e0c43c6225618 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-06-07-18-34-19.bpo-33738.ODZS7a.rst @@ -0,0 +1,4 @@ +Seven macro incompatibilities with the Limited API were fixed, and the +macros :c:func:`PyIter_Check`, :c:func:`PyIndex_Check` and +:c:func:`PyExceptionClass_Name` were added as functions. +A script for automatic macro checks was added. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-06-07-20-18-38.bpo-33803.n-Nq6_.rst b/Misc/NEWS.d/next/Core and Builtins/2018-06-07-20-18-38.bpo-33803.n-Nq6_.rst new file mode 100644 index 00000000000000..9cb8457ac446ba --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-06-07-20-18-38.bpo-33803.n-Nq6_.rst @@ -0,0 +1,2 @@ +Fix a crash in hamt.c caused by enabling GC tracking for an object that +hadn't all of its fields set to NULL. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-06-15-19-39-06.bpo-33824.DfWHT3.rst b/Misc/NEWS.d/next/Core and Builtins/2018-06-15-19-39-06.bpo-33824.DfWHT3.rst new file mode 100644 index 00000000000000..fda2ea7423dd53 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-06-15-19-39-06.bpo-33824.DfWHT3.rst @@ -0,0 +1,2 @@ +Fix "LC_ALL=C python3.7 -V": reset properly the command line parser when the +encoding changes after reading the Python configuration. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-06-23-15-32-02.bpo-33451.sWN-1l.rst b/Misc/NEWS.d/next/Core and Builtins/2018-06-23-15-32-02.bpo-33451.sWN-1l.rst new file mode 100644 index 00000000000000..202fb38a370c9b --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-06-23-15-32-02.bpo-33451.sWN-1l.rst @@ -0,0 +1 @@ +Close directly executed pyc files before calling ``PyEval_EvalCode()``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-06-25-16-54-05.bpo-24596.Rkwova.rst b/Misc/NEWS.d/next/Core and Builtins/2018-06-25-16-54-05.bpo-24596.Rkwova.rst new file mode 100644 index 00000000000000..1b33fd4a44d723 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-06-25-16-54-05.bpo-24596.Rkwova.rst @@ -0,0 +1,2 @@ +Decref the module object in :c:func:`PyRun_SimpleFileExFlags` before calling +:c:func:`PyErr_Print()`. Patch by Zackery Spytz. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-06-25-20-42-44.bpo-33956.1qoTwD.rst b/Misc/NEWS.d/next/Core and Builtins/2018-06-25-20-42-44.bpo-33956.1qoTwD.rst new file mode 100644 index 00000000000000..f8140e1959fff4 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-06-25-20-42-44.bpo-33956.1qoTwD.rst @@ -0,0 +1 @@ +Update vendored Expat library copy to version 2.2.5. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-06-27-18-56-41.bpo-33985.ILJ3Af.rst b/Misc/NEWS.d/next/Core and Builtins/2018-06-27-18-56-41.bpo-33985.ILJ3Af.rst new file mode 100644 index 00000000000000..07c8f907868675 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-06-27-18-56-41.bpo-33985.ILJ3Af.rst @@ -0,0 +1 @@ +Implement contextvars.ContextVar.name attribute. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-07-03-19-00-10.bpo-33418.cfGm3n.rst b/Misc/NEWS.d/next/Core and Builtins/2018-07-03-19-00-10.bpo-33418.cfGm3n.rst new file mode 100644 index 00000000000000..8f136c6a35c1fc --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-07-03-19-00-10.bpo-33418.cfGm3n.rst @@ -0,0 +1,2 @@ +Fix potential memory leak in function object when it creates reference +cycle. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-07-05-15-51-29.bpo-34042.Gr9XUH.rst b/Misc/NEWS.d/next/Core and Builtins/2018-07-05-15-51-29.bpo-34042.Gr9XUH.rst new file mode 100644 index 00000000000000..fd1730d4308b69 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-07-05-15-51-29.bpo-34042.Gr9XUH.rst @@ -0,0 +1,2 @@ +Fix dict.copy() to maintain correct total refcount (as reported by +sys.gettotalrefcount()). diff --git a/Misc/NEWS.d/next/Documentation/2017-09-13-07-14-59.bpo-31432.yAY4Z3.rst b/Misc/NEWS.d/next/Documentation/2017-09-13-07-14-59.bpo-31432.yAY4Z3.rst new file mode 100644 index 00000000000000..18e5353b249473 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2017-09-13-07-14-59.bpo-31432.yAY4Z3.rst @@ -0,0 +1,2 @@ +Clarify meaning of CERT_NONE, CERT_OPTIONAL, and CERT_REQUIRED flags for +ssl.SSLContext.verify_mode. diff --git a/Misc/NEWS.d/next/Documentation/2017-12-22-17-29-37.bpo-32337.eZe-ID.rst b/Misc/NEWS.d/next/Documentation/2017-12-22-17-29-37.bpo-32337.eZe-ID.rst new file mode 100644 index 00000000000000..a905467cd59fc6 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2017-12-22-17-29-37.bpo-32337.eZe-ID.rst @@ -0,0 +1 @@ +Update documentation related with ``dict`` order. diff --git a/Misc/NEWS.d/next/Documentation/2018-01-13-20-30-53.bpo-8243.s98r28.rst b/Misc/NEWS.d/next/Documentation/2018-01-13-20-30-53.bpo-8243.s98r28.rst new file mode 100644 index 00000000000000..a3520d05c09500 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2018-01-13-20-30-53.bpo-8243.s98r28.rst @@ -0,0 +1,2 @@ +Add a note about curses.addch and curses.addstr exception behavior when +writing outside a window, or pad. diff --git a/Misc/NEWS.d/next/Documentation/2018-01-25-13-58-49.bpo-30607.4dXxiq.rst b/Misc/NEWS.d/next/Documentation/2018-01-25-13-58-49.bpo-30607.4dXxiq.rst new file mode 100644 index 00000000000000..8ff3b788781014 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2018-01-25-13-58-49.bpo-30607.4dXxiq.rst @@ -0,0 +1,2 @@ +Use the externalized ``python-docs-theme`` package when building the +documenation. diff --git a/Misc/NEWS.d/next/Documentation/2018-01-25-14-23-12.bpo-31972.w1m_8r.rst b/Misc/NEWS.d/next/Documentation/2018-01-25-14-23-12.bpo-31972.w1m_8r.rst new file mode 100644 index 00000000000000..e0361df578b3d9 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2018-01-25-14-23-12.bpo-31972.w1m_8r.rst @@ -0,0 +1 @@ +Improve docstrings for `pathlib.PurePath` subclasses. diff --git a/Misc/NEWS.d/next/Documentation/2018-01-30-11-28-27.bpo-32722.frdp6A.rst b/Misc/NEWS.d/next/Documentation/2018-01-30-11-28-27.bpo-32722.frdp6A.rst new file mode 100644 index 00000000000000..c4ed27ee2780f2 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2018-01-30-11-28-27.bpo-32722.frdp6A.rst @@ -0,0 +1,2 @@ +Remove the bad example in the tutorial of the Generator Expression. Patch by +Stéphane Wirtel diff --git a/Misc/NEWS.d/next/Documentation/2018-02-01-10-57-24.bpo-20709.1flcnc.rst b/Misc/NEWS.d/next/Documentation/2018-02-01-10-57-24.bpo-20709.1flcnc.rst new file mode 100644 index 00000000000000..b14c0f54eb3b13 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2018-02-01-10-57-24.bpo-20709.1flcnc.rst @@ -0,0 +1,2 @@ +Remove the paragraph where we explain that os.utime() does not support a +directory as path under Windows. Patch by Jan-Philip Gehrcke diff --git a/Misc/NEWS.d/next/Documentation/2018-02-02-07-41-57.bpo-32614.LSqzGw.rst b/Misc/NEWS.d/next/Documentation/2018-02-02-07-41-57.bpo-32614.LSqzGw.rst new file mode 100644 index 00000000000000..9e9f3e3a74df3b --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2018-02-02-07-41-57.bpo-32614.LSqzGw.rst @@ -0,0 +1,3 @@ +Modify RE examples in documentation to use raw strings to prevent +:exc:`DeprecationWarning` and add text to REGEX HOWTO to highlight the +deprecation. diff --git a/Misc/NEWS.d/next/Documentation/2018-02-03-06-11-37.bpo-8722.MPyVyj.rst b/Misc/NEWS.d/next/Documentation/2018-02-03-06-11-37.bpo-8722.MPyVyj.rst new file mode 100644 index 00000000000000..36e6ff7db3cef8 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2018-02-03-06-11-37.bpo-8722.MPyVyj.rst @@ -0,0 +1,2 @@ +Document :meth:`__getattr__` behavior when property :meth:`get` method +raises :exc:`AttributeError`. diff --git a/Misc/NEWS.d/next/Documentation/2018-02-10-12-48-38.bpo-11015.-gUf34.rst b/Misc/NEWS.d/next/Documentation/2018-02-10-12-48-38.bpo-11015.-gUf34.rst new file mode 100644 index 00000000000000..73612dab69e5bd --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2018-02-10-12-48-38.bpo-11015.-gUf34.rst @@ -0,0 +1 @@ +Update :mod:`test.support` documentation. diff --git a/Misc/NEWS.d/next/Documentation/2018-02-10-15-16-04.bpo-32800.FyrqCk.rst b/Misc/NEWS.d/next/Documentation/2018-02-10-15-16-04.bpo-32800.FyrqCk.rst new file mode 100644 index 00000000000000..eac1107bba7676 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2018-02-10-15-16-04.bpo-32800.FyrqCk.rst @@ -0,0 +1 @@ +Update link to w3c doc for xml default namespaces. diff --git a/Misc/NEWS.d/next/Documentation/2018-02-14-11-10-41.bpo-32436.TTJ2jb.rst b/Misc/NEWS.d/next/Documentation/2018-02-14-11-10-41.bpo-32436.TTJ2jb.rst new file mode 100644 index 00000000000000..b764b45cd9682d --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2018-02-14-11-10-41.bpo-32436.TTJ2jb.rst @@ -0,0 +1 @@ +Add documentation for the contextvars module (PEP 567). diff --git a/Misc/NEWS.d/next/Documentation/2018-02-23-12-48-03.bpo-17232.tmuTKL.rst b/Misc/NEWS.d/next/Documentation/2018-02-23-12-48-03.bpo-17232.tmuTKL.rst new file mode 100644 index 00000000000000..5c14e91b3919df --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2018-02-23-12-48-03.bpo-17232.tmuTKL.rst @@ -0,0 +1 @@ +Clarify docs for -O and -OO. Patch by Terry Reedy. diff --git a/Misc/NEWS.d/next/Documentation/2018-02-25-16-33-35.bpo-28124._uzkgq.rst b/Misc/NEWS.d/next/Documentation/2018-02-25-16-33-35.bpo-28124._uzkgq.rst new file mode 100644 index 00000000000000..4f4ca001981dc0 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2018-02-25-16-33-35.bpo-28124._uzkgq.rst @@ -0,0 +1,3 @@ +The ssl module function ssl.wrap_socket() has been de-emphasized +and deprecated in favor of the more secure and efficient +SSLContext.wrap_socket() method. diff --git a/Misc/NEWS.d/next/Documentation/2018-03-11-00-16-56.bpo-27428.B7A8FT.rst b/Misc/NEWS.d/next/Documentation/2018-03-11-00-16-56.bpo-27428.B7A8FT.rst new file mode 100644 index 00000000000000..c9ac8e22df0855 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2018-03-11-00-16-56.bpo-27428.B7A8FT.rst @@ -0,0 +1,2 @@ +Update documentation to clarify that ``WindowsRegistryFinder`` implements +``MetaPathFinder``. (Patch by Himanshu Lakhara) diff --git a/Misc/NEWS.d/next/Documentation/2018-03-11-18-53-47.bpo-18802.JhAqH3.rst b/Misc/NEWS.d/next/Documentation/2018-03-11-18-53-47.bpo-18802.JhAqH3.rst new file mode 100644 index 00000000000000..cb9cc2599aca92 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2018-03-11-18-53-47.bpo-18802.JhAqH3.rst @@ -0,0 +1 @@ +Documentation changes for ipaddress. Patch by Jon Foster and Berker Peksag. diff --git a/Misc/NEWS.d/next/Documentation/2018-03-20-20-11-05.bpo-28247.-V-WS-.rst b/Misc/NEWS.d/next/Documentation/2018-03-20-20-11-05.bpo-28247.-V-WS-.rst new file mode 100644 index 00000000000000..28a802136fa754 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2018-03-20-20-11-05.bpo-28247.-V-WS-.rst @@ -0,0 +1,2 @@ +Update :mod:`zipapp` documentation to describe how to make standalone +applications. diff --git a/Misc/NEWS.d/next/Documentation/2018-03-22-19-23-04.bpo-27212.wrE5KR.rst b/Misc/NEWS.d/next/Documentation/2018-03-22-19-23-04.bpo-27212.wrE5KR.rst new file mode 100644 index 00000000000000..5910d2c17342f5 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2018-03-22-19-23-04.bpo-27212.wrE5KR.rst @@ -0,0 +1,2 @@ +Modify documentation for the :func:`islice` recipe to consume initial values +up to the start index. diff --git a/Misc/NEWS.d/next/Documentation/2018-03-28-17-03-17.bpo-33126.5UGkNv.rst b/Misc/NEWS.d/next/Documentation/2018-03-28-17-03-17.bpo-33126.5UGkNv.rst new file mode 100644 index 00000000000000..1219790e79ec4c --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2018-03-28-17-03-17.bpo-33126.5UGkNv.rst @@ -0,0 +1 @@ +Document PyBuffer_ToContiguous(). diff --git a/Misc/NEWS.d/next/Documentation/2018-04-01-14-30-36.bpo-33195.dRS-XX.rst b/Misc/NEWS.d/next/Documentation/2018-04-01-14-30-36.bpo-33195.dRS-XX.rst new file mode 100644 index 00000000000000..6884640325b07f --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2018-04-01-14-30-36.bpo-33195.dRS-XX.rst @@ -0,0 +1,3 @@ +Deprecate ``Py_UNICODE`` usage in ``c-api/arg`` document. ``Py_UNICODE`` +related APIs are deprecated since Python 3.3, but it is missed in the +document. diff --git a/Misc/NEWS.d/next/Documentation/2018-04-01-21-03-41.bpo-33201.aa8Lkl.rst b/Misc/NEWS.d/next/Documentation/2018-04-01-21-03-41.bpo-33201.aa8Lkl.rst new file mode 100644 index 00000000000000..bdee48ba031443 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2018-04-01-21-03-41.bpo-33201.aa8Lkl.rst @@ -0,0 +1 @@ +Modernize documentation for writing C extension types. diff --git a/Misc/NEWS.d/next/Documentation/2018-04-20-14-09-36.bpo-33276.rA1z_3.rst b/Misc/NEWS.d/next/Documentation/2018-04-20-14-09-36.bpo-33276.rA1z_3.rst new file mode 100644 index 00000000000000..0da58a0ce4c896 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2018-04-20-14-09-36.bpo-33276.rA1z_3.rst @@ -0,0 +1 @@ +Clarify that the ``__path__`` attribute on modules cannot be just any value. diff --git a/Misc/NEWS.d/next/Documentation/2018-04-29-04-02-18.bpo-33378.-anAHN.rst b/Misc/NEWS.d/next/Documentation/2018-04-29-04-02-18.bpo-33378.-anAHN.rst new file mode 100644 index 00000000000000..43214d10b7c569 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2018-04-29-04-02-18.bpo-33378.-anAHN.rst @@ -0,0 +1 @@ +Add Korean language switcher for https://docs.python.org/3/ diff --git a/Misc/NEWS.d/next/Documentation/2018-05-14-15-15-41.bpo-33421.3GU_QO.rst b/Misc/NEWS.d/next/Documentation/2018-05-14-15-15-41.bpo-33421.3GU_QO.rst new file mode 100644 index 00000000000000..75694b7be1e755 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2018-05-14-15-15-41.bpo-33421.3GU_QO.rst @@ -0,0 +1 @@ +Add missing documentation for ``typing.AsyncContextManager``. diff --git a/Misc/NEWS.d/next/Documentation/2018-05-14-20-08-58.bpo-33503.Wvt0qg.rst b/Misc/NEWS.d/next/Documentation/2018-05-14-20-08-58.bpo-33503.Wvt0qg.rst new file mode 100644 index 00000000000000..27025c31a03654 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2018-05-14-20-08-58.bpo-33503.Wvt0qg.rst @@ -0,0 +1 @@ +Fix broken pypi link diff --git a/Misc/NEWS.d/next/Documentation/2018-05-22-11-47-14.bpo-33604.5YHTpz.rst b/Misc/NEWS.d/next/Documentation/2018-05-22-11-47-14.bpo-33604.5YHTpz.rst new file mode 100644 index 00000000000000..3c2f2d0b8230f5 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2018-05-22-11-47-14.bpo-33604.5YHTpz.rst @@ -0,0 +1 @@ +Update HMAC md5 default to a DeprecationWarning, bump removal to 3.8. diff --git a/Misc/NEWS.d/next/Documentation/2018-05-23-11-59-51.bpo-32436.S1LGPa.rst b/Misc/NEWS.d/next/Documentation/2018-05-23-11-59-51.bpo-32436.S1LGPa.rst new file mode 100644 index 00000000000000..8eeb561921a854 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2018-05-23-11-59-51.bpo-32436.S1LGPa.rst @@ -0,0 +1 @@ +Document PEP 567 changes to asyncio. diff --git a/Misc/NEWS.d/next/Documentation/2018-05-29-16-02-31.bpo-23859.E5gba1.rst b/Misc/NEWS.d/next/Documentation/2018-05-29-16-02-31.bpo-23859.E5gba1.rst new file mode 100644 index 00000000000000..b372faa5eb9786 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2018-05-29-16-02-31.bpo-23859.E5gba1.rst @@ -0,0 +1 @@ +Document that `asyncio.wait()` does not cancel its futures on timeout. diff --git a/Misc/NEWS.d/next/Documentation/2018-06-01-12-27-40.bpo-33736.JVegIu.rst b/Misc/NEWS.d/next/Documentation/2018-06-01-12-27-40.bpo-33736.JVegIu.rst new file mode 100644 index 00000000000000..6bd9c40d35e956 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2018-06-01-12-27-40.bpo-33736.JVegIu.rst @@ -0,0 +1,2 @@ +Improve the documentation of :func:`asyncio.open_connection`, +:func:`asyncio.start_server` and their UNIX socket counterparts. diff --git a/Misc/NEWS.d/next/Documentation/2018-06-07-08-33-45.bpo-17045.ZNx6KU.rst b/Misc/NEWS.d/next/Documentation/2018-06-07-08-33-45.bpo-17045.ZNx6KU.rst new file mode 100644 index 00000000000000..0f3836c10d389d --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2018-06-07-08-33-45.bpo-17045.ZNx6KU.rst @@ -0,0 +1,3 @@ +Improve the C-API doc for PyTypeObject. This includes adding several quick- +reference tables and a lot of missing slot/typedef entries. The existing +entries were also cleaned up with a slightly more consistent format. diff --git a/Misc/NEWS.d/next/Documentation/2018-06-08-23-37-14.bpo-33197.OERTKf.rst b/Misc/NEWS.d/next/Documentation/2018-06-08-23-37-14.bpo-33197.OERTKf.rst new file mode 100644 index 00000000000000..ae8df74f71ff89 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2018-06-08-23-37-14.bpo-33197.OERTKf.rst @@ -0,0 +1 @@ +Add versionadded tag to the documentation of ParameterKind.description diff --git a/Misc/NEWS.d/next/Documentation/2018-06-08-23-46-01.bpo-33409.r4z9MM.rst b/Misc/NEWS.d/next/Documentation/2018-06-08-23-46-01.bpo-33409.r4z9MM.rst new file mode 100644 index 00000000000000..5b1a018df55ae1 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2018-06-08-23-46-01.bpo-33409.r4z9MM.rst @@ -0,0 +1,2 @@ +Clarified the relationship between PEP 538's PYTHONCOERCECLOCALE and PEP +540's PYTHONUTF8 mode. diff --git a/Misc/NEWS.d/next/Documentation/2018-06-15-14-58-45.bpo-33847.IIDp6t.rst b/Misc/NEWS.d/next/Documentation/2018-06-15-14-58-45.bpo-33847.IIDp6t.rst new file mode 100644 index 00000000000000..3c7e0cdb7b4367 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2018-06-15-14-58-45.bpo-33847.IIDp6t.rst @@ -0,0 +1 @@ +Add '@' operator entry to index. diff --git a/Misc/NEWS.d/next/Documentation/2018-07-07-20-38-41.bpo-34065.1snofM.rst b/Misc/NEWS.d/next/Documentation/2018-07-07-20-38-41.bpo-34065.1snofM.rst new file mode 100644 index 00000000000000..a3f9fb848f6218 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2018-07-07-20-38-41.bpo-34065.1snofM.rst @@ -0,0 +1 @@ +Fix wrongly written basicConfig documentation markup syntax diff --git a/Misc/NEWS.d/next/IDLE/2018-02-04-17-52-54.bpo-32765.qm0eCu.rst b/Misc/NEWS.d/next/IDLE/2018-02-04-17-52-54.bpo-32765.qm0eCu.rst new file mode 100644 index 00000000000000..1bd6b094ca5dee --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2018-02-04-17-52-54.bpo-32765.qm0eCu.rst @@ -0,0 +1 @@ +Update configdialog General tab docstring to add new widgets to the widget list. diff --git a/Misc/NEWS.d/next/IDLE/2018-02-12-08-08-45.bpo-32831.srDRvU.rst b/Misc/NEWS.d/next/IDLE/2018-02-12-08-08-45.bpo-32831.srDRvU.rst new file mode 100644 index 00000000000000..583e341f94f096 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2018-02-12-08-08-45.bpo-32831.srDRvU.rst @@ -0,0 +1 @@ +Add docstrings and tests for codecontext. diff --git a/Misc/NEWS.d/next/IDLE/2018-02-12-11-05-22.bpo-32826.IxNZrk.rst b/Misc/NEWS.d/next/IDLE/2018-02-12-11-05-22.bpo-32826.IxNZrk.rst new file mode 100644 index 00000000000000..4310ed2e721a51 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2018-02-12-11-05-22.bpo-32826.IxNZrk.rst @@ -0,0 +1,5 @@ +Add "encoding=utf-8" to open() in IDLE's test_help_about. +GUI test test_file_buttons() only looks at initial ascii-only lines, +but failed on systems where open() defaults to 'ascii' because +readline() internally reads and decodes far enough ahead to encounter +a non-ascii character in CREDITS.txt. diff --git a/Misc/NEWS.d/next/IDLE/2018-02-12-17-22-48.bpo-32837.-33QPl.rst b/Misc/NEWS.d/next/IDLE/2018-02-12-17-22-48.bpo-32837.-33QPl.rst new file mode 100644 index 00000000000000..258536a1cd0c6b --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2018-02-12-17-22-48.bpo-32837.-33QPl.rst @@ -0,0 +1,2 @@ +Using the system and place-dependent default encoding for open() is a bad +idea for IDLE's system and location-independent files. diff --git a/Misc/NEWS.d/next/IDLE/2018-02-19-10-56-41.bpo-32874.6pZ9Gv.rst b/Misc/NEWS.d/next/IDLE/2018-02-19-10-56-41.bpo-32874.6pZ9Gv.rst new file mode 100644 index 00000000000000..79655315fff4cd --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2018-02-19-10-56-41.bpo-32874.6pZ9Gv.rst @@ -0,0 +1 @@ +Add tests for pyparse. diff --git a/Misc/NEWS.d/next/IDLE/2018-02-22-00-09-27.bpo-32905.VlXj0x.rst b/Misc/NEWS.d/next/IDLE/2018-02-22-00-09-27.bpo-32905.VlXj0x.rst new file mode 100644 index 00000000000000..c9bedd98f2e015 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2018-02-22-00-09-27.bpo-32905.VlXj0x.rst @@ -0,0 +1 @@ +Remove unused code in pyparse module. diff --git a/Misc/NEWS.d/next/IDLE/2018-02-23-07-32-36.bpo-32916.4MsQ5F.rst b/Misc/NEWS.d/next/IDLE/2018-02-23-07-32-36.bpo-32916.4MsQ5F.rst new file mode 100644 index 00000000000000..0832944f162151 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2018-02-23-07-32-36.bpo-32916.4MsQ5F.rst @@ -0,0 +1 @@ +Change ``str`` to ``code`` in pyparse. diff --git a/Misc/NEWS.d/next/IDLE/2018-02-24-18-20-50.bpo-32940.ZaJ1Rf.rst b/Misc/NEWS.d/next/IDLE/2018-02-24-18-20-50.bpo-32940.ZaJ1Rf.rst new file mode 100644 index 00000000000000..958f9522d4f819 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2018-02-24-18-20-50.bpo-32940.ZaJ1Rf.rst @@ -0,0 +1 @@ +Simplify and rename StringTranslatePseudoMapping in pyparse. diff --git a/Misc/NEWS.d/next/IDLE/2018-03-05-01-29-05.bpo-32984.NGjgT4.rst b/Misc/NEWS.d/next/IDLE/2018-03-05-01-29-05.bpo-32984.NGjgT4.rst new file mode 100644 index 00000000000000..15d40b72caaf6a --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2018-03-05-01-29-05.bpo-32984.NGjgT4.rst @@ -0,0 +1,7 @@ +Set ``__file__`` while running a startup file. Like Python, IDLE optionally +runs one startup file in the Shell window before presenting the first interactive +input prompt. For IDLE, ``-s`` runs a file named in environmental variable + :envvar:`IDLESTARTUP` or :envvar:`PYTHONSTARTUP`; ``-r file`` runs +``file``. Python sets ``__file__`` to the startup file name before running the +file and unsets it before the first prompt. IDLE now does the same when run +normally, without the ``-n`` option. diff --git a/Misc/NEWS.d/next/IDLE/2018-04-02-00-28-13.bpo-33204.NBsuIv.rst b/Misc/NEWS.d/next/IDLE/2018-04-02-00-28-13.bpo-33204.NBsuIv.rst new file mode 100644 index 00000000000000..3ae937bab930d3 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2018-04-02-00-28-13.bpo-33204.NBsuIv.rst @@ -0,0 +1,3 @@ +IDLE: consistently color invalid string prefixes. A 'u' string prefix cannot +be paired with either 'r' or 'f'. Consistently color as much of the prefix, +starting at the right, as is valid. Revise and extend colorizer test. diff --git a/Misc/NEWS.d/next/IDLE/2018-04-29-16-13-02.bpo-21474.bglg-F.rst b/Misc/NEWS.d/next/IDLE/2018-04-29-16-13-02.bpo-21474.bglg-F.rst new file mode 100644 index 00000000000000..caf640b73b2929 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2018-04-29-16-13-02.bpo-21474.bglg-F.rst @@ -0,0 +1,3 @@ +Update word/identifier definition from ascii to unicode. In text and entry +boxes, this affects selection by double-click, movement left/right by +control-left/right, and deletion left/right by control-BACKSPACE/DEL. diff --git a/Misc/NEWS.d/next/IDLE/2018-05-17-19-41-12.bpo-33564.XzHZJe.rst b/Misc/NEWS.d/next/IDLE/2018-05-17-19-41-12.bpo-33564.XzHZJe.rst new file mode 100644 index 00000000000000..df828485f69e93 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2018-05-17-19-41-12.bpo-33564.XzHZJe.rst @@ -0,0 +1 @@ +IDLE's code context now recognizes async as a block opener. diff --git a/Misc/NEWS.d/next/IDLE/2018-05-23-19-51-07.bpo-33628.sLlFLO.rst b/Misc/NEWS.d/next/IDLE/2018-05-23-19-51-07.bpo-33628.sLlFLO.rst new file mode 100644 index 00000000000000..f0b13a21c34657 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2018-05-23-19-51-07.bpo-33628.sLlFLO.rst @@ -0,0 +1,2 @@ +IDLE: Cleanup codecontext.py and its test. + diff --git a/Misc/NEWS.d/next/IDLE/2018-05-24-20-42-44.bpo-33642.J0VQbS.rst b/Misc/NEWS.d/next/IDLE/2018-05-24-20-42-44.bpo-33642.J0VQbS.rst new file mode 100644 index 00000000000000..b1d0763a8a9fac --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2018-05-24-20-42-44.bpo-33642.J0VQbS.rst @@ -0,0 +1,2 @@ +Display up to maxlines non-blank lines for Code Context. +If there is no current context, show a single blank line. diff --git a/Misc/NEWS.d/next/IDLE/2018-05-29-07-14-37.bpo-33679.MgX_Ui.rst b/Misc/NEWS.d/next/IDLE/2018-05-29-07-14-37.bpo-33679.MgX_Ui.rst new file mode 100644 index 00000000000000..2d52fa86490deb --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2018-05-29-07-14-37.bpo-33679.MgX_Ui.rst @@ -0,0 +1,3 @@ +Enable theme-specific color configuration for Code Context. +Use the Highlights tab to see the setting for built-in themes +or add settings to custom themes. diff --git a/Misc/NEWS.d/next/IDLE/2018-06-03-09-13-28.bpo-33664.PZzQyL.rst b/Misc/NEWS.d/next/IDLE/2018-06-03-09-13-28.bpo-33664.PZzQyL.rst new file mode 100644 index 00000000000000..48f602f641c96c --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2018-06-03-09-13-28.bpo-33664.PZzQyL.rst @@ -0,0 +1,5 @@ +Scroll IDLE editor text by lines. +Previously, the mouse wheel and scrollbar slider moved text by a fixed +number of pixels, resulting in partial lines at the top of the editor +box. The change also applies to the shell and grep output windows, +but not to read-only text views. diff --git a/Misc/NEWS.d/next/IDLE/2018-06-03-20-12-57.bpo-33763.URiFlE.rst b/Misc/NEWS.d/next/IDLE/2018-06-03-20-12-57.bpo-33763.URiFlE.rst new file mode 100644 index 00000000000000..187ef650cb73db --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2018-06-03-20-12-57.bpo-33763.URiFlE.rst @@ -0,0 +1 @@ +IDLE: Use read-only text widget for code context instead of label widget. diff --git a/Misc/NEWS.d/next/IDLE/2018-06-04-19-23-11.bpo-33768.I_2qpV.rst b/Misc/NEWS.d/next/IDLE/2018-06-04-19-23-11.bpo-33768.I_2qpV.rst new file mode 100644 index 00000000000000..689aede15ac6ef --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2018-06-04-19-23-11.bpo-33768.I_2qpV.rst @@ -0,0 +1 @@ +Clicking on a context line moves that line to the top of the editor window. diff --git a/Misc/NEWS.d/next/IDLE/2018-06-10-17-59-36.bpo-33656.60ZqJS.rst b/Misc/NEWS.d/next/IDLE/2018-06-10-17-59-36.bpo-33656.60ZqJS.rst new file mode 100644 index 00000000000000..e0c51b2c0f9ef7 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2018-06-10-17-59-36.bpo-33656.60ZqJS.rst @@ -0,0 +1,4 @@ +On Windows, add API call saying that tk scales for DPI. On Windows +8.1+ or 10, with DPI compatibility properties of the Python binary +unchanged, and a monitor resolution greater than 96 DPI, this should +make text and lines sharper. It should otherwise have no effect. diff --git a/Misc/NEWS.d/next/IDLE/2018-06-14-11-35-50.bpo-33855.XL230W.rst b/Misc/NEWS.d/next/IDLE/2018-06-14-11-35-50.bpo-33855.XL230W.rst new file mode 100644 index 00000000000000..aaf4f8fe2b0aed --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2018-06-14-11-35-50.bpo-33855.XL230W.rst @@ -0,0 +1,2 @@ +Minimally test all IDLE modules. Add missing files, import module, +instantiate classes, and check coverage. Check existing files. diff --git a/Misc/NEWS.d/next/IDLE/2018-06-16-21-54-45.bpo-33856.TH8WHU.rst b/Misc/NEWS.d/next/IDLE/2018-06-16-21-54-45.bpo-33856.TH8WHU.rst new file mode 100644 index 00000000000000..058f96e681c22d --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2018-06-16-21-54-45.bpo-33856.TH8WHU.rst @@ -0,0 +1 @@ +Add "help" in the welcome message of IDLE diff --git a/Misc/NEWS.d/next/IDLE/2018-06-19-22-21-27.bpo-33907.z-_B3N.rst b/Misc/NEWS.d/next/IDLE/2018-06-19-22-21-27.bpo-33907.z-_B3N.rst new file mode 100644 index 00000000000000..b4741060bb21e3 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2018-06-19-22-21-27.bpo-33907.z-_B3N.rst @@ -0,0 +1,3 @@ +For consistency and clarity, rename an IDLE module and classes. +Module calltips and its class CallTips are now calltip and Calltip. +In module calltip_w, class CallTip is now CalltipWindow. diff --git a/Misc/NEWS.d/next/IDLE/2018-06-20-12-40-54.bpo-33904.qm0eCu.rst b/Misc/NEWS.d/next/IDLE/2018-06-20-12-40-54.bpo-33904.qm0eCu.rst new file mode 100644 index 00000000000000..efed2379b4bfa1 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2018-06-20-12-40-54.bpo-33904.qm0eCu.rst @@ -0,0 +1 @@ +IDLE: In rstrip, rename class RstripExtension as Rstrip diff --git a/Misc/NEWS.d/next/IDLE/2018-06-20-16-27-48.bpo-33917.ZXHs8x.rst b/Misc/NEWS.d/next/IDLE/2018-06-20-16-27-48.bpo-33917.ZXHs8x.rst new file mode 100644 index 00000000000000..fe62d81461cb78 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2018-06-20-16-27-48.bpo-33917.ZXHs8x.rst @@ -0,0 +1,3 @@ +Fix and document idlelib/idle_test/template.py. The revised file compiles, +runs, and tests OK. idle_test/README.txt explains how to use it to create +new IDLE test files. diff --git a/Misc/NEWS.d/next/IDLE/2018-06-20-19-16-24.bpo-33906.a1lXq0.rst b/Misc/NEWS.d/next/IDLE/2018-06-20-19-16-24.bpo-33906.a1lXq0.rst new file mode 100644 index 00000000000000..141122c3128b97 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2018-06-20-19-16-24.bpo-33906.a1lXq0.rst @@ -0,0 +1,2 @@ +Rename idlelib.windows as window Match Window on the main menu and remove +last plural module name. diff --git a/Misc/NEWS.d/next/IDLE/2018-06-20-22-14-07.bpo-33924.6Rz1wt.rst b/Misc/NEWS.d/next/IDLE/2018-06-20-22-14-07.bpo-33924.6Rz1wt.rst new file mode 100644 index 00000000000000..03f9efd43802c5 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2018-06-20-22-14-07.bpo-33924.6Rz1wt.rst @@ -0,0 +1,2 @@ +Change mainmenu.menudefs key 'windows' to 'window'. Every other menudef key +is lowercase version of main menu entry. diff --git a/Misc/NEWS.d/next/IDLE/2018-06-21-20-35-33.bpo-33905.W2mhiY.rst b/Misc/NEWS.d/next/IDLE/2018-06-21-20-35-33.bpo-33905.W2mhiY.rst new file mode 100644 index 00000000000000..c671e4791da437 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2018-06-21-20-35-33.bpo-33905.W2mhiY.rst @@ -0,0 +1 @@ +Add test for idlelib.stackview.StackBrowser. diff --git a/Misc/NEWS.d/next/IDLE/2018-06-26-22-53-14.bpo-33975.Ow7alv.rst b/Misc/NEWS.d/next/IDLE/2018-06-26-22-53-14.bpo-33975.Ow7alv.rst new file mode 100644 index 00000000000000..fd975bbff3b3a6 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2018-06-26-22-53-14.bpo-33975.Ow7alv.rst @@ -0,0 +1,3 @@ +Avoid small type when running htests. Since part of the purpose of human- +viewed tests is to determine that widgets look right, it is important that +they look the same for testing as when running IDLE. diff --git a/Misc/NEWS.d/next/Library/2017-08-24-17-55-39.bpo-29456.XaB3MP.rst b/Misc/NEWS.d/next/Library/2017-08-24-17-55-39.bpo-29456.XaB3MP.rst new file mode 100644 index 00000000000000..9b30bf654bd024 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-08-24-17-55-39.bpo-29456.XaB3MP.rst @@ -0,0 +1 @@ +Fix bugs in hangul normalization: u1176, u11a7 and u11c3 diff --git a/Misc/NEWS.d/next/Library/2017-09-19-12-38-31.bpo-31508.pDsFJl.rst b/Misc/NEWS.d/next/Library/2017-09-19-12-38-31.bpo-31508.pDsFJl.rst new file mode 100644 index 00000000000000..b3d49ee3e9a706 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-09-19-12-38-31.bpo-31508.pDsFJl.rst @@ -0,0 +1,3 @@ +Removed support of arguments in `tkinter.ttk.Treeview.selection`. It was +deprecated in 3.6. Use specialized methods like `selection_set` for +changing the selection. diff --git a/Misc/NEWS.d/next/Library/2017-09-29-16-40-38.bpo-16865.l-f6I_.rst b/Misc/NEWS.d/next/Library/2017-09-29-16-40-38.bpo-16865.l-f6I_.rst new file mode 100644 index 00000000000000..afaff736bf1ce7 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-09-29-16-40-38.bpo-16865.l-f6I_.rst @@ -0,0 +1 @@ +Support arrays >=2GiB in :mod:`ctypes`. Patch by Segev Finer. diff --git a/Misc/NEWS.d/next/Library/2017-10-05-20-41-48.bpo-27645.1Y_Wag.rst b/Misc/NEWS.d/next/Library/2017-10-05-20-41-48.bpo-27645.1Y_Wag.rst new file mode 100644 index 00000000000000..c4b7185614a50a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-10-05-20-41-48.bpo-27645.1Y_Wag.rst @@ -0,0 +1,3 @@ +:class:`sqlite3.Connection` now exposes a :class:`~sqlite3.Connection.backup` +method, if the underlying SQLite library is at version 3.6.11 +or higher. Patch by Lele Gaifax. diff --git a/Misc/NEWS.d/next/Library/2017-10-31.bpo-31908.g4xh8x.rst b/Misc/NEWS.d/next/Library/2017-10-31.bpo-31908.g4xh8x.rst new file mode 100644 index 00000000000000..700bc690764f0e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-10-31.bpo-31908.g4xh8x.rst @@ -0,0 +1,3 @@ +Fix output of cover files for ``trace`` module command-line tool. +Previously emitted cover files only when ``--missing`` option was used. +Patch by Michael Selik. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2017-11-27-15-09-49.bpo-30693.yC4mJ7.rst b/Misc/NEWS.d/next/Library/2017-11-27-15-09-49.bpo-30693.yC4mJ7.rst new file mode 100644 index 00000000000000..9c895c53de124a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-11-27-15-09-49.bpo-30693.yC4mJ7.rst @@ -0,0 +1 @@ +The ZipFile class now recurses directories in a reproducible way. diff --git a/Misc/NEWS.d/next/Library/2017-11-27-15-09-49.bpo-30693.yC4mJ8.rst b/Misc/NEWS.d/next/Library/2017-11-27-15-09-49.bpo-30693.yC4mJ8.rst new file mode 100644 index 00000000000000..a622e7ed6e5dca --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-11-27-15-09-49.bpo-30693.yC4mJ8.rst @@ -0,0 +1 @@ +The TarFile class now recurses directories in a reproducible way. diff --git a/Misc/NEWS.d/next/Library/2017-11-28-10-23-13.bpo-32147.PI2k1Y.rst b/Misc/NEWS.d/next/Library/2017-11-28-10-23-13.bpo-32147.PI2k1Y.rst new file mode 100644 index 00000000000000..e02a97c5e9e6b2 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-11-28-10-23-13.bpo-32147.PI2k1Y.rst @@ -0,0 +1,2 @@ +:func:`binascii.unhexlify` is now up to 2 times faster. +Patch by Sergey Fedoseev. diff --git a/Misc/NEWS.d/next/Library/2017-12-06-10-10-10.bpo-32221.ideco_.rst b/Misc/NEWS.d/next/Library/2017-12-06-10-10-10.bpo-32221.ideco_.rst new file mode 100644 index 00000000000000..a88dcf48e02b66 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-12-06-10-10-10.bpo-32221.ideco_.rst @@ -0,0 +1,4 @@ +Various functions returning tuple containig IPv6 addresses now omit ``%scope`` +part since the same information is already encoded in *scopeid* tuple item. +Especially this speeds up :func:`socket.recvfrom` when it receives multicast +packet since useless resolving of network interface name is omitted. diff --git a/Misc/NEWS.d/next/Library/2017-12-27-21-55-19.bpo-31639.l3avDJ.rst b/Misc/NEWS.d/next/Library/2017-12-27-21-55-19.bpo-31639.l3avDJ.rst new file mode 100644 index 00000000000000..741b276a302279 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-12-27-21-55-19.bpo-31639.l3avDJ.rst @@ -0,0 +1,2 @@ +http.server now exposes a ThreadingHTTPServer class and uses it when the +module is run with ``-m`` to cope with web browsers pre-opening sockets. diff --git a/Misc/NEWS.d/next/Library/2018-01-18-13-09-00.bpo-32585.qpeijr.rst b/Misc/NEWS.d/next/Library/2018-01-18-13-09-00.bpo-32585.qpeijr.rst new file mode 100644 index 00000000000000..0a602045bacd8f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-01-18-13-09-00.bpo-32585.qpeijr.rst @@ -0,0 +1 @@ +Add Ttk spinbox widget to :mod:`tkinter.ttk`. Patch by Alan D Moore. diff --git a/Misc/NEWS.d/next/Library/2018-01-18-23-34-17.bpo-31848.M2cldy.rst b/Misc/NEWS.d/next/Library/2018-01-18-23-34-17.bpo-31848.M2cldy.rst new file mode 100644 index 00000000000000..c8e61acb0b066b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-01-18-23-34-17.bpo-31848.M2cldy.rst @@ -0,0 +1,2 @@ +Fix the error handling in Aifc_read.initfp() when the SSND chunk is not found. +Patch by Zackery Spytz. diff --git a/Misc/NEWS.d/next/Library/2018-01-20-23-17-25.bpo-24334.GZuQLv.rst b/Misc/NEWS.d/next/Library/2018-01-20-23-17-25.bpo-24334.GZuQLv.rst new file mode 100644 index 00000000000000..2b4877fad7e17a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-01-20-23-17-25.bpo-24334.GZuQLv.rst @@ -0,0 +1,4 @@ +Internal implementation details of ssl module were cleaned up. The SSLSocket +has one less layer of indirection. Owner and session information are now +handled by the SSLSocket and SSLObject constructor. Channel binding +implementation has been simplified. diff --git a/Misc/NEWS.d/next/Library/2018-01-21-15-01-50.bpo-31453.cZiZBe.rst b/Misc/NEWS.d/next/Library/2018-01-21-15-01-50.bpo-31453.cZiZBe.rst new file mode 100644 index 00000000000000..6d43dfd8207d16 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-01-21-15-01-50.bpo-31453.cZiZBe.rst @@ -0,0 +1,4 @@ +Add TLSVersion constants and SSLContext.maximum_version / minimum_version +attributes. The new API wraps OpenSSL 1.1 +https://www.openssl.org/docs/man1.1.0/ssl/SSL_CTX_set_min_proto_version.html +feature. diff --git a/Misc/NEWS.d/next/Library/2018-01-30-17-46-18.bpo-32727.aHVsRC.rst b/Misc/NEWS.d/next/Library/2018-01-30-17-46-18.bpo-32727.aHVsRC.rst new file mode 100644 index 00000000000000..22c219636de29e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-01-30-17-46-18.bpo-32727.aHVsRC.rst @@ -0,0 +1 @@ +Do not include name field in SMTP envelope from address. Patch by Stéphane Wirtel diff --git a/Misc/NEWS.d/next/Library/2018-02-01-01-34-47.bpo-32734.gCV9AD.rst b/Misc/NEWS.d/next/Library/2018-02-01-01-34-47.bpo-32734.gCV9AD.rst new file mode 100644 index 00000000000000..14d4bbdade7527 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-02-01-01-34-47.bpo-32734.gCV9AD.rst @@ -0,0 +1,2 @@ +Fixed ``asyncio.Lock()`` safety issue which allowed acquiring and locking +the same lock multiple times, without it being free. Patch by Bar Harel. diff --git a/Misc/NEWS.d/next/Library/2018-02-01-15-53-35.bpo-32691.VLWVTq.rst b/Misc/NEWS.d/next/Library/2018-02-01-15-53-35.bpo-32691.VLWVTq.rst new file mode 100644 index 00000000000000..93f898e9c68956 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-02-01-15-53-35.bpo-32691.VLWVTq.rst @@ -0,0 +1 @@ +Use mod_spec.parent when running modules with pdb diff --git a/Misc/NEWS.d/next/Library/2018-02-01-17-54-08.bpo-32741.KUvOPL.rst b/Misc/NEWS.d/next/Library/2018-02-01-17-54-08.bpo-32741.KUvOPL.rst new file mode 100644 index 00000000000000..651e7666157a43 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-02-01-17-54-08.bpo-32741.KUvOPL.rst @@ -0,0 +1 @@ +Implement ``asyncio.TimerHandle.when()`` method. diff --git a/Misc/NEWS.d/next/Library/2018-02-02-17-21-24.bpo-32749.u5scIn.rst b/Misc/NEWS.d/next/Library/2018-02-02-17-21-24.bpo-32749.u5scIn.rst new file mode 100644 index 00000000000000..9665ff1f8ec8dc --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-02-02-17-21-24.bpo-32749.u5scIn.rst @@ -0,0 +1,3 @@ +A :mod:`dbm.dumb` database opened with flags 'r' is now read-only. +:func:`dbm.dumb.open` with flags 'r' and 'w' no longer creates a database if +it does not exist. diff --git a/Misc/NEWS.d/next/Library/2018-02-05-13-31-42.bpo-32647.ktmfR_.rst b/Misc/NEWS.d/next/Library/2018-02-05-13-31-42.bpo-32647.ktmfR_.rst new file mode 100644 index 00000000000000..04fc0247bcdefc --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-02-05-13-31-42.bpo-32647.ktmfR_.rst @@ -0,0 +1,2 @@ +The ctypes module used to depend on indirect linking for dlopen. The shared +extension is now explicitly linked against libdl on platforms with dl. diff --git a/Misc/NEWS.d/next/Library/2018-02-05-21-28-28.bpo-32777.C-wIXF.rst b/Misc/NEWS.d/next/Library/2018-02-05-21-28-28.bpo-32777.C-wIXF.rst new file mode 100644 index 00000000000000..d5d7d7b27dc775 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-02-05-21-28-28.bpo-32777.C-wIXF.rst @@ -0,0 +1,3 @@ +Fix a rare but potential pre-exec child process deadlock in subprocess on +POSIX systems when marking file descriptors inheritable on exec in the child +process. This bug appears to have been introduced in 3.4. diff --git a/Misc/NEWS.d/next/Library/2018-02-06-17-58-15.bpo-32622.AE0Jz7.rst b/Misc/NEWS.d/next/Library/2018-02-06-17-58-15.bpo-32622.AE0Jz7.rst new file mode 100644 index 00000000000000..456a6dc55959a8 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-02-06-17-58-15.bpo-32622.AE0Jz7.rst @@ -0,0 +1 @@ +Implement native fast sendfile for Windows proactor event loop. diff --git a/Misc/NEWS.d/next/Library/2018-02-07-19-12-10.bpo-32775.-T77_c.rst b/Misc/NEWS.d/next/Library/2018-02-07-19-12-10.bpo-32775.-T77_c.rst new file mode 100644 index 00000000000000..ed563c17fdc8a1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-02-07-19-12-10.bpo-32775.-T77_c.rst @@ -0,0 +1,5 @@ +:func:`fnmatch.translate()` no longer produces patterns which contain set +operations. Sets starting with '[' or containing '--', '&&', '~~' or '||' +will be interpreted differently in regular expressions in future versions. +Currently they emit warnings. fnmatch.translate() now avoids producing +patterns containing such sets by accident. diff --git a/Misc/NEWS.d/next/Library/2018-02-08-00-47-07.bpo-32792.NtyDb4.rst b/Misc/NEWS.d/next/Library/2018-02-08-00-47-07.bpo-32792.NtyDb4.rst new file mode 100644 index 00000000000000..1f7df62cc3e12e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-02-08-00-47-07.bpo-32792.NtyDb4.rst @@ -0,0 +1 @@ +collections.ChainMap() preserves the order of the underlying mappings. diff --git a/Misc/NEWS.d/next/Library/2018-02-08-18-59-11.bpo-30688.zBh4TH.rst b/Misc/NEWS.d/next/Library/2018-02-08-18-59-11.bpo-30688.zBh4TH.rst new file mode 100644 index 00000000000000..7d31680d651a59 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-02-08-18-59-11.bpo-30688.zBh4TH.rst @@ -0,0 +1,2 @@ +Added support of ``\N{name}`` escapes in regular expressions. Based on +patch by Jonathan Eunice. diff --git a/Misc/NEWS.d/next/Library/2018-02-09-14-44-43.bpo-30157.lEiiAK.rst b/Misc/NEWS.d/next/Library/2018-02-09-14-44-43.bpo-30157.lEiiAK.rst new file mode 100644 index 00000000000000..9f651930ac2b4b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-02-09-14-44-43.bpo-30157.lEiiAK.rst @@ -0,0 +1,2 @@ +Fixed guessing quote and delimiter in csv.Sniffer.sniff() when only the last +field is quoted. Patch by Jake Davis. diff --git a/Misc/NEWS.d/next/Library/2018-02-09-21-41-56.bpo-31787.owSZ2t.rst b/Misc/NEWS.d/next/Library/2018-02-09-21-41-56.bpo-31787.owSZ2t.rst new file mode 100644 index 00000000000000..f0cde59d740f06 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-02-09-21-41-56.bpo-31787.owSZ2t.rst @@ -0,0 +1,2 @@ +Fixed refleaks of ``__init__()`` methods in various modules. +(Contributed by Oren Milman) diff --git a/Misc/NEWS.d/next/Library/2018-02-10-13-51-56.bpo-32394.dFM9SI.rst b/Misc/NEWS.d/next/Library/2018-02-10-13-51-56.bpo-32394.dFM9SI.rst new file mode 100644 index 00000000000000..ee5807619a9376 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-02-10-13-51-56.bpo-32394.dFM9SI.rst @@ -0,0 +1,2 @@ +socket: Remove TCP_FASTOPEN,TCP_KEEPCNT,TCP_KEEPIDLE,TCP_KEEPINTVL flags on +older version Windows during run-time. diff --git a/Misc/NEWS.d/next/Library/2018-02-11-15-54-41.bpo-32819.ZTRX2Q.rst b/Misc/NEWS.d/next/Library/2018-02-11-15-54-41.bpo-32819.ZTRX2Q.rst new file mode 100644 index 00000000000000..7d57bf6978265b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-02-11-15-54-41.bpo-32819.ZTRX2Q.rst @@ -0,0 +1,3 @@ +ssl.match_hostname() has been simplified and no longer depends on re and +ipaddress module for wildcard and IP addresses. Error reporting for invalid +wildcards has been improved. diff --git a/Misc/NEWS.d/next/Library/2018-02-14-00-21-24.bpo-32841.bvHDOc.rst b/Misc/NEWS.d/next/Library/2018-02-14-00-21-24.bpo-32841.bvHDOc.rst new file mode 100644 index 00000000000000..a6d45669d02708 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-02-14-00-21-24.bpo-32841.bvHDOc.rst @@ -0,0 +1,2 @@ +Fixed `asyncio.Condition` issue which silently ignored cancellation after +notifying and cancelling a conditional lock. Patch by Bar Harel. diff --git a/Misc/NEWS.d/next/Library/2018-02-15-08-18-52.bpo-31333.4fF-gM.rst b/Misc/NEWS.d/next/Library/2018-02-15-08-18-52.bpo-31333.4fF-gM.rst new file mode 100644 index 00000000000000..63fc72a5c11be6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-02-15-08-18-52.bpo-31333.4fF-gM.rst @@ -0,0 +1,10 @@ +``_abc`` module is added. It is a speedup module with C implementations for +various functions and methods in ``abc``. Creating an ABC subclass and calling +``isinstance`` or ``issubclass`` with an ABC subclass are up to 1.5x faster. +In addition, this makes Python start-up up to 10% faster. + +Note that the new implementation hides internal registry and caches, previously +accessible via private attributes ``_abc_registry``, ``_abc_cache``, and +``_abc_negative_cache``. There are three debugging helper methods that can be +used instead ``_dump_registry``, ``_abc_registry_clear``, and +``_abc_caches_clear``. diff --git a/Misc/NEWS.d/next/Library/2018-02-15-12-04-29.bpo-32852.HDqIxM.rst b/Misc/NEWS.d/next/Library/2018-02-15-12-04-29.bpo-32852.HDqIxM.rst new file mode 100644 index 00000000000000..8eabbfaea2223c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-02-15-12-04-29.bpo-32852.HDqIxM.rst @@ -0,0 +1 @@ +Make sure sys.argv remains as a list when running trace. diff --git a/Misc/NEWS.d/next/Library/2018-02-16-14-37-14.bpo-32857.-XljAx.rst b/Misc/NEWS.d/next/Library/2018-02-16-14-37-14.bpo-32857.-XljAx.rst new file mode 100644 index 00000000000000..4ebbde4d194611 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-02-16-14-37-14.bpo-32857.-XljAx.rst @@ -0,0 +1 @@ +In :mod:`tkinter`, ``after_cancel(None)`` now raises a :exc:`ValueError` instead of canceling the first scheduled function. Patch by Cheryl Sabella. diff --git a/Misc/NEWS.d/next/Library/2018-02-17-19-20-19.bpo-21060.S1Z-x6.rst b/Misc/NEWS.d/next/Library/2018-02-17-19-20-19.bpo-21060.S1Z-x6.rst new file mode 100644 index 00000000000000..4e0a113620868a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-02-17-19-20-19.bpo-21060.S1Z-x6.rst @@ -0,0 +1,3 @@ +Rewrite confusing message from setup.py upload from +"No dist file created in earlier command" to the more helpful +"Must create and upload files in one command". diff --git a/Misc/NEWS.d/next/Library/2018-02-19-14-27-51.bpo-32556.CsRsgr.rst b/Misc/NEWS.d/next/Library/2018-02-19-14-27-51.bpo-32556.CsRsgr.rst new file mode 100644 index 00000000000000..1a475b308f5ea2 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-02-19-14-27-51.bpo-32556.CsRsgr.rst @@ -0,0 +1,2 @@ +nt._getfinalpathname, nt._getvolumepathname and nt._getdiskusage now +correctly convert from bytes. diff --git a/Misc/NEWS.d/next/Library/2018-02-19-17-46-31.bpo-32859.kAT-Xp.rst b/Misc/NEWS.d/next/Library/2018-02-19-17-46-31.bpo-32859.kAT-Xp.rst new file mode 100644 index 00000000000000..755bdc11861010 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-02-19-17-46-31.bpo-32859.kAT-Xp.rst @@ -0,0 +1,2 @@ +In ``os.dup2``, don't check every call whether the ``dup3`` syscall exists +or not. diff --git a/Misc/NEWS.d/next/Library/2018-02-23-12-21-41.bpo-32759.M-y9GA.rst b/Misc/NEWS.d/next/Library/2018-02-23-12-21-41.bpo-32759.M-y9GA.rst new file mode 100644 index 00000000000000..e9bd326b4af153 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-02-23-12-21-41.bpo-32759.M-y9GA.rst @@ -0,0 +1 @@ +Free unused arenas in multiprocessing.heap. diff --git a/Misc/NEWS.d/next/Library/2018-02-23-19-12-04.bpo-32922.u-xe0B.rst b/Misc/NEWS.d/next/Library/2018-02-23-19-12-04.bpo-32922.u-xe0B.rst new file mode 100644 index 00000000000000..412e588586c02c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-02-23-19-12-04.bpo-32922.u-xe0B.rst @@ -0,0 +1,2 @@ +dbm.open() now encodes filename with the filesystem encoding rather than +default encoding. diff --git a/Misc/NEWS.d/next/Library/2018-02-24-21-40-42.bpo-30622.dQjxSe.rst b/Misc/NEWS.d/next/Library/2018-02-24-21-40-42.bpo-30622.dQjxSe.rst new file mode 100644 index 00000000000000..bcb659b24dd348 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-02-24-21-40-42.bpo-30622.dQjxSe.rst @@ -0,0 +1 @@ +The ssl module now detects missing NPN support in LibreSSL. diff --git a/Misc/NEWS.d/next/Library/2018-02-25-13-06-21.bpo-32947.mqStVW.rst b/Misc/NEWS.d/next/Library/2018-02-25-13-06-21.bpo-32947.mqStVW.rst new file mode 100644 index 00000000000000..28de360c367170 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-02-25-13-06-21.bpo-32947.mqStVW.rst @@ -0,0 +1,2 @@ +Add OP_ENABLE_MIDDLEBOX_COMPAT and test workaround for TLSv1.3 for future +compatibility with OpenSSL 1.1.1. diff --git a/Misc/NEWS.d/next/Library/2018-02-25-13-47-48.bpo-32929.X2gTDH.rst b/Misc/NEWS.d/next/Library/2018-02-25-13-47-48.bpo-32929.X2gTDH.rst new file mode 100644 index 00000000000000..b8a470cbf28085 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-02-25-13-47-48.bpo-32929.X2gTDH.rst @@ -0,0 +1,6 @@ +Remove the tri-state parameter "hash", and add the boolean "unsafe_hash". If +unsafe_hash is True, add a __hash__ function, but if a __hash__ exists, +raise TypeError. If unsafe_hash is False, add a __hash__ based on the +values of eq= and frozen=. The unsafe_hash=False behavior is the same as +the old hash=None behavior. unsafe_hash=False is the default, just as +hash=None used to be. diff --git a/Misc/NEWS.d/next/Library/2018-02-25-18-22-01.bpo-32951.gHrCXq.rst b/Misc/NEWS.d/next/Library/2018-02-25-18-22-01.bpo-32951.gHrCXq.rst new file mode 100644 index 00000000000000..9c038cf2597961 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-02-25-18-22-01.bpo-32951.gHrCXq.rst @@ -0,0 +1,3 @@ +Direct instantiation of SSLSocket and SSLObject objects is now prohibited. +The constructors were never documented, tested, or designed as public +constructors. Users were suppose to use ssl.wrap_socket() or SSLContext. diff --git a/Misc/NEWS.d/next/Library/2018-02-26-09-08-07.bpo-32257.6ElnUt.rst b/Misc/NEWS.d/next/Library/2018-02-26-09-08-07.bpo-32257.6ElnUt.rst new file mode 100644 index 00000000000000..e74c39b6810015 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-02-26-09-08-07.bpo-32257.6ElnUt.rst @@ -0,0 +1,2 @@ +The ssl module now contains OP_NO_RENEGOTIATION constant, available with +OpenSSL 1.1.0h or 1.1.1. diff --git a/Misc/NEWS.d/next/Library/2018-02-26-13-16-36.bpo-32713.55yegW.rst b/Misc/NEWS.d/next/Library/2018-02-26-13-16-36.bpo-32713.55yegW.rst new file mode 100644 index 00000000000000..bb5d64a351cb3f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-02-26-13-16-36.bpo-32713.55yegW.rst @@ -0,0 +1 @@ +Fixed tarfile.itn handling of out-of-bounds float values. Patch by Joffrey Fuhrer. diff --git a/Misc/NEWS.d/next/Library/2018-02-26-20-04-40.bpo-32960.48r0Ml.rst b/Misc/NEWS.d/next/Library/2018-02-26-20-04-40.bpo-32960.48r0Ml.rst new file mode 100644 index 00000000000000..4ad1fa17571dd5 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-02-26-20-04-40.bpo-32960.48r0Ml.rst @@ -0,0 +1,3 @@ +For dataclasses, disallow inheriting frozen from non-frozen classes, and +also disallow inheriting non-frozen from frozen classes. This restriction +will be relaxed at a future date. diff --git a/Misc/NEWS.d/next/Library/2018-02-28-13-08-00.bpo-32844.u8tnAe.rst b/Misc/NEWS.d/next/Library/2018-02-28-13-08-00.bpo-32844.u8tnAe.rst new file mode 100644 index 00000000000000..67412fe5ba46d0 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-02-28-13-08-00.bpo-32844.u8tnAe.rst @@ -0,0 +1,2 @@ +Fix wrong redirection of a low descriptor (0 or 1) to stderr in subprocess +if another low descriptor is closed. diff --git a/Misc/NEWS.d/next/Library/2018-02-28-18-39-48.bpo-32970.IPWtbS.rst b/Misc/NEWS.d/next/Library/2018-02-28-18-39-48.bpo-32970.IPWtbS.rst new file mode 100644 index 00000000000000..e97c16df5a0db8 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-02-28-18-39-48.bpo-32970.IPWtbS.rst @@ -0,0 +1 @@ +Improved disassembly of the MAKE_FUNCTION instruction. diff --git a/Misc/NEWS.d/next/Library/2018-03-01-17-49-56.bpo-32056.IlpfgE.rst b/Misc/NEWS.d/next/Library/2018-03-01-17-49-56.bpo-32056.IlpfgE.rst new file mode 100644 index 00000000000000..421aa3767794e0 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-03-01-17-49-56.bpo-32056.IlpfgE.rst @@ -0,0 +1,3 @@ +Improved exceptions raised for invalid number of channels and sample width +when read an audio file in modules :mod:`aifc`, :mod:`wave` and +:mod:`sunau`. diff --git a/Misc/NEWS.d/next/Library/2018-03-06-00-19-41.bpo-32969.rGTKa0.rst b/Misc/NEWS.d/next/Library/2018-03-06-00-19-41.bpo-32969.rGTKa0.rst new file mode 100644 index 00000000000000..a92307e67bfa54 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-03-06-00-19-41.bpo-32969.rGTKa0.rst @@ -0,0 +1,2 @@ +Expose several missing constants in zlib and fix corresponding +documentation. diff --git a/Misc/NEWS.d/next/Library/2018-03-06-11-54-59.bpo-33009.-Ekysb.rst b/Misc/NEWS.d/next/Library/2018-03-06-11-54-59.bpo-33009.-Ekysb.rst new file mode 100644 index 00000000000000..96bc70a8c9442d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-03-06-11-54-59.bpo-33009.-Ekysb.rst @@ -0,0 +1 @@ +Fix inspect.signature() for single-parameter partialmethods. diff --git a/Misc/NEWS.d/next/Library/2018-03-06-20-30-20.bpo-32999.lgFXWl.rst b/Misc/NEWS.d/next/Library/2018-03-06-20-30-20.bpo-32999.lgFXWl.rst new file mode 100644 index 00000000000000..45e75f939310c6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-03-06-20-30-20.bpo-32999.lgFXWl.rst @@ -0,0 +1,2 @@ +Fix C implemetation of ``ABC.__subclasscheck__(cls, subclass)`` crashed when +``subclass`` is not a type object. diff --git a/Misc/NEWS.d/next/Library/2018-03-07-19-37-00.bpo-22674.2sIMmM.rst b/Misc/NEWS.d/next/Library/2018-03-07-19-37-00.bpo-22674.2sIMmM.rst new file mode 100644 index 00000000000000..a9af5da46ef160 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-03-07-19-37-00.bpo-22674.2sIMmM.rst @@ -0,0 +1,2 @@ +Add the strsignal() function in the signal module that returns the system +description of the given signal, as returned by strsignal(3). diff --git a/Misc/NEWS.d/next/Library/2018-03-07-22-28-17.bpo-27683.572Rv4.rst b/Misc/NEWS.d/next/Library/2018-03-07-22-28-17.bpo-27683.572Rv4.rst new file mode 100644 index 00000000000000..4e6dfa8e978cd1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-03-07-22-28-17.bpo-27683.572Rv4.rst @@ -0,0 +1,3 @@ +Fix a regression in :mod:`ipaddress` that result of :meth:`hosts` +is empty when the network is constructed by a tuple containing an +integer mask and only 1 bit left for addresses. diff --git a/Misc/NEWS.d/next/Library/2018-03-09-23-07-07.bpo-33037.nAJ3at.rst b/Misc/NEWS.d/next/Library/2018-03-09-23-07-07.bpo-33037.nAJ3at.rst new file mode 100644 index 00000000000000..2732eeb4534ba9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-03-09-23-07-07.bpo-33037.nAJ3at.rst @@ -0,0 +1 @@ +Skip sending/receiving data after SSL transport closing. diff --git a/Misc/NEWS.d/next/Library/2018-03-11-00-20-26.bpo-30249.KSkgLB.rst b/Misc/NEWS.d/next/Library/2018-03-11-00-20-26.bpo-30249.KSkgLB.rst new file mode 100644 index 00000000000000..f30dff3124eb07 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-03-11-00-20-26.bpo-30249.KSkgLB.rst @@ -0,0 +1,2 @@ +Improve struct.unpack_from() exception messages for problems with the buffer +size and offset. diff --git a/Misc/NEWS.d/next/Library/2018-03-11-08-44-12.bpo-33034.bpb23d.rst b/Misc/NEWS.d/next/Library/2018-03-11-08-44-12.bpo-33034.bpb23d.rst new file mode 100644 index 00000000000000..c81683abf59286 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-03-11-08-44-12.bpo-33034.bpb23d.rst @@ -0,0 +1,3 @@ +Providing an explicit error message when casting the port property to anything +that is not an integer value using ``urlparse()`` and ``urlsplit()``. +Patch by Matt Eaton. diff --git a/Misc/NEWS.d/next/Library/2018-03-11-19-03-52.bpo-31804.i8KUMp.rst b/Misc/NEWS.d/next/Library/2018-03-11-19-03-52.bpo-31804.i8KUMp.rst new file mode 100644 index 00000000000000..7fcede297aca31 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-03-11-19-03-52.bpo-31804.i8KUMp.rst @@ -0,0 +1,2 @@ +Avoid failing in multiprocessing.Process if the standard streams are closed +or None at exit. diff --git a/Misc/NEWS.d/next/Library/2018-03-12-00-27-56.bpo-33021.m19B9T.rst b/Misc/NEWS.d/next/Library/2018-03-12-00-27-56.bpo-33021.m19B9T.rst new file mode 100644 index 00000000000000..50dfafe600d8d4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-03-12-00-27-56.bpo-33021.m19B9T.rst @@ -0,0 +1,2 @@ +Release the GIL during fstat() calls, avoiding hang of all threads when +calling mmap.mmap(), os.urandom(), and random.seed(). Patch by Nir Soffer. diff --git a/Misc/NEWS.d/next/Library/2018-03-12-16-40-00.bpo-33056.lNN9Eh.rst b/Misc/NEWS.d/next/Library/2018-03-12-16-40-00.bpo-33056.lNN9Eh.rst new file mode 100644 index 00000000000000..6acc19a36dc8e3 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-03-12-16-40-00.bpo-33056.lNN9Eh.rst @@ -0,0 +1 @@ +FIX properly close leaking fds in concurrent.futures.ProcessPoolExecutor. diff --git a/Misc/NEWS.d/next/Library/2018-03-12-19-58-25.bpo-33064.LO2KIY.rst b/Misc/NEWS.d/next/Library/2018-03-12-19-58-25.bpo-33064.LO2KIY.rst new file mode 100644 index 00000000000000..c8e955e335cb76 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-03-12-19-58-25.bpo-33064.LO2KIY.rst @@ -0,0 +1,2 @@ +lib2to3 now properly supports trailing commas after ``*args`` and +``**kwargs`` in function signatures. diff --git a/Misc/NEWS.d/next/Library/2018-03-15-07-38-00.bpo-33078.RmjUF5.rst b/Misc/NEWS.d/next/Library/2018-03-15-07-38-00.bpo-33078.RmjUF5.rst new file mode 100644 index 00000000000000..55c2b1de8668d1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-03-15-07-38-00.bpo-33078.RmjUF5.rst @@ -0,0 +1,2 @@ +Fix the size handling in multiprocessing.Queue when a pickling error +occurs. diff --git a/Misc/NEWS.d/next/Library/2018-03-16-16-07-33.bpo-33061.TRTTek.rst b/Misc/NEWS.d/next/Library/2018-03-16-16-07-33.bpo-33061.TRTTek.rst new file mode 100644 index 00000000000000..b82ffb73a1434b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-03-16-16-07-33.bpo-33061.TRTTek.rst @@ -0,0 +1 @@ +Add missing ``NoReturn`` to ``__all__`` in typing.py diff --git a/Misc/NEWS.d/next/Library/2018-03-18-16-48-23.bpo-33097.Yl4gI2.rst b/Misc/NEWS.d/next/Library/2018-03-18-16-48-23.bpo-33097.Yl4gI2.rst new file mode 100644 index 00000000000000..d9411eb5162353 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-03-18-16-48-23.bpo-33097.Yl4gI2.rst @@ -0,0 +1,2 @@ +Raise RuntimeError when ``executor.submit`` is called during interpreter +shutdown. diff --git a/Misc/NEWS.d/next/Library/2018-03-18-17-38-48.bpo-32953.t8WAWN.rst b/Misc/NEWS.d/next/Library/2018-03-18-17-38-48.bpo-32953.t8WAWN.rst new file mode 100644 index 00000000000000..03c1162c783318 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-03-18-17-38-48.bpo-32953.t8WAWN.rst @@ -0,0 +1,4 @@ +If a non-dataclass inherits from a frozen dataclass, allow attributes to be +added to the derived class. Only attributes from the frozen dataclass +cannot be assigned to. Require all dataclasses in a hierarchy to be either +all frozen or all non-frozen. diff --git a/Misc/NEWS.d/next/Library/2018-03-19-20-47-00.bpo-33100.chyIO4.rst b/Misc/NEWS.d/next/Library/2018-03-19-20-47-00.bpo-33100.chyIO4.rst new file mode 100644 index 00000000000000..080a55c0cfb70a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-03-19-20-47-00.bpo-33100.chyIO4.rst @@ -0,0 +1,2 @@ +Dataclasses: If a field has a default value that's a MemberDescriptorType, +then it's from that field being in __slots__, not an actual default value. diff --git a/Misc/NEWS.d/next/Library/2018-03-20-20-53-21.bpo-32896.ewW3Ln.rst b/Misc/NEWS.d/next/Library/2018-03-20-20-53-21.bpo-32896.ewW3Ln.rst new file mode 100644 index 00000000000000..8363da4667a180 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-03-20-20-53-21.bpo-32896.ewW3Ln.rst @@ -0,0 +1,2 @@ +Fix an error where subclassing a dataclass with a field that uses a +default_factory would generate an incorrect class. diff --git a/Misc/NEWS.d/next/Library/2018-03-21-16-52-26.bpo-33116.Tvzerj.rst b/Misc/NEWS.d/next/Library/2018-03-21-16-52-26.bpo-33116.Tvzerj.rst new file mode 100644 index 00000000000000..90072d8e3030b7 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-03-21-16-52-26.bpo-33116.Tvzerj.rst @@ -0,0 +1 @@ +Add 'Field' to dataclasses.__all__. diff --git a/Misc/NEWS.d/next/Library/2018-03-21-17-59-39.bpo-33078.PQOniT.rst b/Misc/NEWS.d/next/Library/2018-03-21-17-59-39.bpo-33078.PQOniT.rst new file mode 100644 index 00000000000000..8b71bb32e0ecfc --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-03-21-17-59-39.bpo-33078.PQOniT.rst @@ -0,0 +1 @@ +Fix the failure on OSX caused by the tests relying on sem_getvalue diff --git a/Misc/NEWS.d/next/Library/2018-03-22-16-05-56.bpo-32505.YK1N8v.rst b/Misc/NEWS.d/next/Library/2018-03-22-16-05-56.bpo-32505.YK1N8v.rst new file mode 100644 index 00000000000000..91e97bf53f658b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-03-22-16-05-56.bpo-32505.YK1N8v.rst @@ -0,0 +1,2 @@ +Raise TypeError if a member variable of a dataclass is of type Field, but +doesn't have a type annotation. diff --git a/Misc/NEWS.d/next/Library/2018-03-24-15-08-24.bpo-33127.olJmHv.rst b/Misc/NEWS.d/next/Library/2018-03-24-15-08-24.bpo-33127.olJmHv.rst new file mode 100644 index 00000000000000..635aabbde0311b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-03-24-15-08-24.bpo-33127.olJmHv.rst @@ -0,0 +1 @@ +The ssl module now compiles with LibreSSL 2.7.1. diff --git a/Misc/NEWS.d/next/Library/2018-03-24-19-34-26.bpo-33134.hbVeIX.rst b/Misc/NEWS.d/next/Library/2018-03-24-19-34-26.bpo-33134.hbVeIX.rst new file mode 100644 index 00000000000000..3f4ce84bef765d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-03-24-19-34-26.bpo-33134.hbVeIX.rst @@ -0,0 +1,3 @@ +When computing dataclass's __hash__, use the lookup table to contain the +function which returns the __hash__ value. This is an improvement over +looking up a string, and then testing that string to see what to do. diff --git a/Misc/NEWS.d/next/Library/2018-03-24-19-54-48.bpo-32873.cHyoAm.rst b/Misc/NEWS.d/next/Library/2018-03-24-19-54-48.bpo-32873.cHyoAm.rst new file mode 100644 index 00000000000000..99f8088cf13878 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-03-24-19-54-48.bpo-32873.cHyoAm.rst @@ -0,0 +1,3 @@ +Treat type variables and special typing forms as immutable by copy and +pickle. This fixes several minor issues and inconsistencies, and improves +backwards compatibility with Python 3.6. diff --git a/Misc/NEWS.d/next/Library/2018-03-25-13-18-16.bpo-33096.ofdbe7.rst b/Misc/NEWS.d/next/Library/2018-03-25-13-18-16.bpo-33096.ofdbe7.rst new file mode 100644 index 00000000000000..c55ea20b337d77 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-03-25-13-18-16.bpo-33096.ofdbe7.rst @@ -0,0 +1,4 @@ +Allow ttk.Treeview.insert to insert iid that has a false boolean value. +Note iid=0 and iid=False would be same. +Patch by Garvit Khatri. + diff --git a/Misc/NEWS.d/next/Library/2018-03-26-12-33-13.bpo-33141.23wlxf.rst b/Misc/NEWS.d/next/Library/2018-03-26-12-33-13.bpo-33141.23wlxf.rst new file mode 100644 index 00000000000000..1d49c08fed5449 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-03-26-12-33-13.bpo-33141.23wlxf.rst @@ -0,0 +1,2 @@ +Have Field objects pass through __set_name__ to their default values, if +they have their own __set_name__. diff --git a/Misc/NEWS.d/next/Library/2018-03-29-03-09-22.bpo-32380.NhuGig.rst b/Misc/NEWS.d/next/Library/2018-03-29-03-09-22.bpo-32380.NhuGig.rst new file mode 100644 index 00000000000000..ab852a53e92ad5 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-03-29-03-09-22.bpo-32380.NhuGig.rst @@ -0,0 +1,2 @@ +Create functools.singledispatchmethod to support generic single dispatch on +descriptors and methods. diff --git a/Misc/NEWS.d/next/Library/2018-03-29-04-32-25.bpo-33175._zs1yM.rst b/Misc/NEWS.d/next/Library/2018-03-29-04-32-25.bpo-33175._zs1yM.rst new file mode 100644 index 00000000000000..c872499cd67942 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-03-29-04-32-25.bpo-33175._zs1yM.rst @@ -0,0 +1,2 @@ +In dataclasses, Field.__set_name__ now looks up the __set_name__ special +method on the class, not the instance, of the default value. diff --git a/Misc/NEWS.d/next/Library/2018-04-01-19-21-04.bpo-20104.-AKcGa.rst b/Misc/NEWS.d/next/Library/2018-04-01-19-21-04.bpo-20104.-AKcGa.rst new file mode 100644 index 00000000000000..150401dc741203 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-04-01-19-21-04.bpo-20104.-AKcGa.rst @@ -0,0 +1 @@ +Improved error handling and fixed a reference leak in :func:`os.posix_spawn()`. diff --git a/Misc/NEWS.d/next/Library/2018-04-02-16-10-12.bpo-23403.KG7ADV.rst b/Misc/NEWS.d/next/Library/2018-04-02-16-10-12.bpo-23403.KG7ADV.rst new file mode 100644 index 00000000000000..d1fbbebfadc6be --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-04-02-16-10-12.bpo-23403.KG7ADV.rst @@ -0,0 +1,4 @@ +``DEFAULT_PROTOCOL`` in :mod:`pickle` was bumped to 4. Protocol 4 is +described in :pep:`3154` and available since Python 3.4. It offers +better performance and smaller size compared to protocol 3 introduced +in Python 3.0. diff --git a/Misc/NEWS.d/next/Library/2018-04-02-20-44-54.bpo-32861.HeBjzN.rst b/Misc/NEWS.d/next/Library/2018-04-02-20-44-54.bpo-32861.HeBjzN.rst new file mode 100644 index 00000000000000..2bb24d7edab54d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-04-02-20-44-54.bpo-32861.HeBjzN.rst @@ -0,0 +1,4 @@ +The urllib.robotparser's ``__str__`` representation now includes wildcard +entries and the "Crawl-delay" and "Request-rate" fields. Also removes extra +newlines that were being appended to the end of the string. Patch by +Michael Lazar. diff --git a/Misc/NEWS.d/next/Library/2018-04-03-10-37-13.bpo-33209.9sGWE_.rst b/Misc/NEWS.d/next/Library/2018-04-03-10-37-13.bpo-33209.9sGWE_.rst new file mode 100644 index 00000000000000..d98b1e174e5518 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-04-03-10-37-13.bpo-33209.9sGWE_.rst @@ -0,0 +1 @@ +End framing at the end of C implementation of :func:`pickle.Pickler.dump`. diff --git a/Misc/NEWS.d/next/Library/2018-04-04-23-41-30.bpo-33224.pyR0jB.rst b/Misc/NEWS.d/next/Library/2018-04-04-23-41-30.bpo-33224.pyR0jB.rst new file mode 100644 index 00000000000000..87ff100da4b696 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-04-04-23-41-30.bpo-33224.pyR0jB.rst @@ -0,0 +1,2 @@ +Update difflib.mdiff() for PEP 479. Convert an uncaught StopIteration in a +generator into a return-statement. diff --git a/Misc/NEWS.d/next/Library/2018-04-05-11-09-45.bpo-33203.Hje9Py.rst b/Misc/NEWS.d/next/Library/2018-04-05-11-09-45.bpo-33203.Hje9Py.rst new file mode 100644 index 00000000000000..ab6d17b5d1baf1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-04-05-11-09-45.bpo-33203.Hje9Py.rst @@ -0,0 +1,3 @@ +``random.Random.choice()`` now raises ``IndexError`` for empty sequences +consistently even when called from subclasses without a ``getrandbits()`` +implementation. diff --git a/Misc/NEWS.d/next/Library/2018-04-06-14-56-26.bpo-33169.ByhDqb.rst b/Misc/NEWS.d/next/Library/2018-04-06-14-56-26.bpo-33169.ByhDqb.rst new file mode 100644 index 00000000000000..b5bacfcb57325f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-04-06-14-56-26.bpo-33169.ByhDqb.rst @@ -0,0 +1,2 @@ +Delete entries of ``None`` in :data:`sys.path_importer_cache` when +:meth:`importlib.machinery.invalidate_caches` is called. diff --git a/Misc/NEWS.d/next/Library/2018-04-07-13-49-39.bpo-29613.r6FDnB.rst b/Misc/NEWS.d/next/Library/2018-04-07-13-49-39.bpo-29613.r6FDnB.rst new file mode 100644 index 00000000000000..a679cd91194fa9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-04-07-13-49-39.bpo-29613.r6FDnB.rst @@ -0,0 +1,2 @@ +Added support for the ``SameSite`` cookie flag to the ``http.cookies`` +module. diff --git a/Misc/NEWS.d/next/Library/2018-04-08-22-54-07.bpo-33185.Id-Ba9.rst b/Misc/NEWS.d/next/Library/2018-04-08-22-54-07.bpo-33185.Id-Ba9.rst new file mode 100644 index 00000000000000..1f51d7e5120dde --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-04-08-22-54-07.bpo-33185.Id-Ba9.rst @@ -0,0 +1,5 @@ +Fixed regression when running pydoc with the :option:`-m` switch. (The regression +was introduced in 3.7.0b3 by the resolution of :issue:`33053`) + +This fix also changed pydoc to add ``os.getcwd()`` to :data:`sys.path` when +necessary, rather than adding ``"."``. diff --git a/Misc/NEWS.d/next/Library/2018-04-10-14-50-30.bpo-33144.iZr4et.rst b/Misc/NEWS.d/next/Library/2018-04-10-14-50-30.bpo-33144.iZr4et.rst new file mode 100644 index 00000000000000..eb6b9b7fe08d66 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-04-10-14-50-30.bpo-33144.iZr4et.rst @@ -0,0 +1,4 @@ +``random.Random()`` and its subclassing mechanism got optimized to check only +once at class/subclass instantiation time whether its ``getrandbits()`` method +can be relied on by other methods, including ``randrange()``, for the +generation of arbitrarily large random integers. Patch by Wolfgang Maier. diff --git a/Misc/NEWS.d/next/Library/2018-04-10-20-57-14.bpo-33256.ndHkqu.rst b/Misc/NEWS.d/next/Library/2018-04-10-20-57-14.bpo-33256.ndHkqu.rst new file mode 100644 index 00000000000000..a0605c04b4deee --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-04-10-20-57-14.bpo-33256.ndHkqu.rst @@ -0,0 +1 @@ +Fix display of ``<module>`` call in the html produced by ``cgitb.html()``. Patch by Stéphane Blondon. diff --git a/Misc/NEWS.d/next/Library/2018-04-11-20-29-19.bpo-33263.B56Hc1.rst b/Misc/NEWS.d/next/Library/2018-04-11-20-29-19.bpo-33263.B56Hc1.rst new file mode 100644 index 00000000000000..77994f6a598632 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-04-11-20-29-19.bpo-33263.B56Hc1.rst @@ -0,0 +1 @@ +Fix FD leak in `_SelectorSocketTransport` Patch by Vlad Starostin. diff --git a/Misc/NEWS.d/next/Library/2018-04-13-08-12-50.bpo-33265.KPQRk0.rst b/Misc/NEWS.d/next/Library/2018-04-13-08-12-50.bpo-33265.KPQRk0.rst new file mode 100644 index 00000000000000..523ceb9be1d6ed --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-04-13-08-12-50.bpo-33265.KPQRk0.rst @@ -0,0 +1,2 @@ +``contextlib.ExitStack`` and ``contextlib.AsyncExitStack`` now use a method +instead of a wrapper function for exit callbacks. diff --git a/Misc/NEWS.d/next/Library/2018-04-13-15-14-47.bpo-33254.DS4KFK.rst b/Misc/NEWS.d/next/Library/2018-04-13-15-14-47.bpo-33254.DS4KFK.rst new file mode 100644 index 00000000000000..c77a902524b805 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-04-13-15-14-47.bpo-33254.DS4KFK.rst @@ -0,0 +1,3 @@ +Have :func:`importlib.resources.contents` and +:meth:`importlib.abc.ResourceReader.contents` return an :term:`iterable` instead +of an :term:`iterator`. diff --git a/Misc/NEWS.d/next/Library/2018-04-16-08-42-03.bpo-11594.QLo4vv.rst b/Misc/NEWS.d/next/Library/2018-04-16-08-42-03.bpo-11594.QLo4vv.rst new file mode 100644 index 00000000000000..be2abf6c34dd69 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-04-16-08-42-03.bpo-11594.QLo4vv.rst @@ -0,0 +1 @@ +Ensure line-endings are respected when using lib2to3. diff --git a/Misc/NEWS.d/next/Library/2018-04-16-15-59-21.bpo-33266.w2PAm-.rst b/Misc/NEWS.d/next/Library/2018-04-16-15-59-21.bpo-33266.w2PAm-.rst new file mode 100644 index 00000000000000..6c93c48b888601 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-04-16-15-59-21.bpo-33266.w2PAm-.rst @@ -0,0 +1 @@ +lib2to3 now recognizes ``rf'...'`` strings. diff --git a/Misc/NEWS.d/next/Library/2018-04-16-16-21-09.bpo-23403.rxR1Q_.rst b/Misc/NEWS.d/next/Library/2018-04-16-16-21-09.bpo-23403.rxR1Q_.rst new file mode 100644 index 00000000000000..8116e3b9cea9f7 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-04-16-16-21-09.bpo-23403.rxR1Q_.rst @@ -0,0 +1 @@ +lib2to3 now uses pickle protocol 4 for pre-computed grammars. diff --git a/Misc/NEWS.d/next/Library/2018-04-18-19-12-25.bpo-33308.fW75xi.rst b/Misc/NEWS.d/next/Library/2018-04-18-19-12-25.bpo-33308.fW75xi.rst new file mode 100644 index 00000000000000..586004a3c6c956 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-04-18-19-12-25.bpo-33308.fW75xi.rst @@ -0,0 +1,2 @@ +Fixed a crash in the :mod:`parser` module when converting an ST object to a +tree of tuples or lists with ``line_info=False`` and ``col_info=True``. diff --git a/Misc/NEWS.d/next/Library/2018-04-20-10-43-17.bpo-33131.L2E977.rst b/Misc/NEWS.d/next/Library/2018-04-20-10-43-17.bpo-33131.L2E977.rst new file mode 100644 index 00000000000000..875c6ac5f74237 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-04-20-10-43-17.bpo-33131.L2E977.rst @@ -0,0 +1 @@ +Upgrade bundled version of pip to 10.0.1. diff --git a/Misc/NEWS.d/next/Library/2018-04-21-00-24-08.bpo-991266.h93TP_.rst b/Misc/NEWS.d/next/Library/2018-04-21-00-24-08.bpo-991266.h93TP_.rst new file mode 100644 index 00000000000000..3af6c27cf21d49 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-04-21-00-24-08.bpo-991266.h93TP_.rst @@ -0,0 +1 @@ +Fix quoting of the ``Comment`` attribute of :class:`http.cookies.SimpleCookie`. diff --git a/Misc/NEWS.d/next/Library/2018-04-22-20-13-21.bpo-33334.19UMOC.rst b/Misc/NEWS.d/next/Library/2018-04-22-20-13-21.bpo-33334.19UMOC.rst new file mode 100644 index 00000000000000..1df274091863e3 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-04-22-20-13-21.bpo-33334.19UMOC.rst @@ -0,0 +1,2 @@ +:func:`dis.stack_effect` now supports all defined opcodes including NOP and +EXTENDED_ARG. diff --git a/Misc/NEWS.d/next/Library/2018-04-23-13-21-39.bpo-33329.lQ-Eod.rst b/Misc/NEWS.d/next/Library/2018-04-23-13-21-39.bpo-33329.lQ-Eod.rst new file mode 100644 index 00000000000000..d1a4e56d04b947 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-04-23-13-21-39.bpo-33329.lQ-Eod.rst @@ -0,0 +1 @@ +Fix multiprocessing regression on newer glibcs diff --git a/Misc/NEWS.d/next/Library/2018-04-23-18-25-36.bpo-33251.C_K-J9.rst b/Misc/NEWS.d/next/Library/2018-04-23-18-25-36.bpo-33251.C_K-J9.rst new file mode 100644 index 00000000000000..fc6861f0d368ec --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-04-23-18-25-36.bpo-33251.C_K-J9.rst @@ -0,0 +1,2 @@ +`ConfigParser.items()` was fixed so that key-value pairs passed in via `vars` +are not included in the resulting output. diff --git a/Misc/NEWS.d/next/Library/2018-04-23-21-41-30.bpo-33332.Y6OZ8Z.rst b/Misc/NEWS.d/next/Library/2018-04-23-21-41-30.bpo-33332.Y6OZ8Z.rst new file mode 100644 index 00000000000000..05dca54d577629 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-04-23-21-41-30.bpo-33332.Y6OZ8Z.rst @@ -0,0 +1,2 @@ +Add ``signal.valid_signals()`` to expose the POSIX sigfillset() +functionality. diff --git a/Misc/NEWS.d/next/Library/2018-04-25-14-05-21.bpo-27485.nclVSU.rst b/Misc/NEWS.d/next/Library/2018-04-25-14-05-21.bpo-27485.nclVSU.rst new file mode 100644 index 00000000000000..8962d8229264d1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-04-25-14-05-21.bpo-27485.nclVSU.rst @@ -0,0 +1 @@ +Rename and deprecate undocumented functions in :func:`urllib.parse`. diff --git a/Misc/NEWS.d/next/Library/2018-04-28-08-11-35.bpo-33375.Dbq1fz.rst b/Misc/NEWS.d/next/Library/2018-04-28-08-11-35.bpo-33375.Dbq1fz.rst new file mode 100644 index 00000000000000..f3f9d2a508816a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-04-28-08-11-35.bpo-33375.Dbq1fz.rst @@ -0,0 +1,4 @@ +The warnings module now finds the Python file associated with a warning from +the code object, rather than the frame's global namespace. This is +consistent with how tracebacks and pdb find filenames, and should work +better for dynamically executed code. diff --git a/Misc/NEWS.d/next/Library/2018-04-29-11-15-38.bpo-33383.g32YWn.rst b/Misc/NEWS.d/next/Library/2018-04-29-11-15-38.bpo-33383.g32YWn.rst new file mode 100644 index 00000000000000..7b65baac97bf6e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-04-29-11-15-38.bpo-33383.g32YWn.rst @@ -0,0 +1,2 @@ +Fixed crash in the get() method of the :mod:`dbm.ndbm` database object when +it is called with a single argument. diff --git a/Misc/NEWS.d/next/Library/2018-04-29-23-56-20.bpo-33197.dgRLqr.rst b/Misc/NEWS.d/next/Library/2018-04-29-23-56-20.bpo-33197.dgRLqr.rst new file mode 100644 index 00000000000000..1bbb44b2fc39f8 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-04-29-23-56-20.bpo-33197.dgRLqr.rst @@ -0,0 +1,2 @@ +Update error message when constructing invalid inspect.Parameters +Patch by Dong-hee Na. diff --git a/Misc/NEWS.d/next/Library/2018-05-01-02-24-44.bpo-27300.LdIXvK.rst b/Misc/NEWS.d/next/Library/2018-05-01-02-24-44.bpo-27300.LdIXvK.rst new file mode 100644 index 00000000000000..5edbc86b9c9ceb --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-01-02-24-44.bpo-27300.LdIXvK.rst @@ -0,0 +1,2 @@ +The file classes in *tempfile* now accept an *errors* parameter that +complements the already existing *encoding*. Patch by Stephan Hohe. diff --git a/Misc/NEWS.d/next/Library/2018-05-01-22-33-14.bpo-33311.8YPB-k.rst b/Misc/NEWS.d/next/Library/2018-05-01-22-33-14.bpo-33311.8YPB-k.rst new file mode 100644 index 00000000000000..d0218de373ca7c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-01-22-33-14.bpo-33311.8YPB-k.rst @@ -0,0 +1,2 @@ +Text and html output generated by cgitb does not display parentheses if the +current call is done directly in the module. Patch by Stéphane Blondon. diff --git a/Misc/NEWS.d/next/Library/2018-05-01-22-35-50.bpo-33281.d4jOt4.rst b/Misc/NEWS.d/next/Library/2018-05-01-22-35-50.bpo-33281.d4jOt4.rst new file mode 100644 index 00000000000000..ad08caa70b637b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-01-22-35-50.bpo-33281.d4jOt4.rst @@ -0,0 +1 @@ +Fix ctypes.util.find_library regression on macOS. diff --git a/Misc/NEWS.d/next/Library/2018-05-02-07-26-29.bpo-28167.7FwDfN.rst b/Misc/NEWS.d/next/Library/2018-05-02-07-26-29.bpo-28167.7FwDfN.rst new file mode 100644 index 00000000000000..2d7cf01961ff00 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-02-07-26-29.bpo-28167.7FwDfN.rst @@ -0,0 +1,3 @@ +The function ``platform.linux_distribution`` and ``platform.dist`` now +trigger a ``DeprecationWarning`` and have been marked for removal in Python +3.8 diff --git a/Misc/NEWS.d/next/Library/2018-05-05-09-53-05.bpo-33422.4FtQ0q.rst b/Misc/NEWS.d/next/Library/2018-05-05-09-53-05.bpo-33422.4FtQ0q.rst new file mode 100644 index 00000000000000..0d284d508f1061 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-05-09-53-05.bpo-33422.4FtQ0q.rst @@ -0,0 +1,2 @@ +Fix trailing quotation marks getting deleted when looking up byte/string +literals on pydoc. Patch by Andrés Delfino. diff --git a/Misc/NEWS.d/next/Library/2018-05-05-18-02-24.bpo-20087.lJrvXL.rst b/Misc/NEWS.d/next/Library/2018-05-05-18-02-24.bpo-20087.lJrvXL.rst new file mode 100644 index 00000000000000..2342cb781926ad --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-05-18-02-24.bpo-20087.lJrvXL.rst @@ -0,0 +1 @@ +Updated alias mapping with glibc 2.27 supported locales. diff --git a/Misc/NEWS.d/next/Library/2018-05-08-15-01-10.bpo-33365.SicsAd.rst b/Misc/NEWS.d/next/Library/2018-05-08-15-01-10.bpo-33365.SicsAd.rst new file mode 100644 index 00000000000000..41c273f379987f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-08-15-01-10.bpo-33365.SicsAd.rst @@ -0,0 +1 @@ +Print the header values besides the header keys instead just the header keys if *debuglevel* is set to >0 in :mod:`http.client`. Patch by Marco Strigl. diff --git a/Misc/NEWS.d/next/Library/2018-05-08-16-43-42.bpo-28556._xr5mp.rst b/Misc/NEWS.d/next/Library/2018-05-08-16-43-42.bpo-28556._xr5mp.rst new file mode 100644 index 00000000000000..8ed4658211fb7b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-08-16-43-42.bpo-28556._xr5mp.rst @@ -0,0 +1,3 @@ +Minor fixes in typing module: add annotations to ``NamedTuple.__new__``, +pass ``*args`` and ``**kwds`` in ``Generic.__new__``. Original PRs by +Paulius Šarka and Chad Dombrova. diff --git a/Misc/NEWS.d/next/Library/2018-05-12-06-01-02.bpo-33453.Fj-jMD.rst b/Misc/NEWS.d/next/Library/2018-05-12-06-01-02.bpo-33453.Fj-jMD.rst new file mode 100644 index 00000000000000..6595b1265a4ec4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-12-06-01-02.bpo-33453.Fj-jMD.rst @@ -0,0 +1,4 @@ +Fix dataclasses to work if using literal string type annotations or if using +PEP 563 "Postponed Evaluation of Annotations". Only specific string +prefixes are detected for both ClassVar ("ClassVar" and "typing.ClassVar") +and InitVar ("InitVar" and "dataclasses.InitVar"). diff --git a/Misc/NEWS.d/next/Library/2018-05-14-09-07-14.bpo-26103._zU8E2.rst b/Misc/NEWS.d/next/Library/2018-05-14-09-07-14.bpo-26103._zU8E2.rst new file mode 100644 index 00000000000000..cb4c41ba5db928 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-14-09-07-14.bpo-26103._zU8E2.rst @@ -0,0 +1,2 @@ +Correct ``inspect.isdatadescriptor`` to look for ``__set__`` or +``__delete__``. Patch by Aaron Hall. diff --git a/Misc/NEWS.d/next/Library/2018-05-14-10-29-03.bpo-33495.TeGTQJ.rst b/Misc/NEWS.d/next/Library/2018-05-14-10-29-03.bpo-33495.TeGTQJ.rst new file mode 100644 index 00000000000000..22cf04cd2e430b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-14-10-29-03.bpo-33495.TeGTQJ.rst @@ -0,0 +1,3 @@ +Change dataclasses.Fields repr to use the repr of each of its members, +instead of str. This makes it more clear what each field actually +represents. This is especially true for the 'type' member. diff --git a/Misc/NEWS.d/next/Library/2018-05-14-15-01-55.bpo-29235.47Fzwt.rst b/Misc/NEWS.d/next/Library/2018-05-14-15-01-55.bpo-29235.47Fzwt.rst new file mode 100644 index 00000000000000..2ce9096126ab89 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-14-15-01-55.bpo-29235.47Fzwt.rst @@ -0,0 +1,2 @@ +The :class:`cProfile.Profile` class can now be used as a context manager. Patch +by Scott Sanderson. diff --git a/Misc/NEWS.d/next/Library/2018-05-14-17-49-34.bpo-33497.wWT6XM.rst b/Misc/NEWS.d/next/Library/2018-05-14-17-49-34.bpo-33497.wWT6XM.rst new file mode 100644 index 00000000000000..d919dfdca75e43 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-14-17-49-34.bpo-33497.wWT6XM.rst @@ -0,0 +1,2 @@ +Add errors param to cgi.parse_multipart and make an encoding in FieldStorage +use the given errors (needed for Twisted). Patch by Amber Brown. diff --git a/Misc/NEWS.d/next/Library/2018-05-14-18-05-35.bpo-33505.L8pAyt.rst b/Misc/NEWS.d/next/Library/2018-05-14-18-05-35.bpo-33505.L8pAyt.rst new file mode 100644 index 00000000000000..201b02781c1835 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-14-18-05-35.bpo-33505.L8pAyt.rst @@ -0,0 +1 @@ +Optimize asyncio.ensure_future() by reordering if checks: 1.17x faster. diff --git a/Misc/NEWS.d/next/Library/2018-05-15-12-11-13.bpo-33504.czsHFg.rst b/Misc/NEWS.d/next/Library/2018-05-15-12-11-13.bpo-33504.czsHFg.rst new file mode 100644 index 00000000000000..d5065d9224e7e4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-15-12-11-13.bpo-33504.czsHFg.rst @@ -0,0 +1,2 @@ +Switch the default dictionary implementation for :mod:`configparser` from +:class:`collections.OrderedDict` to the standard :class:`dict` type. diff --git a/Misc/NEWS.d/next/Library/2018-05-15-13-49-13.bpo-28167.p4RdQt.rst b/Misc/NEWS.d/next/Library/2018-05-15-13-49-13.bpo-28167.p4RdQt.rst new file mode 100644 index 00000000000000..0079c8a09ced8d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-15-13-49-13.bpo-28167.p4RdQt.rst @@ -0,0 +1 @@ +Remove platform.linux_distribution, which was deprecated since 3.5. diff --git a/Misc/NEWS.d/next/Library/2018-05-15-15-03-48.bpo-28612.E9dz39.rst b/Misc/NEWS.d/next/Library/2018-05-15-15-03-48.bpo-28612.E9dz39.rst new file mode 100644 index 00000000000000..e3e8f16eef07f7 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-15-15-03-48.bpo-28612.E9dz39.rst @@ -0,0 +1,3 @@ +Added support for Site Maps to urllib's ``RobotFileParser`` as +:meth:`RobotFileParser.site_maps() <urllib.robotparser.RobotFileParser.site_maps>`. +Patch by Lady Red, based on patch by Peter Wirtz. diff --git a/Misc/NEWS.d/next/Library/2018-05-15-17-06-42.bpo-33516.ZzARe4.rst b/Misc/NEWS.d/next/Library/2018-05-15-17-06-42.bpo-33516.ZzARe4.rst new file mode 100644 index 00000000000000..77b1428f3c870f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-15-17-06-42.bpo-33516.ZzARe4.rst @@ -0,0 +1 @@ +:class:`unittest.mock.MagicMock` now supports the ``__round__`` magic method. diff --git a/Misc/NEWS.d/next/Library/2018-05-15-18-02-03.bpo-0.pj2Mbb.rst b/Misc/NEWS.d/next/Library/2018-05-15-18-02-03.bpo-0.pj2Mbb.rst new file mode 100644 index 00000000000000..ba8514cdd8950b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-15-18-02-03.bpo-0.pj2Mbb.rst @@ -0,0 +1 @@ +Fix failure in `typing.get_type_hints()` when ClassVar was provided as a string forward reference. diff --git a/Misc/NEWS.d/next/Library/2018-05-16-05-24-43.bpo-26819.taxbVT.rst b/Misc/NEWS.d/next/Library/2018-05-16-05-24-43.bpo-26819.taxbVT.rst new file mode 100644 index 00000000000000..d407a58003182b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-16-05-24-43.bpo-26819.taxbVT.rst @@ -0,0 +1,2 @@ +Fix race condition with `ReadTransport.resume_reading` in Windows proactor +event loop. diff --git a/Misc/NEWS.d/next/Library/2018-05-16-09-30-27.bpo-33542.idNAcs.rst b/Misc/NEWS.d/next/Library/2018-05-16-09-30-27.bpo-33542.idNAcs.rst new file mode 100644 index 00000000000000..16ba799131f41f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-16-09-30-27.bpo-33542.idNAcs.rst @@ -0,0 +1,2 @@ +Prevent ``uuid.get_node`` from using a DUID instead of a MAC on Windows. +Patch by Zvi Effron diff --git a/Misc/NEWS.d/next/Library/2018-05-16-10-07-40.bpo-33536._s0TE8.rst b/Misc/NEWS.d/next/Library/2018-05-16-10-07-40.bpo-33536._s0TE8.rst new file mode 100644 index 00000000000000..2c1024180d34ee --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-16-10-07-40.bpo-33536._s0TE8.rst @@ -0,0 +1,2 @@ +dataclasses.make_dataclass now checks for invalid field names and duplicate +fields. Also, added a check for invalid field specifications. diff --git a/Misc/NEWS.d/next/Library/2018-05-16-12-32-48.bpo-33541.kQORPE.rst b/Misc/NEWS.d/next/Library/2018-05-16-12-32-48.bpo-33541.kQORPE.rst new file mode 100644 index 00000000000000..137189849ea7f1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-16-12-32-48.bpo-33541.kQORPE.rst @@ -0,0 +1,2 @@ +Remove unused private method ``_strptime.LocaleTime.__pad`` (a.k.a. +``_LocaleTime__pad``). diff --git a/Misc/NEWS.d/next/Library/2018-05-16-14-57-58.bpo-33109.nPLL_S.rst b/Misc/NEWS.d/next/Library/2018-05-16-14-57-58.bpo-33109.nPLL_S.rst new file mode 100644 index 00000000000000..be731f99f7f090 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-16-14-57-58.bpo-33109.nPLL_S.rst @@ -0,0 +1,2 @@ +argparse subparsers are once again not required by default, reverting the +change in behavior introduced by bpo-26510 in 3.7.0a2. diff --git a/Misc/NEWS.d/next/Library/2018-05-16-17-05-48.bpo-33548.xWslmx.rst b/Misc/NEWS.d/next/Library/2018-05-16-17-05-48.bpo-33548.xWslmx.rst new file mode 100644 index 00000000000000..65585c152987bd --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-16-17-05-48.bpo-33548.xWslmx.rst @@ -0,0 +1 @@ +tempfile._candidate_tempdir_list should consider common TEMP locations diff --git a/Misc/NEWS.d/next/Library/2018-05-16-18-10-38.bpo-33540.wy9LRV.rst b/Misc/NEWS.d/next/Library/2018-05-16-18-10-38.bpo-33540.wy9LRV.rst new file mode 100644 index 00000000000000..9019cc14f5151a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-16-18-10-38.bpo-33540.wy9LRV.rst @@ -0,0 +1,2 @@ +Add a new ``block_on_close`` class attribute to ``ForkingMixIn`` and +``ThreadingMixIn`` classes of :mod:`socketserver`. diff --git a/Misc/NEWS.d/next/Library/2018-05-17-22-14-58.bpo-12486.HBeh62.rst b/Misc/NEWS.d/next/Library/2018-05-17-22-14-58.bpo-12486.HBeh62.rst new file mode 100644 index 00000000000000..89c88e27373b5b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-17-22-14-58.bpo-12486.HBeh62.rst @@ -0,0 +1,2 @@ +:func:`tokenize.generate_tokens` is now documented as a public API to +tokenize unicode strings. It was previously present but undocumented. diff --git a/Misc/NEWS.d/next/Library/2018-05-17-22-53-08.bpo-28556.C6Hnd1.rst b/Misc/NEWS.d/next/Library/2018-05-17-22-53-08.bpo-28556.C6Hnd1.rst new file mode 100644 index 00000000000000..35e13bde18973f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-17-22-53-08.bpo-28556.C6Hnd1.rst @@ -0,0 +1,3 @@ +Do not simplify arguments to `typing.Union`. Now `Union[Manager, Employee]` +is not simplified to `Employee` at runtime. Such simplification previously +caused several bugs and limited possibilities for introspection. diff --git a/Misc/NEWS.d/next/Library/2018-05-18-21-50-47.bpo-33570.7CZy4t.rst b/Misc/NEWS.d/next/Library/2018-05-18-21-50-47.bpo-33570.7CZy4t.rst new file mode 100644 index 00000000000000..bd719a47e8f820 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-18-21-50-47.bpo-33570.7CZy4t.rst @@ -0,0 +1,3 @@ +Change TLS 1.3 cipher suite settings for compatibility with OpenSSL +1.1.1-pre6 and newer. OpenSSL 1.1.1 will have TLS 1.3 cipers enabled by +default. diff --git a/Misc/NEWS.d/next/Library/2018-05-19-15-58-14.bpo-33582.qBZPmF.rst b/Misc/NEWS.d/next/Library/2018-05-19-15-58-14.bpo-33582.qBZPmF.rst new file mode 100644 index 00000000000000..3471c0e7f0b8b4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-19-15-58-14.bpo-33582.qBZPmF.rst @@ -0,0 +1 @@ +Emit a deprecation warning for inspect.formatargspec diff --git a/Misc/NEWS.d/next/Library/2018-05-22-13-05-12.bpo-30877.JZEGjI.rst b/Misc/NEWS.d/next/Library/2018-05-22-13-05-12.bpo-30877.JZEGjI.rst new file mode 100644 index 00000000000000..4be0fae4ecb68e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-22-13-05-12.bpo-30877.JZEGjI.rst @@ -0,0 +1,3 @@ +Fixed a bug in the Python implementation of the JSON decoder that prevented +the cache of parsed strings from clearing after finishing the decoding. +Based on patch by c-fos. diff --git a/Misc/NEWS.d/next/Library/2018-05-23-00-26-27.bpo-11874.glK5iP.rst b/Misc/NEWS.d/next/Library/2018-05-23-00-26-27.bpo-11874.glK5iP.rst new file mode 100644 index 00000000000000..6c75f142c4beac --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-23-00-26-27.bpo-11874.glK5iP.rst @@ -0,0 +1,2 @@ +Use a better regex when breaking usage into wrappable parts. Avoids bogus +assertion errors from custom metavar strings. diff --git a/Misc/NEWS.d/next/Library/2018-05-23-14-58-05.bpo-33623.wAw1cF.rst b/Misc/NEWS.d/next/Library/2018-05-23-14-58-05.bpo-33623.wAw1cF.rst new file mode 100644 index 00000000000000..641874c3ca3945 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-23-14-58-05.bpo-33623.wAw1cF.rst @@ -0,0 +1 @@ +Fix possible SIGSGV when asyncio.Future is created in __del__ diff --git a/Misc/NEWS.d/next/Library/2018-05-23-20-14-34.bpo-33618.xU39lr.rst b/Misc/NEWS.d/next/Library/2018-05-23-20-14-34.bpo-33618.xU39lr.rst new file mode 100644 index 00000000000000..6cc2452b145c5b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-23-20-14-34.bpo-33618.xU39lr.rst @@ -0,0 +1,2 @@ +Finalize and document preliminary and experimental TLS 1.3 support with +OpenSSL 1.1.1 diff --git a/Misc/NEWS.d/next/Library/2018-05-24-09-15-52.bpo-33238.ooDfoo.rst b/Misc/NEWS.d/next/Library/2018-05-24-09-15-52.bpo-33238.ooDfoo.rst new file mode 100644 index 00000000000000..b03ab106888961 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-24-09-15-52.bpo-33238.ooDfoo.rst @@ -0,0 +1,4 @@ +Add ``InvalidStateError`` to :mod:`concurrent.futures`. +``Future.set_result`` and ``Future.set_exception`` now raise +``InvalidStateError`` if the futures are not pending or running. Patch by +Jason Haydaman. diff --git a/Misc/NEWS.d/next/Library/2018-05-24-17-41-36.bpo-32493.5tAoAu.rst b/Misc/NEWS.d/next/Library/2018-05-24-17-41-36.bpo-32493.5tAoAu.rst new file mode 100644 index 00000000000000..32f88dd0388d5a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-24-17-41-36.bpo-32493.5tAoAu.rst @@ -0,0 +1 @@ +Fixed :func:`uuid.uuid1` on FreeBSD. diff --git a/Misc/NEWS.d/next/Library/2018-05-26-10-13-59.bpo-33652.humFJ1.rst b/Misc/NEWS.d/next/Library/2018-05-26-10-13-59.bpo-33652.humFJ1.rst new file mode 100644 index 00000000000000..f5499f1b53ce3d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-26-10-13-59.bpo-33652.humFJ1.rst @@ -0,0 +1,2 @@ +Pickles of type variables and subscripted generics are now future-proof and +compatible with older Python versions. diff --git a/Misc/NEWS.d/next/Library/2018-05-26-13-09-34.bpo-33654.IbYWxA.rst b/Misc/NEWS.d/next/Library/2018-05-26-13-09-34.bpo-33654.IbYWxA.rst new file mode 100644 index 00000000000000..3ae506ddc55f41 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-26-13-09-34.bpo-33654.IbYWxA.rst @@ -0,0 +1,3 @@ +Fix transport.set_protocol() to support switching between asyncio.Protocol +and asyncio.BufferedProtocol. Fix loop.start_tls() to work with +asyncio.BufferedProtocols. diff --git a/Misc/NEWS.d/next/Library/2018-05-28-12-29-54.bpo-33672.GM_Xm_.rst b/Misc/NEWS.d/next/Library/2018-05-28-12-29-54.bpo-33672.GM_Xm_.rst new file mode 100644 index 00000000000000..36373c028639da --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-28-12-29-54.bpo-33672.GM_Xm_.rst @@ -0,0 +1 @@ +Fix Task.__repr__ crash with Cython's bogus coroutines diff --git a/Misc/NEWS.d/next/Library/2018-05-28-15-55-12.bpo-33469.hmXBpY.rst b/Misc/NEWS.d/next/Library/2018-05-28-15-55-12.bpo-33469.hmXBpY.rst new file mode 100644 index 00000000000000..cc1b2e436f2aa8 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-28-15-55-12.bpo-33469.hmXBpY.rst @@ -0,0 +1 @@ +Fix RuntimeError after closing loop that used run_in_executor diff --git a/Misc/NEWS.d/next/Library/2018-05-28-16-19-35.bpo-32410.Z1DZaF.rst b/Misc/NEWS.d/next/Library/2018-05-28-16-19-35.bpo-32410.Z1DZaF.rst new file mode 100644 index 00000000000000..2d7bb2032ac5cc --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-28-16-19-35.bpo-32410.Z1DZaF.rst @@ -0,0 +1 @@ +Avoid blocking on file IO in sendfile fallback code diff --git a/Misc/NEWS.d/next/Library/2018-05-28-16-40-32.bpo-32610.KvUAsL.rst b/Misc/NEWS.d/next/Library/2018-05-28-16-40-32.bpo-32610.KvUAsL.rst new file mode 100644 index 00000000000000..372908063247d7 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-28-16-40-32.bpo-32610.KvUAsL.rst @@ -0,0 +1 @@ +Make asyncio.all_tasks() return only pending tasks. diff --git a/Misc/NEWS.d/next/Library/2018-05-28-18-40-26.bpo-31647.s4Fad3.rst b/Misc/NEWS.d/next/Library/2018-05-28-18-40-26.bpo-31647.s4Fad3.rst new file mode 100644 index 00000000000000..61cc8baa1cd52d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-28-18-40-26.bpo-31647.s4Fad3.rst @@ -0,0 +1,2 @@ +Fixed bug where calling write_eof() on a _SelectorSocketTransport after it's +already closed raises AttributeError. diff --git a/Misc/NEWS.d/next/Library/2018-05-28-22-49-59.bpo-33674.6LFFj7.rst b/Misc/NEWS.d/next/Library/2018-05-28-22-49-59.bpo-33674.6LFFj7.rst new file mode 100644 index 00000000000000..1e9868073f7892 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-28-22-49-59.bpo-33674.6LFFj7.rst @@ -0,0 +1,4 @@ +Fix a race condition in SSLProtocol.connection_made() of asyncio.sslproto: +start immediately the handshake instead of using call_soon(). Previously, +data_received() could be called before the handshake started, causing the +handshake to hang or fail. diff --git a/Misc/NEWS.d/next/Library/2018-05-28-23-25-17.bpo-33671.GIdKKi.rst b/Misc/NEWS.d/next/Library/2018-05-28-23-25-17.bpo-33671.GIdKKi.rst new file mode 100644 index 00000000000000..b1523f235da624 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-28-23-25-17.bpo-33671.GIdKKi.rst @@ -0,0 +1,10 @@ +:func:`shutil.copyfile`, :func:`shutil.copy`, :func:`shutil.copy2`, +:func:`shutil.copytree` and :func:`shutil.move` use platform-specific +fast-copy syscalls on Linux, Solaris and macOS in order to copy the file +more efficiently. +On Windows :func:`shutil.copyfile` uses a bigger default buffer size (1 MiB +instead of 16 KiB) and a :func:`memoryview`-based variant of +:func:`shutil.copyfileobj` is used. +The speedup for copying a 512MiB file is about +26% on Linux, +50% on macOS and ++40% on Windows. Also, much less CPU cycles are consumed. +(Contributed by Giampaolo Rodola' in :issue:`25427`.) diff --git a/Misc/NEWS.d/next/Library/2018-05-29-00-37-56.bpo-33674.2IkGhL.rst b/Misc/NEWS.d/next/Library/2018-05-29-00-37-56.bpo-33674.2IkGhL.rst new file mode 100644 index 00000000000000..66baca16d69fe6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-29-00-37-56.bpo-33674.2IkGhL.rst @@ -0,0 +1,2 @@ +Pause the transport as early as possible to further reduce the risk of +data_received() being called before connection_made(). diff --git a/Misc/NEWS.d/next/Library/2018-05-29-01-13-39.bpo-33654.sa81Si.rst b/Misc/NEWS.d/next/Library/2018-05-29-01-13-39.bpo-33654.sa81Si.rst new file mode 100644 index 00000000000000..39e8e615d8c45e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-29-01-13-39.bpo-33654.sa81Si.rst @@ -0,0 +1 @@ +Support protocol type switching in SSLTransport.set_protocol(). diff --git a/Misc/NEWS.d/next/Library/2018-05-29-12-51-18.bpo-32684.ZEIism.rst b/Misc/NEWS.d/next/Library/2018-05-29-12-51-18.bpo-32684.ZEIism.rst new file mode 100644 index 00000000000000..b360bbcf7998b4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-29-12-51-18.bpo-32684.ZEIism.rst @@ -0,0 +1 @@ +Fix gather to propagate cancellation of itself even with return_exceptions. diff --git a/Misc/NEWS.d/next/Library/2018-05-29-15-32-18.bpo-32751.oBTqr7.rst b/Misc/NEWS.d/next/Library/2018-05-29-15-32-18.bpo-32751.oBTqr7.rst new file mode 100644 index 00000000000000..3e27cd461ca814 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-29-15-32-18.bpo-32751.oBTqr7.rst @@ -0,0 +1,2 @@ +When cancelling the task due to a timeout, :meth:`asyncio.wait_for` will now +wait until the cancellation is complete. diff --git a/Misc/NEWS.d/next/Library/2018-05-30-00-26-05.bpo-33197.XkE2kL.rst b/Misc/NEWS.d/next/Library/2018-05-30-00-26-05.bpo-33197.XkE2kL.rst new file mode 100644 index 00000000000000..e6f7ac3309b3fe --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-30-00-26-05.bpo-33197.XkE2kL.rst @@ -0,0 +1 @@ +Add description property for _ParameterKind diff --git a/Misc/NEWS.d/next/Library/2018-05-31-06-48-55.bpo-31014.SNY681.rst b/Misc/NEWS.d/next/Library/2018-05-31-06-48-55.bpo-31014.SNY681.rst new file mode 100644 index 00000000000000..bd3c8bbd0f2be5 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-31-06-48-55.bpo-31014.SNY681.rst @@ -0,0 +1,3 @@ +Fixed creating a controller for :mod:`webbrowser` when a user specifies a +path to an entry in the BROWSER environment variable. Based on patch by +John Still. diff --git a/Misc/NEWS.d/next/Library/2018-06-01-10-55-48.bpo-33734.x1W9x0.rst b/Misc/NEWS.d/next/Library/2018-06-01-10-55-48.bpo-33734.x1W9x0.rst new file mode 100644 index 00000000000000..305d40ed8a1ba9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-06-01-10-55-48.bpo-33734.x1W9x0.rst @@ -0,0 +1 @@ +asyncio/ssl: Fix AttributeError, increase default handshake timeout diff --git a/Misc/NEWS.d/next/Library/2018-06-03-22-41-59.bpo-33767.2e82g3.rst b/Misc/NEWS.d/next/Library/2018-06-03-22-41-59.bpo-33767.2e82g3.rst new file mode 100644 index 00000000000000..3483301890953a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-06-03-22-41-59.bpo-33767.2e82g3.rst @@ -0,0 +1,3 @@ +The concatenation (``+``) and repetition (``*``) sequence operations now +raise :exc:`TypeError` instead of :exc:`SystemError` when performed on +:class:`mmap.mmap` objects. Patch by Zackery Spytz. diff --git a/Misc/NEWS.d/next/Library/2018-06-04-13-46-39.bpo-33769.D_pxYz.rst b/Misc/NEWS.d/next/Library/2018-06-04-13-46-39.bpo-33769.D_pxYz.rst new file mode 100644 index 00000000000000..9a124fafc6d24f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-06-04-13-46-39.bpo-33769.D_pxYz.rst @@ -0,0 +1,2 @@ +asyncio/start_tls: Fix error message; cancel callbacks in case of an +unhandled error; mark SSLTransport as closed if it is aborted. diff --git a/Misc/NEWS.d/next/Library/2018-06-05-11-29-26.bpo-33770.oBhxxw.rst b/Misc/NEWS.d/next/Library/2018-06-05-11-29-26.bpo-33770.oBhxxw.rst new file mode 100644 index 00000000000000..a1529dda1a6d33 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-06-05-11-29-26.bpo-33770.oBhxxw.rst @@ -0,0 +1 @@ +improve base64 exception message for encoded inputs of invalid length diff --git a/Misc/NEWS.d/next/Library/2018-06-05-12-43-25.bpo-33165.9TIsVf.rst b/Misc/NEWS.d/next/Library/2018-06-05-12-43-25.bpo-33165.9TIsVf.rst new file mode 100644 index 00000000000000..b3b2126479dbf3 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-06-05-12-43-25.bpo-33165.9TIsVf.rst @@ -0,0 +1,2 @@ +Added a stacklevel parameter to logging calls to allow use of wrapper/helper +functions for logging APIs. diff --git a/Misc/NEWS.d/next/Library/2018-06-05-20-22-30.bpo-33778._tSAS6.rst b/Misc/NEWS.d/next/Library/2018-06-05-20-22-30.bpo-33778._tSAS6.rst new file mode 100644 index 00000000000000..7301b364156562 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-06-05-20-22-30.bpo-33778._tSAS6.rst @@ -0,0 +1 @@ +Update ``unicodedata``'s database to Unicode version 11.0.0. diff --git a/Misc/NEWS.d/next/Library/2018-06-06-22-01-33.bpo-33274.teYqv8.rst b/Misc/NEWS.d/next/Library/2018-06-06-22-01-33.bpo-33274.teYqv8.rst new file mode 100644 index 00000000000000..420652bddf6eb4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-06-06-22-01-33.bpo-33274.teYqv8.rst @@ -0,0 +1,3 @@ +W3C DOM Level 1 specifies return value of Element.removeAttributeNode() as +"The Attr node that was removed." xml.dom.minidom now complies with this +requirement. diff --git a/Misc/NEWS.d/next/Library/2018-06-07-12-38-12.bpo-33792.3aKG7u.rst b/Misc/NEWS.d/next/Library/2018-06-07-12-38-12.bpo-33792.3aKG7u.rst new file mode 100644 index 00000000000000..8c01764bc68233 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-06-07-12-38-12.bpo-33792.3aKG7u.rst @@ -0,0 +1,2 @@ +Add asyncio.WindowsSelectorEventLoopPolicy and +asyncio.WindowsProactorEventLoopPolicy. diff --git a/Misc/NEWS.d/next/Library/2018-06-07-18-55-35.bpo-32493.1Bte62.rst b/Misc/NEWS.d/next/Library/2018-06-07-18-55-35.bpo-32493.1Bte62.rst new file mode 100644 index 00000000000000..3d8bb3ed305cb7 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-06-07-18-55-35.bpo-32493.1Bte62.rst @@ -0,0 +1,2 @@ +Correct test for ``uuid_enc_be`` availability in ``configure.ac``. +Patch by Michael Felt. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2018-06-07-23-51-00.bpo-33694.F1zIR1.rst b/Misc/NEWS.d/next/Library/2018-06-07-23-51-00.bpo-33694.F1zIR1.rst new file mode 100644 index 00000000000000..6b7f15cf8d437e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-06-07-23-51-00.bpo-33694.F1zIR1.rst @@ -0,0 +1,2 @@ +asyncio: Fix a race condition causing data loss on +pause_reading()/resume_reading() when using the ProactorEventLoop. diff --git a/Misc/NEWS.d/next/Library/2018-06-08-17-34-16.bpo-30805.3qCWa0.rst b/Misc/NEWS.d/next/Library/2018-06-08-17-34-16.bpo-30805.3qCWa0.rst new file mode 100644 index 00000000000000..e1ba57675397e6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-06-08-17-34-16.bpo-30805.3qCWa0.rst @@ -0,0 +1 @@ +Avoid race condition with debug logging diff --git a/Misc/NEWS.d/next/Library/2018-06-10-09-43-54.bpo-27397.0_fFQR.rst b/Misc/NEWS.d/next/Library/2018-06-10-09-43-54.bpo-27397.0_fFQR.rst new file mode 100644 index 00000000000000..109817267bd076 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-06-10-09-43-54.bpo-27397.0_fFQR.rst @@ -0,0 +1 @@ +Make email module properly handle invalid-length base64 strings. diff --git a/Misc/NEWS.d/next/Library/2018-06-10-12-15-26.bpo-32108.iEkvh0.rst b/Misc/NEWS.d/next/Library/2018-06-10-12-15-26.bpo-32108.iEkvh0.rst new file mode 100644 index 00000000000000..154d88471f6a12 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-06-10-12-15-26.bpo-32108.iEkvh0.rst @@ -0,0 +1 @@ +In configparser, don't clear section when it is assigned to itself. diff --git a/Misc/NEWS.d/next/Library/2018-06-10-13-26-02.bpo-33812.frGAOr.rst b/Misc/NEWS.d/next/Library/2018-06-10-13-26-02.bpo-33812.frGAOr.rst new file mode 100644 index 00000000000000..0dc3df6a79532a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-06-10-13-26-02.bpo-33812.frGAOr.rst @@ -0,0 +1,2 @@ +Datetime instance d with non-None tzinfo, but with d.tzinfo.utcoffset(d) +returning None is now treated as naive by the astimezone() method. diff --git a/Misc/NEWS.d/next/Library/2018-06-10-15-14-17.bpo-33805.5LAz5a.rst b/Misc/NEWS.d/next/Library/2018-06-10-15-14-17.bpo-33805.5LAz5a.rst new file mode 100644 index 00000000000000..74bcf6d7c8c8b6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-06-10-15-14-17.bpo-33805.5LAz5a.rst @@ -0,0 +1 @@ +Improve error message of dataclasses.replace() when an InitVar is not specified diff --git a/Misc/NEWS.d/next/Library/2018-06-10-19-29-17.bpo-30167.G5EgC5.rst b/Misc/NEWS.d/next/Library/2018-06-10-19-29-17.bpo-30167.G5EgC5.rst new file mode 100644 index 00000000000000..072a001adab883 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-06-10-19-29-17.bpo-30167.G5EgC5.rst @@ -0,0 +1 @@ +Prevent site.main() exception if PYTHONSTARTUP is set. Patch by Steve Weber. diff --git a/Misc/NEWS.d/next/Library/2018-06-12-18-34-54.bpo-33842.RZXSGu.rst b/Misc/NEWS.d/next/Library/2018-06-12-18-34-54.bpo-33842.RZXSGu.rst new file mode 100644 index 00000000000000..4d8d7c2fb2d0ea --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-06-12-18-34-54.bpo-33842.RZXSGu.rst @@ -0,0 +1 @@ +Remove ``tarfile.filemode`` which is deprecated since Python 3.3. diff --git a/Misc/NEWS.d/next/Library/2018-06-12-18-59-16.bpo-33843.qVAK8g.rst b/Misc/NEWS.d/next/Library/2018-06-12-18-59-16.bpo-33843.qVAK8g.rst new file mode 100644 index 00000000000000..c79b2513095f63 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-06-12-18-59-16.bpo-33843.qVAK8g.rst @@ -0,0 +1 @@ +Remove deprecated ``cgi.escape``, ``cgi.parse_qs`` and ``cgi.parse_qsl``. diff --git a/Misc/NEWS.d/next/Library/2018-06-17-10-48-03.bpo-33663.sUuGmq.rst b/Misc/NEWS.d/next/Library/2018-06-17-10-48-03.bpo-33663.sUuGmq.rst new file mode 100644 index 00000000000000..b2a8e3cc00c67c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-06-17-10-48-03.bpo-33663.sUuGmq.rst @@ -0,0 +1 @@ +Convert content length to string before putting to header. diff --git a/Misc/NEWS.d/next/Library/2018-06-21-09-33-02.bpo-32568.f_meGY.rst b/Misc/NEWS.d/next/Library/2018-06-21-09-33-02.bpo-32568.f_meGY.rst new file mode 100644 index 00000000000000..3ade8cf6f3d4f9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-06-21-09-33-02.bpo-32568.f_meGY.rst @@ -0,0 +1,2 @@ +Make select.epoll() and its documentation consistent regarding *sizehint* and +*flags*. diff --git a/Misc/NEWS.d/next/Library/2018-06-21-11-35-47.bpo-33916.cZgPCD.rst b/Misc/NEWS.d/next/Library/2018-06-21-11-35-47.bpo-33916.cZgPCD.rst new file mode 100644 index 00000000000000..65b9d2bf89a588 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-06-21-11-35-47.bpo-33916.cZgPCD.rst @@ -0,0 +1,2 @@ +bz2 and lzma: When Decompressor.__init__() is called twice, free the old +lock to not leak memory. diff --git a/Misc/NEWS.d/next/Library/2018-06-23-18-09-28.bpo-33897.Hu0yvt.rst b/Misc/NEWS.d/next/Library/2018-06-23-18-09-28.bpo-33897.Hu0yvt.rst new file mode 100644 index 00000000000000..64ec3a166f807f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-06-23-18-09-28.bpo-33897.Hu0yvt.rst @@ -0,0 +1 @@ +Added a 'force' keyword argument to logging.basicConfig(). diff --git a/Misc/NEWS.d/next/Library/2018-06-24-01-57-14.bpo-33899.IaOcAr.rst b/Misc/NEWS.d/next/Library/2018-06-24-01-57-14.bpo-33899.IaOcAr.rst new file mode 100644 index 00000000000000..21c9095993630e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-06-24-01-57-14.bpo-33899.IaOcAr.rst @@ -0,0 +1,3 @@ +Tokenize module now implicitly emits a NEWLINE when provided with input that +does not have a trailing new line. This behavior now matches what the C +tokenizer does internally. Contributed by Ammar Askar. diff --git a/Misc/NEWS.d/next/Library/2018-06-26-02-09-18.bpo-33929.OcCLah.rst b/Misc/NEWS.d/next/Library/2018-06-26-02-09-18.bpo-33929.OcCLah.rst new file mode 100644 index 00000000000000..6ddb17c81cd903 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-06-26-02-09-18.bpo-33929.OcCLah.rst @@ -0,0 +1,5 @@ +multiprocessing: Fix a race condition in Popen of +multiprocessing.popen_spawn_win32. The child process now duplicates the read +end of pipe instead of "stealing" it. Previously, the read end of pipe was +"stolen" by the child process, but it leaked a handle if the child process had +been terminated before it could steal the handle from the parent process. diff --git a/Misc/NEWS.d/next/Library/2018-06-26-16-55-59.bpo-25007.6LQWOF.rst b/Misc/NEWS.d/next/Library/2018-06-26-16-55-59.bpo-25007.6LQWOF.rst new file mode 100644 index 00000000000000..b7d832be1ade32 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-06-26-16-55-59.bpo-25007.6LQWOF.rst @@ -0,0 +1,2 @@ +Add :func:`copy.copy` and :func:`copy.deepcopy` support to zlib compressors +and decompressors. Patch by Zackery Spytz. diff --git a/Misc/NEWS.d/next/Library/2018-06-27-00-31-30.bpo-24567.FuePyY.rst b/Misc/NEWS.d/next/Library/2018-06-27-00-31-30.bpo-24567.FuePyY.rst new file mode 100644 index 00000000000000..d496f2bc411c4e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-06-27-00-31-30.bpo-24567.FuePyY.rst @@ -0,0 +1,2 @@ +Improve random.choices() to handle subnormal input weights that could +occasionally trigger an IndexError. diff --git a/Misc/NEWS.d/next/Library/2018-06-28-13-00-12.bpo-27500._s1gZ5.rst b/Misc/NEWS.d/next/Library/2018-06-28-13-00-12.bpo-27500._s1gZ5.rst new file mode 100644 index 00000000000000..4762e27956432e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-06-28-13-00-12.bpo-27500._s1gZ5.rst @@ -0,0 +1 @@ +Fix getaddrinfo to resolve IPv6 addresses correctly. diff --git a/Misc/NEWS.d/next/Library/2018-06-28-14-56-44.bpo-33974.SA8nNP.rst b/Misc/NEWS.d/next/Library/2018-06-28-14-56-44.bpo-33974.SA8nNP.rst new file mode 100644 index 00000000000000..8c03babd4f2eff --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-06-28-14-56-44.bpo-33974.SA8nNP.rst @@ -0,0 +1,3 @@ +Fixed passing lists and tuples of strings containing special characters +``"``, ``\``, ``{``, ``}`` and ``\n`` as options to :mod:`~tkinter.ttk` +widgets. diff --git a/Misc/NEWS.d/next/Library/2018-06-29-00-31-36.bpo-14117.3nvDuR.rst b/Misc/NEWS.d/next/Library/2018-06-29-00-31-36.bpo-14117.3nvDuR.rst new file mode 100644 index 00000000000000..eee55f24c811db --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-06-29-00-31-36.bpo-14117.3nvDuR.rst @@ -0,0 +1,3 @@ +Make minor tweaks to turtledemo. The 'wikipedia' example is now 'rosette', +decribing what it draws. The 'penrose' print output is reduced. The'1024' +output of 'tree' is eliminated. diff --git a/Misc/NEWS.d/next/Library/2018-06-29-12-23-34.bpo-33978.y4csIw.rst b/Misc/NEWS.d/next/Library/2018-06-29-12-23-34.bpo-33978.y4csIw.rst new file mode 100644 index 00000000000000..12638957ee3895 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-06-29-12-23-34.bpo-33978.y4csIw.rst @@ -0,0 +1,2 @@ +Closed existing logging handlers before reconfiguration via fileConfig +and dictConfig. Patch by Karthikeyan Singaravelan. diff --git a/Misc/NEWS.d/next/Library/2018-07-02-05-59-11.bpo-34019.ZXJIife.rst b/Misc/NEWS.d/next/Library/2018-07-02-05-59-11.bpo-34019.ZXJIife.rst new file mode 100644 index 00000000000000..8a9fe79b80cfb3 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-07-02-05-59-11.bpo-34019.ZXJIife.rst @@ -0,0 +1,2 @@ +webbrowser: Correct the arguments passed to Opera Browser when opening a new URL +using the ``webbrowser`` module. Patch by Bumsik Kim. diff --git a/Misc/NEWS.d/next/Library/2018-07-04-07-36-53.bpo-34010.VNDkde.rst b/Misc/NEWS.d/next/Library/2018-07-04-07-36-53.bpo-34010.VNDkde.rst new file mode 100644 index 00000000000000..4cb7892ee81a93 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-07-04-07-36-53.bpo-34010.VNDkde.rst @@ -0,0 +1,2 @@ +Fixed a performance regression for reading streams with tarfile. The +buffered read should use a list, instead of appending to a bytes object. diff --git a/Misc/NEWS.d/next/Library/2018-07-04-17-14-26.bpo-34044.KWAu4y.rst b/Misc/NEWS.d/next/Library/2018-07-04-17-14-26.bpo-34044.KWAu4y.rst new file mode 100644 index 00000000000000..42a6ffbf84af7b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-07-04-17-14-26.bpo-34044.KWAu4y.rst @@ -0,0 +1,3 @@ +``subprocess.Popen`` now copies the *startupinfo* argument to leave it +unchanged: it will modify the copy, so that the same ``STARTUPINFO`` object can +be used multiple times. diff --git a/Misc/NEWS.d/next/Library/2018-07-04-21-14-35.bpo-34043.0YJNq9.rst b/Misc/NEWS.d/next/Library/2018-07-04-21-14-35.bpo-34043.0YJNq9.rst new file mode 100644 index 00000000000000..c035ba7275f8e5 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-07-04-21-14-35.bpo-34043.0YJNq9.rst @@ -0,0 +1 @@ +Optimize tarfile uncompress performance about 15% when gzip is used. diff --git a/Misc/NEWS.d/next/Library/2018-07-05-18-37-05.bpo-34054.nWRS6M.rst b/Misc/NEWS.d/next/Library/2018-07-05-18-37-05.bpo-34054.nWRS6M.rst new file mode 100644 index 00000000000000..9d4d1f24db496f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-07-05-18-37-05.bpo-34054.nWRS6M.rst @@ -0,0 +1,3 @@ +The multiprocessing module now uses the monotonic clock +:func:`time.monotonic` instead of the system clock :func:`time.time` to +implement timeout. diff --git a/Misc/NEWS.d/next/Library/2018-07-05-22-45-46.bpo-34056.86isrU.rst b/Misc/NEWS.d/next/Library/2018-07-05-22-45-46.bpo-34056.86isrU.rst new file mode 100644 index 00000000000000..edc0135efc6057 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-07-05-22-45-46.bpo-34056.86isrU.rst @@ -0,0 +1,3 @@ +Ensure the loader shim created by ``imp.load_module`` always returns bytes +from its ``get_data()`` function. This fixes using ``imp.load_module`` with +:pep:`552` hash-based pycs. diff --git a/Misc/NEWS.d/next/Library/2018-07-06-15-06-32.bpo-34041.0zrKLh.rst b/Misc/NEWS.d/next/Library/2018-07-06-15-06-32.bpo-34041.0zrKLh.rst new file mode 100644 index 00000000000000..c41876bc60cbb4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-07-06-15-06-32.bpo-34041.0zrKLh.rst @@ -0,0 +1,2 @@ +Add the parameter *deterministic* to the +:meth:`sqlite3.Connection.create_function` method. Patch by Sergey Fedoseev. diff --git a/Misc/NEWS.d/next/Security/2017-08-06-14-43-45.bpo-28414.mzZ6vD.rst b/Misc/NEWS.d/next/Security/2017-08-06-14-43-45.bpo-28414.mzZ6vD.rst new file mode 100644 index 00000000000000..06528c93ee19f6 --- /dev/null +++ b/Misc/NEWS.d/next/Security/2017-08-06-14-43-45.bpo-28414.mzZ6vD.rst @@ -0,0 +1 @@ +The ssl module now allows users to perform their own IDN en/decoding when using SNI. diff --git a/Misc/NEWS.d/next/Security/2018-03-02-10-24-52.bpo-32981.O_qDyj.rst b/Misc/NEWS.d/next/Security/2018-03-02-10-24-52.bpo-32981.O_qDyj.rst new file mode 100644 index 00000000000000..9ebabb44f91e7c --- /dev/null +++ b/Misc/NEWS.d/next/Security/2018-03-02-10-24-52.bpo-32981.O_qDyj.rst @@ -0,0 +1,4 @@ +Regexes in difflib and poplib were vulnerable to catastrophic backtracking. +These regexes formed potential DOS vectors (REDOS). They have been +refactored. This resolves CVE-2018-1060 and CVE-2018-1061. +Patch by Jamie Davis. diff --git a/Misc/NEWS.d/next/Security/2018-03-05-10-09-51.bpo-33001.elj4Aa.rst b/Misc/NEWS.d/next/Security/2018-03-05-10-09-51.bpo-33001.elj4Aa.rst new file mode 100644 index 00000000000000..2acbac9e1af6f8 --- /dev/null +++ b/Misc/NEWS.d/next/Security/2018-03-05-10-09-51.bpo-33001.elj4Aa.rst @@ -0,0 +1 @@ +Minimal fix to prevent buffer overrun in os.symlink on Windows diff --git a/Misc/NEWS.d/next/Security/2018-03-25-12-05-43.bpo-33136.TzSN4x.rst b/Misc/NEWS.d/next/Security/2018-03-25-12-05-43.bpo-33136.TzSN4x.rst new file mode 100644 index 00000000000000..c3505167092b25 --- /dev/null +++ b/Misc/NEWS.d/next/Security/2018-03-25-12-05-43.bpo-33136.TzSN4x.rst @@ -0,0 +1,3 @@ +Harden ssl module against LibreSSL CVE-2018-8970. +X509_VERIFY_PARAM_set1_host() is called with an explicit namelen. A new test +ensures that NULL bytes are not allowed. diff --git a/Misc/NEWS.d/next/Tests/2017-10-18-18-07-45.bpo-31809.KlQrkE.rst b/Misc/NEWS.d/next/Tests/2017-10-18-18-07-45.bpo-31809.KlQrkE.rst new file mode 100644 index 00000000000000..8a48508b8c1f6b --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2017-10-18-18-07-45.bpo-31809.KlQrkE.rst @@ -0,0 +1 @@ +Add tests to verify connection with secp ECDH curves. diff --git a/Misc/NEWS.d/next/Tests/2018-01-08-13-33-47.bpo-19417.2asoXy.rst b/Misc/NEWS.d/next/Tests/2018-01-08-13-33-47.bpo-19417.2asoXy.rst new file mode 100644 index 00000000000000..739352fcdd6743 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2018-01-08-13-33-47.bpo-19417.2asoXy.rst @@ -0,0 +1 @@ +Add test_bdb.py. diff --git a/Misc/NEWS.d/next/Tests/2018-03-09-07-05-12.bpo-32517.ugc1iW.rst b/Misc/NEWS.d/next/Tests/2018-03-09-07-05-12.bpo-32517.ugc1iW.rst new file mode 100644 index 00000000000000..43f148f06ecbea --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2018-03-09-07-05-12.bpo-32517.ugc1iW.rst @@ -0,0 +1,2 @@ +Fix failing ``test_asyncio`` on macOS 10.12.2+ due to transport of +``KqueueSelector`` loop was not being closed. diff --git a/Misc/NEWS.d/next/Tests/2018-03-28-01-35-02.bpo-32872.J5NDUj.rst b/Misc/NEWS.d/next/Tests/2018-03-28-01-35-02.bpo-32872.J5NDUj.rst new file mode 100644 index 00000000000000..06d656bbfd640d --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2018-03-28-01-35-02.bpo-32872.J5NDUj.rst @@ -0,0 +1 @@ +Avoid regrtest compatibility issue with namespace packages. diff --git a/Misc/NEWS.d/next/Tests/2018-04-27-11-46-35.bpo-33358._OcR59.rst b/Misc/NEWS.d/next/Tests/2018-04-27-11-46-35.bpo-33358._OcR59.rst new file mode 100644 index 00000000000000..89406e994a9193 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2018-04-27-11-46-35.bpo-33358._OcR59.rst @@ -0,0 +1,2 @@ +Fix ``test_embed.test_pre_initialization_sys_options()`` when the interpreter +is built with ``--enable-shared``. diff --git a/Misc/NEWS.d/next/Tests/2018-05-26-16-01-40.bpo-33655.Frb4LA.rst b/Misc/NEWS.d/next/Tests/2018-05-26-16-01-40.bpo-33655.Frb4LA.rst new file mode 100644 index 00000000000000..7ed2ea2323717d --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2018-05-26-16-01-40.bpo-33655.Frb4LA.rst @@ -0,0 +1,2 @@ +Ignore test_posix_fallocate failures on BSD platforms that might be due to +running on ZFS. diff --git a/Misc/NEWS.d/next/Tests/2018-06-01-14-25-31.bpo-33562.GutEHf.rst b/Misc/NEWS.d/next/Tests/2018-06-01-14-25-31.bpo-33562.GutEHf.rst new file mode 100644 index 00000000000000..f63e2632a192eb --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2018-06-01-14-25-31.bpo-33562.GutEHf.rst @@ -0,0 +1,2 @@ +Check that a global asyncio event loop policy is not left behind by any +tests. diff --git a/Misc/NEWS.d/next/Tests/2018-06-16-01-37-31.bpo-33873.d86vab.rst b/Misc/NEWS.d/next/Tests/2018-06-16-01-37-31.bpo-33873.d86vab.rst new file mode 100644 index 00000000000000..f4f425570267db --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2018-06-16-01-37-31.bpo-33873.d86vab.rst @@ -0,0 +1,4 @@ +Fix a bug in ``regrtest`` that caused an extra test to run if +--huntrleaks/-R was used. Exit with error in case that invalid +parameters are specified to --huntrleaks/-R (at least one warmup +run and one repetition must be used). diff --git a/Misc/NEWS.d/next/Tests/2018-06-19-14-04-21.bpo-33901.OFW1Sr.rst b/Misc/NEWS.d/next/Tests/2018-06-19-14-04-21.bpo-33901.OFW1Sr.rst new file mode 100644 index 00000000000000..2a2dec3e9fa192 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2018-06-19-14-04-21.bpo-33901.OFW1Sr.rst @@ -0,0 +1,2 @@ +Fix test_dbm_gnu on macOS with gdbm 1.15: add a larger value to make sure that +the file size changes. diff --git a/Misc/NEWS.d/next/Tests/2018-06-19-17-55-46.bpo-33746.Sz7avn.rst b/Misc/NEWS.d/next/Tests/2018-06-19-17-55-46.bpo-33746.Sz7avn.rst new file mode 100644 index 00000000000000..e79399f03be553 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2018-06-19-17-55-46.bpo-33746.Sz7avn.rst @@ -0,0 +1 @@ +Fix test_unittest when run in verbose mode. diff --git a/Misc/NEWS.d/next/Tools-Demos/2017-09-26-10-11-21.bpo-31583.TM90_H.rst b/Misc/NEWS.d/next/Tools-Demos/2017-09-26-10-11-21.bpo-31583.TM90_H.rst new file mode 100644 index 00000000000000..472f61c5129e33 --- /dev/null +++ b/Misc/NEWS.d/next/Tools-Demos/2017-09-26-10-11-21.bpo-31583.TM90_H.rst @@ -0,0 +1,2 @@ +Fix 2to3 for using with --add-suffix option but without --output-dir +option for relative path to files in current directory. diff --git a/Misc/NEWS.d/next/Tools-Demos/2017-12-07-20-51-20.bpo-32222.hPBcGT.rst b/Misc/NEWS.d/next/Tools-Demos/2017-12-07-20-51-20.bpo-32222.hPBcGT.rst new file mode 100644 index 00000000000000..b0b4c5e9357ce6 --- /dev/null +++ b/Misc/NEWS.d/next/Tools-Demos/2017-12-07-20-51-20.bpo-32222.hPBcGT.rst @@ -0,0 +1,3 @@ +Fix pygettext not extracting docstrings for functions with type annotated +arguments. +Patch by Toby Harradine. diff --git a/Misc/NEWS.d/next/Tools-Demos/2018-02-20-12-16-47.bpo-32885.dL5x7C.rst b/Misc/NEWS.d/next/Tools-Demos/2018-02-20-12-16-47.bpo-32885.dL5x7C.rst new file mode 100644 index 00000000000000..e003e1d84fd01f --- /dev/null +++ b/Misc/NEWS.d/next/Tools-Demos/2018-02-20-12-16-47.bpo-32885.dL5x7C.rst @@ -0,0 +1,2 @@ +Add an ``-n`` flag for ``Tools/scripts/pathfix.py`` to disbale automatic +backup creation (files with ``~`` suffix). diff --git a/Misc/NEWS.d/next/Tools-Demos/2018-03-02-16-23-31.bpo-25427.1mgMOG.rst b/Misc/NEWS.d/next/Tools-Demos/2018-03-02-16-23-31.bpo-25427.1mgMOG.rst new file mode 100644 index 00000000000000..fe4495e8b5740c --- /dev/null +++ b/Misc/NEWS.d/next/Tools-Demos/2018-03-02-16-23-31.bpo-25427.1mgMOG.rst @@ -0,0 +1,3 @@ +Remove the pyvenv script in favor of ``python3 -m venv`` in order to lower +confusion as to what Python interpreter a virtual environment will be +created for. diff --git a/Misc/NEWS.d/next/Tools-Demos/2018-03-16-17-25-05.bpo-29673.m8QtaW.rst b/Misc/NEWS.d/next/Tools-Demos/2018-03-16-17-25-05.bpo-29673.m8QtaW.rst new file mode 100644 index 00000000000000..3d515b3ee4dbe7 --- /dev/null +++ b/Misc/NEWS.d/next/Tools-Demos/2018-03-16-17-25-05.bpo-29673.m8QtaW.rst @@ -0,0 +1 @@ +Fix pystackv and pystack gdbinit macros. diff --git a/Misc/NEWS.d/next/Tools-Demos/2018-03-26-18-54-24.bpo-31920.u_WKsT.rst b/Misc/NEWS.d/next/Tools-Demos/2018-03-26-18-54-24.bpo-31920.u_WKsT.rst new file mode 100644 index 00000000000000..39c694b0728dab --- /dev/null +++ b/Misc/NEWS.d/next/Tools-Demos/2018-03-26-18-54-24.bpo-31920.u_WKsT.rst @@ -0,0 +1,2 @@ +Fixed handling directories as arguments in the ``pygettext`` script. Based +on patch by Oleg Krasnikov. diff --git a/Misc/NEWS.d/next/Tools-Demos/2018-04-03-18-10-00.bpo-33189.QrXR00.rst b/Misc/NEWS.d/next/Tools-Demos/2018-04-03-18-10-00.bpo-33189.QrXR00.rst new file mode 100644 index 00000000000000..4d4137240e61aa --- /dev/null +++ b/Misc/NEWS.d/next/Tools-Demos/2018-04-03-18-10-00.bpo-33189.QrXR00.rst @@ -0,0 +1,2 @@ +:program:`pygettext.py` now recognizes only literal strings as docstrings +and translatable strings, and rejects bytes literals and f-string expressions. diff --git a/Misc/NEWS.d/next/Tools-Demos/2018-06-14-16-16-53.bpo-32962.2YfdwI.rst b/Misc/NEWS.d/next/Tools-Demos/2018-06-14-16-16-53.bpo-32962.2YfdwI.rst new file mode 100644 index 00000000000000..de40070795e953 --- /dev/null +++ b/Misc/NEWS.d/next/Tools-Demos/2018-06-14-16-16-53.bpo-32962.2YfdwI.rst @@ -0,0 +1,2 @@ +python-gdb now catchs ValueError on read_var(): when Python has no debug +symbols for example. diff --git a/Misc/NEWS.d/next/Tools-Demos/2018-06-14-16-23-07.bpo-32962.Q3Dwns.rst b/Misc/NEWS.d/next/Tools-Demos/2018-06-14-16-23-07.bpo-32962.Q3Dwns.rst new file mode 100644 index 00000000000000..fc14261019a03f --- /dev/null +++ b/Misc/NEWS.d/next/Tools-Demos/2018-06-14-16-23-07.bpo-32962.Q3Dwns.rst @@ -0,0 +1,2 @@ +python-gdb now catchs ``UnicodeDecodeError`` exceptions when calling +``string()``. diff --git a/Misc/NEWS.d/next/Windows/2018-02-07-17-50-48.bpo-29248.Xzwj-6.rst b/Misc/NEWS.d/next/Windows/2018-02-07-17-50-48.bpo-29248.Xzwj-6.rst new file mode 100644 index 00000000000000..3030ef6958de0f --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2018-02-07-17-50-48.bpo-29248.Xzwj-6.rst @@ -0,0 +1,3 @@ +Fix :func:`os.readlink` on Windows, which was mistakenly treating the +``PrintNameOffset`` field of the reparse data buffer as a number of +characters instead of bytes. Patch by Craig Holmquist and SSE4. diff --git a/Misc/NEWS.d/next/Windows/2018-02-10-15-38-19.bpo-32370.kcKuct.rst b/Misc/NEWS.d/next/Windows/2018-02-10-15-38-19.bpo-32370.kcKuct.rst new file mode 100644 index 00000000000000..7f076d45bef9db --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2018-02-10-15-38-19.bpo-32370.kcKuct.rst @@ -0,0 +1,2 @@ +Use the correct encoding for ipconfig output in the uuid module. +Patch by Segev Finer. diff --git a/Misc/NEWS.d/next/Windows/2018-02-19-08-54-06.bpo-32457.vVP0Iz.rst b/Misc/NEWS.d/next/Windows/2018-02-19-08-54-06.bpo-32457.vVP0Iz.rst new file mode 100644 index 00000000000000..b55ec821e622c1 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2018-02-19-08-54-06.bpo-32457.vVP0Iz.rst @@ -0,0 +1 @@ +Improves handling of denormalized executable path when launching Python. diff --git a/Misc/NEWS.d/next/Windows/2018-02-19-10-00-57.bpo-32409.nocuDg.rst b/Misc/NEWS.d/next/Windows/2018-02-19-10-00-57.bpo-32409.nocuDg.rst new file mode 100644 index 00000000000000..36251b0b4783b5 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2018-02-19-10-00-57.bpo-32409.nocuDg.rst @@ -0,0 +1 @@ +Ensures activate.bat can handle Unicode contents. diff --git a/Misc/NEWS.d/next/Windows/2018-02-19-13-54-42.bpo-31966._Q3HPb.rst b/Misc/NEWS.d/next/Windows/2018-02-19-13-54-42.bpo-31966._Q3HPb.rst new file mode 100644 index 00000000000000..042a4d835abf17 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2018-02-19-13-54-42.bpo-31966._Q3HPb.rst @@ -0,0 +1 @@ +Fixed WindowsConsoleIO.write() for writing empty data. diff --git a/Misc/NEWS.d/next/Windows/2018-02-23-00-47-13.bpo-32901.mGKz5_.rst b/Misc/NEWS.d/next/Windows/2018-02-23-00-47-13.bpo-32901.mGKz5_.rst new file mode 100644 index 00000000000000..af0ca65e3c8216 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2018-02-23-00-47-13.bpo-32901.mGKz5_.rst @@ -0,0 +1 @@ +Update Tcl and Tk versions to 8.6.8 diff --git a/Misc/NEWS.d/next/Windows/2018-02-28-11-03-24.bpo-32903.1SXY4t.rst b/Misc/NEWS.d/next/Windows/2018-02-28-11-03-24.bpo-32903.1SXY4t.rst new file mode 100644 index 00000000000000..a20a414790f819 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2018-02-28-11-03-24.bpo-32903.1SXY4t.rst @@ -0,0 +1,2 @@ +Fix a memory leak in os.chdir() on Windows if the current directory is set +to a UNC path. diff --git a/Misc/NEWS.d/next/Windows/2018-03-07-01-33-33.bpo-33016.Z_Med0.rst b/Misc/NEWS.d/next/Windows/2018-03-07-01-33-33.bpo-33016.Z_Med0.rst new file mode 100644 index 00000000000000..f4f78d489bf1ea --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2018-03-07-01-33-33.bpo-33016.Z_Med0.rst @@ -0,0 +1 @@ +Fix potential use of uninitialized memory in nt._getfinalpathname diff --git a/Misc/NEWS.d/next/Windows/2018-04-13-11-28-55.bpo-33184.7YhqQE.rst b/Misc/NEWS.d/next/Windows/2018-04-13-11-28-55.bpo-33184.7YhqQE.rst new file mode 100644 index 00000000000000..ca47a98110883c --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2018-04-13-11-28-55.bpo-33184.7YhqQE.rst @@ -0,0 +1 @@ +Update Windows installer to use OpenSSL 1.1.0h. diff --git a/Misc/NEWS.d/next/Windows/2018-06-04-09-20-53.bpo-33720.VKDXHK.rst b/Misc/NEWS.d/next/Windows/2018-06-04-09-20-53.bpo-33720.VKDXHK.rst new file mode 100644 index 00000000000000..f7e2f9d1eae4f5 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2018-06-04-09-20-53.bpo-33720.VKDXHK.rst @@ -0,0 +1 @@ +Reduces maximum marshal recursion depth on release builds. diff --git a/Misc/NEWS.d/next/Windows/2018-06-27-23-33-54.bpo-31546.zJlap-.rst b/Misc/NEWS.d/next/Windows/2018-06-27-23-33-54.bpo-31546.zJlap-.rst new file mode 100644 index 00000000000000..8f487632ce053c --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2018-06-27-23-33-54.bpo-31546.zJlap-.rst @@ -0,0 +1,3 @@ +Restore running PyOS_InputHook while waiting for user input at the prompt. +The restores integration of interactive GUI windows (such as Matplotlib +figures) with the prompt on Windows. diff --git a/Misc/NEWS.d/next/Windows/2018-07-02-14-19-32.bpo-34006.7SgBT_.rst b/Misc/NEWS.d/next/Windows/2018-07-02-14-19-32.bpo-34006.7SgBT_.rst new file mode 100644 index 00000000000000..f21e51646f1a73 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2018-07-02-14-19-32.bpo-34006.7SgBT_.rst @@ -0,0 +1,3 @@ +Revert line length limit for Windows help docs. The line-length limit is not +needed because the pages appear in a separate app rather than on a browser +tab. It can also interact badly with the DPI setting. diff --git a/Misc/NEWS.d/next/macOS/2018-02-27-17-33-15.bpo-32901.hQu0w3.rst b/Misc/NEWS.d/next/macOS/2018-02-27-17-33-15.bpo-32901.hQu0w3.rst new file mode 100644 index 00000000000000..73e69a9b711940 --- /dev/null +++ b/Misc/NEWS.d/next/macOS/2018-02-27-17-33-15.bpo-32901.hQu0w3.rst @@ -0,0 +1 @@ +Update macOS 10.9+ installer to Tcl/Tk 8.6.8. diff --git a/Misc/NEWS.d/next/macOS/2018-03-29-06-56-12.bpo-32726.urS9uX.rst b/Misc/NEWS.d/next/macOS/2018-03-29-06-56-12.bpo-32726.urS9uX.rst new file mode 100644 index 00000000000000..9b769a831e58d7 --- /dev/null +++ b/Misc/NEWS.d/next/macOS/2018-03-29-06-56-12.bpo-32726.urS9uX.rst @@ -0,0 +1,5 @@ +Build and link with private copy of Tcl/Tk 8.6 for the macOS 10.6+ +installer. The 10.9+ installer variant already does this. This means that +the Python 3.7 provided by the python.org macOS installers no longer need or +use any external versions of Tcl/Tk, either system-provided or +user-installed, such as ActiveTcl. diff --git a/Misc/NEWS.d/next/macOS/2018-04-07-00-51-34.bpo-33184.3j208P.rst b/Misc/NEWS.d/next/macOS/2018-04-07-00-51-34.bpo-33184.3j208P.rst new file mode 100644 index 00000000000000..03308ed6a72b54 --- /dev/null +++ b/Misc/NEWS.d/next/macOS/2018-04-07-00-51-34.bpo-33184.3j208P.rst @@ -0,0 +1 @@ +Update macOS installer build to use OpenSSL 1.1.0h. diff --git a/Misc/NEWS.d/next/macOS/2018-05-16-13-25-58.bpo-13631.UIjDyY.rst b/Misc/NEWS.d/next/macOS/2018-05-16-13-25-58.bpo-13631.UIjDyY.rst new file mode 100644 index 00000000000000..d9d505e937a848 --- /dev/null +++ b/Misc/NEWS.d/next/macOS/2018-05-16-13-25-58.bpo-13631.UIjDyY.rst @@ -0,0 +1,2 @@ +The .editrc file in user's home directory is now processed correctly during +the readline initialization through editline emulation on macOS. diff --git a/Misc/gdbinit b/Misc/gdbinit index bb10bdba799aa6..afefe0818e4c77 100644 --- a/Misc/gdbinit +++ b/Misc/gdbinit @@ -14,9 +14,11 @@ # with embedded macros that you may find superior to what is in here. # See Tools/gdb/libpython.py and http://bugs.python.org/issue8032. -# Prints a representation of the object to stderr, along with the -# number of reference counts it current has and the hex address the -# object is allocated at. The argument must be a PyObject* +document pyo + Prints a representation of the object to stderr, along with the + number of reference counts it currently has and the hex address the + object is allocated at. The argument must be a PyObject* +end define pyo # side effect of calling _PyObject_Dump is to dump the object's # info - assigning just prevents gdb from printing the @@ -24,14 +26,18 @@ define pyo set $_unused_void = _PyObject_Dump($arg0) end -# Prints a representation of the object to stderr, along with the -# number of reference counts it current has and the hex address the -# object is allocated at. The argument must be a PyGC_Head* +document pyg + Prints a representation of the object to stderr, along with the + number of reference counts it currently has and the hex address the + object is allocated at. The argument must be a PyGC_Head* +end define pyg print _PyGC_Dump($arg0) end -# print the local variables of the current frame +document pylocals + Print the local variables of the current frame. +end define pylocals set $_i = 0 while $_i < f->f_code->co_nlocals @@ -69,7 +75,9 @@ define lineno printf "%d", $__li end -# print the current frame - verbose +document pyframev + Print the current frame - verbose +end define pyframev pyframe pylocals @@ -126,7 +134,9 @@ end # the interpreter you may will have to change the functions you compare with # $pc. -# print the entire Python call stack +document pystack + Print the entire Python call stack +end define pystack while $pc < Py_Main || $pc > Py_GetArgcArgv if $pc > PyEval_EvalFrameEx && $pc < _PyEval_EvalFrameDefault @@ -137,7 +147,9 @@ define pystack select-frame 0 end -# print the entire Python call stack - verbose mode +document pystackv + Print the entire Python call stack - verbose mode +end define pystackv while $pc < Py_Main || $pc > Py_GetArgcArgv if $pc > PyEval_EvalFrameEx && $pc < _PyEval_EvalFrameDefault @@ -148,7 +160,9 @@ define pystackv select-frame 0 end -# generally useful macro to print a Unicode string +document pu + Generally useful macro to print a Unicode string +end def pu set $uni = $arg0 set $i = 0 diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index e3537cc81c4ccb..ebda10404eb5df 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -1738,7 +1738,7 @@ static PyGetSetDef TaskStepMethWrapper_getsetlist[] = { {NULL} /* Sentinel */ }; -PyTypeObject TaskStepMethWrapper_Type = { +static PyTypeObject TaskStepMethWrapper_Type = { PyVarObject_HEAD_INIT(NULL, 0) "TaskStepMethWrapper", .tp_basicsize = sizeof(TaskStepMethWrapper), @@ -1813,7 +1813,7 @@ TaskWakeupMethWrapper_dealloc(TaskWakeupMethWrapper *o) Py_TYPE(o)->tp_free(o); } -PyTypeObject TaskWakeupMethWrapper_Type = { +static PyTypeObject TaskWakeupMethWrapper_Type = { PyVarObject_HEAD_INIT(NULL, 0) "TaskWakeupMethWrapper", .tp_basicsize = sizeof(TaskWakeupMethWrapper), diff --git a/Modules/_bz2module.c b/Modules/_bz2module.c index 0789b6179e52be..3890b60b1b87b3 100644 --- a/Modules/_bz2module.c +++ b/Modules/_bz2module.c @@ -634,11 +634,15 @@ _bz2_BZ2Decompressor___init___impl(BZ2Decompressor *self) { int bzerror; - self->lock = PyThread_allocate_lock(); - if (self->lock == NULL) { + PyThread_type_lock lock = PyThread_allocate_lock(); + if (lock == NULL) { PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock"); return -1; } + if (self->lock != NULL) { + PyThread_free_lock(self->lock); + } + self->lock = lock; self->needs_input = 1; self->bzs_avail_in_real = 0; diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c index 4116d405354701..65d556c5a0e5b4 100644 --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -512,7 +512,7 @@ deque_inplace_concat(dequeobject *deque, PyObject *other) } static PyObject * -deque_copy(PyObject *deque) +deque_copy(PyObject *deque, PyObject *Py_UNUSED(ignored)) { dequeobject *old_deque = (dequeobject *)deque; if (Py_TYPE(deque) == &deque_type) { @@ -563,7 +563,7 @@ deque_concat(dequeobject *deque, PyObject *other) return NULL; } - new_deque = deque_copy((PyObject *)deque); + new_deque = deque_copy((PyObject *)deque, NULL); if (new_deque == NULL) return NULL; result = deque_extend((dequeobject *)new_deque, other); @@ -660,7 +660,7 @@ deque_clear(dequeobject *deque) } static PyObject * -deque_clearmethod(dequeobject *deque) +deque_clearmethod(dequeobject *deque, PyObject *Py_UNUSED(ignored)) { deque_clear(deque); Py_RETURN_NONE; @@ -755,7 +755,7 @@ deque_repeat(dequeobject *deque, Py_ssize_t n) dequeobject *new_deque; PyObject *rv; - new_deque = (dequeobject *)deque_copy((PyObject *) deque); + new_deque = (dequeobject *)deque_copy((PyObject *) deque, NULL); if (new_deque == NULL) return NULL; rv = deque_inplace_repeat(new_deque, n); @@ -1577,7 +1577,7 @@ static PyNumberMethods deque_as_number = { }; static PyObject *deque_iter(dequeobject *deque); -static PyObject *deque_reviter(dequeobject *deque); +static PyObject *deque_reviter(dequeobject *deque, PyObject *Py_UNUSED(ignored)); PyDoc_STRVAR(reversed_doc, "D.__reversed__() -- return a reverse iterator over the deque"); @@ -1588,9 +1588,9 @@ static PyMethodDef deque_methods[] = { METH_O, appendleft_doc}, {"clear", (PyCFunction)deque_clearmethod, METH_NOARGS, clear_doc}, - {"__copy__", (PyCFunction)deque_copy, + {"__copy__", deque_copy, METH_NOARGS, copy_doc}, - {"copy", (PyCFunction)deque_copy, + {"copy", deque_copy, METH_NOARGS, copy_doc}, {"count", (PyCFunction)deque_count, METH_O, count_doc}, @@ -1775,7 +1775,7 @@ dequeiter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } static PyObject * -dequeiter_len(dequeiterobject *it) +dequeiter_len(dequeiterobject *it, PyObject *Py_UNUSED(ignored)) { return PyLong_FromSsize_t(it->counter); } @@ -1783,7 +1783,7 @@ dequeiter_len(dequeiterobject *it) PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); static PyObject * -dequeiter_reduce(dequeiterobject *it) +dequeiter_reduce(dequeiterobject *it, PyObject *Py_UNUSED(ignored)) { return Py_BuildValue("O(On)", Py_TYPE(it), it->deque, Py_SIZE(it->deque) - it->counter); } @@ -1842,7 +1842,7 @@ static PyTypeObject dequeiter_type = { static PyTypeObject dequereviter_type; static PyObject * -deque_reviter(dequeobject *deque) +deque_reviter(dequeobject *deque, PyObject *Py_UNUSED(ignored)) { dequeiterobject *it; @@ -1897,7 +1897,7 @@ dequereviter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; assert(type == &dequereviter_type); - it = (dequeiterobject*)deque_reviter((dequeobject *)deque); + it = (dequeiterobject*)deque_reviter((dequeobject *)deque, NULL); if (!it) return NULL; /* consume items from the queue */ @@ -2002,7 +2002,7 @@ defdict_missing(defdictobject *dd, PyObject *key) PyDoc_STRVAR(defdict_copy_doc, "D.copy() -> a shallow copy of D."); static PyObject * -defdict_copy(defdictobject *dd) +defdict_copy(defdictobject *dd, PyObject *Py_UNUSED(ignored)) { /* This calls the object's class. That only works for subclasses whose class constructor has the same signature. Subclasses that @@ -2016,7 +2016,7 @@ defdict_copy(defdictobject *dd) } static PyObject * -defdict_reduce(defdictobject *dd) +defdict_reduce(defdictobject *dd, PyObject *Py_UNUSED(ignored)) { /* __reduce__ must return a 5-tuple as follows: diff --git a/Modules/_csv.c b/Modules/_csv.c index e616151bae63c8..610f7bb063257b 100644 --- a/Modules/_csv.c +++ b/Modules/_csv.c @@ -1523,15 +1523,15 @@ PyDoc_STRVAR(csv_module_doc, "\n" "SETTINGS:\n" "\n" -" * quotechar - specifies a one-character string to use as the \n" +" * quotechar - specifies a one-character string to use as the\n" " quoting character. It defaults to '\"'.\n" -" * delimiter - specifies a one-character string to use as the \n" +" * delimiter - specifies a one-character string to use as the\n" " field separator. It defaults to ','.\n" " * skipinitialspace - specifies how to interpret whitespace which\n" " immediately follows a delimiter. It defaults to False, which\n" " means that whitespace immediately following a delimiter is part\n" " of the following field.\n" -" * lineterminator - specifies the character sequence which should \n" +" * lineterminator - specifies the character sequence which should\n" " terminate rows.\n" " * quoting - controls when quotes should be generated by the writer.\n" " It can take on any of the following module constants:\n" @@ -1543,7 +1543,7 @@ PyDoc_STRVAR(csv_module_doc, " fields which do not parse as integers or floating point\n" " numbers.\n" " csv.QUOTE_NONE means that quotes are never placed around fields.\n" -" * escapechar - specifies a one-character string used to escape \n" +" * escapechar - specifies a one-character string used to escape\n" " the delimiter when quoting is set to QUOTE_NONE.\n" " * doublequote - controls the handling of quotes inside fields. When\n" " True, two consecutive quotes are interpreted as one during read,\n" diff --git a/Modules/_curses_panel.c b/Modules/_curses_panel.c index a98d2bf3f85f54..609718f65f15ab 100644 --- a/Modules/_curses_panel.c +++ b/Modules/_curses_panel.c @@ -162,38 +162,69 @@ find_po(PANEL *pan) return temp->po; } -/* Function Prototype Macros - They are ugly but very, very useful. ;-) - - X - function name - TYPE - parameter Type - ERGSTR - format string for construction of the return value - PARSESTR - format string for argument parsing */ - -#define Panel_NoArgNoReturnFunction(X) \ -static PyObject *PyCursesPanel_##X(PyCursesPanelObject *self) \ -{ return PyCursesCheckERR(X(self->pan), # X); } - -#define Panel_NoArgTrueFalseFunction(X) \ -static PyObject *PyCursesPanel_##X(PyCursesPanelObject *self) \ -{ \ - if (X (self->pan) == FALSE) { Py_RETURN_FALSE; } \ - else { Py_RETURN_TRUE; } } - -#define Panel_TwoArgNoReturnFunction(X, TYPE, PARSESTR) \ -static PyObject *PyCursesPanel_##X(PyCursesPanelObject *self, PyObject *args) \ -{ \ - TYPE arg1, arg2; \ - if (!PyArg_ParseTuple(args, PARSESTR, &arg1, &arg2)) return NULL; \ - return PyCursesCheckERR(X(self->pan, arg1, arg2), # X); } +/*[clinic input] +module _curses_panel +class _curses_panel.panel "PyCursesPanelObject *" "&PyCursesPanel_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=2f4ef263ca850a31]*/ + +#include "clinic/_curses_panel.c.h" /* ------------- PANEL routines --------------- */ -Panel_NoArgNoReturnFunction(bottom_panel) -Panel_NoArgNoReturnFunction(hide_panel) -Panel_NoArgNoReturnFunction(show_panel) -Panel_NoArgNoReturnFunction(top_panel) -Panel_NoArgTrueFalseFunction(panel_hidden) -Panel_TwoArgNoReturnFunction(move_panel, int, "ii;y,x") +/*[clinic input] +_curses_panel.panel.bottom + +Push the panel to the bottom of the stack. +[clinic start generated code]*/ + +static PyObject * +_curses_panel_panel_bottom_impl(PyCursesPanelObject *self) +/*[clinic end generated code: output=7aa7d14d7e1d1ce6 input=b6c920c071b61e2e]*/ +{ + return PyCursesCheckERR(bottom_panel(self->pan), "bottom"); +} + +/*[clinic input] +_curses_panel.panel.hide + +Hide the panel. + +This does not delete the object, it just makes the window on screen invisible. +[clinic start generated code]*/ + +static PyObject * +_curses_panel_panel_hide_impl(PyCursesPanelObject *self) +/*[clinic end generated code: output=a7bbbd523e1eab49 input=f6ab884e99386118]*/ +{ + return PyCursesCheckERR(hide_panel(self->pan), "hide"); +} + +/*[clinic input] +_curses_panel.panel.show + +Display the panel (which might have been hidden). +[clinic start generated code]*/ + +static PyObject * +_curses_panel_panel_show_impl(PyCursesPanelObject *self) +/*[clinic end generated code: output=6b4553ab45c97769 input=57b167bbefaa3755]*/ +{ + return PyCursesCheckERR(show_panel(self->pan), "show"); +} + +/*[clinic input] +_curses_panel.panel.top + +Push panel to the top of the stack. +[clinic start generated code]*/ + +static PyObject * +_curses_panel_panel_top_impl(PyCursesPanelObject *self) +/*[clinic end generated code: output=0f5f2f8cdd2d1777 input=be33975ec3ca0e9a]*/ +{ + return PyCursesCheckERR(top_panel(self->pan), "top"); +} /* Allocation and deallocation of Panel Objects */ @@ -234,8 +265,15 @@ PyCursesPanel_Dealloc(PyCursesPanelObject *po) /* panel_above(NULL) returns the bottom panel in the stack. To get this behaviour we use curses.panel.bottom_panel(). */ +/*[clinic input] +_curses_panel.panel.above + +Return the panel above the current panel. +[clinic start generated code]*/ + static PyObject * -PyCursesPanel_above(PyCursesPanelObject *self) +_curses_panel_panel_above_impl(PyCursesPanelObject *self) +/*[clinic end generated code: output=70ac06d25fd3b4da input=c059994022976788]*/ { PANEL *pan; PyCursesPanelObject *po; @@ -258,8 +296,15 @@ PyCursesPanel_above(PyCursesPanelObject *self) /* panel_below(NULL) returns the top panel in the stack. To get this behaviour we use curses.panel.top_panel(). */ +/*[clinic input] +_curses_panel.panel.below + +Return the panel below the current panel. +[clinic start generated code]*/ + static PyObject * -PyCursesPanel_below(PyCursesPanelObject *self) +_curses_panel_panel_below_impl(PyCursesPanelObject *self) +/*[clinic end generated code: output=282861122e06e3de input=cc08f61936d297c6]*/ { PANEL *pan; PyCursesPanelObject *po; @@ -280,28 +325,70 @@ PyCursesPanel_below(PyCursesPanelObject *self) return (PyObject *)po; } +/*[clinic input] +_curses_panel.panel.hidden + +Return True if the panel is hidden (not visible), False otherwise. +[clinic start generated code]*/ + static PyObject * -PyCursesPanel_window(PyCursesPanelObject *self) +_curses_panel_panel_hidden_impl(PyCursesPanelObject *self) +/*[clinic end generated code: output=66eebd1ab4501a71 input=453d4b4fce25e21a]*/ +{ + if (panel_hidden(self->pan)) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; +} + +/*[clinic input] +_curses_panel.panel.move + + y: int + x: int + / + +Move the panel to the screen coordinates (y, x). +[clinic start generated code]*/ + +static PyObject * +_curses_panel_panel_move_impl(PyCursesPanelObject *self, int y, int x) +/*[clinic end generated code: output=d867535a89777415 input=e0b36b78acc03fba]*/ +{ + return PyCursesCheckERR(move_panel(self->pan, y, x), "move_panel"); +} + +/*[clinic input] +_curses_panel.panel.window + +Return the window object associated with the panel. +[clinic start generated code]*/ + +static PyObject * +_curses_panel_panel_window_impl(PyCursesPanelObject *self) +/*[clinic end generated code: output=5f05940d4106b4cb input=6067353d2c307901]*/ { Py_INCREF(self->wo); return (PyObject *)self->wo; } +/*[clinic input] +_curses_panel.panel.replace + + win: object(type="PyCursesWindowObject *", subclass_of="&PyCursesWindow_Type") + / + +Change the window associated with the panel to the window win. +[clinic start generated code]*/ + static PyObject * -PyCursesPanel_replace_panel(PyCursesPanelObject *self, PyObject *args) +_curses_panel_panel_replace_impl(PyCursesPanelObject *self, + PyCursesWindowObject *win) +/*[clinic end generated code: output=2253a95f7b287255 input=4b1c4283987d9dfa]*/ { PyCursesPanelObject *po; - PyCursesWindowObject *temp; int rtn; - if (PyTuple_Size(args) != 1) { - PyErr_SetString(PyExc_TypeError, "replace requires one argument"); - return NULL; - } - if (!PyArg_ParseTuple(args, "O!;window object", - &PyCursesWindow_Type, &temp)) - return NULL; - po = find_po(self->pan); if (po == NULL) { PyErr_SetString(PyExc_RuntimeError, @@ -309,18 +396,28 @@ PyCursesPanel_replace_panel(PyCursesPanelObject *self, PyObject *args) return NULL; } - rtn = replace_panel(self->pan, temp->win); + rtn = replace_panel(self->pan, win->win); if (rtn == ERR) { PyErr_SetString(_curses_panelstate_global->PyCursesError, "replace_panel() returned ERR"); return NULL; } - Py_INCREF(temp); - Py_SETREF(po->wo, temp); + Py_INCREF(win); + Py_SETREF(po->wo, win); Py_RETURN_NONE; } +/*[clinic input] +_curses_panel.panel.set_userptr + + obj: object + / + +Set the panel’s user pointer to obj. +[clinic start generated code]*/ + static PyObject * -PyCursesPanel_set_panel_userptr(PyCursesPanelObject *self, PyObject *obj) +_curses_panel_panel_set_userptr(PyCursesPanelObject *self, PyObject *obj) +/*[clinic end generated code: output=6fb145b3af88cf4a input=2056be1cd148b05c]*/ { PyObject *oldobj; int rc; @@ -336,8 +433,15 @@ PyCursesPanel_set_panel_userptr(PyCursesPanelObject *self, PyObject *obj) return PyCursesCheckERR(rc, "set_panel_userptr"); } +/*[clinic input] +_curses_panel.panel.userptr + +Return the user pointer for the panel. +[clinic start generated code]*/ + static PyObject * -PyCursesPanel_userptr(PyCursesPanelObject *self) +_curses_panel_panel_userptr_impl(PyCursesPanelObject *self) +/*[clinic end generated code: output=e849c307b5dc9237 input=f78b7a47aef0fd50]*/ { PyObject *obj; PyCursesInitialised; @@ -355,18 +459,18 @@ PyCursesPanel_userptr(PyCursesPanelObject *self) /* Module interface */ static PyMethodDef PyCursesPanel_Methods[] = { - {"above", (PyCFunction)PyCursesPanel_above, METH_NOARGS}, - {"below", (PyCFunction)PyCursesPanel_below, METH_NOARGS}, - {"bottom", (PyCFunction)PyCursesPanel_bottom_panel, METH_NOARGS}, - {"hidden", (PyCFunction)PyCursesPanel_panel_hidden, METH_NOARGS}, - {"hide", (PyCFunction)PyCursesPanel_hide_panel, METH_NOARGS}, - {"move", (PyCFunction)PyCursesPanel_move_panel, METH_VARARGS}, - {"replace", (PyCFunction)PyCursesPanel_replace_panel, METH_VARARGS}, - {"set_userptr", (PyCFunction)PyCursesPanel_set_panel_userptr, METH_O}, - {"show", (PyCFunction)PyCursesPanel_show_panel, METH_NOARGS}, - {"top", (PyCFunction)PyCursesPanel_top_panel, METH_NOARGS}, - {"userptr", (PyCFunction)PyCursesPanel_userptr, METH_NOARGS}, - {"window", (PyCFunction)PyCursesPanel_window, METH_NOARGS}, + _CURSES_PANEL_PANEL_ABOVE_METHODDEF + _CURSES_PANEL_PANEL_BELOW_METHODDEF + _CURSES_PANEL_PANEL_BOTTOM_METHODDEF + _CURSES_PANEL_PANEL_HIDDEN_METHODDEF + _CURSES_PANEL_PANEL_HIDE_METHODDEF + _CURSES_PANEL_PANEL_MOVE_METHODDEF + _CURSES_PANEL_PANEL_REPLACE_METHODDEF + _CURSES_PANEL_PANEL_SET_USERPTR_METHODDEF + _CURSES_PANEL_PANEL_SHOW_METHODDEF + _CURSES_PANEL_PANEL_TOP_METHODDEF + _CURSES_PANEL_PANEL_USERPTR_METHODDEF + _CURSES_PANEL_PANEL_WINDOW_METHODDEF {NULL, NULL} /* sentinel */ }; @@ -379,7 +483,7 @@ static PyType_Slot PyCursesPanel_Type_slots[] = { }; static PyType_Spec PyCursesPanel_Type_spec = { - "_curses_panel.curses panel", + "_curses_panel.panel", sizeof(PyCursesPanelObject), 0, Py_TPFLAGS_DEFAULT, @@ -390,8 +494,15 @@ static PyType_Spec PyCursesPanel_Type_spec = { panel of the stack, so it's renamed to bottom_panel(). panel.above() *requires* a panel object in the first place which may be undesirable. */ +/*[clinic input] +_curses_panel.bottom_panel + +Return the bottom panel in the panel stack. +[clinic start generated code]*/ + static PyObject * -PyCurses_bottom_panel(PyObject *self) +_curses_panel_bottom_panel_impl(PyObject *module) +/*[clinic end generated code: output=3aba9f985f4c2bd0 input=634c2a8078b3d7e4]*/ { PANEL *pan; PyCursesPanelObject *po; @@ -414,15 +525,20 @@ PyCurses_bottom_panel(PyObject *self) return (PyObject *)po; } +/*[clinic input] +_curses_panel.new_panel + + win: object(type="PyCursesWindowObject *", subclass_of="&PyCursesWindow_Type") + / + +Return a panel object, associating it with the given window win. +[clinic start generated code]*/ + static PyObject * -PyCurses_new_panel(PyObject *self, PyObject *args) +_curses_panel_new_panel_impl(PyObject *module, PyCursesWindowObject *win) +/*[clinic end generated code: output=45e948e0176a9bd2 input=74d4754e0ebe4800]*/ { - PyCursesWindowObject *win; - PANEL *pan; - - if (!PyArg_ParseTuple(args, "O!", &PyCursesWindow_Type, &win)) - return NULL; - pan = new_panel(win->win); + PANEL *pan = new_panel(win->win); if (pan == NULL) { PyErr_SetString(_curses_panelstate_global->PyCursesError, catchall_NULL); return NULL; @@ -435,8 +551,15 @@ PyCurses_new_panel(PyObject *self, PyObject *args) of the stack, so it's renamed to top_panel(). panel.below() *requires* a panel object in the first place which may be undesirable. */ +/*[clinic input] +_curses_panel.top_panel + +Return the top panel in the panel stack. +[clinic start generated code]*/ + static PyObject * -PyCurses_top_panel(PyObject *self) +_curses_panel_top_panel_impl(PyObject *module) +/*[clinic end generated code: output=86704988bea8508e input=e62d6278dba39e79]*/ { PANEL *pan; PyCursesPanelObject *po; @@ -459,7 +582,17 @@ PyCurses_top_panel(PyObject *self) return (PyObject *)po; } -static PyObject *PyCurses_update_panels(PyObject *self) +/*[clinic input] +_curses_panel.update_panels + +Updates the virtual screen after changes in the panel stack. + +This does not call curses.doupdate(), so you’ll have to do this yourself. +[clinic start generated code]*/ + +static PyObject * +_curses_panel_update_panels_impl(PyObject *module) +/*[clinic end generated code: output=2f3b4c2e03d90ded input=a127069202b0a097]*/ { PyCursesInitialised; update_panels(); @@ -470,10 +603,10 @@ static PyObject *PyCurses_update_panels(PyObject *self) /* List of functions defined in the module */ static PyMethodDef PyCurses_methods[] = { - {"bottom_panel", (PyCFunction)PyCurses_bottom_panel, METH_NOARGS}, - {"new_panel", (PyCFunction)PyCurses_new_panel, METH_VARARGS}, - {"top_panel", (PyCFunction)PyCurses_top_panel, METH_NOARGS}, - {"update_panels", (PyCFunction)PyCurses_update_panels, METH_NOARGS}, + _CURSES_PANEL_BOTTOM_PANEL_METHODDEF + _CURSES_PANEL_NEW_PANEL_METHODDEF + _CURSES_PANEL_TOP_PANEL_METHODDEF + _CURSES_PANEL_UPDATE_PANELS_METHODDEF {NULL, NULL} /* sentinel */ }; @@ -523,6 +656,9 @@ PyInit__curses_panel(void) PyDict_SetItemString(d, "version", v); PyDict_SetItemString(d, "__version__", v); Py_DECREF(v); + + Py_INCREF(_curses_panelstate(m)->PyCursesPanel_Type); + PyModule_AddObject(m, "panel", (PyObject *)_curses_panelstate(m)->PyCursesPanel_Type); return m; fail: Py_XDECREF(m); diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c index 7936aef0cc9044..a728a24f6caef9 100644 --- a/Modules/_cursesmodule.c +++ b/Modules/_cursesmodule.c @@ -135,12 +135,10 @@ typedef chtype attr_t; /* No attr_t type is available */ #endif /*[clinic input] -module curses -class curses.window "PyCursesWindowObject *" "&PyCursesWindow_Type" +module _curses +class _curses.window "PyCursesWindowObject *" "&PyCursesWindow_Type" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=88c860abdbb50e0c]*/ - -#include "clinic/_cursesmodule.c.h" +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=43265c372c2887d6]*/ /* Definition of exception curses.error */ @@ -423,8 +421,7 @@ PyTypeObject PyCursesWindow_Type; static PyObject * PyCursesWindow_ ## X \ (PyCursesWindowObject *self) \ { \ - if (X (self->win) == FALSE) { Py_RETURN_FALSE; } \ - else { Py_RETURN_TRUE; } } + return PyBool_FromLong(X(self->win)); } #define Window_NoArgNoReturnVoidFunction(X) \ static PyObject * PyCursesWindow_ ## X \ @@ -562,26 +559,25 @@ PyCursesWindow_Dealloc(PyCursesWindowObject *wo) /* Addch, Addstr, Addnstr */ /*[clinic input] - -curses.window.addch +_curses.window.addch [ y: int - Y-coordinate. + Y-coordinate. x: int - X-coordinate. + X-coordinate. ] ch: object - Character to add. + Character to add. [ - attr: long - Attributes for the character. + attr: long(c_default="A_NORMAL") = _curses.A_NORMAL + Attributes for the character. ] / -Paint character ch at (y, x) with attributes attr. +Paint the character. Paint character ch at (y, x) with attributes attr, overwriting any character previously painted at that location. @@ -590,13 +586,12 @@ current settings for the window object. [clinic start generated code]*/ static PyObject * -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=99f7f85078ec06c3 input=5a41efb34a2de338]*/ +_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=00f4c37af3378f45 input=95ce131578458196]*/ { - PyCursesWindowObject *cwself = (PyCursesWindowObject *)self; int coordinates_group = group_left_1; - int attr_group = group_right_1; int rtn; int type; chtype cch = 0; @@ -606,31 +601,28 @@ curses_window_addch_impl(PyCursesWindowObject *self, int group_left_1, int y, #endif const char *funcname; - if (!attr_group) - attr = A_NORMAL; - #ifdef HAVE_NCURSESW - type = PyCurses_ConvertToCchar_t(cwself, ch, &cch, wstr); + type = PyCurses_ConvertToCchar_t(self, ch, &cch, wstr); if (type == 2) { funcname = "add_wch"; wstr[1] = L'\0'; setcchar(&wcval, wstr, attr, 0, NULL); if (coordinates_group) - rtn = mvwadd_wch(cwself->win,y,x, &wcval); + rtn = mvwadd_wch(self->win,y,x, &wcval); else { - rtn = wadd_wch(cwself->win, &wcval); + rtn = wadd_wch(self->win, &wcval); } } else #else - type = PyCurses_ConvertToCchar_t(cwself, ch, &cch); + type = PyCurses_ConvertToCchar_t(self, ch, &cch); #endif if (type == 1) { funcname = "addch"; if (coordinates_group) - rtn = mvwaddch(cwself->win,y,x, cch | attr); + rtn = mvwaddch(self->win,y,x, cch | (attr_t) attr); else { - rtn = waddch(cwself->win, cch | attr); + rtn = waddch(self->win, cch | (attr_t) attr); } } else { @@ -639,62 +631,64 @@ curses_window_addch_impl(PyCursesWindowObject *self, int group_left_1, int y, return PyCursesCheckERR(rtn, funcname); } +/*[clinic input] +_curses.window.addstr + + [ + y: int + Y-coordinate. + x: int + X-coordinate. + ] + + str: object + String to add. + + [ + attr: long + Attributes for characters. + ] + / + +Paint the string. + +Paint the string str at (y, x) with attributes attr, +overwriting anything previously on the display. +By default, the character position and attributes are the +current settings for the window object. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_AddStr(PyCursesWindowObject *self, PyObject *args) +_curses_window_addstr_impl(PyCursesWindowObject *self, int group_left_1, + int y, int x, PyObject *str, int group_right_1, + long attr) +/*[clinic end generated code: output=65a928ea85ff3115 input=ff6cbb91448a22a3]*/ { int rtn; - int x, y; int strtype; - PyObject *strobj, *bytesobj = NULL; + PyObject *bytesobj = NULL; #ifdef HAVE_NCURSESW wchar_t *wstr = NULL; #endif - attr_t attr = A_NORMAL , attr_old = A_NORMAL; - long lattr; - int use_xy = FALSE, use_attr = FALSE; + attr_t attr_old = A_NORMAL; + int use_xy = group_left_1, use_attr = group_right_1; const char *funcname; - switch (PyTuple_Size(args)) { - case 1: - if (!PyArg_ParseTuple(args,"O;str", &strobj)) - return NULL; - break; - case 2: - if (!PyArg_ParseTuple(args,"Ol;str,attr", &strobj, &lattr)) - return NULL; - attr = lattr; - use_attr = TRUE; - break; - case 3: - if (!PyArg_ParseTuple(args,"iiO;int,int,str", &y, &x, &strobj)) - return NULL; - use_xy = TRUE; - break; - case 4: - if (!PyArg_ParseTuple(args,"iiOl;int,int,str,attr", &y, &x, &strobj, &lattr)) - return NULL; - attr = lattr; - use_xy = use_attr = TRUE; - break; - default: - PyErr_SetString(PyExc_TypeError, "addstr requires 1 to 4 arguments"); - return NULL; - } #ifdef HAVE_NCURSESW - strtype = PyCurses_ConvertToString(self, strobj, &bytesobj, &wstr); + strtype = PyCurses_ConvertToString(self, str, &bytesobj, &wstr); #else - strtype = PyCurses_ConvertToString(self, strobj, &bytesobj, NULL); + strtype = PyCurses_ConvertToString(self, str, &bytesobj, NULL); #endif if (strtype == 0) return NULL; - if (use_attr == TRUE) { + if (use_attr) { attr_old = getattrs(self->win); (void)wattrset(self->win,attr); } #ifdef HAVE_NCURSESW if (strtype == 2) { funcname = "addwstr"; - if (use_xy == TRUE) + if (use_xy) rtn = mvwaddwstr(self->win,y,x,wstr); else rtn = waddwstr(self->win,wstr); @@ -705,73 +699,79 @@ PyCursesWindow_AddStr(PyCursesWindowObject *self, PyObject *args) { char *str = PyBytes_AS_STRING(bytesobj); funcname = "addstr"; - if (use_xy == TRUE) + if (use_xy) rtn = mvwaddstr(self->win,y,x,str); else rtn = waddstr(self->win,str); Py_DECREF(bytesobj); } - if (use_attr == TRUE) + if (use_attr) (void)wattrset(self->win,attr_old); return PyCursesCheckERR(rtn, funcname); } +/*[clinic input] +_curses.window.addnstr + + [ + y: int + Y-coordinate. + x: int + X-coordinate. + ] + + str: object + String to add. + + n: int + Maximal number of characters. + + [ + attr: long + Attributes for characters. + ] + / + +Paint at most n characters of the string. + +Paint at most n characters of the string str at (y, x) with +attributes attr, overwriting anything previously on the display. +By default, the character position and attributes are the +current settings for the window object. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_AddNStr(PyCursesWindowObject *self, PyObject *args) +_curses_window_addnstr_impl(PyCursesWindowObject *self, int group_left_1, + int y, int x, PyObject *str, int n, + int group_right_1, long attr) +/*[clinic end generated code: output=6d21cee2ce6876d9 input=72718415c2744a2a]*/ { - int rtn, x, y, n; + int rtn; int strtype; - PyObject *strobj, *bytesobj = NULL; + PyObject *bytesobj = NULL; #ifdef HAVE_NCURSESW wchar_t *wstr = NULL; #endif - attr_t attr = A_NORMAL , attr_old = A_NORMAL; - long lattr; - int use_xy = FALSE, use_attr = FALSE; + attr_t attr_old = A_NORMAL; + int use_xy = group_left_1, use_attr = group_right_1; const char *funcname; - switch (PyTuple_Size(args)) { - case 2: - if (!PyArg_ParseTuple(args,"Oi;str,n", &strobj, &n)) - return NULL; - break; - case 3: - if (!PyArg_ParseTuple(args,"Oil;str,n,attr", &strobj, &n, &lattr)) - return NULL; - attr = lattr; - use_attr = TRUE; - break; - case 4: - if (!PyArg_ParseTuple(args,"iiOi;y,x,str,n", &y, &x, &strobj, &n)) - return NULL; - use_xy = TRUE; - break; - case 5: - if (!PyArg_ParseTuple(args,"iiOil;y,x,str,n,attr", &y, &x, &strobj, &n, &lattr)) - return NULL; - attr = lattr; - use_xy = use_attr = TRUE; - break; - default: - PyErr_SetString(PyExc_TypeError, "addnstr requires 2 to 5 arguments"); - return NULL; - } #ifdef HAVE_NCURSESW - strtype = PyCurses_ConvertToString(self, strobj, &bytesobj, &wstr); + strtype = PyCurses_ConvertToString(self, str, &bytesobj, &wstr); #else - strtype = PyCurses_ConvertToString(self, strobj, &bytesobj, NULL); + strtype = PyCurses_ConvertToString(self, str, &bytesobj, NULL); #endif if (strtype == 0) return NULL; - if (use_attr == TRUE) { + if (use_attr) { attr_old = getattrs(self->win); (void)wattrset(self->win,attr); } #ifdef HAVE_NCURSESW if (strtype == 2) { funcname = "addnwstr"; - if (use_xy == TRUE) + if (use_xy) rtn = mvwaddnwstr(self->win,y,x,wstr,n); else rtn = waddnwstr(self->win,wstr,n); @@ -782,125 +782,172 @@ PyCursesWindow_AddNStr(PyCursesWindowObject *self, PyObject *args) { char *str = PyBytes_AS_STRING(bytesobj); funcname = "addnstr"; - if (use_xy == TRUE) + if (use_xy) rtn = mvwaddnstr(self->win,y,x,str,n); else rtn = waddnstr(self->win,str,n); Py_DECREF(bytesobj); } - if (use_attr == TRUE) + if (use_attr) (void)wattrset(self->win,attr_old); return PyCursesCheckERR(rtn, funcname); } +/*[clinic input] +_curses.window.bkgd + + ch: object + Background character. + attr: long(c_default="A_NORMAL") = _curses.A_NORMAL + Background attributes. + / + +Set the background property of the window. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_Bkgd(PyCursesWindowObject *self, PyObject *args) +_curses_window_bkgd_impl(PyCursesWindowObject *self, PyObject *ch, long attr) +/*[clinic end generated code: output=058290afb2cf4034 input=634015bcb339283d]*/ { - PyObject *temp; chtype bkgd; - attr_t attr = A_NORMAL; - long lattr; - - switch (PyTuple_Size(args)) { - case 1: - if (!PyArg_ParseTuple(args, "O;ch or int", &temp)) - return NULL; - break; - case 2: - if (!PyArg_ParseTuple(args,"Ol;ch or int,attr", &temp, &lattr)) - return NULL; - attr = lattr; - break; - default: - PyErr_SetString(PyExc_TypeError, "bkgd requires 1 or 2 arguments"); - return NULL; - } - if (!PyCurses_ConvertToChtype(self, temp, &bkgd)) + if (!PyCurses_ConvertToChtype(self, ch, &bkgd)) return NULL; return PyCursesCheckERR(wbkgd(self->win, bkgd | attr), "bkgd"); } +/*[clinic input] +_curses.window.attroff + + attr: long + / + +Remove attribute attr from the "background" set. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_AttrOff(PyCursesWindowObject *self, PyObject *args) +_curses_window_attroff_impl(PyCursesWindowObject *self, long attr) +/*[clinic end generated code: output=8a2fcd4df682fc64 input=786beedf06a7befe]*/ { - long lattr; - if (!PyArg_ParseTuple(args,"l;attr", &lattr)) - return NULL; - return PyCursesCheckERR(wattroff(self->win, (attr_t)lattr), "attroff"); + return PyCursesCheckERR(wattroff(self->win, (attr_t)attr), "attroff"); } +/*[clinic input] +_curses.window.attron + + attr: long + / + +Add attribute attr from the "background" set. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_AttrOn(PyCursesWindowObject *self, PyObject *args) +_curses_window_attron_impl(PyCursesWindowObject *self, long attr) +/*[clinic end generated code: output=7afea43b237fa870 input=5a88fba7b1524f32]*/ { - long lattr; - if (!PyArg_ParseTuple(args,"l;attr", &lattr)) - return NULL; - return PyCursesCheckERR(wattron(self->win, (attr_t)lattr), "attron"); + return PyCursesCheckERR(wattron(self->win, (attr_t)attr), "attron"); } +/*[clinic input] +_curses.window.attrset + + attr: long + / + +Set the "background" set of attributes. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_AttrSet(PyCursesWindowObject *self, PyObject *args) +_curses_window_attrset_impl(PyCursesWindowObject *self, long attr) +/*[clinic end generated code: output=84e379bff20c0433 input=42e400c0d0154ab5]*/ { - long lattr; - if (!PyArg_ParseTuple(args,"l;attr", &lattr)) - return NULL; - return PyCursesCheckERR(wattrset(self->win, (attr_t)lattr), "attrset"); + return PyCursesCheckERR(wattrset(self->win, (attr_t)attr), "attrset"); } +/*[clinic input] +_curses.window.bkgdset + + ch: object + Background character. + attr: long(c_default="A_NORMAL") = _curses.A_NORMAL + Background attributes. + / + +Set the window's background. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_BkgdSet(PyCursesWindowObject *self, PyObject *args) +_curses_window_bkgdset_impl(PyCursesWindowObject *self, PyObject *ch, + long attr) +/*[clinic end generated code: output=8cb994fc4d7e2496 input=e09c682425c9e45b]*/ { - PyObject *temp; chtype bkgd; - attr_t attr = A_NORMAL; - long lattr; - - switch (PyTuple_Size(args)) { - case 1: - if (!PyArg_ParseTuple(args, "O;ch or int", &temp)) - return NULL; - break; - case 2: - if (!PyArg_ParseTuple(args,"Ol;ch or int,attr", &temp, &lattr)) - return NULL; - attr = lattr; - break; - default: - PyErr_SetString(PyExc_TypeError, "bkgdset requires 1 or 2 arguments"); - return NULL; - } - if (!PyCurses_ConvertToChtype(self, temp, &bkgd)) + if (!PyCurses_ConvertToChtype(self, ch, &bkgd)) return NULL; wbkgdset(self->win, bkgd | attr); return PyCursesCheckERR(0, "bkgdset"); } +/*[clinic input] +_curses.window.border + + ls: object(c_default="NULL") = _curses.ACS_VLINE + Left side. + rs: object(c_default="NULL") = _curses.ACS_VLINE + Right side. + ts: object(c_default="NULL") = _curses.ACS_HLINE + Top side. + bs: object(c_default="NULL") = _curses.ACS_HLINE + Bottom side. + tl: object(c_default="NULL") = _curses.ACS_ULCORNER + Upper-left corner. + tr: object(c_default="NULL") = _curses.ACS_URCORNER + Upper-right corner. + bl: object(c_default="NULL") = _curses.ACS_LLCORNER + Bottom-left corner. + br: object(c_default="NULL") = _curses.ACS_LRCORNER + Bottom-right corner. + / + +Draw a border around the edges of the window. + +Each parameter specifies the character to use for a specific part of the +border. The characters can be specified as integers or as one-character +strings. A 0 value for any parameter will cause the default character to be +used for that parameter. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_Border(PyCursesWindowObject *self, PyObject *args) +_curses_window_border_impl(PyCursesWindowObject *self, PyObject *ls, + PyObject *rs, PyObject *ts, PyObject *bs, + PyObject *tl, PyObject *tr, PyObject *bl, + PyObject *br) +/*[clinic end generated code: output=670ef38d3d7c2aa3 input=e015f735d67a240b]*/ { - PyObject *temp[8]; chtype ch[8]; int i; /* Clear the array of parameters */ - for(i=0; i<8; i++) { - temp[i] = NULL; + for(i=0; i<8; i++) ch[i] = 0; - } - if (!PyArg_ParseTuple(args,"|OOOOOOOO;ls,rs,ts,bs,tl,tr,bl,br", - &temp[0], &temp[1], &temp[2], &temp[3], - &temp[4], &temp[5], &temp[6], &temp[7])) +#define CONVERTTOCHTYPE(obj, i) \ + if ((obj) != NULL && !PyCurses_ConvertToChtype(self, (obj), &ch[(i)])) \ return NULL; - for(i=0; i<8; i++) { - if (temp[i] != NULL && !PyCurses_ConvertToChtype(self, temp[i], &ch[i])) - return NULL; - } + CONVERTTOCHTYPE(ls, 0); + CONVERTTOCHTYPE(rs, 1); + CONVERTTOCHTYPE(ts, 2); + CONVERTTOCHTYPE(bs, 3); + CONVERTTOCHTYPE(tl, 4); + CONVERTTOCHTYPE(tr, 5); + CONVERTTOCHTYPE(bl, 6); + CONVERTTOCHTYPE(br, 7); + +#undef CONVERTTOCHTYPE wborder(self->win, ch[0], ch[1], ch[2], ch[3], @@ -908,20 +955,34 @@ PyCursesWindow_Border(PyCursesWindowObject *self, PyObject *args) Py_RETURN_NONE; } +/*[clinic input] +_curses.window.box + + [ + verch: object(c_default="_PyLong_Zero") = 0 + Left and right side. + horch: object(c_default="_PyLong_Zero") = 0 + Top and bottom side. + ] + / + +Draw a border around the edges of the window. + +Similar to border(), but both ls and rs are verch and both ts and bs are +horch. The default corner characters are always used by this function. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_Box(PyCursesWindowObject *self, PyObject *args) +_curses_window_box_impl(PyCursesWindowObject *self, int group_right_1, + PyObject *verch, PyObject *horch) +/*[clinic end generated code: output=f3fcb038bb287192 input=465a121741c1efdf]*/ { - PyObject *temp1, *temp2; - chtype ch1=0,ch2=0; - switch(PyTuple_Size(args)){ - case 0: break; - default: - if (!PyArg_ParseTuple(args,"OO;verch,horch", &temp1, &temp2)) - return NULL; - if (!PyCurses_ConvertToChtype(self, temp1, &ch1)) { + chtype ch1 = 0, ch2 = 0; + if (group_right_1) { + if (!PyCurses_ConvertToChtype(self, verch, &ch1)) { return NULL; } - if (!PyCurses_ConvertToChtype(self, temp2, &ch2)) { + if (!PyCurses_ConvertToChtype(self, horch, &ch2)) { return NULL; } } @@ -949,6 +1010,32 @@ int py_mvwdelch(WINDOW *w, int y, int x) /* chgat, added by Fabian Kreutz <fabian.kreutz at gmx.net> */ #ifdef HAVE_CURSES_WCHGAT +/*[-clinic input] +_curses.window.chgat + + [ + y: int + Y-coordinate. + x: int + X-coordinate. + ] + + n: int = -1 + Number of characters. + + attr: long + Attributes for characters. + / + +Set the attributes of characters. + +Set the attributes of num characters at the current cursor position, or at +position (y, x) if supplied. If no value of num is given or num = -1, the +attribute will be set on all the characters to the end of the line. This +function does not move the cursor. The changed line will be touched using +the touchline() method so that the contents will be redisplayed by the next +window refresh. +[-clinic start generated code]*/ static PyObject * PyCursesWindow_ChgAt(PyCursesWindowObject *self, PyObject *args) { @@ -991,7 +1078,7 @@ PyCursesWindow_ChgAt(PyCursesWindowObject *self, PyObject *args) color = (short)((attr >> 8) & 0xff); attr = attr - (color << 8); - if (use_xy == TRUE) { + if (use_xy) { rtn = mvwchgat(self->win,y,x,num,attr,color,NULL); touchline(self->win,y,1); } else { @@ -1003,50 +1090,61 @@ PyCursesWindow_ChgAt(PyCursesWindowObject *self, PyObject *args) } #endif +/*[clinic input] +_curses.window.delch + + [ + y: int + Y-coordinate. + x: int + X-coordinate. + ] + / + +Delete any character at (y, x). +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_DelCh(PyCursesWindowObject *self, PyObject *args) +_curses_window_delch_impl(PyCursesWindowObject *self, int group_right_1, + int y, int x) +/*[clinic end generated code: output=22e77bb9fa11b461 input=d2f79e630a4fc6d0]*/ { - int rtn; - int x, y; - - switch (PyTuple_Size(args)) { - case 0: - rtn = wdelch(self->win); - break; - case 2: - if (!PyArg_ParseTuple(args,"ii;y,x", &y, &x)) - return NULL; - rtn = py_mvwdelch(self->win,y,x); - break; - default: - PyErr_SetString(PyExc_TypeError, "delch requires 0 or 2 arguments"); - return NULL; + if (!group_right_1) { + return PyCursesCheckERR(wdelch(self->win), "wdelch"); + } + else { + return PyCursesCheckERR(py_mvwdelch(self->win, y, x), "mvwdelch"); } - return PyCursesCheckERR(rtn, "[mv]wdelch"); } +/*[clinic input] +_curses.window.derwin + + [ + nlines: int = 0 + Height. + ncols: int = 0 + Width. + ] + begin_y: int + Top side y-coordinate. + begin_x: int + Left side x-coordinate. + / + +Create a sub-window (window-relative coordinates). + +derwin() is the same as calling subwin(), except that begin_y and begin_x +are relative to the origin of the window, rather than relative to the entire +screen. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_DerWin(PyCursesWindowObject *self, PyObject *args) +_curses_window_derwin_impl(PyCursesWindowObject *self, int group_left_1, + int nlines, int ncols, int begin_y, int begin_x) +/*[clinic end generated code: output=7924b112d9f70d6e input=966d9481f7f5022e]*/ { WINDOW *win; - int nlines, ncols, begin_y, begin_x; - - nlines = 0; - ncols = 0; - switch (PyTuple_Size(args)) { - case 2: - if (!PyArg_ParseTuple(args,"ii;begin_y,begin_x",&begin_y,&begin_x)) - return NULL; - break; - case 4: - if (!PyArg_ParseTuple(args, "iiii;nlines,ncols,begin_y,begin_x", - &nlines,&ncols,&begin_y,&begin_x)) - return NULL; - break; - default: - PyErr_SetString(PyExc_TypeError, "derwin requires 2 or 4 arguments"); - return NULL; - } win = derwin(self->win,nlines,ncols,begin_y,begin_x); @@ -1058,112 +1156,145 @@ PyCursesWindow_DerWin(PyCursesWindowObject *self, PyObject *args) return (PyObject *)PyCursesWindow_New(win, NULL); } -static PyObject * -PyCursesWindow_EchoChar(PyCursesWindowObject *self, PyObject *args) -{ - PyObject *temp; - chtype ch; - attr_t attr = A_NORMAL; - long lattr; +/*[clinic input] +_curses.window.echochar - switch (PyTuple_Size(args)) { - case 1: - if (!PyArg_ParseTuple(args,"O;ch or int", &temp)) - return NULL; - break; - case 2: - if (!PyArg_ParseTuple(args,"Ol;ch or int,attr", &temp, &lattr)) - return NULL; - attr = lattr; - break; - default: - PyErr_SetString(PyExc_TypeError, "echochar requires 1 or 2 arguments"); + ch: object + Character to add. + attr: long(c_default="A_NORMAL") = _curses.A_NORMAL + Attributes for the character. + / - return NULL; - } +Add character ch with attribute attr, and refresh. +[clinic start generated code]*/ + +static PyObject * +_curses_window_echochar_impl(PyCursesWindowObject *self, PyObject *ch, + long attr) +/*[clinic end generated code: output=13e7dd875d4b9642 input=e7f34b964e92b156]*/ +{ + chtype ch_; - if (!PyCurses_ConvertToChtype(self, temp, &ch)) + if (!PyCurses_ConvertToChtype(self, ch, &ch_)) return NULL; #ifdef py_is_pad if (py_is_pad(self->win)) { - return PyCursesCheckERR(pechochar(self->win, ch | attr), + return PyCursesCheckERR(pechochar(self->win, ch_ | (attr_t)attr), "echochar"); } else #endif - return PyCursesCheckERR(wechochar(self->win, ch | attr), + return PyCursesCheckERR(wechochar(self->win, ch_ | (attr_t)attr), "echochar"); } #ifdef NCURSES_MOUSE_VERSION -static PyObject * -PyCursesWindow_Enclose(PyCursesWindowObject *self, PyObject *args) -{ - int x, y; - if (!PyArg_ParseTuple(args,"ii;y,x", &y, &x)) - return NULL; +/*[clinic input] +_curses.window.enclose -> long - return PyLong_FromLong( wenclose(self->win,y,x) ); -} -#endif + y: int + Y-coordinate. + x: int + X-coordinate. + / -static PyObject * -PyCursesWindow_GetBkgd(PyCursesWindowObject *self) +Return True if the screen-relative coordinates are enclosed by the window. +[clinic start generated code]*/ + +static long +_curses_window_enclose_impl(PyCursesWindowObject *self, int y, int x) +/*[clinic end generated code: output=5251c961cbe3df63 input=dfe1d9d4d05d8642]*/ { - return PyLong_FromLong((long) getbkgd(self->win)); + return wenclose(self->win, y, x); } +#endif -static PyObject * -PyCursesWindow_GetCh(PyCursesWindowObject *self, PyObject *args) +/*[clinic input] +_curses.window.getbkgd -> long + +Return the window's current background character/attribute pair. +[clinic start generated code]*/ + +static long +_curses_window_getbkgd_impl(PyCursesWindowObject *self) +/*[clinic end generated code: output=c52b25dc16b215c3 input=a69db882fa35426c]*/ +{ + return (long) getbkgd(self->win); +} + +/*[clinic input] +_curses.window.getch -> int + + [ + y: int + Y-coordinate. + x: int + X-coordinate. + ] + / + +Get a character code from terminal keyboard. + +The integer returned does not have to be in ASCII range: function keys, +keypad keys and so on return numbers higher than 256. In no-delay mode, -1 +is returned if there is no input, else getch() waits until a key is pressed. +[clinic start generated code]*/ + +static int +_curses_window_getch_impl(PyCursesWindowObject *self, int group_right_1, + int y, int x) +/*[clinic end generated code: output=980aa6af0c0ca387 input=bb24ebfb379f991f]*/ { - int x, y; int rtn; - switch (PyTuple_Size(args)) { - case 0: - Py_BEGIN_ALLOW_THREADS + Py_BEGIN_ALLOW_THREADS + if (!group_right_1) { rtn = wgetch(self->win); - Py_END_ALLOW_THREADS - break; - case 2: - if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x)) - return NULL; - Py_BEGIN_ALLOW_THREADS - rtn = mvwgetch(self->win,y,x); - Py_END_ALLOW_THREADS - break; - default: - PyErr_SetString(PyExc_TypeError, "getch requires 0 or 2 arguments"); - return NULL; } - return PyLong_FromLong((long)rtn); + else { + rtn = mvwgetch(self->win, y, x); + } + Py_END_ALLOW_THREADS + + return rtn; } +/*[clinic input] +_curses.window.getkey + + [ + y: int + Y-coordinate. + x: int + X-coordinate. + ] + / + +Get a character (string) from terminal keyboard. + +Returning a string instead of an integer, as getch() does. Function keys, +keypad keys and other special keys return a multibyte string containing the +key name. In no-delay mode, an exception is raised if there is no input. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_GetKey(PyCursesWindowObject *self, PyObject *args) +_curses_window_getkey_impl(PyCursesWindowObject *self, int group_right_1, + int y, int x) +/*[clinic end generated code: output=8490a182db46b10f input=be2dee34f5cf57f8]*/ { - int x, y; int rtn; - switch (PyTuple_Size(args)) { - case 0: - Py_BEGIN_ALLOW_THREADS + Py_BEGIN_ALLOW_THREADS + if (!group_right_1) { rtn = wgetch(self->win); - Py_END_ALLOW_THREADS - break; - case 2: - if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x)) - return NULL; - Py_BEGIN_ALLOW_THREADS - rtn = mvwgetch(self->win,y,x); - Py_END_ALLOW_THREADS - break; - default: - PyErr_SetString(PyExc_TypeError, "getkey requires 0 or 2 arguments"); - return NULL; } + else { + rtn = mvwgetch(self->win, y, x); + } + Py_END_ALLOW_THREADS + if (rtn == ERR) { /* getch() returns ERR in nodelay mode */ PyErr_CheckSignals(); @@ -1187,30 +1318,40 @@ PyCursesWindow_GetKey(PyCursesWindowObject *self, PyObject *args) } #ifdef HAVE_NCURSESW +/*[clinic input] +_curses.window.get_wch + + [ + y: int + Y-coordinate. + x: int + X-coordinate. + ] + / + +Get a wide character from terminal keyboard. + +Return a character for most keys, or an integer for function keys, +keypad keys, and other special keys. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_Get_WCh(PyCursesWindowObject *self, PyObject *args) +_curses_window_get_wch_impl(PyCursesWindowObject *self, int group_right_1, + int y, int x) +/*[clinic end generated code: output=9f4f86e91fe50ef3 input=dd7e5367fb49dc48]*/ { - int x, y; int ct; wint_t rtn; - switch (PyTuple_Size(args)) { - case 0: - Py_BEGIN_ALLOW_THREADS - ct = wget_wch(self->win,&rtn); - Py_END_ALLOW_THREADS - break; - case 2: - if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x)) - return NULL; - Py_BEGIN_ALLOW_THREADS - ct = mvwget_wch(self->win,y,x,&rtn); - Py_END_ALLOW_THREADS - break; - default: - PyErr_SetString(PyExc_TypeError, "get_wch requires 0 or 2 arguments"); - return NULL; + Py_BEGIN_ALLOW_THREADS + if (!group_right_1) { + ct = wget_wch(self->win ,&rtn); + } + else { + ct = mvwget_wch(self->win, y, x, &rtn); } + Py_END_ALLOW_THREADS + if (ct == ERR) { if (PyErr_CheckSignals()) return NULL; @@ -1226,6 +1367,22 @@ PyCursesWindow_Get_WCh(PyCursesWindowObject *self, PyObject *args) } #endif +/*[-clinic input] +_curses.window.getstr + + [ + y: int + Y-coordinate. + x: int + X-coordinate. + ] + n: int = 1023 + Maximal number of characters. + / + +Read a string from the user, with primitive line editing capacity. +[-clinic start generated code]*/ + static PyObject * PyCursesWindow_GetStr(PyCursesWindowObject *self, PyObject *args) { @@ -1288,118 +1445,148 @@ PyCursesWindow_GetStr(PyCursesWindowObject *self, PyObject *args) return PyBytes_FromString(rtn); } +/*[clinic input] +_curses.window.hline + + [ + y: int + Starting Y-coordinate. + x: int + Starting X-coordinate. + ] + + ch: object + Character to draw. + n: int + Line length. + + [ + attr: long(c_default="A_NORMAL") = _curses.A_NORMAL + Attributes for the characters. + ] + / + +Display a horizontal line. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_Hline(PyCursesWindowObject *self, PyObject *args) +_curses_window_hline_impl(PyCursesWindowObject *self, int group_left_1, + int y, int x, PyObject *ch, int n, + int group_right_1, long attr) +/*[clinic end generated code: output=c00d489d61fc9eef input=81a4dea47268163e]*/ { - PyObject *temp; - chtype ch; - int n, x, y, code = OK; - attr_t attr = A_NORMAL; - long lattr; + chtype ch_; - switch (PyTuple_Size(args)) { - case 2: - if (!PyArg_ParseTuple(args, "Oi;ch or int,n", &temp, &n)) - return NULL; - break; - case 3: - if (!PyArg_ParseTuple(args, "Oil;ch or int,n,attr", &temp, &n, &lattr)) - return NULL; - attr = lattr; - break; - case 4: - if (!PyArg_ParseTuple(args, "iiOi;y,x,ch or int,n", &y, &x, &temp, &n)) - return NULL; - code = wmove(self->win, y, x); - break; - case 5: - if (!PyArg_ParseTuple(args, "iiOil; y,x,ch or int,n,attr", - &y, &x, &temp, &n, &lattr)) - return NULL; - attr = lattr; - code = wmove(self->win, y, x); - break; - default: - PyErr_SetString(PyExc_TypeError, "hline requires 2 to 5 arguments"); + if (!PyCurses_ConvertToChtype(self, ch, &ch_)) return NULL; + if (group_left_1) { + if (wmove(self->win, y, x) == ERR) { + return PyCursesCheckERR(ERR, "wmove"); + } } - - if (code != ERR) { - if (!PyCurses_ConvertToChtype(self, temp, &ch)) - return NULL; - return PyCursesCheckERR(whline(self->win, ch | attr, n), "hline"); - } else - return PyCursesCheckERR(code, "wmove"); + return PyCursesCheckERR(whline(self->win, ch_ | (attr_t)attr, n), "hline"); } +/*[clinic input] +_curses.window.insch + + [ + y: int + Y-coordinate. + x: int + X-coordinate. + ] + + ch: object + Character to insert. + + [ + attr: long(c_default="A_NORMAL") = _curses.A_NORMAL + Attributes for the character. + ] + / + +Insert a character before the current or specified position. + +All characters to the right of the cursor are shifted one position right, with +the rightmost characters on the line being lost. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_InsCh(PyCursesWindowObject *self, PyObject *args) +_curses_window_insch_impl(PyCursesWindowObject *self, int group_left_1, + int y, int x, PyObject *ch, int group_right_1, + long attr) +/*[clinic end generated code: output=ade8cfe3a3bf3e34 input=336342756ee19812]*/ { - int rtn, x, y, use_xy = FALSE; - PyObject *temp; - chtype ch = 0; - attr_t attr = A_NORMAL; - long lattr; - - switch (PyTuple_Size(args)) { - case 1: - if (!PyArg_ParseTuple(args, "O;ch or int", &temp)) - return NULL; - break; - case 2: - if (!PyArg_ParseTuple(args, "Ol;ch or int,attr", &temp, &lattr)) - return NULL; - attr = lattr; - break; - case 3: - if (!PyArg_ParseTuple(args,"iiO;y,x,ch or int", &y, &x, &temp)) - return NULL; - use_xy = TRUE; - break; - case 4: - if (!PyArg_ParseTuple(args,"iiOl;y,x,ch or int, attr", &y, &x, &temp, &lattr)) - return NULL; - attr = lattr; - use_xy = TRUE; - break; - default: - PyErr_SetString(PyExc_TypeError, "insch requires 1 to 4 arguments"); - return NULL; - } + int rtn; + chtype ch_ = 0; - if (!PyCurses_ConvertToChtype(self, temp, &ch)) + if (!PyCurses_ConvertToChtype(self, ch, &ch_)) return NULL; - if (use_xy == TRUE) - rtn = mvwinsch(self->win,y,x, ch | attr); + if (!group_left_1) { + rtn = winsch(self->win, ch_ | (attr_t)attr); + } else { - rtn = winsch(self->win, ch | attr); + rtn = mvwinsch(self->win, y, x, ch_ | (attr_t)attr); } + return PyCursesCheckERR(rtn, "insch"); } -static PyObject * -PyCursesWindow_InCh(PyCursesWindowObject *self, PyObject *args) +/*[clinic input] +_curses.window.inch -> unsigned_long + + [ + y: int + Y-coordinate. + x: int + X-coordinate. + ] + / + +Return the character at the given position in the window. + +The bottom 8 bits are the character proper, and upper bits are the attributes. +[clinic start generated code]*/ + +static unsigned long +_curses_window_inch_impl(PyCursesWindowObject *self, int group_right_1, + int y, int x) +/*[clinic end generated code: output=6c4719fe978fe86a input=fac23ee11e3b3a66]*/ { - int x, y; unsigned long rtn; - switch (PyTuple_Size(args)) { - case 0: + if (!group_right_1) { rtn = winch(self->win); - break; - case 2: - if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x)) - return NULL; - rtn = mvwinch(self->win,y,x); - break; - default: - PyErr_SetString(PyExc_TypeError, "inch requires 0 to 2 arguments"); - return NULL; } - return PyLong_FromUnsignedLong(rtn); + else { + rtn = mvwinch(self->win, y, x); + } + + return rtn; } +/*[-clinic input] +_curses.window.instr + + [ + y: int + Y-coordinate. + x: int + X-coordinate. + ] + n: int = 1023 + Maximal number of characters. + / + +Return a string of characters, extracted from the window. + +Return a string of characters, extracted from the window starting at the +current cursor position, or at y, x if specified. Attributes are stripped +from the characters. If n is specified, instr() returns a string at most +n characters long (exclusive of the trailing NUL). +[-clinic start generated code]*/ static PyObject * PyCursesWindow_InStr(PyCursesWindowObject *self, PyObject *args) { @@ -1443,64 +1630,66 @@ PyCursesWindow_InStr(PyCursesWindowObject *self, PyObject *args) return PyBytes_FromString(rtn); } +/*[clinic input] +_curses.window.insstr + + [ + y: int + Y-coordinate. + x: int + X-coordinate. + ] + + str: object + String to insert. + + [ + attr: long + Attributes for characters. + ] + / + +Insert the string before the current or specified position. + +Insert a character string (as many characters as will fit on the line) +before the character under the cursor. All characters to the right of +the cursor are shifted right, with the rightmost characters on the line +being lost. The cursor position does not change (after moving to y, x, +if specified). +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_InsStr(PyCursesWindowObject *self, PyObject *args) +_curses_window_insstr_impl(PyCursesWindowObject *self, int group_left_1, + int y, int x, PyObject *str, int group_right_1, + long attr) +/*[clinic end generated code: output=c259a5265ad0b777 input=6827cddc6340a7f3]*/ { int rtn; - int x, y; int strtype; - PyObject *strobj, *bytesobj = NULL; + PyObject *bytesobj = NULL; #ifdef HAVE_NCURSESW wchar_t *wstr = NULL; #endif - attr_t attr = A_NORMAL , attr_old = A_NORMAL; - long lattr; - int use_xy = FALSE, use_attr = FALSE; + attr_t attr_old = A_NORMAL; + int use_xy = group_left_1, use_attr = group_right_1; const char *funcname; - switch (PyTuple_Size(args)) { - case 1: - if (!PyArg_ParseTuple(args,"O;str", &strobj)) - return NULL; - break; - case 2: - if (!PyArg_ParseTuple(args,"Ol;str,attr", &strobj, &lattr)) - return NULL; - attr = lattr; - use_attr = TRUE; - break; - case 3: - if (!PyArg_ParseTuple(args,"iiO;y,x,str", &y, &x, &strobj)) - return NULL; - use_xy = TRUE; - break; - case 4: - if (!PyArg_ParseTuple(args,"iiOl;y,x,str,attr", &y, &x, &strobj, &lattr)) - return NULL; - attr = lattr; - use_xy = use_attr = TRUE; - break; - default: - PyErr_SetString(PyExc_TypeError, "insstr requires 1 to 4 arguments"); - return NULL; - } - #ifdef HAVE_NCURSESW - strtype = PyCurses_ConvertToString(self, strobj, &bytesobj, &wstr); + strtype = PyCurses_ConvertToString(self, str, &bytesobj, &wstr); #else - strtype = PyCurses_ConvertToString(self, strobj, &bytesobj, NULL); + strtype = PyCurses_ConvertToString(self, str, &bytesobj, NULL); #endif if (strtype == 0) return NULL; - if (use_attr == TRUE) { + if (use_attr) { attr_old = getattrs(self->win); - (void)wattrset(self->win,attr); + (void)wattrset(self->win, (attr_t)attr); } #ifdef HAVE_NCURSESW if (strtype == 2) { funcname = "inswstr"; - if (use_xy == TRUE) + if (use_xy) rtn = mvwins_wstr(self->win,y,x,wstr); else rtn = wins_wstr(self->win,wstr); @@ -1511,74 +1700,81 @@ PyCursesWindow_InsStr(PyCursesWindowObject *self, PyObject *args) { char *str = PyBytes_AS_STRING(bytesobj); funcname = "insstr"; - if (use_xy == TRUE) + if (use_xy) rtn = mvwinsstr(self->win,y,x,str); else rtn = winsstr(self->win,str); Py_DECREF(bytesobj); } - if (use_attr == TRUE) + if (use_attr) (void)wattrset(self->win,attr_old); return PyCursesCheckERR(rtn, funcname); } +/*[clinic input] +_curses.window.insnstr + + [ + y: int + Y-coordinate. + x: int + X-coordinate. + ] + + str: object + String to insert. + + n: int + Maximal number of characters. + + [ + attr: long + Attributes for characters. + ] + / + +Insert at most n characters of the string. + +Insert a character string (as many characters as will fit on the line) +before the character under the cursor, up to n characters. If n is zero +or negative, the entire string is inserted. All characters to the right +of the cursor are shifted right, with the rightmost characters on the line +being lost. The cursor position does not change (after moving to y, x, if +specified). +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_InsNStr(PyCursesWindowObject *self, PyObject *args) +_curses_window_insnstr_impl(PyCursesWindowObject *self, int group_left_1, + int y, int x, PyObject *str, int n, + int group_right_1, long attr) +/*[clinic end generated code: output=971a32ea6328ec8b input=70fa0cd543901a4c]*/ { - int rtn, x, y, n; + int rtn; int strtype; - PyObject *strobj, *bytesobj = NULL; + PyObject *bytesobj = NULL; #ifdef HAVE_NCURSESW wchar_t *wstr = NULL; #endif - attr_t attr = A_NORMAL , attr_old = A_NORMAL; - long lattr; - int use_xy = FALSE, use_attr = FALSE; + attr_t attr_old = A_NORMAL; + int use_xy = group_left_1, use_attr = group_right_1; const char *funcname; - switch (PyTuple_Size(args)) { - case 2: - if (!PyArg_ParseTuple(args,"Oi;str,n", &strobj, &n)) - return NULL; - break; - case 3: - if (!PyArg_ParseTuple(args,"Oil;str,n,attr", &strobj, &n, &lattr)) - return NULL; - attr = lattr; - use_attr = TRUE; - break; - case 4: - if (!PyArg_ParseTuple(args,"iiOi;y,x,str,n", &y, &x, &strobj, &n)) - return NULL; - use_xy = TRUE; - break; - case 5: - if (!PyArg_ParseTuple(args,"iiOil;y,x,str,n,attr", &y, &x, &strobj, &n, &lattr)) - return NULL; - attr = lattr; - use_xy = use_attr = TRUE; - break; - default: - PyErr_SetString(PyExc_TypeError, "insnstr requires 2 to 5 arguments"); - return NULL; - } - #ifdef HAVE_NCURSESW - strtype = PyCurses_ConvertToString(self, strobj, &bytesobj, &wstr); + strtype = PyCurses_ConvertToString(self, str, &bytesobj, &wstr); #else - strtype = PyCurses_ConvertToString(self, strobj, &bytesobj, NULL); + strtype = PyCurses_ConvertToString(self, str, &bytesobj, NULL); #endif if (strtype == 0) return NULL; - if (use_attr == TRUE) { + if (use_attr) { attr_old = getattrs(self->win); - (void)wattrset(self->win,attr); + (void)wattrset(self->win, (attr_t)attr); } #ifdef HAVE_NCURSESW if (strtype == 2) { funcname = "insn_wstr"; - if (use_xy == TRUE) + if (use_xy) rtn = mvwins_nwstr(self->win,y,x,wstr,n); else rtn = wins_nwstr(self->win,wstr,n); @@ -1589,160 +1785,226 @@ PyCursesWindow_InsNStr(PyCursesWindowObject *self, PyObject *args) { char *str = PyBytes_AS_STRING(bytesobj); funcname = "insnstr"; - if (use_xy == TRUE) + if (use_xy) rtn = mvwinsnstr(self->win,y,x,str,n); else rtn = winsnstr(self->win,str,n); Py_DECREF(bytesobj); } - if (use_attr == TRUE) + if (use_attr) (void)wattrset(self->win,attr_old); return PyCursesCheckERR(rtn, funcname); } +/*[clinic input] +_curses.window.is_linetouched + + line: int + Line number. + / + +Return True if the specified line was modified, otherwise return False. + +Raise a curses.error exception if line is not valid for the given window. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_Is_LineTouched(PyCursesWindowObject *self, PyObject *args) +_curses_window_is_linetouched_impl(PyCursesWindowObject *self, int line) +/*[clinic end generated code: output=ad4a4edfee2db08c input=a7be0c189f243914]*/ { - int line, erg; - if (!PyArg_ParseTuple(args,"i;line", &line)) - return NULL; + int erg; erg = is_linetouched(self->win, line); if (erg == ERR) { PyErr_SetString(PyExc_TypeError, "is_linetouched: line number outside of boundaries"); return NULL; - } else - if (erg == FALSE) { - Py_RETURN_FALSE; - } else { - Py_RETURN_TRUE; - } + } + return PyBool_FromLong(erg); } -static PyObject * -PyCursesWindow_NoOutRefresh(PyCursesWindowObject *self, PyObject *args) -{ - int pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol; - int rtn; +#ifdef py_is_pad +/*[clinic input] +_curses.window.noutrefresh -#ifndef py_is_pad - if (0) + [ + pminrow: int + pmincol: int + sminrow: int + smincol: int + smaxrow: int + smaxcol: int + ] + / + +Mark for refresh but wait. + +This function updates the data structure representing the desired state of the +window, but does not force an update of the physical screen. To accomplish +that, call doupdate(). +[clinic start generated code]*/ + +static PyObject * +_curses_window_noutrefresh_impl(PyCursesWindowObject *self, + int group_right_1, int pminrow, int pmincol, + int sminrow, int smincol, int smaxrow, + int smaxcol) +/*[clinic end generated code: output=809a1f3c6a03e23e input=3e56898388cd739e]*/ #else - if (py_is_pad(self->win)) -#endif - { - switch(PyTuple_Size(args)) { - case 6: - if (!PyArg_ParseTuple(args, - "iiiiii;" \ - "pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol", - &pminrow, &pmincol, &sminrow, - &smincol, &smaxrow, &smaxcol)) - return NULL; - Py_BEGIN_ALLOW_THREADS - rtn = pnoutrefresh(self->win, - pminrow, pmincol, sminrow, - smincol, smaxrow, smaxcol); - Py_END_ALLOW_THREADS - return PyCursesCheckERR(rtn, "pnoutrefresh"); - default: - PyErr_SetString(PyCursesError, - "noutrefresh() called for a pad " - "requires 6 arguments"); - return NULL; - } - } else { - if (!PyArg_ParseTuple(args, ":noutrefresh")) - return NULL; +/*[clinic input] +_curses.window.noutrefresh - Py_BEGIN_ALLOW_THREADS - rtn = wnoutrefresh(self->win); - Py_END_ALLOW_THREADS - return PyCursesCheckERR(rtn, "wnoutrefresh"); - } -} +Mark for refresh but wait. + +This function updates the data structure representing the desired state of the +window, but does not force an update of the physical screen. To accomplish +that, call doupdate(). +[clinic start generated code]*/ static PyObject * -PyCursesWindow_Overlay(PyCursesWindowObject *self, PyObject *args) +_curses_window_noutrefresh_impl(PyCursesWindowObject *self) +/*[clinic end generated code: output=6ef6dec666643fee input=876902e3fa431dbd]*/ +#endif { - PyCursesWindowObject *temp; - int use_copywin = FALSE; - int sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol; int rtn; - switch (PyTuple_Size(args)) { - case 1: - if (!PyArg_ParseTuple(args, "O!;window object", - &PyCursesWindow_Type, &temp)) - return NULL; - break; - case 7: - if (!PyArg_ParseTuple(args, "O!iiiiii;window object, int, int, int, int, int, int", - &PyCursesWindow_Type, &temp, &sminrow, &smincol, - &dminrow, &dmincol, &dmaxrow, &dmaxcol)) +#ifdef py_is_pad + if (py_is_pad(self->win)) { + if (!group_right_1) { + PyErr_SetString(PyCursesError, + "noutrefresh() called for a pad " + "requires 6 arguments"); return NULL; - use_copywin = TRUE; - break; - default: + } + Py_BEGIN_ALLOW_THREADS + rtn = pnoutrefresh(self->win, pminrow, pmincol, + sminrow, smincol, smaxrow, smaxcol); + Py_END_ALLOW_THREADS + return PyCursesCheckERR(rtn, "pnoutrefresh"); + } + if (group_right_1) { PyErr_SetString(PyExc_TypeError, - "overlay requires one or seven arguments"); + "noutrefresh() takes no arguments (6 given)"); return NULL; } +#endif + Py_BEGIN_ALLOW_THREADS + rtn = wnoutrefresh(self->win); + Py_END_ALLOW_THREADS + return PyCursesCheckERR(rtn, "wnoutrefresh"); +} + +/*[clinic input] +_curses.window.overlay + + destwin: object(type="PyCursesWindowObject *", subclass_of="&PyCursesWindow_Type") + + [ + sminrow: int + smincol: int + dminrow: int + dmincol: int + dmaxrow: int + dmaxcol: int + ] + / + +Overlay the window on top of destwin. + +The windows need not be the same size, only the overlapping region is copied. +This copy is non-destructive, which means that the current background +character does not overwrite the old contents of destwin. + +To get fine-grained control over the copied region, the second form of +overlay() can be used. sminrow and smincol are the upper-left coordinates +of the source window, and the other variables mark a rectangle in the +destination window. +[clinic start generated code]*/ - if (use_copywin == TRUE) { - rtn = copywin(self->win, temp->win, sminrow, smincol, +static PyObject * +_curses_window_overlay_impl(PyCursesWindowObject *self, + PyCursesWindowObject *destwin, int group_right_1, + int sminrow, int smincol, int dminrow, + int dmincol, int dmaxrow, int dmaxcol) +/*[clinic end generated code: output=82bb2c4cb443ca58 input=7edd23ad22cc1984]*/ +{ + int rtn; + + if (group_right_1) { + rtn = copywin(self->win, destwin->win, sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol, TRUE); return PyCursesCheckERR(rtn, "copywin"); } else { - rtn = overlay(self->win, temp->win); + rtn = overlay(self->win, destwin->win); return PyCursesCheckERR(rtn, "overlay"); } } +/*[clinic input] +_curses.window.overwrite + + destwin: object(type="PyCursesWindowObject *", subclass_of="&PyCursesWindow_Type") + + [ + sminrow: int + smincol: int + dminrow: int + dmincol: int + dmaxrow: int + dmaxcol: int + ] + / + +Overwrite the window on top of destwin. + +The windows need not be the same size, in which case only the overlapping +region is copied. This copy is destructive, which means that the current +background character overwrites the old contents of destwin. + +To get fine-grained control over the copied region, the second form of +overwrite() can be used. sminrow and smincol are the upper-left coordinates +of the source window, the other variables mark a rectangle in the destination +window. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_Overwrite(PyCursesWindowObject *self, PyObject *args) +_curses_window_overwrite_impl(PyCursesWindowObject *self, + PyCursesWindowObject *destwin, + int group_right_1, int sminrow, int smincol, + int dminrow, int dmincol, int dmaxrow, + int dmaxcol) +/*[clinic end generated code: output=12ae007d1681be28 input=ea5de1b35cd948e0]*/ { - PyCursesWindowObject *temp; - int use_copywin = FALSE; - int sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol; int rtn; - switch (PyTuple_Size(args)) { - case 1: - if (!PyArg_ParseTuple(args, "O!;window object", - &PyCursesWindow_Type, &temp)) - return NULL; - break; - case 7: - if (!PyArg_ParseTuple(args, "O!iiiiii;window object, int, int, int, int, int, int", - &PyCursesWindow_Type, &temp, &sminrow, &smincol, - &dminrow, &dmincol, &dmaxrow, &dmaxcol)) - return NULL; - use_copywin = TRUE; - break; - default: - PyErr_SetString(PyExc_TypeError, - "overwrite requires one or seven arguments"); - return NULL; - } - - if (use_copywin == TRUE) { - rtn = copywin(self->win, temp->win, sminrow, smincol, + if (group_right_1) { + rtn = copywin(self->win, destwin->win, sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol, FALSE); return PyCursesCheckERR(rtn, "copywin"); } else { - rtn = overwrite(self->win, temp->win); + rtn = overwrite(self->win, destwin->win); return PyCursesCheckERR(rtn, "overwrite"); } } +/*[clinic input] +_curses.window.putwin + + file: object + / + +Write all data associated with the window into the provided file object. + +This information can be later retrieved using the getwin() function. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_PutWin(PyCursesWindowObject *self, PyObject *stream) +_curses_window_putwin(PyCursesWindowObject *self, PyObject *file) +/*[clinic end generated code: output=3a25e2a5e7a040ac input=0608648e09c8ea0a]*/ { /* We have to simulate this by writing to a temporary FILE*, - then reading back, then writing to the argument stream. */ + then reading back, then writing to the argument file. */ FILE *fp; PyObject *res = NULL; @@ -1763,7 +2025,7 @@ PyCursesWindow_PutWin(PyCursesWindowObject *self, PyObject *stream) if (n <= 0) break; Py_DECREF(res); - res = _PyObject_CallMethodId(stream, &PyId_write, "y#", buf, n); + res = _PyObject_CallMethodId(file, &PyId_write, "y#", buf, n); if (res == NULL) break; } @@ -1773,88 +2035,137 @@ PyCursesWindow_PutWin(PyCursesWindowObject *self, PyObject *stream) return res; } +/*[clinic input] +_curses.window.redrawln + + beg: int + Starting line number. + num: int + The number of lines. + / + +Mark the specified lines corrupted. + +They should be completely redrawn on the next refresh() call. +[clinic start generated code]*/ + +static PyObject * +_curses_window_redrawln_impl(PyCursesWindowObject *self, int beg, int num) +/*[clinic end generated code: output=ea216e334f9ce1b4 input=152155e258a77a7a]*/ +{ + return PyCursesCheckERR(wredrawln(self->win,beg,num), "redrawln"); +} + +/*[clinic input] +_curses.window.refresh + + [ + pminrow: int + pmincol: int + sminrow: int + smincol: int + smaxrow: int + smaxcol: int + ] + / + +Update the display immediately. + +Synchronize actual screen with previous drawing/deleting methods. +The 6 optional arguments can only be specified when the window is a pad +created with newpad(). The additional parameters are needed to indicate +what part of the pad and screen are involved. pminrow and pmincol specify +the upper left-hand corner of the rectangle to be displayed in the pad. +sminrow, smincol, smaxrow, and smaxcol specify the edges of the rectangle to +be displayed on the screen. The lower right-hand corner of the rectangle to +be displayed in the pad is calculated from the screen coordinates, since the +rectangles must be the same size. Both rectangles must be entirely contained +within their respective structures. Negative values of pminrow, pmincol, +sminrow, or smincol are treated as if they were zero. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_RedrawLine(PyCursesWindowObject *self, PyObject *args) +_curses_window_refresh_impl(PyCursesWindowObject *self, int group_right_1, + int pminrow, int pmincol, int sminrow, + int smincol, int smaxrow, int smaxcol) +/*[clinic end generated code: output=42199543115e6e63 input=95e01cb5ffc635d0]*/ { - int beg, num; - if (!PyArg_ParseTuple(args, "ii;beg,num", &beg, &num)) + int rtn; + +#ifdef py_is_pad + if (py_is_pad(self->win)) { + if (!group_right_1) { + PyErr_SetString(PyCursesError, + "refresh() for a pad requires 6 arguments"); + return NULL; + } + Py_BEGIN_ALLOW_THREADS + rtn = prefresh(self->win, pminrow, pmincol, + sminrow, smincol, smaxrow, smaxcol); + Py_END_ALLOW_THREADS + return PyCursesCheckERR(rtn, "prefresh"); + } +#endif + if (group_right_1) { + PyErr_SetString(PyExc_TypeError, + "refresh() takes no arguments (6 given)"); return NULL; - return PyCursesCheckERR(wredrawln(self->win,beg,num), "redrawln"); + } + Py_BEGIN_ALLOW_THREADS + rtn = wrefresh(self->win); + Py_END_ALLOW_THREADS + return PyCursesCheckERR(rtn, "prefresh"); } -static PyObject * -PyCursesWindow_Refresh(PyCursesWindowObject *self, PyObject *args) -{ - int pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol; - int rtn; +/*[clinic input] +_curses.window.setscrreg -#ifndef py_is_pad - if (0) -#else - if (py_is_pad(self->win)) -#endif - { - switch(PyTuple_Size(args)) { - case 6: - if (!PyArg_ParseTuple(args, - "iiiiii;" \ - "pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol", - &pminrow, &pmincol, &sminrow, - &smincol, &smaxrow, &smaxcol)) - return NULL; - - Py_BEGIN_ALLOW_THREADS - rtn = prefresh(self->win, - pminrow, pmincol, sminrow, - smincol, smaxrow, smaxcol); - Py_END_ALLOW_THREADS - return PyCursesCheckERR(rtn, "prefresh"); - default: - PyErr_SetString(PyCursesError, - "refresh() for a pad requires 6 arguments"); - return NULL; - } - } else { - if (!PyArg_ParseTuple(args, ":refresh")) - return NULL; - Py_BEGIN_ALLOW_THREADS - rtn = wrefresh(self->win); - Py_END_ALLOW_THREADS - return PyCursesCheckERR(rtn, "prefresh"); - } -} + top: int + First line number. + bottom: int + Last line number. + / + +Define a software scrolling region. + +All scrolling actions will take place in this region. +[clinic start generated code]*/ static PyObject * -PyCursesWindow_SetScrollRegion(PyCursesWindowObject *self, PyObject *args) +_curses_window_setscrreg_impl(PyCursesWindowObject *self, int top, + int bottom) +/*[clinic end generated code: output=486ab5db218d2b1a input=1b517b986838bf0e]*/ { - int x, y; - if (!PyArg_ParseTuple(args,"ii;top, bottom",&y,&x)) - return NULL; - return PyCursesCheckERR(wsetscrreg(self->win,y,x), "wsetscrreg"); + return PyCursesCheckERR(wsetscrreg(self->win, top, bottom), "wsetscrreg"); } +/*[clinic input] +_curses.window.subwin + + [ + nlines: int = 0 + Height. + ncols: int = 0 + Width. + ] + begin_y: int + Top side y-coordinate. + begin_x: int + Left side x-coordinate. + / + +Create a sub-window (screen-relative coordinates). + +By default, the sub-window will extend from the specified position to the +lower right corner of the window. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_SubWin(PyCursesWindowObject *self, PyObject *args) +_curses_window_subwin_impl(PyCursesWindowObject *self, int group_left_1, + int nlines, int ncols, int begin_y, int begin_x) +/*[clinic end generated code: output=93e898afc348f59a input=2129fa47fd57721c]*/ { WINDOW *win; - int nlines, ncols, begin_y, begin_x; - - nlines = 0; - ncols = 0; - switch (PyTuple_Size(args)) { - case 2: - if (!PyArg_ParseTuple(args,"ii;begin_y,begin_x",&begin_y,&begin_x)) - return NULL; - break; - case 4: - if (!PyArg_ParseTuple(args, "iiii;nlines,ncols,begin_y,begin_x", - &nlines,&ncols,&begin_y,&begin_x)) - return NULL; - break; - default: - PyErr_SetString(PyExc_TypeError, "subwin requires 2 or 4 arguments"); - return NULL; - } /* printf("Subwin: %i %i %i %i \n", nlines, ncols, begin_y, begin_x); */ #ifdef py_is_pad @@ -1873,84 +2184,101 @@ PyCursesWindow_SubWin(PyCursesWindowObject *self, PyObject *args) return (PyObject *)PyCursesWindow_New(win, self->encoding); } +/*[clinic input] +_curses.window.scroll + + [ + lines: int = 1 + Number of lines to scroll. + ] + / + +Scroll the screen or scrolling region. + +Scroll upward if the argument is positive and downward if it is negative. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_Scroll(PyCursesWindowObject *self, PyObject *args) +_curses_window_scroll_impl(PyCursesWindowObject *self, int group_right_1, + int lines) +/*[clinic end generated code: output=4541a8a11852d360 input=c969ca0cfabbdbec]*/ { - int nlines; - switch(PyTuple_Size(args)) { - case 0: + if (!group_right_1) { return PyCursesCheckERR(scroll(self->win), "scroll"); - case 1: - if (!PyArg_ParseTuple(args, "i;nlines", &nlines)) - return NULL; - return PyCursesCheckERR(wscrl(self->win, nlines), "scroll"); - default: - PyErr_SetString(PyExc_TypeError, "scroll requires 0 or 1 arguments"); - return NULL; + } + else { + return PyCursesCheckERR(wscrl(self->win, lines), "scroll"); } } +/*[clinic input] +_curses.window.touchline + + start: int + count: int + [ + changed: bool(accept={int}) = True + ] + / + +Pretend count lines have been changed, starting with line start. + +If changed is supplied, it specifies whether the affected lines are marked +as having been changed (changed=True) or unchanged (changed=False). +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_TouchLine(PyCursesWindowObject *self, PyObject *args) +_curses_window_touchline_impl(PyCursesWindowObject *self, int start, + int count, int group_right_1, int changed) +/*[clinic end generated code: output=65d05b3f7438c61d input=918ad1cbdadf93ea]*/ { - int st, cnt, val; - switch (PyTuple_Size(args)) { - case 2: - if (!PyArg_ParseTuple(args,"ii;start,count",&st,&cnt)) - return NULL; - return PyCursesCheckERR(touchline(self->win,st,cnt), "touchline"); - case 3: - if (!PyArg_ParseTuple(args, "iii;start,count,val", &st, &cnt, &val)) - return NULL; - return PyCursesCheckERR(wtouchln(self->win, st, cnt, val), "touchline"); - default: - PyErr_SetString(PyExc_TypeError, "touchline requires 2 or 3 arguments"); - return NULL; + if (!group_right_1) { + return PyCursesCheckERR(touchline(self->win, start, count), "touchline"); + } + else { + return PyCursesCheckERR(wtouchln(self->win, start, count, changed), "touchline"); } } +/*[clinic input] +_curses.window.vline + + [ + y: int + Starting Y-coordinate. + x: int + Starting X-coordinate. + ] + + ch: object + Character to draw. + n: int + Line length. + + [ + attr: long(c_default="A_NORMAL") = _curses.A_NORMAL + Attributes for the character. + ] + / + +Display a vertical line. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_Vline(PyCursesWindowObject *self, PyObject *args) +_curses_window_vline_impl(PyCursesWindowObject *self, int group_left_1, + int y, int x, PyObject *ch, int n, + int group_right_1, long attr) +/*[clinic end generated code: output=287ad1cc8982217f input=a6f2dc86a4648b32]*/ { - PyObject *temp; - chtype ch; - int n, x, y, code = OK; - attr_t attr = A_NORMAL; - long lattr; + chtype ch_; - switch (PyTuple_Size(args)) { - case 2: - if (!PyArg_ParseTuple(args, "Oi;ch or int,n", &temp, &n)) - return NULL; - break; - case 3: - if (!PyArg_ParseTuple(args, "Oil;ch or int,n,attr", &temp, &n, &lattr)) - return NULL; - attr = lattr; - break; - case 4: - if (!PyArg_ParseTuple(args, "iiOi;y,x,ch or int,n", &y, &x, &temp, &n)) - return NULL; - code = wmove(self->win, y, x); - break; - case 5: - if (!PyArg_ParseTuple(args, "iiOil; y,x,ch or int,n,attr", - &y, &x, &temp, &n, &lattr)) - return NULL; - attr = lattr; - code = wmove(self->win, y, x); - break; - default: - PyErr_SetString(PyExc_TypeError, "vline requires 2 to 5 arguments"); + if (!PyCurses_ConvertToChtype(self, ch, &ch_)) return NULL; + if (group_left_1) { + if (wmove(self->win, y, x) == ERR) + return PyCursesCheckERR(ERR, "wmove"); } - - if (code != ERR) { - if (!PyCurses_ConvertToChtype(self, temp, &ch)) - return NULL; - return PyCursesCheckERR(wvline(self->win, ch | attr, n), "vline"); - } else - return PyCursesCheckERR(code, "wmove"); + return PyCursesCheckERR(wvline(self->win, ch_ | (attr_t)attr, n), "vline"); } static PyObject * @@ -1991,59 +2319,56 @@ PyCursesWindow_set_encoding(PyCursesWindowObject *self, PyObject *value) return 0; } +#include "clinic/_cursesmodule.c.h" static PyMethodDef PyCursesWindow_Methods[] = { - CURSES_WINDOW_ADDCH_METHODDEF - {"addnstr", (PyCFunction)PyCursesWindow_AddNStr, METH_VARARGS}, - {"addstr", (PyCFunction)PyCursesWindow_AddStr, METH_VARARGS}, - {"attroff", (PyCFunction)PyCursesWindow_AttrOff, METH_VARARGS}, - {"attron", (PyCFunction)PyCursesWindow_AttrOn, METH_VARARGS}, - {"attrset", (PyCFunction)PyCursesWindow_AttrSet, METH_VARARGS}, - {"bkgd", (PyCFunction)PyCursesWindow_Bkgd, METH_VARARGS}, + _CURSES_WINDOW_ADDCH_METHODDEF + _CURSES_WINDOW_ADDNSTR_METHODDEF + _CURSES_WINDOW_ADDSTR_METHODDEF + _CURSES_WINDOW_ATTROFF_METHODDEF + _CURSES_WINDOW_ATTRON_METHODDEF + _CURSES_WINDOW_ATTRSET_METHODDEF + _CURSES_WINDOW_BKGD_METHODDEF #ifdef HAVE_CURSES_WCHGAT {"chgat", (PyCFunction)PyCursesWindow_ChgAt, METH_VARARGS}, #endif - {"bkgdset", (PyCFunction)PyCursesWindow_BkgdSet, METH_VARARGS}, - {"border", (PyCFunction)PyCursesWindow_Border, METH_VARARGS}, - {"box", (PyCFunction)PyCursesWindow_Box, METH_VARARGS}, + _CURSES_WINDOW_BKGDSET_METHODDEF + _CURSES_WINDOW_BORDER_METHODDEF + _CURSES_WINDOW_BOX_METHODDEF {"clear", (PyCFunction)PyCursesWindow_wclear, METH_NOARGS}, {"clearok", (PyCFunction)PyCursesWindow_clearok, METH_VARARGS}, {"clrtobot", (PyCFunction)PyCursesWindow_wclrtobot, METH_NOARGS}, {"clrtoeol", (PyCFunction)PyCursesWindow_wclrtoeol, METH_NOARGS}, {"cursyncup", (PyCFunction)PyCursesWindow_wcursyncup, METH_NOARGS}, - {"delch", (PyCFunction)PyCursesWindow_DelCh, METH_VARARGS}, + _CURSES_WINDOW_DELCH_METHODDEF {"deleteln", (PyCFunction)PyCursesWindow_wdeleteln, METH_NOARGS}, - {"derwin", (PyCFunction)PyCursesWindow_DerWin, METH_VARARGS}, - {"echochar", (PyCFunction)PyCursesWindow_EchoChar, METH_VARARGS}, -#ifdef NCURSES_MOUSE_VERSION - {"enclose", (PyCFunction)PyCursesWindow_Enclose, METH_VARARGS}, -#endif + _CURSES_WINDOW_DERWIN_METHODDEF + _CURSES_WINDOW_ECHOCHAR_METHODDEF + _CURSES_WINDOW_ENCLOSE_METHODDEF {"erase", (PyCFunction)PyCursesWindow_werase, METH_NOARGS}, {"getbegyx", (PyCFunction)PyCursesWindow_getbegyx, METH_NOARGS}, - {"getbkgd", (PyCFunction)PyCursesWindow_GetBkgd, METH_NOARGS}, - {"getch", (PyCFunction)PyCursesWindow_GetCh, METH_VARARGS}, - {"getkey", (PyCFunction)PyCursesWindow_GetKey, METH_VARARGS}, -#ifdef HAVE_NCURSESW - {"get_wch", (PyCFunction)PyCursesWindow_Get_WCh, METH_VARARGS}, -#endif + _CURSES_WINDOW_GETBKGD_METHODDEF + _CURSES_WINDOW_GETCH_METHODDEF + _CURSES_WINDOW_GETKEY_METHODDEF + _CURSES_WINDOW_GET_WCH_METHODDEF {"getmaxyx", (PyCFunction)PyCursesWindow_getmaxyx, METH_NOARGS}, {"getparyx", (PyCFunction)PyCursesWindow_getparyx, METH_NOARGS}, {"getstr", (PyCFunction)PyCursesWindow_GetStr, METH_VARARGS}, {"getyx", (PyCFunction)PyCursesWindow_getyx, METH_NOARGS}, - {"hline", (PyCFunction)PyCursesWindow_Hline, METH_VARARGS}, + _CURSES_WINDOW_HLINE_METHODDEF {"idcok", (PyCFunction)PyCursesWindow_idcok, METH_VARARGS}, {"idlok", (PyCFunction)PyCursesWindow_idlok, METH_VARARGS}, #ifdef HAVE_CURSES_IMMEDOK {"immedok", (PyCFunction)PyCursesWindow_immedok, METH_VARARGS}, #endif - {"inch", (PyCFunction)PyCursesWindow_InCh, METH_VARARGS}, - {"insch", (PyCFunction)PyCursesWindow_InsCh, METH_VARARGS}, + _CURSES_WINDOW_INCH_METHODDEF + _CURSES_WINDOW_INSCH_METHODDEF {"insdelln", (PyCFunction)PyCursesWindow_winsdelln, METH_VARARGS}, {"insertln", (PyCFunction)PyCursesWindow_winsertln, METH_NOARGS}, - {"insnstr", (PyCFunction)PyCursesWindow_InsNStr, METH_VARARGS}, - {"insstr", (PyCFunction)PyCursesWindow_InsStr, METH_VARARGS}, + _CURSES_WINDOW_INSNSTR_METHODDEF + _CURSES_WINDOW_INSSTR_METHODDEF {"instr", (PyCFunction)PyCursesWindow_InStr, METH_VARARGS}, - {"is_linetouched", (PyCFunction)PyCursesWindow_Is_LineTouched, METH_VARARGS}, + _CURSES_WINDOW_IS_LINETOUCHED_METHODDEF {"is_wintouched", (PyCFunction)PyCursesWindow_is_wintouched, METH_NOARGS}, {"keypad", (PyCFunction)PyCursesWindow_keypad, METH_VARARGS}, {"leaveok", (PyCFunction)PyCursesWindow_leaveok, METH_VARARGS}, @@ -2052,34 +2377,33 @@ static PyMethodDef PyCursesWindow_Methods[] = { {"mvwin", (PyCFunction)PyCursesWindow_mvwin, METH_VARARGS}, {"nodelay", (PyCFunction)PyCursesWindow_nodelay, METH_VARARGS}, {"notimeout", (PyCFunction)PyCursesWindow_notimeout, METH_VARARGS}, - {"noutrefresh", (PyCFunction)PyCursesWindow_NoOutRefresh, METH_VARARGS}, - {"overlay", (PyCFunction)PyCursesWindow_Overlay, METH_VARARGS}, - {"overwrite", (PyCFunction)PyCursesWindow_Overwrite, - METH_VARARGS}, - {"putwin", (PyCFunction)PyCursesWindow_PutWin, METH_O}, - {"redrawln", (PyCFunction)PyCursesWindow_RedrawLine, METH_VARARGS}, + _CURSES_WINDOW_NOUTREFRESH_METHODDEF + _CURSES_WINDOW_OVERLAY_METHODDEF + _CURSES_WINDOW_OVERWRITE_METHODDEF + _CURSES_WINDOW_PUTWIN_METHODDEF + _CURSES_WINDOW_REDRAWLN_METHODDEF {"redrawwin", (PyCFunction)PyCursesWindow_redrawwin, METH_NOARGS}, - {"refresh", (PyCFunction)PyCursesWindow_Refresh, METH_VARARGS}, + _CURSES_WINDOW_REFRESH_METHODDEF #ifndef STRICT_SYSV_CURSES {"resize", (PyCFunction)PyCursesWindow_wresize, METH_VARARGS}, #endif - {"scroll", (PyCFunction)PyCursesWindow_Scroll, METH_VARARGS}, + _CURSES_WINDOW_SCROLL_METHODDEF {"scrollok", (PyCFunction)PyCursesWindow_scrollok, METH_VARARGS}, - {"setscrreg", (PyCFunction)PyCursesWindow_SetScrollRegion, METH_VARARGS}, + _CURSES_WINDOW_SETSCRREG_METHODDEF {"standend", (PyCFunction)PyCursesWindow_wstandend, METH_NOARGS}, {"standout", (PyCFunction)PyCursesWindow_wstandout, METH_NOARGS}, - {"subpad", (PyCFunction)PyCursesWindow_SubWin, METH_VARARGS}, - {"subwin", (PyCFunction)PyCursesWindow_SubWin, METH_VARARGS}, + {"subpad", (PyCFunction)_curses_window_subwin, METH_VARARGS, _curses_window_subwin__doc__}, + _CURSES_WINDOW_SUBWIN_METHODDEF {"syncdown", (PyCFunction)PyCursesWindow_wsyncdown, METH_NOARGS}, #ifdef HAVE_CURSES_SYNCOK {"syncok", (PyCFunction)PyCursesWindow_syncok, METH_VARARGS}, #endif {"syncup", (PyCFunction)PyCursesWindow_wsyncup, METH_NOARGS}, {"timeout", (PyCFunction)PyCursesWindow_wtimeout, METH_VARARGS}, - {"touchline", (PyCFunction)PyCursesWindow_TouchLine, METH_VARARGS}, + _CURSES_WINDOW_TOUCHLINE_METHODDEF {"touchwin", (PyCFunction)PyCursesWindow_touchwin, METH_NOARGS}, {"untouchwin", (PyCFunction)PyCursesWindow_untouchwin, METH_NOARGS}, - {"vline", (PyCFunction)PyCursesWindow_Vline, METH_VARARGS}, + _CURSES_WINDOW_VLINE_METHODDEF {NULL, NULL} /* sentinel */ }; @@ -2127,47 +2451,63 @@ PyTypeObject PyCursesWindow_Type = { PyCursesWindow_getsets, /* tp_getset */ }; +/* Function Prototype Macros - They are ugly but very, very useful. ;-) + + X - function name + TYPE - parameter Type + ERGSTR - format string for construction of the return value + PARSESTR - format string for argument parsing + */ + +#define NoArgNoReturnFunctionBody(X) \ +{ \ + PyCursesInitialised \ + return PyCursesCheckERR(X(), # X); } + +#define NoArgOrFlagNoReturnFunctionBody(X, flag) \ +{ \ + PyCursesInitialised \ + if (flag) \ + return PyCursesCheckERR(X(), # X); \ + else \ + return PyCursesCheckERR(no ## X(), # X); \ +} + +#define NoArgReturnIntFunctionBody(X) \ +{ \ + PyCursesInitialised \ + return PyLong_FromLong((long) X()); } + + +#define NoArgReturnStringFunctionBody(X) \ +{ \ + PyCursesInitialised \ + return PyBytes_FromString(X()); } + +#define NoArgTrueFalseFunctionBody(X) \ +{ \ + PyCursesInitialised \ + return PyBool_FromLong(X()); } + +#define NoArgNoReturnVoidFunctionBody(X) \ +{ \ + PyCursesInitialised \ + X(); \ + Py_RETURN_NONE; } + /********************************************************************* Global Functions **********************************************************************/ -NoArgNoReturnFunction(beep) -NoArgNoReturnFunction(def_prog_mode) -NoArgNoReturnFunction(def_shell_mode) -NoArgNoReturnFunction(doupdate) -NoArgNoReturnFunction(endwin) -NoArgNoReturnFunction(flash) -NoArgNoReturnFunction(nocbreak) -NoArgNoReturnFunction(noecho) -NoArgNoReturnFunction(nonl) -NoArgNoReturnFunction(noraw) -NoArgNoReturnFunction(reset_prog_mode) -NoArgNoReturnFunction(reset_shell_mode) -NoArgNoReturnFunction(resetty) -NoArgNoReturnFunction(savetty) - -NoArgOrFlagNoReturnFunction(cbreak) -NoArgOrFlagNoReturnFunction(echo) -NoArgOrFlagNoReturnFunction(nl) -NoArgOrFlagNoReturnFunction(raw) - -NoArgReturnIntFunction(baudrate) -NoArgReturnIntFunction(termattrs) - -NoArgReturnStringFunction(termname) -NoArgReturnStringFunction(longname) - -NoArgTrueFalseFunction(can_change_color) -NoArgTrueFalseFunction(has_colors) -NoArgTrueFalseFunction(has_ic) -NoArgTrueFalseFunction(has_il) -NoArgTrueFalseFunction(isendwin) -NoArgNoReturnVoidFunction(flushinp) -NoArgNoReturnVoidFunction(noqiflush) - #ifdef HAVE_CURSES_FILTER +/*[clinic input] +_curses.filter + +[clinic start generated code]*/ + static PyObject * -PyCurses_filter(PyObject *self) +_curses_filter_impl(PyObject *module) +/*[clinic end generated code: output=fb5b8a3642eb70b5 input=668c75a6992d3624]*/ { /* not checking for PyCursesInitialised here since filter() must be called before initscr() */ @@ -2176,17 +2516,83 @@ PyCurses_filter(PyObject *self) } #endif +/*[clinic input] +_curses.baudrate + +Return the output speed of the terminal in bits per second. +[clinic start generated code]*/ + +static PyObject * +_curses_baudrate_impl(PyObject *module) +/*[clinic end generated code: output=3c63c6c401d7d9c0 input=921f022ed04a0fd9]*/ +NoArgReturnIntFunctionBody(baudrate) + +/*[clinic input] +_curses.beep + +Emit a short attention sound. +[clinic start generated code]*/ + +static PyObject * +_curses_beep_impl(PyObject *module) +/*[clinic end generated code: output=425274962abe49a2 input=a35698ca7d0162bc]*/ +NoArgNoReturnFunctionBody(beep) + +/*[clinic input] +_curses.can_change_color + +Return True if the programmer can change the colors displayed by the terminal. +[clinic start generated code]*/ + +static PyObject * +_curses_can_change_color_impl(PyObject *module) +/*[clinic end generated code: output=359df8c3c77d8bf1 input=d7718884de0092f2]*/ +NoArgTrueFalseFunctionBody(can_change_color) + +/*[clinic input] +_curses.cbreak + + flag: bool(accept={int}) = True + If false, the effect is the same as calling nocbreak(). + / + +Enter cbreak mode. + +In cbreak mode (sometimes called "rare" mode) normal tty line buffering is +turned off and characters are available to be read one by one. However, +unlike raw mode, special characters (interrupt, quit, suspend, and flow +control) retain their effects on the tty driver and calling program. +Calling first raw() then cbreak() leaves the terminal in cbreak mode. +[clinic start generated code]*/ + +static PyObject * +_curses_cbreak_impl(PyObject *module, int flag) +/*[clinic end generated code: output=9f9dee9664769751 input=150be619eb1f1458]*/ +NoArgOrFlagNoReturnFunctionBody(cbreak, flag) + +/*[clinic input] +_curses.color_content + + color_number: short + The number of the color (0 - COLORS). + / + +Return the red, green, and blue (RGB) components of the specified color. + +A 3-tuple is returned, containing the R, G, B values for the given color, +which will be between 0 (no component) and 1000 (maximum amount of component). +[clinic start generated code]*/ + static PyObject * -PyCurses_Color_Content(PyObject *self, PyObject *args) +_curses_color_content_impl(PyObject *module, short color_number) +/*[clinic end generated code: output=cb15cf3120d4bfc1 input=5555abb1c11e11b7]*/ { - short color,r,g,b; + short r,g,b; PyCursesInitialised; PyCursesInitialisedColor; - if (!PyArg_ParseTuple(args, "h:color_content", &color)) return NULL; - - if (color_content(color, &r, &g, &b) != ERR) + if (color_content(color_number, &r, &g, &b) != ERR) return Py_BuildValue("(iii)", r, g, b); else { PyErr_SetString(PyCursesError, @@ -2195,47 +2601,155 @@ PyCurses_Color_Content(PyObject *self, PyObject *args) } } +/*[clinic input] +_curses.color_pair + + color_number: short + The number of the color (0 - COLORS). + / + +Return the attribute value for displaying text in the specified color. + +This attribute value can be combined with A_STANDOUT, A_REVERSE, and the +other A_* attributes. pair_number() is the counterpart to this function. +[clinic start generated code]*/ + static PyObject * -PyCurses_color_pair(PyObject *self, PyObject *args) +_curses_color_pair_impl(PyObject *module, short color_number) +/*[clinic end generated code: output=6a84cb6b29ecaf9a input=a9d3eb6f50e4dc12]*/ { - int n; - PyCursesInitialised; PyCursesInitialisedColor; - if (!PyArg_ParseTuple(args, "i:color_pair", &n)) return NULL; - return PyLong_FromLong((long) (n << 8)); + return PyLong_FromLong((long) (color_number << 8)); } +/*[clinic input] +_curses.curs_set + + visibility: int + 0 for invisible, 1 for normal visible, or 2 for very visible. + / + +Set the cursor state. + +If the terminal supports the visibility requested, the previous cursor +state is returned; otherwise, an exception is raised. On many terminals, +the "visible" mode is an underline cursor and the "very visible" mode is +a block cursor. +[clinic start generated code]*/ + static PyObject * -PyCurses_Curs_Set(PyObject *self, PyObject *args) +_curses_curs_set_impl(PyObject *module, int visibility) +/*[clinic end generated code: output=ee8e62483b1d6cd4 input=81a7924a65d29504]*/ { - int vis,erg; + int erg; PyCursesInitialised; - if (!PyArg_ParseTuple(args, "i:curs_set", &vis)) return NULL; - - erg = curs_set(vis); + erg = curs_set(visibility); if (erg == ERR) return PyCursesCheckERR(erg, "curs_set"); return PyLong_FromLong((long) erg); } +/*[clinic input] +_curses.def_prog_mode + +Save the current terminal mode as the "program" mode. + +The "program" mode is the mode when the running program is using curses. + +Subsequent calls to reset_prog_mode() will restore this mode. +[clinic start generated code]*/ + static PyObject * -PyCurses_Delay_Output(PyObject *self, PyObject *args) -{ - int ms; +_curses_def_prog_mode_impl(PyObject *module) +/*[clinic end generated code: output=05d5a351fff874aa input=768b9cace620dda5]*/ +NoArgNoReturnFunctionBody(def_prog_mode) - PyCursesInitialised; +/*[clinic input] +_curses.def_shell_mode + +Save the current terminal mode as the "shell" mode. + +The "shell" mode is the mode when the running program is not using curses. + +Subsequent calls to reset_shell_mode() will restore this mode. +[clinic start generated code]*/ + +static PyObject * +_curses_def_shell_mode_impl(PyObject *module) +/*[clinic end generated code: output=d6e42f5c768f860f input=5ead21f6f0baa894]*/ +NoArgNoReturnFunctionBody(def_shell_mode) + +/*[clinic input] +_curses.delay_output + + ms: int + Duration in milliseconds. + / + +Insert a pause in output. +[clinic start generated code]*/ - if (!PyArg_ParseTuple(args, "i:delay_output", &ms)) return NULL; +static PyObject * +_curses_delay_output_impl(PyObject *module, int ms) +/*[clinic end generated code: output=b6613a67f17fa4f4 input=5316457f5f59196c]*/ +{ + PyCursesInitialised; return PyCursesCheckERR(delay_output(ms), "delay_output"); } +/*[clinic input] +_curses.doupdate + +Update the physical screen to match the virtual screen. +[clinic start generated code]*/ + +static PyObject * +_curses_doupdate_impl(PyObject *module) +/*[clinic end generated code: output=f34536975a75680c input=8da80914432a6489]*/ +NoArgNoReturnFunctionBody(doupdate) + +/*[clinic input] +_curses.echo + + flag: bool(accept={int}) = True + If false, the effect is the same as calling noecho(). + / + +Enter echo mode. + +In echo mode, each character input is echoed to the screen as it is entered. +[clinic start generated code]*/ + +static PyObject * +_curses_echo_impl(PyObject *module, int flag) +/*[clinic end generated code: output=03acb2ddfa6c8729 input=2e9e891d637eac5d]*/ +NoArgOrFlagNoReturnFunctionBody(echo, flag) + +/*[clinic input] +_curses.endwin + +De-initialize the library, and return terminal to normal status. +[clinic start generated code]*/ + +static PyObject * +_curses_endwin_impl(PyObject *module) +/*[clinic end generated code: output=c0150cd96d2f4128 input=e172cfa43062f3fa]*/ +NoArgNoReturnFunctionBody(endwin) + +/*[clinic input] +_curses.erasechar + +Return the user's current erase character. +[clinic start generated code]*/ + static PyObject * -PyCurses_EraseChar(PyObject *self) +_curses_erasechar_impl(PyObject *module) +/*[clinic end generated code: output=3df305dc6b926b3f input=628c136c3c5758d3]*/ { char ch; @@ -2246,9 +2760,45 @@ PyCurses_EraseChar(PyObject *self) return PyBytes_FromStringAndSize(&ch, 1); } +/*[clinic input] +_curses.flash + +Flash the screen. + +That is, change it to reverse-video and then change it back in a short interval. +[clinic start generated code]*/ + +static PyObject * +_curses_flash_impl(PyObject *module) +/*[clinic end generated code: output=488b8a0ebd9ea9b8 input=02fdfb06c8fc3171]*/ +NoArgNoReturnFunctionBody(flash) + +/*[clinic input] +_curses.flushinp + +Flush all input buffers. + +This throws away any typeahead that has been typed by the user and has not +yet been processed by the program. +[clinic start generated code]*/ + +static PyObject * +_curses_flushinp_impl(PyObject *module) +/*[clinic end generated code: output=7e7a1fc1473960f5 input=59d042e705cef5ec]*/ +NoArgNoReturnVoidFunctionBody(flushinp) + #ifdef getsyx +/*[clinic input] +_curses.getsyx + +Return the current coordinates of the virtual screen cursor. + +Return a (y, x) tuple. If leaveok is currently true, return (-1, -1). +[clinic start generated code]*/ + static PyObject * -PyCurses_getsyx(PyObject *self) +_curses_getsyx_impl(PyObject *module) +/*[clinic end generated code: output=c8e6c3f42349a038 input=9e1f862f3b4f7cba]*/ { int x = 0; int y = 0; @@ -2262,8 +2812,18 @@ PyCurses_getsyx(PyObject *self) #endif #ifdef NCURSES_MOUSE_VERSION +/*[clinic input] +_curses.getmouse + +Retrieve the queued mouse event. + +After getch() returns KEY_MOUSE to signal a mouse event, this function +returns a 5-tuple (id, x, y, z, bstate). +[clinic start generated code]*/ + static PyObject * -PyCurses_GetMouse(PyObject *self) +_curses_getmouse_impl(PyObject *module) +/*[clinic end generated code: output=ccf4242546b9cfa8 input=5b756ee6f5b481b1]*/ { int rtn; MEVENT event; @@ -2281,18 +2841,29 @@ PyCurses_GetMouse(PyObject *self) (unsigned long) event.bstate); } +/*[clinic input] +_curses.ungetmouse + + id: short + x: int + y: int + z: int + bstate: unsigned_long(bitwise=True) + / + +Push a KEY_MOUSE event onto the input queue. + +The following getmouse() will return the given state data. +[clinic start generated code]*/ + static PyObject * -PyCurses_UngetMouse(PyObject *self, PyObject *args) +_curses_ungetmouse_impl(PyObject *module, short id, int x, int y, int z, + unsigned long bstate) +/*[clinic end generated code: output=3430c9b0fc5c4341 input=fd650b2ca5a01e8f]*/ { MEVENT event; - short id; - int x, y, z; - unsigned long bstate; PyCursesInitialised; - if (!PyArg_ParseTuple(args, "hiiik", - &id, &x, &y, &z, &bstate)) - return NULL; event.id = id; event.x = x; @@ -2303,8 +2874,21 @@ PyCurses_UngetMouse(PyObject *self, PyObject *args) } #endif +/*[clinic input] +_curses.getwin + + file: object + / + +Read window related data stored in the file by an earlier putwin() call. + +The routine then creates and initializes a new window using that data, +returning the new window object. +[clinic start generated code]*/ + static PyObject * -PyCurses_GetWin(PyCursesWindowObject *self, PyObject *stream) +_curses_getwin(PyObject *module, PyObject *file) +/*[clinic end generated code: output=a79e0df3379af756 input=f713d2bba0e4c929]*/ { FILE *fp; PyObject *data; @@ -2322,8 +2906,7 @@ PyCurses_GetWin(PyCursesWindowObject *self, PyObject *stream) if (_Py_set_inheritable(fileno(fp), 0, NULL) < 0) goto error; - - data = _PyObject_CallMethodId(stream, &PyId_read, NULL); + data = _PyObject_CallMethodId(file, &PyId_read, NULL); if (data == NULL) goto error; if (!PyBytes_Check(data)) { @@ -2354,82 +2937,158 @@ PyCurses_GetWin(PyCursesWindowObject *self, PyObject *stream) return res; } +/*[clinic input] +_curses.halfdelay + + tenths: byte + Maximal blocking delay in tenths of seconds (1 - 255). + / + +Enter half-delay mode. + +Use nocbreak() to leave half-delay mode. +[clinic start generated code]*/ + static PyObject * -PyCurses_HalfDelay(PyObject *self, PyObject *args) +_curses_halfdelay_impl(PyObject *module, unsigned char tenths) +/*[clinic end generated code: output=e92cdf0ef33c0663 input=e42dce7259c15100]*/ { - unsigned char tenths; - PyCursesInitialised; - if (!PyArg_ParseTuple(args, "b:halfdelay", &tenths)) return NULL; - return PyCursesCheckERR(halfdelay(tenths), "halfdelay"); } +/*[clinic input] +_curses.has_colors + +Return True if the terminal can display colors; otherwise, return False. +[clinic start generated code]*/ + +static PyObject * +_curses_has_colors_impl(PyObject *module) +/*[clinic end generated code: output=db5667483139e3e2 input=b2ec41b739d896c6]*/ +NoArgTrueFalseFunctionBody(has_colors) + +/*[clinic input] +_curses.has_ic + +Return True if the terminal has insert- and delete-character capabilities. +[clinic start generated code]*/ + +static PyObject * +_curses_has_ic_impl(PyObject *module) +/*[clinic end generated code: output=6be24da9cb1268fe input=9bc2d3a797cc7324]*/ +NoArgTrueFalseFunctionBody(has_ic) + +/*[clinic input] +_curses.has_il + +Return True if the terminal has insert- and delete-line capabilities. +[clinic start generated code]*/ + +static PyObject * +_curses_has_il_impl(PyObject *module) +/*[clinic end generated code: output=d45bd7788ff9f5f4 input=cd939d5607ee5427]*/ +NoArgTrueFalseFunctionBody(has_il) + #ifdef HAVE_CURSES_HAS_KEY +/*[clinic input] +_curses.has_key + + key: int + Key number. + / + +Return True if the current terminal type recognizes a key with that value. +[clinic start generated code]*/ + static PyObject * -PyCurses_has_key(PyObject *self, PyObject *args) +_curses_has_key_impl(PyObject *module, int key) +/*[clinic end generated code: output=19ad48319414d0b1 input=78bd44acf1a4997c]*/ { - int ch; - PyCursesInitialised; - if (!PyArg_ParseTuple(args,"i",&ch)) return NULL; - - if (has_key(ch) == FALSE) { - Py_RETURN_FALSE; - } - Py_RETURN_TRUE; + return PyBool_FromLong(has_key(key)); } #endif +/*[clinic input] +_curses.init_color + + color_number: short + The number of the color to be changed (0 - COLORS). + r: short + Red component (0 - 1000). + g: short + Green component (0 - 1000). + b: short + Blue component (0 - 1000). + / + +Change the definition of a color. + +When init_color() is used, all occurrences of that color on the screen +immediately change to the new definition. This function is a no-op on +most terminals; it is active only if can_change_color() returns 1. +[clinic start generated code]*/ + static PyObject * -PyCurses_Init_Color(PyObject *self, PyObject *args) +_curses_init_color_impl(PyObject *module, short color_number, short r, + short g, short b) +/*[clinic end generated code: output=280236f5efe9776a input=f3a05bd38f619175]*/ { - short color, r, g, b; - PyCursesInitialised; PyCursesInitialisedColor; - switch(PyTuple_Size(args)) { - case 4: - if (!PyArg_ParseTuple(args, "hhhh;color,r,g,b", &color, &r, &g, &b)) return NULL; - break; - default: - PyErr_SetString(PyExc_TypeError, "init_color requires 4 arguments"); - return NULL; - } - - return PyCursesCheckERR(init_color(color, r, g, b), "init_color"); + return PyCursesCheckERR(init_color(color_number, r, g, b), "init_color"); } +/*[clinic input] +_curses.init_pair + + pair_number: short + The number of the color-pair to be changed (1 - (COLOR_PAIRS-1)). + fg: short + Foreground color number (0 - COLORS). + bg: short + Background color number (0 - COLORS). + / + +Change the definition of a color-pair. + +If the color-pair was previously initialized, the screen is refreshed and +all occurrences of that color-pair are changed to the new definition. +[clinic start generated code]*/ + static PyObject * -PyCurses_Init_Pair(PyObject *self, PyObject *args) +_curses_init_pair_impl(PyObject *module, short pair_number, short fg, + short bg) +/*[clinic end generated code: output=9c2ce39c22f376b6 input=c9f0b11b17a2ac6d]*/ { - short pair, f, b; - PyCursesInitialised; PyCursesInitialisedColor; - if (PyTuple_Size(args) != 3) { - PyErr_SetString(PyExc_TypeError, "init_pair requires 3 arguments"); - return NULL; - } - - if (!PyArg_ParseTuple(args, "hhh;pair, f, b", &pair, &f, &b)) return NULL; - - return PyCursesCheckERR(init_pair(pair, f, b), "init_pair"); + return PyCursesCheckERR(init_pair(pair_number, fg, bg), "init_pair"); } static PyObject *ModDict; +/*[clinic input] +_curses.initscr + +Initialize the library. + +Return a WindowObject which represents the whole screen. +[clinic start generated code]*/ + static PyObject * -PyCurses_InitScr(PyObject *self) +_curses_initscr_impl(PyObject *module) +/*[clinic end generated code: output=619fb68443810b7b input=514f4bce1821f6b5]*/ { WINDOW *win; PyCursesWindowObject *winobj; - if (initialised == TRUE) { + if (initialised) { wrefresh(stdscr); return (PyObject *)PyCursesWindow_New(stdscr, NULL); } @@ -2528,19 +3187,24 @@ PyCurses_InitScr(PyObject *self) return (PyObject *)winobj; } +/*[clinic input] +_curses.setupterm + + term: str(accept={str, NoneType}) = NULL + Terminal name. + If omitted, the value of the TERM environment variable will be used. + fd: int = -1 + File descriptor to which any initialization sequences will be sent. + If not supplied, the file descriptor for sys.stdout will be used. + +Initialize the terminal. +[clinic start generated code]*/ + static PyObject * -PyCurses_setupterm(PyObject* self, PyObject *args, PyObject* keywds) +_curses_setupterm_impl(PyObject *module, const char *term, int fd) +/*[clinic end generated code: output=4584e587350f2848 input=8ac5f78ec6268be3]*/ { - int fd = -1; int err; - char* termstr = NULL; - - static char *kwlist[] = {"term", "fd", NULL}; - - if (!PyArg_ParseTupleAndKeywords( - args, keywds, "|zi:setupterm", kwlist, &termstr, &fd)) { - return NULL; - } if (fd == -1) { PyObject* sys_stdout; @@ -2561,7 +3225,7 @@ PyCurses_setupterm(PyObject* self, PyObject *args, PyObject* keywds) } } - if (!initialised_setupterm && setupterm(termstr,fd,&err) == ERR) { + if (!initialised_setupterm && setupterm((char *)term, fd, &err) == ERR) { const char* s = "setupterm: unknown error"; if (err == 0) { @@ -2579,67 +3243,93 @@ PyCurses_setupterm(PyObject* self, PyObject *args, PyObject* keywds) Py_RETURN_NONE; } +/*[clinic input] +_curses.intrflush + + flag: bool(accept={int}) + / + +[clinic start generated code]*/ + static PyObject * -PyCurses_IntrFlush(PyObject *self, PyObject *args) +_curses_intrflush_impl(PyObject *module, int flag) +/*[clinic end generated code: output=c1986df35e999a0f input=fcba57bb28dfd795]*/ { - int ch; - PyCursesInitialised; - switch(PyTuple_Size(args)) { - case 1: - if (!PyArg_ParseTuple(args,"i;True(1), False(0)",&ch)) return NULL; - break; - default: - PyErr_SetString(PyExc_TypeError, "intrflush requires 1 argument"); - return NULL; - } - - return PyCursesCheckERR(intrflush(NULL,ch), "intrflush"); + return PyCursesCheckERR(intrflush(NULL, flag), "intrflush"); } +/*[clinic input] +_curses.isendwin + +Return True if endwin() has been called. +[clinic start generated code]*/ + +static PyObject * +_curses_isendwin_impl(PyObject *module) +/*[clinic end generated code: output=d73179e4a7e1eb8c input=6cdb01a7ebf71397]*/ +NoArgTrueFalseFunctionBody(isendwin) + #ifdef HAVE_CURSES_IS_TERM_RESIZED +/*[clinic input] +_curses.is_term_resized + + nlines: int + Height. + ncols: int + Width. + / + +Return True if resize_term() would modify the window structure, False otherwise. +[clinic start generated code]*/ + static PyObject * -PyCurses_Is_Term_Resized(PyObject *self, PyObject *args) +_curses_is_term_resized_impl(PyObject *module, int nlines, int ncols) +/*[clinic end generated code: output=aafe04afe50f1288 input=ca9c0bd0fb8ab444]*/ { - int lines; - int columns; - int result; - PyCursesInitialised; - if (!PyArg_ParseTuple(args,"ii:is_term_resized", &lines, &columns)) - return NULL; - result = is_term_resized(lines, columns); - if (result == TRUE) { - Py_RETURN_TRUE; - } else { - Py_RETURN_FALSE; - } + return PyBool_FromLong(is_term_resized(nlines, ncols)); } #endif /* HAVE_CURSES_IS_TERM_RESIZED */ +/*[clinic input] +_curses.keyname + + key: int + Key number. + / + +Return the name of specified key. +[clinic start generated code]*/ + static PyObject * -PyCurses_KeyName(PyObject *self, PyObject *args) +_curses_keyname_impl(PyObject *module, int key) +/*[clinic end generated code: output=fa2675ab3f4e056b input=ee4b1d0f243a2a2b]*/ { const char *knp; - int ch; PyCursesInitialised; - if (!PyArg_ParseTuple(args,"i",&ch)) return NULL; - - if (ch < 0) { + if (key < 0) { PyErr_SetString(PyExc_ValueError, "invalid key number"); return NULL; } - knp = keyname(ch); + knp = keyname(key); return PyBytes_FromString((knp == NULL) ? "" : knp); } +/*[clinic input] +_curses.killchar + +Return the user's current line kill character. +[clinic start generated code]*/ + static PyObject * -PyCurses_KillChar(PyObject *self) +_curses_killchar_impl(PyObject *module) +/*[clinic end generated code: output=31c3a45b2c528269 input=1ff171c38df5ccad]*/ { char ch; @@ -2648,74 +3338,132 @@ PyCurses_KillChar(PyObject *self) return PyBytes_FromStringAndSize(&ch, 1); } +/*[clinic input] +_curses.longname + +Return the terminfo long name field describing the current terminal. + +The maximum length of a verbose description is 128 characters. It is defined +only after the call to initscr(). +[clinic start generated code]*/ + static PyObject * -PyCurses_Meta(PyObject *self, PyObject *args) -{ - int ch; +_curses_longname_impl(PyObject *module) +/*[clinic end generated code: output=fdf30433727ef568 input=84c3f20201b1098e]*/ +NoArgReturnStringFunctionBody(longname) - PyCursesInitialised; +/*[clinic input] +_curses.meta - switch(PyTuple_Size(args)) { - case 1: - if (!PyArg_ParseTuple(args,"i;True(1), False(0)",&ch)) return NULL; - break; - default: - PyErr_SetString(PyExc_TypeError, "meta requires 1 argument"); - return NULL; - } + yes: bool(accept={int}) + / + +Enable/disable meta keys. + +If yes is True, allow 8-bit characters to be input. If yes is False, +allow only 7-bit characters. +[clinic start generated code]*/ - return PyCursesCheckERR(meta(stdscr, ch), "meta"); +static PyObject * +_curses_meta_impl(PyObject *module, int yes) +/*[clinic end generated code: output=22f5abda46a605d8 input=af9892e3a74f35db]*/ +{ + PyCursesInitialised; + + return PyCursesCheckERR(meta(stdscr, yes), "meta"); } #ifdef NCURSES_MOUSE_VERSION +/*[clinic input] +_curses.mouseinterval + + interval: int + Time in milliseconds. + / + +Set and retrieve the maximum time between press and release in a click. + +Set the maximum time that can elapse between press and release events in +order for them to be recognized as a click, and return the previous interval +value. +[clinic start generated code]*/ + static PyObject * -PyCurses_MouseInterval(PyObject *self, PyObject *args) +_curses_mouseinterval_impl(PyObject *module, int interval) +/*[clinic end generated code: output=c4f5ff04354634c5 input=75aaa3f0db10ac4e]*/ { - int interval; PyCursesInitialised; - if (!PyArg_ParseTuple(args,"i;interval",&interval)) - return NULL; return PyCursesCheckERR(mouseinterval(interval), "mouseinterval"); } +/*[clinic input] +_curses.mousemask + + newmask: unsigned_long(bitwise=True) + / + +Set the mouse events to be reported, and return a tuple (availmask, oldmask). + +Return a tuple (availmask, oldmask). availmask indicates which of the +specified mouse events can be reported; on complete failure it returns 0. +oldmask is the previous value of the given window's mouse event mask. +If this function is never called, no mouse events are ever reported. +[clinic start generated code]*/ + static PyObject * -PyCurses_MouseMask(PyObject *self, PyObject *args) +_curses_mousemask_impl(PyObject *module, unsigned long newmask) +/*[clinic end generated code: output=9406cf1b8a36e485 input=bdf76b7568a3c541]*/ { - unsigned long newmask; mmask_t oldmask, availmask; PyCursesInitialised; - if (!PyArg_ParseTuple(args,"k;mousemask",&newmask)) - return NULL; availmask = mousemask((mmask_t)newmask, &oldmask); return Py_BuildValue("(kk)", (unsigned long)availmask, (unsigned long)oldmask); } #endif +/*[clinic input] +_curses.napms + + ms: int + Duration in milliseconds. + / + +Sleep for specified time. +[clinic start generated code]*/ + static PyObject * -PyCurses_Napms(PyObject *self, PyObject *args) +_curses_napms_impl(PyObject *module, int ms) +/*[clinic end generated code: output=a40a1da2e39ea438 input=20cd3af2b6900f56]*/ { - int ms; - PyCursesInitialised; - if (!PyArg_ParseTuple(args, "i;ms", &ms)) return NULL; return Py_BuildValue("i", napms(ms)); } +/*[clinic input] +_curses.newpad + + nlines: int + Height. + ncols: int + Width. + / + +Create and return a pointer to a new pad data structure. +[clinic start generated code]*/ + static PyObject * -PyCurses_NewPad(PyObject *self, PyObject *args) +_curses_newpad_impl(PyObject *module, int nlines, int ncols) +/*[clinic end generated code: output=de52a56eb1098ec9 input=93f1272f240d8894]*/ { WINDOW *win; - int nlines, ncols; PyCursesInitialised; - if (!PyArg_ParseTuple(args,"ii;nlines,ncols",&nlines,&ncols)) return NULL; - win = newpad(nlines, ncols); if (win == NULL) { @@ -2726,29 +3474,36 @@ PyCurses_NewPad(PyObject *self, PyObject *args) return (PyObject *)PyCursesWindow_New(win, NULL); } +/*[clinic input] +_curses.newwin + + nlines: int + Height. + ncols: int + Width. + [ + begin_y: int = 0 + Top side y-coordinate. + begin_x: int = 0 + Left side x-coordinate. + ] + / + +Return a new window. + +By default, the window will extend from the specified position to the lower +right corner of the screen. +[clinic start generated code]*/ + static PyObject * -PyCurses_NewWindow(PyObject *self, PyObject *args) +_curses_newwin_impl(PyObject *module, int nlines, int ncols, + int group_right_1, int begin_y, int begin_x) +/*[clinic end generated code: output=c1e0a8dc8ac2826c input=29312c15a72a003d]*/ { WINDOW *win; - int nlines, ncols, begin_y=0, begin_x=0; PyCursesInitialised; - switch (PyTuple_Size(args)) { - case 2: - if (!PyArg_ParseTuple(args,"ii;nlines,ncols",&nlines,&ncols)) - return NULL; - break; - case 4: - if (!PyArg_ParseTuple(args, "iiii;nlines,ncols,begin_y,begin_x", - &nlines,&ncols,&begin_y,&begin_x)) - return NULL; - break; - default: - PyErr_SetString(PyExc_TypeError, "newwin requires 2 or 4 arguments"); - return NULL; - } - win = newwin(nlines,ncols,begin_y,begin_x); if (win == NULL) { PyErr_SetString(PyCursesError, catchall_NULL); @@ -2758,24 +3513,111 @@ PyCurses_NewWindow(PyObject *self, PyObject *args) return (PyObject *)PyCursesWindow_New(win, NULL); } +/*[clinic input] +_curses.nl + + flag: bool(accept={int}) = True + If false, the effect is the same as calling nonl(). + / + +Enter newline mode. + +This mode translates the return key into newline on input, and translates +newline into return and line-feed on output. Newline mode is initially on. +[clinic start generated code]*/ + static PyObject * -PyCurses_Pair_Content(PyObject *self, PyObject *args) -{ - short pair,f,b; +_curses_nl_impl(PyObject *module, int flag) +/*[clinic end generated code: output=b39cc0ffc9015003 input=cf36a63f7b86e28a]*/ +NoArgOrFlagNoReturnFunctionBody(nl, flag) - PyCursesInitialised; - PyCursesInitialisedColor; +/*[clinic input] +_curses.nocbreak - switch(PyTuple_Size(args)) { - case 1: - if (!PyArg_ParseTuple(args, "h;pair", &pair)) return NULL; - break; - default: - PyErr_SetString(PyExc_TypeError, "pair_content requires 1 argument"); - return NULL; - } +Leave cbreak mode. + +Return to normal "cooked" mode with line buffering. +[clinic start generated code]*/ + +static PyObject * +_curses_nocbreak_impl(PyObject *module) +/*[clinic end generated code: output=eabf3833a4fbf620 input=e4b65f7d734af400]*/ +NoArgNoReturnFunctionBody(nocbreak) + +/*[clinic input] +_curses.noecho + +Leave echo mode. + +Echoing of input characters is turned off. +[clinic start generated code]*/ + +static PyObject * +_curses_noecho_impl(PyObject *module) +/*[clinic end generated code: output=cc95ab45bc98f41b input=76714df529e614c3]*/ +NoArgNoReturnFunctionBody(noecho) + +/*[clinic input] +_curses.nonl + +Leave newline mode. + +Disable translation of return into newline on input, and disable low-level +translation of newline into newline/return on output. +[clinic start generated code]*/ + +static PyObject * +_curses_nonl_impl(PyObject *module) +/*[clinic end generated code: output=99e917e9715770c6 input=9d37dd122d3022fc]*/ +NoArgNoReturnFunctionBody(nonl) + +/*[clinic input] +_curses.noqiflush + +Disable queue flushing. + +When queue flushing is disabled, normal flush of input and output queues +associated with the INTR, QUIT and SUSP characters will not be done. +[clinic start generated code]*/ + +static PyObject * +_curses_noqiflush_impl(PyObject *module) +/*[clinic end generated code: output=8b95a4229bbf0877 input=ba3e6b2e3e54c4df]*/ +NoArgNoReturnVoidFunctionBody(noqiflush) + +/*[clinic input] +_curses.noraw + +Leave raw mode. + +Return to normal "cooked" mode with line buffering. +[clinic start generated code]*/ + +static PyObject * +_curses_noraw_impl(PyObject *module) +/*[clinic end generated code: output=39894e5524c430cc input=6ec86692096dffb5]*/ +NoArgNoReturnFunctionBody(noraw) + +/*[clinic input] +_curses.pair_content + + pair_number: short + The number of the color pair (1 - (COLOR_PAIRS-1)). + / + +Return a tuple (fg, bg) containing the colors for the requested color pair. +[clinic start generated code]*/ + +static PyObject * +_curses_pair_content_impl(PyObject *module, short pair_number) +/*[clinic end generated code: output=5a72aa1a28bbacf3 input=f4d7fec5643b976b]*/ +{ + short f, b; + + PyCursesInitialised; + PyCursesInitialisedColor; - if (pair_content(pair, &f, &b)==ERR) { + if (pair_content(pair_number, &f, &b)==ERR) { PyErr_SetString(PyCursesError, "Argument 1 was out of range. (1..COLOR_PAIRS-1)"); return NULL; @@ -2784,57 +3626,71 @@ PyCurses_Pair_Content(PyObject *self, PyObject *args) return Py_BuildValue("(ii)", f, b); } +/*[clinic input] +_curses.pair_number + + attr: int + / + +Return the number of the color-pair set by the specified attribute value. + +color_pair() is the counterpart to this function. +[clinic start generated code]*/ + static PyObject * -PyCurses_pair_number(PyObject *self, PyObject *args) +_curses_pair_number_impl(PyObject *module, int attr) +/*[clinic end generated code: output=85bce7d65c0aa3f4 input=d478548e33f5e61a]*/ { - int n; - PyCursesInitialised; PyCursesInitialisedColor; - switch(PyTuple_Size(args)) { - case 1: - if (!PyArg_ParseTuple(args, "i;pairvalue", &n)) return NULL; - break; - default: - PyErr_SetString(PyExc_TypeError, - "pair_number requires 1 argument"); - return NULL; - } - - return PyLong_FromLong((long) ((n & A_COLOR) >> 8)); + return PyLong_FromLong((long) ((attr & A_COLOR) >> 8)); } +/*[clinic input] +_curses.putp + + string: str(accept={robuffer}) + / + +Emit the value of a specified terminfo capability for the current terminal. + +Note that the output of putp() always goes to standard output. +[clinic start generated code]*/ + static PyObject * -PyCurses_Putp(PyObject *self, PyObject *args) +_curses_putp_impl(PyObject *module, const char *string) +/*[clinic end generated code: output=e98081d1b8eb5816 input=1601faa828b44cb3]*/ { - char *str; - - if (!PyArg_ParseTuple(args,"y;str", &str)) - return NULL; - return PyCursesCheckERR(putp(str), "putp"); + return PyCursesCheckERR(putp(string), "putp"); } +/*[clinic input] +_curses.qiflush + + flag: bool(accept={int}) = True + If false, the effect is the same as calling noqiflush(). + / + +Enable queue flushing. + +If queue flushing is enabled, all output in the display driver queue +will be flushed when the INTR, QUIT and SUSP characters are read. +[clinic start generated code]*/ + static PyObject * -PyCurses_QiFlush(PyObject *self, PyObject *args) +_curses_qiflush_impl(PyObject *module, int flag) +/*[clinic end generated code: output=9167e862f760ea30 input=e9e4a389946a0dbc]*/ { - int flag = 0; - PyCursesInitialised; - switch(PyTuple_Size(args)) { - case 0: + if (flag) { qiflush(); - Py_RETURN_NONE; - case 1: - if (!PyArg_ParseTuple(args, "i;True(1) or False(0)", &flag)) return NULL; - if (flag) qiflush(); - else noqiflush(); - Py_RETURN_NONE; - default: - PyErr_SetString(PyExc_TypeError, "qiflush requires 0 or 1 arguments"); - return NULL; } + else { + noqiflush(); + } + Py_RETURN_NONE; } /* Internal helper used for updating curses.LINES, curses.COLS, _curses.LINES @@ -2888,28 +3744,97 @@ update_lines_cols(void) return 1; } -static PyObject * -PyCurses_update_lines_cols(PyObject *self) +/*[clinic input] +_curses.update_lines_cols -> int + +[clinic start generated code]*/ + +static int +_curses_update_lines_cols_impl(PyObject *module) +/*[clinic end generated code: output=0345e7f072ea711a input=3a87760f7d5197f0]*/ { - return PyLong_FromLong((long) update_lines_cols()); + return update_lines_cols(); } #endif +/*[clinic input] +_curses.raw + + flag: bool(accept={int}) = True + If false, the effect is the same as calling noraw(). + / + +Enter raw mode. + +In raw mode, normal line buffering and processing of interrupt, quit, +suspend, and flow control keys are turned off; characters are presented to +curses input functions one by one. +[clinic start generated code]*/ + +static PyObject * +_curses_raw_impl(PyObject *module, int flag) +/*[clinic end generated code: output=a750e4b342be015b input=e36d8db27832b848]*/ +NoArgOrFlagNoReturnFunctionBody(raw, flag) + +/*[clinic input] +_curses.reset_prog_mode + +Restore the terminal to "program" mode, as previously saved by def_prog_mode(). +[clinic start generated code]*/ + +static PyObject * +_curses_reset_prog_mode_impl(PyObject *module) +/*[clinic end generated code: output=15eb765abf0b6575 input=3d82bea2b3243471]*/ +NoArgNoReturnFunctionBody(reset_prog_mode) + +/*[clinic input] +_curses.reset_shell_mode + +Restore the terminal to "shell" mode, as previously saved by def_shell_mode(). +[clinic start generated code]*/ + +static PyObject * +_curses_reset_shell_mode_impl(PyObject *module) +/*[clinic end generated code: output=0238de2962090d33 input=1c738fa64bd1a24f]*/ +NoArgNoReturnFunctionBody(reset_shell_mode) + +/*[clinic input] +_curses.resetty + +Restore terminal mode. +[clinic start generated code]*/ + +static PyObject * +_curses_resetty_impl(PyObject *module) +/*[clinic end generated code: output=ff4b448e80a7cd63 input=940493de03624bb0]*/ +NoArgNoReturnFunctionBody(resetty) + #ifdef HAVE_CURSES_RESIZETERM +/*[clinic input] +_curses.resizeterm + + nlines: int + Height. + ncols: int + Width. + / + +Resize the standard and current windows to the specified dimensions. + +Adjusts other bookkeeping data used by the curses library that record the +window dimensions (in particular the SIGWINCH handler). +[clinic start generated code]*/ + static PyObject * -PyCurses_ResizeTerm(PyObject *self, PyObject *args) +_curses_resizeterm_impl(PyObject *module, int nlines, int ncols) +/*[clinic end generated code: output=56d6bcc5194ad055 input=0fca02ebad5ffa82]*/ { - int lines; - int columns; PyObject *result; PyCursesInitialised; - if (!PyArg_ParseTuple(args,"ii:resizeterm", &lines, &columns)) - return NULL; - - result = PyCursesCheckERR(resizeterm(lines, columns), "resizeterm"); + result = PyCursesCheckERR(resizeterm(nlines, ncols), "resizeterm"); if (!result) return NULL; if (!update_lines_cols()) @@ -2920,20 +3845,33 @@ PyCurses_ResizeTerm(PyObject *self, PyObject *args) #endif #ifdef HAVE_CURSES_RESIZE_TERM +/*[clinic input] +_curses.resize_term + + nlines: int + Height. + ncols: int + Width. + / + +Backend function used by resizeterm(), performing most of the work. + +When resizing the windows, resize_term() blank-fills the areas that are +extended. The calling application should fill in these areas with appropriate +data. The resize_term() function attempts to resize all windows. However, +due to the calling convention of pads, it is not possible to resize these +without additional interaction with the application. +[clinic start generated code]*/ + static PyObject * -PyCurses_Resize_Term(PyObject *self, PyObject *args) +_curses_resize_term_impl(PyObject *module, int nlines, int ncols) +/*[clinic end generated code: output=9e26d8b9ea311ed2 input=2197edd05b049ed4]*/ { - int lines; - int columns; - PyObject *result; PyCursesInitialised; - if (!PyArg_ParseTuple(args,"ii:resize_term", &lines, &columns)) - return NULL; - - result = PyCursesCheckERR(resize_term(lines, columns), "resize_term"); + result = PyCursesCheckERR(resize_term(nlines, ncols), "resize_term"); if (!result) return NULL; if (!update_lines_cols()) @@ -2942,20 +3880,37 @@ PyCurses_Resize_Term(PyObject *self, PyObject *args) } #endif /* HAVE_CURSES_RESIZE_TERM */ -#ifdef getsyx +/*[clinic input] +_curses.savetty + +Save terminal mode. +[clinic start generated code]*/ + static PyObject * -PyCurses_setsyx(PyObject *self, PyObject *args) -{ - int y,x; +_curses_savetty_impl(PyObject *module) +/*[clinic end generated code: output=6babc49f12b42199 input=fce6b2b7d2200102]*/ +NoArgNoReturnFunctionBody(savetty) - PyCursesInitialised; +#ifdef getsyx +/*[clinic input] +_curses.setsyx - if (PyTuple_Size(args)!=2) { - PyErr_SetString(PyExc_TypeError, "setsyx requires 2 arguments"); - return NULL; - } + y: int + Y-coordinate. + x: int + X-coordinate. + / + +Set the virtual screen cursor. + +If y and x are both -1, then leaveok is set. +[clinic start generated code]*/ - if (!PyArg_ParseTuple(args, "ii;y, x", &y, &x)) return NULL; +static PyObject * +_curses_setsyx_impl(PyObject *module, int y, int x) +/*[clinic end generated code: output=23dcf753511a2464 input=fa7f2b208e10a557]*/ +{ + PyCursesInitialised; setsyx(y,x); @@ -2963,8 +3918,22 @@ PyCurses_setsyx(PyObject *self, PyObject *args) } #endif +/*[clinic input] +_curses.start_color + +Initializes eight basic colors and global variables COLORS and COLOR_PAIRS. + +Must be called if the programmer wants to use colors, and before any other +color manipulation routine is called. It is good practice to call this +routine right after initscr(). + +It also restores the colors on the terminal to the values they had when the +terminal was just turned on. +[clinic start generated code]*/ + static PyObject * -PyCurses_Start_Color(PyObject *self) +_curses_start_color_impl(PyObject *module) +/*[clinic end generated code: output=8b772b41d8090ede input=0ca0ecb2b77e1a12]*/ { int code; PyObject *c, *cp; @@ -2991,65 +3960,127 @@ PyCurses_Start_Color(PyObject *self) } } +/*[clinic input] +_curses.termattrs + +Return a logical OR of all video attributes supported by the terminal. +[clinic start generated code]*/ + static PyObject * -PyCurses_tigetflag(PyObject *self, PyObject *args) -{ - char *capname; +_curses_termattrs_impl(PyObject *module) +/*[clinic end generated code: output=b06f437fce1b6fc4 input=0559882a04f84d1d]*/ +NoArgReturnIntFunctionBody(termattrs) - PyCursesSetupTermCalled; +/*[clinic input] +_curses.termname - if (!PyArg_ParseTuple(args, "s", &capname)) - return NULL; +Return the value of the environment variable TERM, truncated to 14 characters. +[clinic start generated code]*/ - return PyLong_FromLong( (long) tigetflag( capname ) ); -} +static PyObject * +_curses_termname_impl(PyObject *module) +/*[clinic end generated code: output=96375577ebbd67fd input=33c08d000944f33f]*/ +NoArgReturnStringFunctionBody(termname) + +/*[clinic input] +_curses.tigetflag + + capname: str + The terminfo capability name. + / + +Return the value of the Boolean capability. + +The value -1 is returned if capname is not a Boolean capability, or 0 if +it is canceled or absent from the terminal description. +[clinic start generated code]*/ static PyObject * -PyCurses_tigetnum(PyObject *self, PyObject *args) +_curses_tigetflag_impl(PyObject *module, const char *capname) +/*[clinic end generated code: output=8853c0e55542195b input=b0787af9e3e9a6ce]*/ { - char *capname; - PyCursesSetupTermCalled; - if (!PyArg_ParseTuple(args, "s", &capname)) - return NULL; - - return PyLong_FromLong( (long) tigetnum( capname ) ); + return PyLong_FromLong( (long) tigetflag( (char *)capname ) ); } +/*[clinic input] +_curses.tigetnum + + capname: str + The terminfo capability name. + / + +Return the value of the numeric capability. + +The value -2 is returned if capname is not a numeric capability, or -1 if +it is canceled or absent from the terminal description. +[clinic start generated code]*/ + static PyObject * -PyCurses_tigetstr(PyObject *self, PyObject *args) +_curses_tigetnum_impl(PyObject *module, const char *capname) +/*[clinic end generated code: output=46f8b0a1b5dff42f input=5cdf2f410b109720]*/ { - char *capname; - PyCursesSetupTermCalled; - if (!PyArg_ParseTuple(args, "s", &capname)) - return NULL; + return PyLong_FromLong( (long) tigetnum( (char *)capname ) ); +} + +/*[clinic input] +_curses.tigetstr + + capname: str + The terminfo capability name. + / + +Return the value of the string capability. + +None is returned if capname is not a string capability, or is canceled or +absent from the terminal description. +[clinic start generated code]*/ - capname = tigetstr( capname ); +static PyObject * +_curses_tigetstr_impl(PyObject *module, const char *capname) +/*[clinic end generated code: output=f22b576ad60248f3 input=36644df25c73c0a7]*/ +{ + PyCursesSetupTermCalled; + + capname = tigetstr( (char *)capname ); if (capname == NULL || capname == (char*) -1) { Py_RETURN_NONE; } return PyBytes_FromString( capname ); } +/*[clinic input] +_curses.tparm + + str: str(accept={robuffer}) + Parameterized byte string obtained from the terminfo database. + i1: int = 0 + i2: int = 0 + i3: int = 0 + i4: int = 0 + i5: int = 0 + i6: int = 0 + i7: int = 0 + i8: int = 0 + i9: int = 0 + / + +Instantiate the specified byte string with the supplied parameters. +[clinic start generated code]*/ + static PyObject * -PyCurses_tparm(PyObject *self, PyObject *args) +_curses_tparm_impl(PyObject *module, const char *str, int i1, int i2, int i3, + int i4, int i5, int i6, int i7, int i8, int i9) +/*[clinic end generated code: output=599f62b615c667ff input=5e30b15786f032aa]*/ { - char* fmt; char* result = NULL; - int i1=0,i2=0,i3=0,i4=0,i5=0,i6=0,i7=0,i8=0,i9=0; PyCursesSetupTermCalled; - if (!PyArg_ParseTuple(args, "y|iiiiiiiii:tparm", - &fmt, &i1, &i2, &i3, &i4, - &i5, &i6, &i7, &i8, &i9)) { - return NULL; - } - - result = tparm(fmt,i1,i2,i3,i4,i5,i6,i7,i8,i9); + result = tparm((char *)str,i1,i2,i3,i4,i5,i6,i7,i8,i9); if (!result) { PyErr_SetString(PyCursesError, "tparm() returned NULL"); return NULL; @@ -3059,50 +4090,75 @@ PyCurses_tparm(PyObject *self, PyObject *args) } #ifdef HAVE_CURSES_TYPEAHEAD +/*[clinic input] +_curses.typeahead + + fd: int + File descriptor. + / + +Specify that the file descriptor fd be used for typeahead checking. + +If fd is -1, then no typeahead checking is done. +[clinic start generated code]*/ + static PyObject * -PyCurses_TypeAhead(PyObject *self, PyObject *args) +_curses_typeahead_impl(PyObject *module, int fd) +/*[clinic end generated code: output=084bb649d7066583 input=f2968d8e1805051b]*/ { - int fd; - PyCursesInitialised; - if (!PyArg_ParseTuple(args,"i;fd",&fd)) return NULL; - return PyCursesCheckERR(typeahead( fd ), "typeahead"); } #endif +/*[clinic input] +_curses.unctrl + + ch: object + / + +Return a string which is a printable representation of the character ch. + +Control characters are displayed as a caret followed by the character, +for example as ^C. Printing characters are left as they are. +[clinic start generated code]*/ + static PyObject * -PyCurses_UnCtrl(PyObject *self, PyObject *args) +_curses_unctrl(PyObject *module, PyObject *ch) +/*[clinic end generated code: output=8e07fafc430c9434 input=cd1e35e16cd1ace4]*/ { - PyObject *temp; - chtype ch; + chtype ch_; PyCursesInitialised; - if (!PyArg_ParseTuple(args,"O;ch or int",&temp)) return NULL; - - if (!PyCurses_ConvertToChtype(NULL, temp, &ch)) + if (!PyCurses_ConvertToChtype(NULL, ch, &ch_)) return NULL; - return PyBytes_FromString(unctrl(ch)); + return PyBytes_FromString(unctrl(ch_)); } +/*[clinic input] +_curses.ungetch + + ch: object + / + +Push ch so the next getch() will return it. +[clinic start generated code]*/ + static PyObject * -PyCurses_UngetCh(PyObject *self, PyObject *args) +_curses_ungetch(PyObject *module, PyObject *ch) +/*[clinic end generated code: output=9b19d8268376d887 input=6681e6ae4c42e5eb]*/ { - PyObject *temp; - chtype ch; + chtype ch_; PyCursesInitialised; - if (!PyArg_ParseTuple(args,"O;ch or int",&temp)) - return NULL; - - if (!PyCurses_ConvertToChtype(NULL, temp, &ch)) + if (!PyCurses_ConvertToChtype(NULL, ch, &ch_)) return NULL; - return PyCursesCheckERR(ungetch(ch), "ungetch"); + return PyCursesCheckERR(ungetch(ch_), "ungetch"); } #ifdef HAVE_NCURSESW @@ -3153,46 +4209,70 @@ PyCurses_ConvertToWchar_t(PyObject *obj, } } +/*[clinic input] +_curses.unget_wch + + ch: object + / + +Push ch so the next get_wch() will return it. +[clinic start generated code]*/ + static PyObject * -PyCurses_Unget_Wch(PyObject *self, PyObject *args) +_curses_unget_wch(PyObject *module, PyObject *ch) +/*[clinic end generated code: output=1974c9fb01d37863 input=0d56dc65a46feebb]*/ { - PyObject *obj; wchar_t wch; PyCursesInitialised; - if (!PyArg_ParseTuple(args,"O", &obj)) - return NULL; - - if (!PyCurses_ConvertToWchar_t(obj, &wch)) + if (!PyCurses_ConvertToWchar_t(ch, &wch)) return NULL; return PyCursesCheckERR(unget_wch(wch), "unget_wch"); } #endif -#ifdef HAVE_CURSES_TYPEAHEAD +#ifdef HAVE_CURSES_USE_ENV +/*[clinic input] +_curses.use_env + + flag: bool(accept={int}) + / + +Use environment variables LINES and COLUMNS. + +If used, this function should be called before initscr() or newterm() are +called. + +When flag is False, the values of lines and columns specified in the terminfo +database will be used, even if environment variables LINES and COLUMNS (used +by default) are set, or if curses is running in a window (in which case +default behavior would be to use the window size if LINES and COLUMNS are +not set). +[clinic start generated code]*/ + static PyObject * -PyCurses_Use_Env(PyObject *self, PyObject *args) +_curses_use_env_impl(PyObject *module, int flag) +/*[clinic end generated code: output=b2c445e435c0b164 input=1778eb1e9151ea37]*/ { - int flag; - - switch(PyTuple_Size(args)) { - case 1: - if (!PyArg_ParseTuple(args,"i;True(1), False(0)",&flag)) - return NULL; - break; - default: - PyErr_SetString(PyExc_TypeError, "use_env requires 1 argument"); - return NULL; - } use_env(flag); Py_RETURN_NONE; } #endif #ifndef STRICT_SYSV_CURSES +/*[clinic input] +_curses.use_default_colors + +Allow use of default values for colors on terminals supporting this feature. + +Use this to support transparency in your application. The default color +is assigned to the color number -1. +[clinic start generated code]*/ + static PyObject * -PyCurses_Use_Default_Colors(PyObject *self) +_curses_use_default_colors_impl(PyObject *module) +/*[clinic end generated code: output=a3b81ff71dd901be input=656844367470e8fc]*/ { int code; @@ -3212,109 +4292,80 @@ PyCurses_Use_Default_Colors(PyObject *self) /* List of functions defined in the module */ static PyMethodDef PyCurses_methods[] = { - {"baudrate", (PyCFunction)PyCurses_baudrate, METH_NOARGS}, - {"beep", (PyCFunction)PyCurses_beep, METH_NOARGS}, - {"can_change_color", (PyCFunction)PyCurses_can_change_color, METH_NOARGS}, - {"cbreak", (PyCFunction)PyCurses_cbreak, METH_VARARGS}, - {"color_content", (PyCFunction)PyCurses_Color_Content, METH_VARARGS}, - {"color_pair", (PyCFunction)PyCurses_color_pair, METH_VARARGS}, - {"curs_set", (PyCFunction)PyCurses_Curs_Set, METH_VARARGS}, - {"def_prog_mode", (PyCFunction)PyCurses_def_prog_mode, METH_NOARGS}, - {"def_shell_mode", (PyCFunction)PyCurses_def_shell_mode, METH_NOARGS}, - {"delay_output", (PyCFunction)PyCurses_Delay_Output, METH_VARARGS}, - {"doupdate", (PyCFunction)PyCurses_doupdate, METH_NOARGS}, - {"echo", (PyCFunction)PyCurses_echo, METH_VARARGS}, - {"endwin", (PyCFunction)PyCurses_endwin, METH_NOARGS}, - {"erasechar", (PyCFunction)PyCurses_EraseChar, METH_NOARGS}, -#ifdef HAVE_CURSES_FILTER - {"filter", (PyCFunction)PyCurses_filter, METH_NOARGS}, -#endif - {"flash", (PyCFunction)PyCurses_flash, METH_NOARGS}, - {"flushinp", (PyCFunction)PyCurses_flushinp, METH_NOARGS}, -#ifdef NCURSES_MOUSE_VERSION - {"getmouse", (PyCFunction)PyCurses_GetMouse, METH_NOARGS}, - {"ungetmouse", (PyCFunction)PyCurses_UngetMouse, METH_VARARGS}, -#endif -#ifdef getsyx - {"getsyx", (PyCFunction)PyCurses_getsyx, METH_NOARGS}, -#endif - {"getwin", (PyCFunction)PyCurses_GetWin, METH_O}, - {"has_colors", (PyCFunction)PyCurses_has_colors, METH_NOARGS}, - {"has_ic", (PyCFunction)PyCurses_has_ic, METH_NOARGS}, - {"has_il", (PyCFunction)PyCurses_has_il, METH_NOARGS}, -#ifdef HAVE_CURSES_HAS_KEY - {"has_key", (PyCFunction)PyCurses_has_key, METH_VARARGS}, -#endif - {"halfdelay", (PyCFunction)PyCurses_HalfDelay, METH_VARARGS}, - {"init_color", (PyCFunction)PyCurses_Init_Color, METH_VARARGS}, - {"init_pair", (PyCFunction)PyCurses_Init_Pair, METH_VARARGS}, - {"initscr", (PyCFunction)PyCurses_InitScr, METH_NOARGS}, - {"intrflush", (PyCFunction)PyCurses_IntrFlush, METH_VARARGS}, - {"isendwin", (PyCFunction)PyCurses_isendwin, METH_NOARGS}, -#ifdef HAVE_CURSES_IS_TERM_RESIZED - {"is_term_resized", (PyCFunction)PyCurses_Is_Term_Resized, METH_VARARGS}, -#endif - {"keyname", (PyCFunction)PyCurses_KeyName, METH_VARARGS}, - {"killchar", (PyCFunction)PyCurses_KillChar, METH_NOARGS}, - {"longname", (PyCFunction)PyCurses_longname, METH_NOARGS}, - {"meta", (PyCFunction)PyCurses_Meta, METH_VARARGS}, -#ifdef NCURSES_MOUSE_VERSION - {"mouseinterval", (PyCFunction)PyCurses_MouseInterval, METH_VARARGS}, - {"mousemask", (PyCFunction)PyCurses_MouseMask, METH_VARARGS}, -#endif - {"napms", (PyCFunction)PyCurses_Napms, METH_VARARGS}, - {"newpad", (PyCFunction)PyCurses_NewPad, METH_VARARGS}, - {"newwin", (PyCFunction)PyCurses_NewWindow, METH_VARARGS}, - {"nl", (PyCFunction)PyCurses_nl, METH_VARARGS}, - {"nocbreak", (PyCFunction)PyCurses_nocbreak, METH_NOARGS}, - {"noecho", (PyCFunction)PyCurses_noecho, METH_NOARGS}, - {"nonl", (PyCFunction)PyCurses_nonl, METH_NOARGS}, - {"noqiflush", (PyCFunction)PyCurses_noqiflush, METH_NOARGS}, - {"noraw", (PyCFunction)PyCurses_noraw, METH_NOARGS}, - {"pair_content", (PyCFunction)PyCurses_Pair_Content, METH_VARARGS}, - {"pair_number", (PyCFunction)PyCurses_pair_number, METH_VARARGS}, - {"putp", (PyCFunction)PyCurses_Putp, METH_VARARGS}, - {"qiflush", (PyCFunction)PyCurses_QiFlush, METH_VARARGS}, - {"raw", (PyCFunction)PyCurses_raw, METH_VARARGS}, - {"reset_prog_mode", (PyCFunction)PyCurses_reset_prog_mode, METH_NOARGS}, - {"reset_shell_mode", (PyCFunction)PyCurses_reset_shell_mode, METH_NOARGS}, - {"resetty", (PyCFunction)PyCurses_resetty, METH_NOARGS}, -#ifdef HAVE_CURSES_RESIZETERM - {"resizeterm", (PyCFunction)PyCurses_ResizeTerm, METH_VARARGS}, -#endif -#ifdef HAVE_CURSES_RESIZE_TERM - {"resize_term", (PyCFunction)PyCurses_Resize_Term, METH_VARARGS}, -#endif - {"savetty", (PyCFunction)PyCurses_savetty, METH_NOARGS}, -#ifdef getsyx - {"setsyx", (PyCFunction)PyCurses_setsyx, METH_VARARGS}, -#endif - {"setupterm", (PyCFunction)PyCurses_setupterm, - METH_VARARGS|METH_KEYWORDS}, - {"start_color", (PyCFunction)PyCurses_Start_Color, METH_NOARGS}, - {"termattrs", (PyCFunction)PyCurses_termattrs, METH_NOARGS}, - {"termname", (PyCFunction)PyCurses_termname, METH_NOARGS}, - {"tigetflag", (PyCFunction)PyCurses_tigetflag, METH_VARARGS}, - {"tigetnum", (PyCFunction)PyCurses_tigetnum, METH_VARARGS}, - {"tigetstr", (PyCFunction)PyCurses_tigetstr, METH_VARARGS}, - {"tparm", (PyCFunction)PyCurses_tparm, METH_VARARGS}, -#ifdef HAVE_CURSES_TYPEAHEAD - {"typeahead", (PyCFunction)PyCurses_TypeAhead, METH_VARARGS}, -#endif - {"unctrl", (PyCFunction)PyCurses_UnCtrl, METH_VARARGS}, - {"ungetch", (PyCFunction)PyCurses_UngetCh, METH_VARARGS}, -#if defined(HAVE_CURSES_RESIZETERM) || defined(HAVE_CURSES_RESIZE_TERM) - {"update_lines_cols", (PyCFunction)PyCurses_update_lines_cols, METH_NOARGS}, -#endif -#ifdef HAVE_NCURSESW - {"unget_wch", (PyCFunction)PyCurses_Unget_Wch, METH_VARARGS}, -#endif -#ifdef HAVE_CURSES_USE_ENV - {"use_env", (PyCFunction)PyCurses_Use_Env, METH_VARARGS}, -#endif -#ifndef STRICT_SYSV_CURSES - {"use_default_colors", (PyCFunction)PyCurses_Use_Default_Colors, METH_NOARGS}, -#endif + _CURSES_BAUDRATE_METHODDEF + _CURSES_BEEP_METHODDEF + _CURSES_CAN_CHANGE_COLOR_METHODDEF + _CURSES_CBREAK_METHODDEF + _CURSES_COLOR_CONTENT_METHODDEF + _CURSES_COLOR_PAIR_METHODDEF + _CURSES_CURS_SET_METHODDEF + _CURSES_DEF_PROG_MODE_METHODDEF + _CURSES_DEF_SHELL_MODE_METHODDEF + _CURSES_DELAY_OUTPUT_METHODDEF + _CURSES_DOUPDATE_METHODDEF + _CURSES_ECHO_METHODDEF + _CURSES_ENDWIN_METHODDEF + _CURSES_ERASECHAR_METHODDEF + _CURSES_FILTER_METHODDEF + _CURSES_FLASH_METHODDEF + _CURSES_FLUSHINP_METHODDEF + _CURSES_GETMOUSE_METHODDEF + _CURSES_UNGETMOUSE_METHODDEF + _CURSES_GETSYX_METHODDEF + _CURSES_GETWIN_METHODDEF + _CURSES_HAS_COLORS_METHODDEF + _CURSES_HAS_IC_METHODDEF + _CURSES_HAS_IL_METHODDEF + _CURSES_HAS_KEY_METHODDEF + _CURSES_HALFDELAY_METHODDEF + _CURSES_INIT_COLOR_METHODDEF + _CURSES_INIT_PAIR_METHODDEF + _CURSES_INITSCR_METHODDEF + _CURSES_INTRFLUSH_METHODDEF + _CURSES_ISENDWIN_METHODDEF + _CURSES_IS_TERM_RESIZED_METHODDEF + _CURSES_KEYNAME_METHODDEF + _CURSES_KILLCHAR_METHODDEF + _CURSES_LONGNAME_METHODDEF + _CURSES_META_METHODDEF + _CURSES_MOUSEINTERVAL_METHODDEF + _CURSES_MOUSEMASK_METHODDEF + _CURSES_NAPMS_METHODDEF + _CURSES_NEWPAD_METHODDEF + _CURSES_NEWWIN_METHODDEF + _CURSES_NL_METHODDEF + _CURSES_NOCBREAK_METHODDEF + _CURSES_NOECHO_METHODDEF + _CURSES_NONL_METHODDEF + _CURSES_NOQIFLUSH_METHODDEF + _CURSES_NORAW_METHODDEF + _CURSES_PAIR_CONTENT_METHODDEF + _CURSES_PAIR_NUMBER_METHODDEF + _CURSES_PUTP_METHODDEF + _CURSES_QIFLUSH_METHODDEF + _CURSES_RAW_METHODDEF + _CURSES_RESET_PROG_MODE_METHODDEF + _CURSES_RESET_SHELL_MODE_METHODDEF + _CURSES_RESETTY_METHODDEF + _CURSES_RESIZETERM_METHODDEF + _CURSES_RESIZE_TERM_METHODDEF + _CURSES_SAVETTY_METHODDEF + _CURSES_SETSYX_METHODDEF + _CURSES_SETUPTERM_METHODDEF + _CURSES_START_COLOR_METHODDEF + _CURSES_TERMATTRS_METHODDEF + _CURSES_TERMNAME_METHODDEF + _CURSES_TIGETFLAG_METHODDEF + _CURSES_TIGETNUM_METHODDEF + _CURSES_TIGETSTR_METHODDEF + _CURSES_TPARM_METHODDEF + _CURSES_TYPEAHEAD_METHODDEF + _CURSES_UNCTRL_METHODDEF + _CURSES_UNGETCH_METHODDEF + _CURSES_UPDATE_LINES_COLS_METHODDEF + _CURSES_UNGET_WCH_METHODDEF + _CURSES_USE_ENV_METHODDEF + _CURSES_USE_DEFAULT_COLORS_METHODDEF {NULL, NULL} /* sentinel */ }; @@ -3496,5 +4547,8 @@ PyInit__curses(void) SetDictInt("KEY_MIN", KEY_MIN); SetDictInt("KEY_MAX", KEY_MAX); } + + Py_INCREF(&PyCursesWindow_Type); + PyModule_AddObject(m, "window", (PyObject *)&PyCursesWindow_Type); return m; } diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index 0a3856caa88d74..31aa88d4a26a86 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -2590,7 +2590,7 @@ delta_getstate(PyDateTime_Delta *self) } static PyObject * -delta_total_seconds(PyObject *self) +delta_total_seconds(PyObject *self, PyObject *Py_UNUSED(ignored)) { PyObject *total_seconds; PyObject *total_microseconds; @@ -2606,7 +2606,7 @@ delta_total_seconds(PyObject *self) } static PyObject * -delta_reduce(PyDateTime_Delta* self) +delta_reduce(PyDateTime_Delta* self, PyObject *Py_UNUSED(ignored)) { return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self)); } @@ -2627,7 +2627,7 @@ static PyMemberDef delta_members[] = { }; static PyMethodDef delta_methods[] = { - {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS, + {"total_seconds", delta_total_seconds, METH_NOARGS, PyDoc_STR("Total seconds in the duration.")}, {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS, @@ -2991,7 +2991,7 @@ date_repr(PyDateTime_Date *self) } static PyObject * -date_isoformat(PyDateTime_Date *self) +date_isoformat(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored)) { return PyUnicode_FromFormat("%04d-%02d-%02d", GET_YEAR(self), GET_MONTH(self), GET_DAY(self)); @@ -3006,7 +3006,7 @@ date_str(PyDateTime_Date *self) static PyObject * -date_ctime(PyDateTime_Date *self) +date_ctime(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored)) { return format_ctime(self, 0, 0, 0); } @@ -3055,7 +3055,7 @@ date_format(PyDateTime_Date *self, PyObject *args) /* ISO methods. */ static PyObject * -date_isoweekday(PyDateTime_Date *self) +date_isoweekday(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored)) { int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self)); @@ -3063,7 +3063,7 @@ date_isoweekday(PyDateTime_Date *self) } static PyObject * -date_isocalendar(PyDateTime_Date *self) +date_isocalendar(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored)) { int year = GET_YEAR(self); int week1_monday = iso_week1_monday(year); @@ -3100,7 +3100,7 @@ date_richcompare(PyObject *self, PyObject *other, int op) } static PyObject * -date_timetuple(PyDateTime_Date *self) +date_timetuple(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored)) { return build_struct_time(GET_YEAR(self), GET_MONTH(self), @@ -3149,14 +3149,14 @@ date_hash(PyDateTime_Date *self) } static PyObject * -date_toordinal(PyDateTime_Date *self) +date_toordinal(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored)) { return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self), GET_DAY(self))); } static PyObject * -date_weekday(PyDateTime_Date *self) +date_weekday(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored)) { int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self)); @@ -3435,7 +3435,7 @@ tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt) */ static PyObject * -tzinfo_reduce(PyObject *self) +tzinfo_reduce(PyObject *self, PyObject *Py_UNUSED(ignored)) { PyObject *args, *state; PyObject *getinitargs, *getstate; @@ -3502,7 +3502,7 @@ static PyMethodDef tzinfo_methods[] = { {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O, PyDoc_STR("datetime in UTC -> datetime in local time.")}, - {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS, + {"__reduce__", tzinfo_reduce, METH_NOARGS, PyDoc_STR("-> (cls, state)")}, {NULL, NULL} @@ -3720,7 +3720,7 @@ timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt) } static PyObject * -timezone_getinitargs(PyDateTime_TimeZone *self) +timezone_getinitargs(PyDateTime_TimeZone *self, PyObject *Py_UNUSED(ignored)) { if (self->name == NULL) return Py_BuildValue("(O)", self->offset); @@ -5173,7 +5173,7 @@ datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw) } static PyObject * -datetime_ctime(PyDateTime_DateTime *self) +datetime_ctime(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored)) { return format_ctime((PyDateTime_Date *)self, DATE_GET_HOUR(self), @@ -5663,7 +5663,7 @@ datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw) } static PyObject * -datetime_timetuple(PyDateTime_DateTime *self) +datetime_timetuple(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored)) { int dstflag = -1; @@ -5738,7 +5738,7 @@ local_to_seconds(int year, int month, int day, #define EPOCH_SECONDS (719163LL * 24 * 60 * 60) static PyObject * -datetime_timestamp(PyDateTime_DateTime *self) +datetime_timestamp(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored)) { PyObject *result; @@ -5747,7 +5747,7 @@ datetime_timestamp(PyDateTime_DateTime *self) delta = datetime_subtract((PyObject *)self, PyDateTime_Epoch); if (delta == NULL) return NULL; - result = delta_total_seconds(delta); + result = delta_total_seconds(delta, NULL); Py_DECREF(delta); } else { @@ -5768,7 +5768,7 @@ datetime_timestamp(PyDateTime_DateTime *self) } static PyObject * -datetime_getdate(PyDateTime_DateTime *self) +datetime_getdate(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored)) { return new_date(GET_YEAR(self), GET_MONTH(self), @@ -5776,7 +5776,7 @@ datetime_getdate(PyDateTime_DateTime *self) } static PyObject * -datetime_gettime(PyDateTime_DateTime *self) +datetime_gettime(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored)) { return new_time(DATE_GET_HOUR(self), DATE_GET_MINUTE(self), @@ -5787,7 +5787,7 @@ datetime_gettime(PyDateTime_DateTime *self) } static PyObject * -datetime_gettimetz(PyDateTime_DateTime *self) +datetime_gettimetz(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored)) { return new_time(DATE_GET_HOUR(self), DATE_GET_MINUTE(self), @@ -5798,7 +5798,7 @@ datetime_gettimetz(PyDateTime_DateTime *self) } static PyObject * -datetime_utctimetuple(PyDateTime_DateTime *self) +datetime_utctimetuple(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored)) { int y, m, d, hh, mm, ss; PyObject *tzinfo; diff --git a/Modules/_gdbmmodule.c b/Modules/_gdbmmodule.c index 9996d8c26fb7d1..10560040e446b3 100644 --- a/Modules/_gdbmmodule.c +++ b/Modules/_gdbmmodule.c @@ -654,20 +654,46 @@ static struct PyModuleDef _gdbmmodule = { PyMODINIT_FUNC PyInit__gdbm(void) { - PyObject *m, *d, *s; + PyObject *m; if (PyType_Ready(&Dbmtype) < 0) return NULL; m = PyModule_Create(&_gdbmmodule); - if (m == NULL) + if (m == NULL) { return NULL; - d = PyModule_GetDict(m); + } + DbmError = PyErr_NewException("_gdbm.error", PyExc_OSError, NULL); - if (DbmError != NULL) { - PyDict_SetItemString(d, "error", DbmError); - s = PyUnicode_FromString(dbmmodule_open_flags); - PyDict_SetItemString(d, "open_flags", s); - Py_DECREF(s); + if (DbmError == NULL) { + goto error; + } + Py_INCREF(DbmError); + if (PyModule_AddObject(m, "error", DbmError) < 0) { + Py_DECREF(DbmError); + goto error; } + + if (PyModule_AddStringConstant(m, "open_flags", + dbmmodule_open_flags) < 0) { + goto error; + } + +#if defined(GDBM_VERSION_MAJOR) && defined(GDBM_VERSION_MINOR) && \ + defined(GDBM_VERSION_PATCH) + PyObject *obj = Py_BuildValue("iii", GDBM_VERSION_MAJOR, + GDBM_VERSION_MINOR, GDBM_VERSION_PATCH); + if (obj == NULL) { + goto error; + } + if (PyModule_AddObject(m, "_GDBM_VERSION", obj) < 0) { + Py_DECREF(obj); + goto error; + } +#endif + return m; + +error: + Py_DECREF(m); + return NULL; } diff --git a/Modules/_io/bytesio.c b/Modules/_io/bytesio.c index ba33f8c50d6aad..a50add2389e561 100644 --- a/Modules/_io/bytesio.c +++ b/Modules/_io/bytesio.c @@ -758,7 +758,7 @@ _io_BytesIO_close_impl(bytesio *self) */ static PyObject * -bytesio_getstate(bytesio *self) +bytesio_getstate(bytesio *self, PyObject *Py_UNUSED(ignored)) { PyObject *initvalue = _io_BytesIO_getvalue_impl(self); PyObject *dict; diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c index 0d5bf3b22114e5..c0e43e0ae41a8f 100644 --- a/Modules/_io/fileio.c +++ b/Modules/_io/fileio.c @@ -1123,7 +1123,7 @@ _io_FileIO_isatty_impl(fileio *self) } static PyObject * -fileio_getstate(fileio *self) +fileio_getstate(fileio *self, PyObject *Py_UNUSED(ignored)) { PyErr_Format(PyExc_TypeError, "cannot serialize '%s' object", Py_TYPE(self)->tp_name); diff --git a/Modules/_io/stringio.c b/Modules/_io/stringio.c index 718b1ac1d82db2..5a03715fbde04c 100644 --- a/Modules/_io/stringio.c +++ b/Modules/_io/stringio.c @@ -812,7 +812,7 @@ _io_StringIO_seekable_impl(stringio *self) */ static PyObject * -stringio_getstate(stringio *self) +stringio_getstate(stringio *self, PyObject *Py_UNUSED(ignored)) { PyObject *initvalue = _io_StringIO_getvalue_impl(self); PyObject *dict; @@ -826,8 +826,10 @@ stringio_getstate(stringio *self) } else { dict = PyDict_Copy(self->dict); - if (dict == NULL) + if (dict == NULL) { + Py_DECREF(initvalue); return NULL; + } } state = Py_BuildValue("(OOnN)", initvalue, diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c index 717b56ab319b61..a466d3a03a5ba3 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -66,7 +66,7 @@ PyDoc_STRVAR(textiobase_detach_doc, ); static PyObject * -textiobase_detach(PyObject *self) +textiobase_detach(PyObject *self, PyObject *Py_UNUSED(ignored)) { return _unsupported("detach"); } @@ -148,7 +148,7 @@ textiobase_errors_get(PyObject *self, void *context) static PyMethodDef textiobase_methods[] = { - {"detach", (PyCFunction)textiobase_detach, METH_NOARGS, textiobase_detach_doc}, + {"detach", textiobase_detach, METH_NOARGS, textiobase_detach_doc}, {"read", textiobase_read, METH_VARARGS, textiobase_read_doc}, {"readline", textiobase_readline, METH_VARARGS, textiobase_readline_doc}, {"write", textiobase_write, METH_VARARGS, textiobase_write_doc}, @@ -694,6 +694,9 @@ typedef struct PyObject *dict; } textio; +static void +textiowrapper_set_decoded_chars(textio *self, PyObject *chars); + /* A couple of specialized cases in order to bypass the slow incremental encoding methods for the most popular encodings. */ @@ -1606,6 +1609,7 @@ _io_TextIOWrapper_write_impl(textio *self, PyObject *text) Py_DECREF(ret); } + textiowrapper_set_decoded_chars(self, NULL); Py_CLEAR(self->snapshot); if (self->decoder) { @@ -1769,11 +1773,16 @@ textiowrapper_read_chunk(textio *self, Py_ssize_t size_hint) */ PyObject *next_input = dec_buffer; PyBytes_Concat(&next_input, input_chunk); + dec_buffer = NULL; /* Reference lost to PyBytes_Concat */ if (next_input == NULL) { - dec_buffer = NULL; /* Reference lost to PyBytes_Concat */ goto fail; } - Py_XSETREF(self->snapshot, Py_BuildValue("NN", dec_flags, next_input)); + PyObject *snapshot = Py_BuildValue("NN", dec_flags, next_input); + if (snapshot == NULL) { + dec_flags = NULL; + goto fail; + } + Py_XSETREF(self->snapshot, snapshot); } Py_DECREF(input_chunk); @@ -1835,6 +1844,7 @@ _io_TextIOWrapper_read_impl(textio *self, Py_ssize_t n) if (result == NULL) goto fail; + textiowrapper_set_decoded_chars(self, NULL); Py_CLEAR(self->snapshot); return result; } @@ -2321,6 +2331,7 @@ _io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence) cookie_type cookie; PyObject *res; int cmp; + PyObject *snapshot; CHECK_ATTACHED(self); CHECK_CLOSED(self); @@ -2455,11 +2466,11 @@ _io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence) goto fail; } - self->snapshot = Py_BuildValue("iN", cookie.dec_flags, input_chunk); - if (self->snapshot == NULL) { - Py_DECREF(input_chunk); + snapshot = Py_BuildValue("iN", cookie.dec_flags, input_chunk); + if (snapshot == NULL) { goto fail; } + Py_XSETREF(self->snapshot, snapshot); decoded = _PyObject_CallMethodId(self->decoder, &PyId_decode, "Oi", input_chunk, (int)cookie.need_eof); @@ -2477,9 +2488,10 @@ _io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence) self->decoded_chars_used = cookie.chars_to_skip; } else { - self->snapshot = Py_BuildValue("iy", cookie.dec_flags, ""); - if (self->snapshot == NULL) + snapshot = Py_BuildValue("iy", cookie.dec_flags, ""); + if (snapshot == NULL) goto fail; + Py_XSETREF(self->snapshot, snapshot); } /* Finally, reset the encoder (merely useful for proper BOM handling) */ diff --git a/Modules/_io/winconsoleio.c b/Modules/_io/winconsoleio.c index b85c11b3405a73..2bf48eb55532d8 100644 --- a/Modules/_io/winconsoleio.c +++ b/Modules/_io/winconsoleio.c @@ -1057,7 +1057,7 @@ _io__WindowsConsoleIO_isatty_impl(winconsoleio *self) } static PyObject * -winconsoleio_getstate(winconsoleio *self) +winconsoleio_getstate(winconsoleio *self, PyObject *Py_UNUSED(ignored)) { PyErr_Format(PyExc_TypeError, "cannot serialize '%s' object", Py_TYPE(self)->tp_name); diff --git a/Modules/_localemodule.c b/Modules/_localemodule.c index f9eeeb72dd9e1e..524886d466009b 100644 --- a/Modules/_localemodule.c +++ b/Modules/_localemodule.c @@ -132,7 +132,7 @@ PyDoc_STRVAR(localeconv__doc__, "() -> dict. Returns numeric and monetary locale-specific parameters."); static PyObject* -PyLocale_localeconv(PyObject* self) +PyLocale_localeconv(PyObject* self, PyObject *Py_UNUSED(ignored)) { PyObject* result; struct lconv *l; @@ -317,7 +317,7 @@ PyLocale_strxfrm(PyObject* self, PyObject* args) #if defined(MS_WINDOWS) static PyObject* -PyLocale_getdefaultlocale(PyObject* self) +PyLocale_getdefaultlocale(PyObject* self, PyObject *Py_UNUSED(ignored)) { char encoding[100]; char locale[100]; @@ -605,8 +605,7 @@ PyIntl_bind_textdomain_codeset(PyObject* self,PyObject*args) static struct PyMethodDef PyLocale_Methods[] = { {"setlocale", (PyCFunction) PyLocale_setlocale, METH_VARARGS, setlocale__doc__}, - {"localeconv", (PyCFunction) PyLocale_localeconv, - METH_NOARGS, localeconv__doc__}, + {"localeconv", PyLocale_localeconv, METH_NOARGS, localeconv__doc__}, #ifdef HAVE_WCSCOLL {"strcoll", (PyCFunction) PyLocale_strcoll, METH_VARARGS, strcoll__doc__}, @@ -616,7 +615,7 @@ static struct PyMethodDef PyLocale_Methods[] = { METH_VARARGS, strxfrm__doc__}, #endif #if defined(MS_WINDOWS) - {"_getdefaultlocale", (PyCFunction) PyLocale_getdefaultlocale, METH_NOARGS}, + {"_getdefaultlocale", PyLocale_getdefaultlocale, METH_NOARGS}, #endif #ifdef HAVE_LANGINFO_H {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo, diff --git a/Modules/_lzmamodule.c b/Modules/_lzmamodule.c index 5bcd088d772188..7b501d8202d8b9 100644 --- a/Modules/_lzmamodule.c +++ b/Modules/_lzmamodule.c @@ -1163,11 +1163,15 @@ _lzma_LZMADecompressor___init___impl(Decompressor *self, int format, self->lzs.allocator = &self->alloc; self->lzs.next_in = NULL; - self->lock = PyThread_allocate_lock(); - if (self->lock == NULL) { + PyThread_type_lock lock = PyThread_allocate_lock(); + if (lock == NULL) { PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock"); return -1; } + if (self->lock != NULL) { + PyThread_free_lock(self->lock); + } + self->lock = lock; self->check = LZMA_CHECK_UNKNOWN; self->needs_input = 1; diff --git a/Modules/_multiprocessing/semaphore.c b/Modules/_multiprocessing/semaphore.c index 0092b139346416..b1d3a216cbe83a 100644 --- a/Modules/_multiprocessing/semaphore.c +++ b/Modules/_multiprocessing/semaphore.c @@ -518,20 +518,20 @@ semlock_dealloc(SemLockObject* self) } static PyObject * -semlock_count(SemLockObject *self) +semlock_count(SemLockObject *self, PyObject *Py_UNUSED(ignored)) { return PyLong_FromLong((long)self->count); } static PyObject * -semlock_ismine(SemLockObject *self) +semlock_ismine(SemLockObject *self, PyObject *Py_UNUSED(ignored)) { /* only makes sense for a lock */ return PyBool_FromLong(ISMINE(self)); } static PyObject * -semlock_getvalue(SemLockObject *self) +semlock_getvalue(SemLockObject *self, PyObject *Py_UNUSED(ignored)) { #ifdef HAVE_BROKEN_SEM_GETVALUE PyErr_SetNone(PyExc_NotImplementedError); @@ -549,7 +549,7 @@ semlock_getvalue(SemLockObject *self) } static PyObject * -semlock_iszero(SemLockObject *self) +semlock_iszero(SemLockObject *self, PyObject *Py_UNUSED(ignored)) { #ifdef HAVE_BROKEN_SEM_GETVALUE if (sem_trywait(self->handle) < 0) { @@ -570,7 +570,7 @@ semlock_iszero(SemLockObject *self) } static PyObject * -semlock_afterfork(SemLockObject *self) +semlock_afterfork(SemLockObject *self, PyObject *Py_UNUSED(ignored)) { self->count = 0; Py_RETURN_NONE; diff --git a/Modules/_operator.c b/Modules/_operator.c index f2fd65695f2e0e..dc678209ad3db3 100644 --- a/Modules/_operator.c +++ b/Modules/_operator.c @@ -1040,7 +1040,7 @@ itemgetter_repr(itemgetterobject *ig) } static PyObject * -itemgetter_reduce(itemgetterobject *ig) +itemgetter_reduce(itemgetterobject *ig, PyObject *Py_UNUSED(ignored)) { if (ig->nitems == 1) return Py_BuildValue("O(O)", Py_TYPE(ig), ig->item); @@ -1382,7 +1382,7 @@ attrgetter_repr(attrgetterobject *ag) } static PyObject * -attrgetter_reduce(attrgetterobject *ag) +attrgetter_reduce(attrgetterobject *ag, PyObject *Py_UNUSED(ignored)) { PyObject *attrstrings = attrgetter_args(ag); if (attrstrings == NULL) @@ -1615,7 +1615,7 @@ methodcaller_repr(methodcallerobject *mc) } static PyObject * -methodcaller_reduce(methodcallerobject *mc) +methodcaller_reduce(methodcallerobject *mc, PyObject *Py_UNUSED(ignored)) { PyObject *newargs; if (!mc->kwds || PyDict_GET_SIZE(mc->kwds) == 0) { diff --git a/Modules/_pickle.c b/Modules/_pickle.c index 8ca822315471dc..2f8e36a14a160b 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -20,10 +20,12 @@ class _pickle.UnpicklerMemoProxy "UnpicklerMemoProxyObject *" "&UnpicklerMemoPro [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=4b3e113468a58e6c]*/ -/* Bump this when new opcodes are added to the pickle protocol. */ +/* Bump HIGHEST_PROTOCOL when new opcodes are added to the pickle protocol. + Bump DEFAULT_PROTOCOL only when the oldest still supported version of Python + already includes it. */ enum { HIGHEST_PROTOCOL = 4, - DEFAULT_PROTOCOL = 3 + DEFAULT_PROTOCOL = 4 }; /* Pickle opcodes. These must be kept updated with pickle.py. @@ -7181,8 +7183,9 @@ 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 and 4. The default -protocol is 3; a backward-incompatible protocol designed for Python 3. +protocol; supported protocols are 0, 1, 2, 3 and 4. The default +protocol is 4. It was introduced in Python 3.4, it is incompatible +with previous versions. Specifying a negative protocol version selects the highest protocol version supported. The higher the protocol used, the more recent the @@ -7201,7 +7204,7 @@ to map the new Python 3 names to the old module names used in Python static PyObject * _pickle_dump_impl(PyObject *module, PyObject *obj, PyObject *file, PyObject *protocol, int fix_imports) -/*[clinic end generated code: output=a4774d5fde7d34de input=830f8a64cef6f042]*/ +/*[clinic end generated code: output=a4774d5fde7d34de input=93f1408489a87472]*/ { PicklerObject *pickler = _Pickler_New(); @@ -7241,7 +7244,8 @@ 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 and 4. The default -protocol is 3; a backward-incompatible protocol designed for Python 3. +protocol is 4. It was introduced in Python 3.4, it is incompatible +with previous versions. Specifying a negative protocol version selects the highest protocol version supported. The higher the protocol used, the more recent the @@ -7255,7 +7259,7 @@ Python 2, so that the pickle data stream is readable with Python 2. static PyObject * _pickle_dumps_impl(PyObject *module, PyObject *obj, PyObject *protocol, int fix_imports) -/*[clinic end generated code: output=d75d5cda456fd261 input=293dbeda181580b7]*/ +/*[clinic end generated code: output=d75d5cda456fd261 input=b6efb45a7d19b5ab]*/ { PyObject *result; PicklerObject *pickler = _Pickler_New(); diff --git a/Modules/_queuemodule.c b/Modules/_queuemodule.c index 8715337fb51179..0eb99302745940 100644 --- a/Modules/_queuemodule.c +++ b/Modules/_queuemodule.c @@ -8,7 +8,7 @@ class _queue.SimpleQueue "simplequeueobject *" "&PySimpleQueueType" [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=cf49af81bcbbbea6]*/ -extern PyTypeObject PySimpleQueueType; /* forward decl */ +static PyTypeObject PySimpleQueueType; /* forward decl */ static PyObject *EmptyError; @@ -306,7 +306,7 @@ static PyMethodDef simplequeue_methods[] = { }; -PyTypeObject PySimpleQueueType = { +static PyTypeObject PySimpleQueueType = { PyVarObject_HEAD_INIT(NULL, 0) "_queue.SimpleQueue", /*tp_name*/ sizeof(simplequeueobject), /*tp_size*/ diff --git a/Modules/_randommodule.c b/Modules/_randommodule.c index 51677f8b00a492..dae9d42fcb225c 100644 --- a/Modules/_randommodule.c +++ b/Modules/_randommodule.c @@ -138,7 +138,7 @@ genrand_int32(RandomObject *self) * The original code credited Isaku Wada for this algorithm, 2002/01/09. */ static PyObject * -random_random(RandomObject *self) +random_random(RandomObject *self, PyObject *Py_UNUSED(ignored)) { uint32_t a=genrand_int32(self)>>5, b=genrand_int32(self)>>6; return PyFloat_FromDouble((a*67108864.0+b)*(1.0/9007199254740992.0)); @@ -319,7 +319,7 @@ random_seed(RandomObject *self, PyObject *args) } static PyObject * -random_getstate(RandomObject *self) +random_getstate(RandomObject *self, PyObject *Py_UNUSED(ignored)) { PyObject *state; PyObject *element; diff --git a/Modules/_scproxy.c b/Modules/_scproxy.c index 0e3b02879b833d..8861dc456d759a 100644 --- a/Modules/_scproxy.c +++ b/Modules/_scproxy.c @@ -53,7 +53,7 @@ cfstring_to_pystring(CFStringRef ref) static PyObject* -get_proxy_settings(PyObject* mod __attribute__((__unused__))) +get_proxy_settings(PyObject* Py_UNUSED(mod), PyObject *Py_UNUSED(ignored)) { CFDictionaryRef proxyDict = NULL; CFNumberRef aNum = NULL; @@ -166,7 +166,7 @@ set_proxy(PyObject* proxies, const char* proto, CFDictionaryRef proxyDict, static PyObject* -get_proxies(PyObject* mod __attribute__((__unused__))) +get_proxies(PyObject* Py_UNUSED(mod), PyObject *Py_UNUSED(ignored)) { PyObject* result = NULL; int r; @@ -212,13 +212,13 @@ get_proxies(PyObject* mod __attribute__((__unused__))) static PyMethodDef mod_methods[] = { { "_get_proxy_settings", - (PyCFunction)get_proxy_settings, + get_proxy_settings, METH_NOARGS, NULL, }, { "_get_proxies", - (PyCFunction)get_proxies, + get_proxies, METH_NOARGS, NULL, }, diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 6e0576151ccba2..b8470df7fb8ffd 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -810,24 +810,48 @@ static void _pysqlite_drop_unused_cursor_references(pysqlite_Connection* self) PyObject* pysqlite_connection_create_function(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) { - static char *kwlist[] = {"name", "narg", "func", NULL, NULL}; + static char *kwlist[] = {"name", "narg", "func", "deterministic", NULL}; PyObject* func; char* name; int narg; int rc; + int deterministic = 0; + int flags = SQLITE_UTF8; if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; } - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "siO", kwlist, - &name, &narg, &func)) + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "siO|$p", kwlist, + &name, &narg, &func, &deterministic)) { return NULL; } - rc = sqlite3_create_function(self->db, name, narg, SQLITE_UTF8, (void*)func, _pysqlite_func_callback, NULL, NULL); + if (deterministic) { +#if SQLITE_VERSION_NUMBER < 3008003 + PyErr_SetString(pysqlite_NotSupportedError, + "deterministic=True requires SQLite 3.8.3 or higher"); + return NULL; +#else + if (sqlite3_libversion_number() < 3008003) { + PyErr_SetString(pysqlite_NotSupportedError, + "deterministic=True requires SQLite 3.8.3 or higher"); + return NULL; + } + flags |= SQLITE_DETERMINISTIC; +#endif + } + + rc = sqlite3_create_function(self->db, + name, + narg, + flags, + (void*)func, + _pysqlite_func_callback, + NULL, + NULL); if (rc != SQLITE_OK) { /* Workaround for SQLite bug: no error code or string is available here */ @@ -1461,17 +1485,33 @@ pysqlite_connection_backup(pysqlite_Connection *self, PyObject *args, PyObject * const char *name = "main"; int rc; int callback_error = 0; - double sleep_secs = 0.250; + PyObject *sleep_obj = NULL; + int sleep_ms = 250; sqlite3 *bck_conn; sqlite3_backup *bck_handle; static char *keywords[] = {"target", "pages", "progress", "name", "sleep", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|$iOsd:backup", keywords, + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|$iOsO:backup", keywords, &pysqlite_ConnectionType, &target, - &pages, &progress, &name, &sleep_secs)) { + &pages, &progress, &name, &sleep_obj)) { return NULL; } + if (sleep_obj != NULL) { + _PyTime_t sleep_secs; + if (_PyTime_FromSecondsObject(&sleep_secs, sleep_obj, + _PyTime_ROUND_TIMEOUT)) { + return NULL; + } + _PyTime_t ms = _PyTime_AsMilliseconds(sleep_secs, + _PyTime_ROUND_TIMEOUT); + if (ms < INT_MIN || ms > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, "sleep is too large"); + return NULL; + } + sleep_ms = (int)ms; + } + if (!pysqlite_check_connection((pysqlite_Connection *)target)) { return NULL; } @@ -1531,7 +1571,7 @@ pysqlite_connection_backup(pysqlite_Connection *self, PyObject *args, PyObject * the engine could not make any progress */ if (rc == SQLITE_BUSY || rc == SQLITE_LOCKED) { Py_BEGIN_ALLOW_THREADS - sqlite3_sleep(sleep_secs * 1000.0); + sqlite3_sleep(sleep_ms); Py_END_ALLOW_THREADS } } while (rc == SQLITE_OK || rc == SQLITE_BUSY || rc == SQLITE_LOCKED); diff --git a/Modules/_sqlite/row.c b/Modules/_sqlite/row.c index ec2c788ae7c046..2fc26a8822dcea 100644 --- a/Modules/_sqlite/row.c +++ b/Modules/_sqlite/row.c @@ -155,7 +155,7 @@ Py_ssize_t pysqlite_row_length(pysqlite_Row* self, PyObject* args, PyObject* kwa return PyTuple_GET_SIZE(self->data); } -PyObject* pysqlite_row_keys(pysqlite_Row* self, PyObject* args, PyObject* kwargs) +PyObject* pysqlite_row_keys(pysqlite_Row* self, PyObject *Py_UNUSED(ignored)) { PyObject* list; Py_ssize_t nitems, i; @@ -176,11 +176,6 @@ PyObject* pysqlite_row_keys(pysqlite_Row* self, PyObject* args, PyObject* kwargs return list; } -static int pysqlite_row_print(pysqlite_Row* self, FILE *fp, int flags) -{ - return (&PyTuple_Type)->tp_print(self->data, fp, flags); -} - static PyObject* pysqlite_iter(pysqlite_Row* self) { return PyObject_GetIter(self->data); @@ -235,7 +230,7 @@ PyTypeObject pysqlite_RowType = { sizeof(pysqlite_Row), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)pysqlite_row_dealloc, /* tp_dealloc */ - (printfunc)pysqlite_row_print, /* tp_print */ + 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved */ diff --git a/Modules/_ssl.c b/Modules/_ssl.c index bf379f01a1d2bf..2bce4816d26fe7 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -901,7 +901,6 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, #endif /* Make sure the SSL error state is initialized */ - (void) ERR_get_state(); ERR_clear_error(); PySSL_BEGIN_ALLOW_THREADS diff --git a/Modules/_struct.c b/Modules/_struct.c index 66f74d63b735f7..0be52d9ab94b01 100644 --- a/Modules/_struct.c +++ b/Modules/_struct.c @@ -1553,7 +1553,8 @@ Return a tuple containing unpacked values. Values are unpacked according to the format string Struct.format. -The buffer's size in bytes, minus offset, must be at least Struct.size. +The buffer's size in bytes, starting at position offset, must be +at least Struct.size. See help(struct) for more on format strings. [clinic start generated code]*/ @@ -1561,16 +1562,38 @@ See help(struct) for more on format strings. static PyObject * Struct_unpack_from_impl(PyStructObject *self, Py_buffer *buffer, Py_ssize_t offset) -/*[clinic end generated code: output=57fac875e0977316 input=97ade52422f8962f]*/ +/*[clinic end generated code: output=57fac875e0977316 input=cafd4851d473c894]*/ { assert(self->s_codes != NULL); - if (offset < 0) + if (offset < 0) { + if (offset + self->s_size > 0) { + PyErr_Format(StructError, + "not enough data to unpack %zd bytes at offset %zd", + self->s_size, + offset); + return NULL; + } + + if (offset + buffer->len < 0) { + PyErr_Format(StructError, + "offset %zd out of range for %zd-byte buffer", + offset, + buffer->len); + return NULL; + } offset += buffer->len; - if (offset < 0 || buffer->len - offset < self->s_size) { + } + + if ((buffer->len - offset) < self->s_size) { PyErr_Format(StructError, - "unpack_from requires a buffer of at least %zd bytes", - self->s_size); + "unpack_from requires a buffer of at least %zu bytes for " + "unpacking %zd bytes at offset %zd " + "(actual buffer size is %zd)", + (size_t)self->s_size + (size_t)offset, + self->s_size, + offset, + buffer->len); return NULL; } return s_unpack_internal(self, (char*)buffer->buf + offset); @@ -1606,7 +1629,7 @@ unpackiter_traverse(unpackiterobject *self, visitproc visit, void *arg) } static PyObject * -unpackiter_len(unpackiterobject *self) +unpackiter_len(unpackiterobject *self, PyObject *Py_UNUSED(ignored)) { Py_ssize_t len; if (self->so == NULL) diff --git a/Modules/_testbuffer.c b/Modules/_testbuffer.c index 6b8ab34d931cd3..344d06d0525d78 100644 --- a/Modules/_testbuffer.c +++ b/Modules/_testbuffer.c @@ -8,13 +8,13 @@ /* struct module */ -PyObject *structmodule = NULL; -PyObject *Struct = NULL; -PyObject *calcsize = NULL; +static PyObject *structmodule = NULL; +static PyObject *Struct = NULL; +static PyObject *calcsize = NULL; /* cache simple format string */ static const char *simple_fmt = "B"; -PyObject *simple_format = NULL; +static PyObject *simple_format = NULL; #define SIMPLE_FORMAT(fmt) (fmt == NULL || strcmp(fmt, "B") == 0) #define FIX_FORMAT(fmt) (fmt == NULL ? "B" : fmt) @@ -2354,7 +2354,7 @@ get_pointer(PyObject *self, PyObject *args) } static PyObject * -get_sizeof_void_p(PyObject *self) +get_sizeof_void_p(PyObject *self, PyObject *Py_UNUSED(ignored)) { return PyLong_FromSize_t(sizeof(void *)); } @@ -2807,7 +2807,7 @@ static PyTypeObject StaticArray_Type = { static struct PyMethodDef _testbuffer_functions[] = { {"slice_indices", slice_indices, METH_VARARGS, NULL}, {"get_pointer", get_pointer, METH_VARARGS, NULL}, - {"get_sizeof_void_p", (PyCFunction)get_sizeof_void_p, METH_NOARGS, NULL}, + {"get_sizeof_void_p", get_sizeof_void_p, METH_NOARGS, NULL}, {"get_contiguous", get_contiguous, METH_VARARGS, NULL}, {"py_buffer_to_contiguous", py_buffer_to_contiguous, METH_VARARGS, NULL}, {"is_contiguous", is_contiguous, METH_VARARGS, NULL}, diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index afce6c9448952b..014c2f325af3e8 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -51,7 +51,7 @@ sizeof_error(const char* fatname, const char* typname, } static PyObject* -test_config(PyObject *self) +test_config(PyObject *self, PyObject *Py_UNUSED(ignored)) { #define CHECK_SIZEOF(FATNAME, TYPE) \ if (FATNAME != sizeof(TYPE)) \ @@ -70,7 +70,7 @@ test_config(PyObject *self) } static PyObject* -test_sizeof_c_types(PyObject *self) +test_sizeof_c_types(PyObject *self, PyObject *Py_UNUSED(ignored)) { #if defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))) #pragma GCC diagnostic push @@ -131,7 +131,7 @@ test_sizeof_c_types(PyObject *self) static PyObject* -test_list_api(PyObject *self) +test_list_api(PyObject *self, PyObject *Py_UNUSED(ignored)) { PyObject* list; int i; @@ -223,7 +223,7 @@ test_dict_inner(int count) } static PyObject* -test_dict_iteration(PyObject* self) +test_dict_iteration(PyObject* self, PyObject *Py_UNUSED(ignored)) { int i; @@ -315,7 +315,7 @@ static PyTypeObject _HashInheritanceTester_Type = { }; static PyObject* -test_lazy_hash_inheritance(PyObject* self) +test_lazy_hash_inheritance(PyObject* self, PyObject *Py_UNUSED(ignored)) { PyTypeObject *type; PyObject *obj; @@ -411,7 +411,7 @@ raise_test_long_error(const char* msg) #include "testcapi_long.h" static PyObject * -test_long_api(PyObject* self) +test_long_api(PyObject* self, PyObject *Py_UNUSED(ignored)) { return TESTNAME(raise_test_long_error); } @@ -457,7 +457,7 @@ test_longlong_api(PyObject* self, PyObject *args) */ static PyObject * -test_long_and_overflow(PyObject *self) +test_long_and_overflow(PyObject *self, PyObject *Py_UNUSED(ignored)) { PyObject *num, *one, *temp; long value; @@ -621,7 +621,7 @@ test_long_and_overflow(PyObject *self) */ static PyObject * -test_long_long_and_overflow(PyObject *self) +test_long_long_and_overflow(PyObject *self, PyObject *Py_UNUSED(ignored)) { PyObject *num, *one, *temp; long long value; @@ -785,7 +785,7 @@ test_long_long_and_overflow(PyObject *self) */ static PyObject * -test_long_as_size_t(PyObject *self) +test_long_as_size_t(PyObject *self, PyObject *Py_UNUSED(ignored)) { size_t out_u; Py_ssize_t out_s; @@ -821,7 +821,7 @@ test_long_as_size_t(PyObject *self) */ static PyObject * -test_long_as_double(PyObject *self) +test_long_as_double(PyObject *self, PyObject *Py_UNUSED(ignored)) { double out; @@ -846,7 +846,7 @@ test_long_as_double(PyObject *self) it fails. */ static PyObject * -test_L_code(PyObject *self) +test_L_code(PyObject *self, PyObject *Py_UNUSED(ignored)) { PyObject *tuple, *num; long long value; @@ -1173,7 +1173,7 @@ getargs_K(PyObject *self, PyObject *args) /* This function not only tests the 'k' getargs code, but also the PyLong_AsUnsignedLongMask() function. */ static PyObject * -test_k_code(PyObject *self) +test_k_code(PyObject *self, PyObject *Py_UNUSED(ignored)) { PyObject *tuple, *num; unsigned long value; @@ -1531,7 +1531,7 @@ getargs_et_hash(PyObject *self, PyObject *args) /* Test the s and z codes for PyArg_ParseTuple. */ static PyObject * -test_s_code(PyObject *self) +test_s_code(PyObject *self, PyObject *Py_UNUSED(ignored)) { /* Unicode strings should be accepted */ PyObject *tuple, *obj; @@ -1637,7 +1637,7 @@ static volatile int x; of an error. */ static PyObject * -test_u_code(PyObject *self) +test_u_code(PyObject *self, PyObject *Py_UNUSED(ignored)) { PyObject *tuple, *obj; Py_UNICODE *value; @@ -1680,7 +1680,7 @@ test_u_code(PyObject *self) /* Test Z and Z# codes for PyArg_ParseTuple */ static PyObject * -test_Z_code(PyObject *self) +test_Z_code(PyObject *self, PyObject *Py_UNUSED(ignored)) { PyObject *tuple, *obj; const Py_UNICODE *value1, *value2; @@ -1735,7 +1735,7 @@ test_Z_code(PyObject *self) } static PyObject * -test_widechar(PyObject *self) +test_widechar(PyObject *self, PyObject *Py_UNUSED(ignored)) { #if defined(SIZEOF_WCHAR_T) && (SIZEOF_WCHAR_T == 4) const wchar_t wtext[2] = {(wchar_t)0x10ABCDu}; @@ -2033,7 +2033,7 @@ getargs_w_star(PyObject *self, PyObject *args) static PyObject * -test_empty_argparse(PyObject *self) +test_empty_argparse(PyObject *self, PyObject *Py_UNUSED(ignored)) { /* Test that formats can begin with '|'. See issue #4720. */ PyObject *tuple, *dict = NULL; @@ -2083,7 +2083,7 @@ codec_incrementaldecoder(PyObject *self, PyObject *args) /* Simple test of _PyLong_NumBits and _PyLong_Sign. */ static PyObject * -test_long_numbits(PyObject *self) +test_long_numbits(PyObject *self, PyObject *Py_UNUSED(ignored)) { struct triple { long input; @@ -2131,7 +2131,7 @@ test_long_numbits(PyObject *self) /* Example passing NULLs to PyObject_Str(NULL). */ static PyObject * -test_null_strings(PyObject *self) +test_null_strings(PyObject *self, PyObject *Py_UNUSED(ignored)) { PyObject *o1 = PyObject_Str(NULL), *o2 = PyObject_Str(NULL); PyObject *tuple = PyTuple_Pack(2, o1, o2); @@ -2429,7 +2429,8 @@ static int _pending_callback(void *arg) /* The following requests n callbacks to _pending_callback. It can be * run from any python thread. */ -PyObject *pending_threadfunc(PyObject *self, PyObject *arg) +static PyObject * +pending_threadfunc(PyObject *self, PyObject *arg) { PyObject *callable; int r; @@ -2492,7 +2493,7 @@ test_string_from_format(PyObject *self, PyObject *args) static PyObject * -test_unicode_compare_with_ascii(PyObject *self) { +test_unicode_compare_with_ascii(PyObject *self, PyObject *Py_UNUSED(ignored)) { PyObject *py_s = PyUnicode_FromStringAndSize("str\0", 4); int result; if (py_s == NULL) @@ -2509,14 +2510,14 @@ test_unicode_compare_with_ascii(PyObject *self) { /* This is here to provide a docstring for test_descr. */ static PyObject * -test_with_docstring(PyObject *self) +test_with_docstring(PyObject *self, PyObject *Py_UNUSED(ignored)) { Py_RETURN_NONE; } /* Test PyOS_string_to_double. */ static PyObject * -test_string_to_double(PyObject *self) { +test_string_to_double(PyObject *self, PyObject *Py_UNUSED(ignored)) { double result; const char *msg; @@ -2881,7 +2882,7 @@ exception_print(PyObject *self, PyObject *args) /* reliably raise a MemoryError */ static PyObject * -raise_memoryerror(PyObject *self) +raise_memoryerror(PyObject *self, PyObject *Py_UNUSED(ignored)) { PyErr_NoMemory(); return NULL; @@ -2954,7 +2955,7 @@ make_exception_with_doc(PyObject *self, PyObject *args, PyObject *kwargs) } static PyObject * -make_memoryview_from_NULL_pointer(PyObject *self) +make_memoryview_from_NULL_pointer(PyObject *self, PyObject *Py_UNUSED(ignored)) { Py_buffer info; if (PyBuffer_FillInfo(&info, NULL, NULL, 1, 1, PyBUF_FULL_RO) < 0) @@ -3067,7 +3068,7 @@ getbuffer_with_null_view(PyObject* self, PyObject *obj) /* Test that the fatal error from not having a current thread doesn't cause an infinite loop. Run via Lib/test/test_capi.py */ static PyObject * -crash_no_current_thread(PyObject *self) +crash_no_current_thread(PyObject *self, PyObject *Py_UNUSED(ignored)) { Py_BEGIN_ALLOW_THREADS /* Using PyThreadState_Get() directly allows the test to pass in @@ -3215,8 +3216,7 @@ slot_tp_del(PyObject *self) _Py_NewReference(self); self->ob_refcnt = refcnt; } - assert(!PyType_IS_GC(Py_TYPE(self)) || - _Py_AS_GC(self)->gc.gc_refs != _PyGC_REFS_UNTRACKED); + assert(!PyType_IS_GC(Py_TYPE(self)) || _PyObject_GC_IS_TRACKED(self)); /* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so * we need to undo that. */ _Py_DEC_REFTOTAL; @@ -3274,7 +3274,7 @@ _test_incref(PyObject *ob) } static PyObject * -test_xincref_doesnt_leak(PyObject *ob) +test_xincref_doesnt_leak(PyObject *ob, PyObject *Py_UNUSED(ignored)) { PyObject *obj = PyLong_FromLong(0); Py_XINCREF(_test_incref(obj)); @@ -3285,7 +3285,7 @@ test_xincref_doesnt_leak(PyObject *ob) } static PyObject * -test_incref_doesnt_leak(PyObject *ob) +test_incref_doesnt_leak(PyObject *ob, PyObject *Py_UNUSED(ignored)) { PyObject *obj = PyLong_FromLong(0); Py_INCREF(_test_incref(obj)); @@ -3296,21 +3296,21 @@ test_incref_doesnt_leak(PyObject *ob) } static PyObject * -test_xdecref_doesnt_leak(PyObject *ob) +test_xdecref_doesnt_leak(PyObject *ob, PyObject *Py_UNUSED(ignored)) { Py_XDECREF(PyLong_FromLong(0)); Py_RETURN_NONE; } static PyObject * -test_decref_doesnt_leak(PyObject *ob) +test_decref_doesnt_leak(PyObject *ob, PyObject *Py_UNUSED(ignored)) { Py_DECREF(PyLong_FromLong(0)); Py_RETURN_NONE; } static PyObject * -test_incref_decref_API(PyObject *ob) +test_incref_decref_API(PyObject *ob, PyObject *Py_UNUSED(ignored)) { PyObject *obj = PyLong_FromLong(0); Py_IncRef(obj); @@ -3320,7 +3320,7 @@ test_incref_decref_API(PyObject *ob) } static PyObject * -test_pymem_alloc0(PyObject *self) +test_pymem_alloc0(PyObject *self, PyObject *Py_UNUSED(ignored)) { void *ptr; @@ -3546,19 +3546,19 @@ test_setallocators(PyMemAllocatorDomain domain) } static PyObject * -test_pymem_setrawallocators(PyObject *self) +test_pymem_setrawallocators(PyObject *self, PyObject *Py_UNUSED(ignored)) { return test_setallocators(PYMEM_DOMAIN_RAW); } static PyObject * -test_pymem_setallocators(PyObject *self) +test_pymem_setallocators(PyObject *self, PyObject *Py_UNUSED(ignored)) { return test_setallocators(PYMEM_DOMAIN_MEM); } static PyObject * -test_pyobject_setallocators(PyObject *self) +test_pyobject_setallocators(PyObject *self, PyObject *Py_UNUSED(ignored)) { return test_setallocators(PYMEM_DOMAIN_OBJ); } @@ -3681,7 +3681,7 @@ set_nomemory(PyObject *self, PyObject *args) } static PyObject* -remove_mem_hooks(PyObject *self) +remove_mem_hooks(PyObject *self, PyObject *Py_UNUSED(ignored)) { fm_remove_hooks(); Py_RETURN_NONE; @@ -4552,10 +4552,10 @@ new_hamt(PyObject *self, PyObject *args) static PyMethodDef TestMethods[] = { {"raise_exception", raise_exception, METH_VARARGS}, - {"raise_memoryerror", (PyCFunction)raise_memoryerror, METH_NOARGS}, + {"raise_memoryerror", raise_memoryerror, METH_NOARGS}, {"set_errno", set_errno, METH_VARARGS}, - {"test_config", (PyCFunction)test_config, METH_NOARGS}, - {"test_sizeof_c_types", (PyCFunction)test_sizeof_c_types, METH_NOARGS}, + {"test_config", test_config, METH_NOARGS}, + {"test_sizeof_c_types", test_sizeof_c_types, METH_NOARGS}, {"test_datetime_capi", test_datetime_capi, METH_NOARGS}, {"datetime_check_date", datetime_check_date, METH_VARARGS}, {"datetime_check_time", datetime_check_time, METH_VARARGS}, @@ -4565,31 +4565,31 @@ static PyMethodDef TestMethods[] = { {"make_timezones_capi", make_timezones_capi, METH_NOARGS}, {"get_timezones_offset_zero", get_timezones_offset_zero, METH_NOARGS}, {"get_timezone_utc_capi", get_timezone_utc_capi, METH_VARARGS}, - {"test_list_api", (PyCFunction)test_list_api, METH_NOARGS}, - {"test_dict_iteration", (PyCFunction)test_dict_iteration,METH_NOARGS}, + {"test_list_api", test_list_api, METH_NOARGS}, + {"test_dict_iteration", test_dict_iteration, METH_NOARGS}, {"dict_getitem_knownhash", dict_getitem_knownhash, METH_VARARGS}, {"dict_hassplittable", dict_hassplittable, METH_O}, - {"test_lazy_hash_inheritance", (PyCFunction)test_lazy_hash_inheritance,METH_NOARGS}, - {"test_long_api", (PyCFunction)test_long_api, METH_NOARGS}, - {"test_xincref_doesnt_leak",(PyCFunction)test_xincref_doesnt_leak, METH_NOARGS}, - {"test_incref_doesnt_leak", (PyCFunction)test_incref_doesnt_leak, METH_NOARGS}, - {"test_xdecref_doesnt_leak",(PyCFunction)test_xdecref_doesnt_leak, METH_NOARGS}, - {"test_decref_doesnt_leak", (PyCFunction)test_decref_doesnt_leak, METH_NOARGS}, - {"test_incref_decref_API", (PyCFunction)test_incref_decref_API, METH_NOARGS}, - {"test_long_and_overflow", (PyCFunction)test_long_and_overflow, - METH_NOARGS}, - {"test_long_as_double", (PyCFunction)test_long_as_double,METH_NOARGS}, - {"test_long_as_size_t", (PyCFunction)test_long_as_size_t,METH_NOARGS}, - {"test_long_numbits", (PyCFunction)test_long_numbits, METH_NOARGS}, - {"test_k_code", (PyCFunction)test_k_code, METH_NOARGS}, - {"test_empty_argparse", (PyCFunction)test_empty_argparse,METH_NOARGS}, + {"test_lazy_hash_inheritance", test_lazy_hash_inheritance,METH_NOARGS}, + {"test_long_api", test_long_api, METH_NOARGS}, + {"test_xincref_doesnt_leak",test_xincref_doesnt_leak, METH_NOARGS}, + {"test_incref_doesnt_leak", test_incref_doesnt_leak, METH_NOARGS}, + {"test_xdecref_doesnt_leak",test_xdecref_doesnt_leak, METH_NOARGS}, + {"test_decref_doesnt_leak", test_decref_doesnt_leak, METH_NOARGS}, + {"test_incref_decref_API", test_incref_decref_API, METH_NOARGS}, + {"test_long_and_overflow", test_long_and_overflow, METH_NOARGS}, + {"test_long_as_double", test_long_as_double, METH_NOARGS}, + {"test_long_as_size_t", test_long_as_size_t, METH_NOARGS}, + {"test_long_numbits", test_long_numbits, METH_NOARGS}, + {"test_k_code", test_k_code, METH_NOARGS}, + {"test_empty_argparse", test_empty_argparse, METH_NOARGS}, {"parse_tuple_and_keywords", parse_tuple_and_keywords, METH_VARARGS}, - {"test_null_strings", (PyCFunction)test_null_strings, METH_NOARGS}, + {"test_null_strings", test_null_strings, METH_NOARGS}, {"test_string_from_format", (PyCFunction)test_string_from_format, METH_NOARGS}, - {"test_with_docstring", (PyCFunction)test_with_docstring, METH_NOARGS, + {"test_with_docstring", test_with_docstring, METH_NOARGS, PyDoc_STR("This is a pretty normal docstring.")}, - {"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_string_to_double", test_string_to_double, METH_NOARGS}, + {"test_unicode_compare_with_ascii", 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__) @@ -4620,9 +4620,8 @@ static PyMethodDef TestMethods[] = { {"getargs_L", getargs_L, METH_VARARGS}, {"getargs_K", getargs_K, METH_VARARGS}, {"test_longlong_api", test_longlong_api, METH_NOARGS}, - {"test_long_long_and_overflow", - (PyCFunction)test_long_long_and_overflow, METH_NOARGS}, - {"test_L_code", (PyCFunction)test_L_code, METH_NOARGS}, + {"test_long_long_and_overflow",test_long_long_and_overflow, METH_NOARGS}, + {"test_L_code", test_L_code, METH_NOARGS}, {"getargs_f", getargs_f, METH_VARARGS}, {"getargs_d", getargs_d, METH_VARARGS}, {"getargs_D", getargs_D, METH_VARARGS}, @@ -4653,10 +4652,10 @@ static PyMethodDef TestMethods[] = { (PyCFunction)codec_incrementalencoder, METH_VARARGS}, {"codec_incrementaldecoder", (PyCFunction)codec_incrementaldecoder, METH_VARARGS}, - {"test_s_code", (PyCFunction)test_s_code, METH_NOARGS}, - {"test_u_code", (PyCFunction)test_u_code, METH_NOARGS}, - {"test_Z_code", (PyCFunction)test_Z_code, METH_NOARGS}, - {"test_widechar", (PyCFunction)test_widechar, METH_NOARGS}, + {"test_s_code", test_s_code, METH_NOARGS}, + {"test_u_code", test_u_code, METH_NOARGS}, + {"test_Z_code", test_Z_code, METH_NOARGS}, + {"test_widechar", test_widechar, METH_NOARGS}, {"unicode_aswidechar", unicode_aswidechar, METH_VARARGS}, {"unicode_aswidecharstring",unicode_aswidecharstring, METH_VARARGS}, {"unicode_asucs4", unicode_asucs4, METH_VARARGS}, @@ -4677,26 +4676,22 @@ static PyMethodDef TestMethods[] = { {"code_newempty", code_newempty, METH_VARARGS}, {"make_exception_with_doc", (PyCFunction)make_exception_with_doc, METH_VARARGS | METH_KEYWORDS}, - {"make_memoryview_from_NULL_pointer", (PyCFunction)make_memoryview_from_NULL_pointer, + {"make_memoryview_from_NULL_pointer", make_memoryview_from_NULL_pointer, METH_NOARGS}, - {"crash_no_current_thread", (PyCFunction)crash_no_current_thread, METH_NOARGS}, + {"crash_no_current_thread", crash_no_current_thread, METH_NOARGS}, {"run_in_subinterp", run_in_subinterp, METH_VARARGS}, {"pytime_object_to_time_t", test_pytime_object_to_time_t, METH_VARARGS}, {"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}, {"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}, - {"test_pyobject_setallocators", - (PyCFunction)test_pyobject_setallocators, METH_NOARGS}, + {"test_pymem_alloc0", test_pymem_alloc0, METH_NOARGS}, + {"test_pymem_setrawallocators",test_pymem_setrawallocators, METH_NOARGS}, + {"test_pymem_setallocators",test_pymem_setallocators, METH_NOARGS}, + {"test_pyobject_setallocators",test_pyobject_setallocators, METH_NOARGS}, {"set_nomemory", (PyCFunction)set_nomemory, METH_VARARGS, PyDoc_STR("set_nomemory(start:int, stop:int = 0)")}, - {"remove_mem_hooks", (PyCFunction)remove_mem_hooks, METH_NOARGS, + {"remove_mem_hooks", remove_mem_hooks, METH_NOARGS, PyDoc_STR("Remove memory hooks.")}, {"no_docstring", (PyCFunction)test_with_docstring, METH_NOARGS}, @@ -5199,7 +5194,7 @@ static PyMethodDef generic_alias_methods[] = { {NULL} /* sentinel */ }; -PyTypeObject GenericAlias_Type = { +static PyTypeObject GenericAlias_Type = { PyVarObject_HEAD_INIT(NULL, 0) "GenericAlias", sizeof(PyGenericAliasObject), @@ -5236,7 +5231,7 @@ static PyMethodDef generic_methods[] = { {NULL} /* sentinel */ }; -PyTypeObject Generic_Type = { +static PyTypeObject Generic_Type = { PyVarObject_HEAD_INIT(NULL, 0) "Generic", sizeof(PyGenericObject), diff --git a/Modules/_testmultiphase.c b/Modules/_testmultiphase.c index 68404f2c6cdb6b..5776df7d765db9 100644 --- a/Modules/_testmultiphase.c +++ b/Modules/_testmultiphase.c @@ -236,7 +236,7 @@ static int execfunc(PyObject *m) #define TEST_MODULE_DEF(name, slots, methods) TEST_MODULE_DEF_EX(name, slots, methods, 0, NULL) -PyModuleDef_Slot main_slots[] = { +static PyModuleDef_Slot main_slots[] = { {Py_mod_exec, execfunc}, {0, NULL}, }; @@ -486,7 +486,7 @@ createfunc_null(PyObject *spec, PyModuleDef *def) return NULL; } -PyModuleDef_Slot slots_create_null[] = { +static PyModuleDef_Slot slots_create_null[] = { {Py_mod_create, createfunc_null}, {0, NULL}, }; diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c index f594bda678a8ac..69e27be9cc81a4 100644 --- a/Modules/_threadmodule.c +++ b/Modules/_threadmodule.c @@ -163,7 +163,7 @@ and the return value reflects whether the lock is acquired.\n\ The blocking operation is interruptible."); static PyObject * -lock_PyThread_release_lock(lockobject *self) +lock_PyThread_release_lock(lockobject *self, PyObject *Py_UNUSED(ignored)) { /* Sanity check: the lock must be locked */ if (!self->locked) { @@ -185,7 +185,7 @@ the lock to acquire the lock. The lock must be in the locked state,\n\ but it needn't be locked by the same thread that unlocks it."); static PyObject * -lock_locked_lock(lockobject *self) +lock_locked_lock(lockobject *self, PyObject *Py_UNUSED(ignored)) { return PyBool_FromLong((long)self->locked); } @@ -333,7 +333,7 @@ internal counter is simply incremented. If nobody holds the lock,\n\ the lock is taken and its internal counter initialized to 1."); static PyObject * -rlock_release(rlockobject *self) +rlock_release(rlockobject *self, PyObject *Py_UNUSED(ignored)) { unsigned long tid = PyThread_get_thread_ident(); @@ -392,7 +392,7 @@ PyDoc_STRVAR(rlock_acquire_restore_doc, For internal use by `threading.Condition`."); static PyObject * -rlock_release_save(rlockobject *self) +rlock_release_save(rlockobject *self, PyObject *Py_UNUSED(ignored)) { unsigned long owner; unsigned long count; @@ -418,7 +418,7 @@ For internal use by `threading.Condition`."); static PyObject * -rlock_is_owned(rlockobject *self) +rlock_is_owned(rlockobject *self, PyObject *Py_UNUSED(ignored)) { unsigned long tid = PyThread_get_thread_ident(); @@ -1087,7 +1087,7 @@ when the function raises an unhandled exception; a stack trace will be\n\ printed unless the exception is SystemExit.\n"); static PyObject * -thread_PyThread_exit_thread(PyObject *self) +thread_PyThread_exit_thread(PyObject *self, PyObject *Py_UNUSED(ignored)) { PyErr_SetNone(PyExc_SystemExit); return NULL; @@ -1101,7 +1101,7 @@ This is synonymous to ``raise SystemExit''. It will cause the current\n\ thread to exit silently unless the exception is caught."); static PyObject * -thread_PyThread_interrupt_main(PyObject * self) +thread_PyThread_interrupt_main(PyObject * self, PyObject *Py_UNUSED(ignored)) { PyErr_SetInterrupt(); Py_RETURN_NONE; @@ -1117,7 +1117,7 @@ A subthread can use this function to interrupt the main thread." static lockobject *newlockobject(void); static PyObject * -thread_PyThread_allocate_lock(PyObject *self) +thread_PyThread_allocate_lock(PyObject *self, PyObject *Py_UNUSED(ignored)) { return (PyObject *) newlockobject(); } @@ -1130,7 +1130,7 @@ Create a new lock object. See help(type(threading.Lock())) for\n\ information about locks."); static PyObject * -thread_get_ident(PyObject *self) +thread_get_ident(PyObject *self, PyObject *Py_UNUSED(ignored)) { unsigned long ident = PyThread_get_thread_ident(); if (ident == PYTHREAD_INVALID_THREAD_ID) { @@ -1152,7 +1152,7 @@ be relied upon, and the number should be seen purely as a magic cookie.\n\ A thread's identity may be reused for another thread after it exits."); static PyObject * -thread__count(PyObject *self) +thread__count(PyObject *self, PyObject *Py_UNUSED(ignored)) { PyThreadState *tstate = PyThreadState_Get(); return PyLong_FromLong(tstate->interp->num_threads); @@ -1162,7 +1162,7 @@ PyDoc_STRVAR(_count_doc, "_count() -> integer\n\ \n\ \ -Return the number of currently running Python threads, excluding \n\ +Return the number of currently running Python threads, excluding\n\ the main thread. The returned number comprises all threads created\n\ through `start_new_thread()` as well as `threading.Thread`, and not\n\ yet finished.\n\ @@ -1192,7 +1192,7 @@ release_sentinel(void *wr) } static PyObject * -thread__set_sentinel(PyObject *self) +thread__set_sentinel(PyObject *self, PyObject *Py_UNUSED(ignored)) { PyObject *wr; PyThreadState *tstate = PyThreadState_Get(); @@ -1289,23 +1289,23 @@ static PyMethodDef thread_methods[] = { METH_VARARGS, start_new_doc}, {"start_new", (PyCFunction)thread_PyThread_start_new_thread, METH_VARARGS, start_new_doc}, - {"allocate_lock", (PyCFunction)thread_PyThread_allocate_lock, + {"allocate_lock", thread_PyThread_allocate_lock, METH_NOARGS, allocate_doc}, - {"allocate", (PyCFunction)thread_PyThread_allocate_lock, + {"allocate", thread_PyThread_allocate_lock, METH_NOARGS, allocate_doc}, - {"exit_thread", (PyCFunction)thread_PyThread_exit_thread, + {"exit_thread", thread_PyThread_exit_thread, METH_NOARGS, exit_doc}, - {"exit", (PyCFunction)thread_PyThread_exit_thread, + {"exit", thread_PyThread_exit_thread, METH_NOARGS, exit_doc}, - {"interrupt_main", (PyCFunction)thread_PyThread_interrupt_main, + {"interrupt_main", thread_PyThread_interrupt_main, METH_NOARGS, interrupt_doc}, - {"get_ident", (PyCFunction)thread_get_ident, + {"get_ident", thread_get_ident, METH_NOARGS, get_ident_doc}, - {"_count", (PyCFunction)thread__count, + {"_count", thread__count, METH_NOARGS, _count_doc}, {"stack_size", (PyCFunction)thread_stack_size, METH_VARARGS, stack_size_doc}, - {"_set_sentinel", (PyCFunction)thread__set_sentinel, + {"_set_sentinel", thread__set_sentinel, METH_NOARGS, _set_sentinel_doc}, {NULL, NULL} /* sentinel */ }; diff --git a/Modules/_uuidmodule.c b/Modules/_uuidmodule.c index 89499143a61b2b..0b7f2a2545d4eb 100644 --- a/Modules/_uuidmodule.c +++ b/Modules/_uuidmodule.c @@ -10,7 +10,8 @@ static PyObject * -py_uuid_generate_time_safe(void) +py_uuid_generate_time_safe(PyObject *Py_UNUSED(context), + PyObject *Py_UNUSED(ignored)) { uuid_t uuid; #ifdef HAVE_UUID_GENERATE_TIME_SAFE @@ -36,7 +37,7 @@ py_uuid_generate_time_safe(void) static PyMethodDef uuid_methods[] = { - {"generate_time_safe", (PyCFunction) py_uuid_generate_time_safe, METH_NOARGS, NULL}, + {"generate_time_safe", py_uuid_generate_time_safe, METH_NOARGS, NULL}, {NULL, NULL, 0, NULL} /* sentinel */ }; diff --git a/Modules/_winapi.c b/Modules/_winapi.c index d474eb6a31b345..f29833ad36b62f 100644 --- a/Modules/_winapi.c +++ b/Modules/_winapi.c @@ -163,6 +163,7 @@ create_converter('LPSECURITY_ATTRIBUTES', '" F_POINTER "') create_converter('BOOL', 'i') # F_BOOL used previously (always 'i') create_converter('DWORD', 'k') # F_DWORD is always "k" (which is much shorter) create_converter('LPCTSTR', 's') +create_converter('LPCWSTR', 'u') create_converter('LPWSTR', 'u') create_converter('UINT', 'I') # F_UINT used previously (always 'I') @@ -186,7 +187,7 @@ class DWORD_return_converter(CReturnConverter): data.return_conversion.append( 'return_value = Py_BuildValue("k", _return_value);\n') [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=4527052fe06e5823]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=27456f8555228b62]*/ #include "clinic/_winapi.c.h" diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index 0b1f6103de949f..48558372858de7 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -2777,26 +2777,26 @@ the type of objects stored in them is constrained. The type is specified\n\ at object creation time by using a type code, which is a single character.\n\ The following type codes are defined:\n\ \n\ - Type code C Type Minimum size in bytes \n\ - 'b' signed integer 1 \n\ - 'B' unsigned integer 1 \n\ - 'u' Unicode character 2 (see note) \n\ - 'h' signed integer 2 \n\ - 'H' unsigned integer 2 \n\ - 'i' signed integer 2 \n\ - 'I' unsigned integer 2 \n\ - 'l' signed integer 4 \n\ - 'L' unsigned integer 4 \n\ - 'q' signed integer 8 (see note) \n\ - 'Q' unsigned integer 8 (see note) \n\ - 'f' floating point 4 \n\ - 'd' floating point 8 \n\ + Type code C Type Minimum size in bytes\n\ + 'b' signed integer 1\n\ + 'B' unsigned integer 1\n\ + 'u' Unicode character 2 (see note)\n\ + 'h' signed integer 2\n\ + 'H' unsigned integer 2\n\ + 'i' signed integer 2\n\ + 'I' unsigned integer 2\n\ + 'l' signed integer 4\n\ + 'L' unsigned integer 4\n\ + 'q' signed integer 8 (see note)\n\ + 'Q' unsigned integer 8 (see note)\n\ + 'f' floating point 4\n\ + 'd' floating point 8\n\ \n\ -NOTE: The 'u' typecode corresponds to Python's unicode character. On \n\ +NOTE: The 'u' typecode corresponds to Python's unicode character. On\n\ narrow builds this is 2-bytes on wide builds this is 4-bytes.\n\ \n\ -NOTE: The 'q' and 'Q' type codes are only available if the platform \n\ -C compiler used to build Python supports 'long long', or, on Windows, \n\ +NOTE: The 'q' and 'Q' type codes are only available if the platform\n\ +C compiler used to build Python supports 'long long', or, on Windows,\n\ '__int64'.\n\ \n\ Methods:\n\ diff --git a/Modules/binascii.c b/Modules/binascii.c index 2df80affb69564..5667018d6e1bfa 100644 --- a/Modules/binascii.c +++ b/Modules/binascii.c @@ -1141,21 +1141,6 @@ binascii_hexlify_impl(PyObject *module, Py_buffer *data) return _Py_strhex_bytes((const char *)data->buf, data->len); } -static int -to_int(int c) -{ - if (Py_ISDIGIT(c)) - return c - '0'; - else { - if (Py_ISUPPER(c)) - c = Py_TOLOWER(c); - if (c >= 'a' && c <= 'f') - return c - 'a' + 10; - } - return -1; -} - - /*[clinic input] binascii.a2b_hex @@ -1198,9 +1183,9 @@ binascii_a2b_hex_impl(PyObject *module, Py_buffer *hexstr) retbuf = PyBytes_AS_STRING(retval); for (i=j=0; i < arglen; i += 2) { - int top = to_int(Py_CHARMASK(argbuf[i])); - int bot = to_int(Py_CHARMASK(argbuf[i+1])); - if (top == -1 || bot == -1) { + unsigned int top = _PyLong_DigitValue[Py_CHARMASK(argbuf[i])]; + unsigned int bot = _PyLong_DigitValue[Py_CHARMASK(argbuf[i+1])]; + if (top >= 16 || bot >= 16) { PyErr_SetString(Error, "Non-hexadecimal digit found"); goto finally; @@ -1229,19 +1214,6 @@ binascii_unhexlify_impl(PyObject *module, Py_buffer *hexstr) return binascii_a2b_hex_impl(module, hexstr); } -static const int table_hex[128] = { - -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, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1, -1,-1,-1,-1, - -1,10,11,12, 13,14,15,-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,10,11,12, 13,14,15,-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 -}; - -#define hexval(c) table_hex[(unsigned int)(c)] - #define MAXLINESIZE 76 @@ -1304,9 +1276,9 @@ binascii_a2b_qp_impl(PyObject *module, Py_buffer *data, int header) (ascii_data[in+1] >= 'a' && ascii_data[in+1] <= 'f') || (ascii_data[in+1] >= '0' && ascii_data[in+1] <= '9'))) { /* hexval */ - ch = hexval(ascii_data[in]) << 4; + ch = _PyLong_DigitValue[ascii_data[in]] << 4; in++; - ch |= hexval(ascii_data[in]); + ch |= _PyLong_DigitValue[ascii_data[in]]; in++; odata[out++] = ch; } diff --git a/Modules/clinic/_curses_panel.c.h b/Modules/clinic/_curses_panel.c.h new file mode 100644 index 00000000000000..e11c68d864a6b3 --- /dev/null +++ b/Modules/clinic/_curses_panel.c.h @@ -0,0 +1,317 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_curses_panel_panel_bottom__doc__, +"bottom($self, /)\n" +"--\n" +"\n" +"Push the panel to the bottom of the stack."); + +#define _CURSES_PANEL_PANEL_BOTTOM_METHODDEF \ + {"bottom", (PyCFunction)_curses_panel_panel_bottom, METH_NOARGS, _curses_panel_panel_bottom__doc__}, + +static PyObject * +_curses_panel_panel_bottom_impl(PyCursesPanelObject *self); + +static PyObject * +_curses_panel_panel_bottom(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _curses_panel_panel_bottom_impl(self); +} + +PyDoc_STRVAR(_curses_panel_panel_hide__doc__, +"hide($self, /)\n" +"--\n" +"\n" +"Hide the panel.\n" +"\n" +"This does not delete the object, it just makes the window on screen invisible."); + +#define _CURSES_PANEL_PANEL_HIDE_METHODDEF \ + {"hide", (PyCFunction)_curses_panel_panel_hide, METH_NOARGS, _curses_panel_panel_hide__doc__}, + +static PyObject * +_curses_panel_panel_hide_impl(PyCursesPanelObject *self); + +static PyObject * +_curses_panel_panel_hide(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _curses_panel_panel_hide_impl(self); +} + +PyDoc_STRVAR(_curses_panel_panel_show__doc__, +"show($self, /)\n" +"--\n" +"\n" +"Display the panel (which might have been hidden)."); + +#define _CURSES_PANEL_PANEL_SHOW_METHODDEF \ + {"show", (PyCFunction)_curses_panel_panel_show, METH_NOARGS, _curses_panel_panel_show__doc__}, + +static PyObject * +_curses_panel_panel_show_impl(PyCursesPanelObject *self); + +static PyObject * +_curses_panel_panel_show(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _curses_panel_panel_show_impl(self); +} + +PyDoc_STRVAR(_curses_panel_panel_top__doc__, +"top($self, /)\n" +"--\n" +"\n" +"Push panel to the top of the stack."); + +#define _CURSES_PANEL_PANEL_TOP_METHODDEF \ + {"top", (PyCFunction)_curses_panel_panel_top, METH_NOARGS, _curses_panel_panel_top__doc__}, + +static PyObject * +_curses_panel_panel_top_impl(PyCursesPanelObject *self); + +static PyObject * +_curses_panel_panel_top(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _curses_panel_panel_top_impl(self); +} + +PyDoc_STRVAR(_curses_panel_panel_above__doc__, +"above($self, /)\n" +"--\n" +"\n" +"Return the panel above the current panel."); + +#define _CURSES_PANEL_PANEL_ABOVE_METHODDEF \ + {"above", (PyCFunction)_curses_panel_panel_above, METH_NOARGS, _curses_panel_panel_above__doc__}, + +static PyObject * +_curses_panel_panel_above_impl(PyCursesPanelObject *self); + +static PyObject * +_curses_panel_panel_above(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _curses_panel_panel_above_impl(self); +} + +PyDoc_STRVAR(_curses_panel_panel_below__doc__, +"below($self, /)\n" +"--\n" +"\n" +"Return the panel below the current panel."); + +#define _CURSES_PANEL_PANEL_BELOW_METHODDEF \ + {"below", (PyCFunction)_curses_panel_panel_below, METH_NOARGS, _curses_panel_panel_below__doc__}, + +static PyObject * +_curses_panel_panel_below_impl(PyCursesPanelObject *self); + +static PyObject * +_curses_panel_panel_below(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _curses_panel_panel_below_impl(self); +} + +PyDoc_STRVAR(_curses_panel_panel_hidden__doc__, +"hidden($self, /)\n" +"--\n" +"\n" +"Return True if the panel is hidden (not visible), False otherwise."); + +#define _CURSES_PANEL_PANEL_HIDDEN_METHODDEF \ + {"hidden", (PyCFunction)_curses_panel_panel_hidden, METH_NOARGS, _curses_panel_panel_hidden__doc__}, + +static PyObject * +_curses_panel_panel_hidden_impl(PyCursesPanelObject *self); + +static PyObject * +_curses_panel_panel_hidden(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _curses_panel_panel_hidden_impl(self); +} + +PyDoc_STRVAR(_curses_panel_panel_move__doc__, +"move($self, y, x, /)\n" +"--\n" +"\n" +"Move the panel to the screen coordinates (y, x)."); + +#define _CURSES_PANEL_PANEL_MOVE_METHODDEF \ + {"move", (PyCFunction)_curses_panel_panel_move, METH_FASTCALL, _curses_panel_panel_move__doc__}, + +static PyObject * +_curses_panel_panel_move_impl(PyCursesPanelObject *self, int y, int x); + +static PyObject * +_curses_panel_panel_move(PyCursesPanelObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int y; + int x; + + if (!_PyArg_ParseStack(args, nargs, "ii:move", + &y, &x)) { + goto exit; + } + return_value = _curses_panel_panel_move_impl(self, y, x); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_panel_panel_window__doc__, +"window($self, /)\n" +"--\n" +"\n" +"Return the window object associated with the panel."); + +#define _CURSES_PANEL_PANEL_WINDOW_METHODDEF \ + {"window", (PyCFunction)_curses_panel_panel_window, METH_NOARGS, _curses_panel_panel_window__doc__}, + +static PyObject * +_curses_panel_panel_window_impl(PyCursesPanelObject *self); + +static PyObject * +_curses_panel_panel_window(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _curses_panel_panel_window_impl(self); +} + +PyDoc_STRVAR(_curses_panel_panel_replace__doc__, +"replace($self, win, /)\n" +"--\n" +"\n" +"Change the window associated with the panel to the window win."); + +#define _CURSES_PANEL_PANEL_REPLACE_METHODDEF \ + {"replace", (PyCFunction)_curses_panel_panel_replace, METH_O, _curses_panel_panel_replace__doc__}, + +static PyObject * +_curses_panel_panel_replace_impl(PyCursesPanelObject *self, + PyCursesWindowObject *win); + +static PyObject * +_curses_panel_panel_replace(PyCursesPanelObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + PyCursesWindowObject *win; + + if (!PyArg_Parse(arg, "O!:replace", &PyCursesWindow_Type, &win)) { + goto exit; + } + return_value = _curses_panel_panel_replace_impl(self, win); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_panel_panel_set_userptr__doc__, +"set_userptr($self, obj, /)\n" +"--\n" +"\n" +"Set the panel’s user pointer to obj."); + +#define _CURSES_PANEL_PANEL_SET_USERPTR_METHODDEF \ + {"set_userptr", (PyCFunction)_curses_panel_panel_set_userptr, METH_O, _curses_panel_panel_set_userptr__doc__}, + +PyDoc_STRVAR(_curses_panel_panel_userptr__doc__, +"userptr($self, /)\n" +"--\n" +"\n" +"Return the user pointer for the panel."); + +#define _CURSES_PANEL_PANEL_USERPTR_METHODDEF \ + {"userptr", (PyCFunction)_curses_panel_panel_userptr, METH_NOARGS, _curses_panel_panel_userptr__doc__}, + +static PyObject * +_curses_panel_panel_userptr_impl(PyCursesPanelObject *self); + +static PyObject * +_curses_panel_panel_userptr(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _curses_panel_panel_userptr_impl(self); +} + +PyDoc_STRVAR(_curses_panel_bottom_panel__doc__, +"bottom_panel($module, /)\n" +"--\n" +"\n" +"Return the bottom panel in the panel stack."); + +#define _CURSES_PANEL_BOTTOM_PANEL_METHODDEF \ + {"bottom_panel", (PyCFunction)_curses_panel_bottom_panel, METH_NOARGS, _curses_panel_bottom_panel__doc__}, + +static PyObject * +_curses_panel_bottom_panel_impl(PyObject *module); + +static PyObject * +_curses_panel_bottom_panel(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_panel_bottom_panel_impl(module); +} + +PyDoc_STRVAR(_curses_panel_new_panel__doc__, +"new_panel($module, win, /)\n" +"--\n" +"\n" +"Return a panel object, associating it with the given window win."); + +#define _CURSES_PANEL_NEW_PANEL_METHODDEF \ + {"new_panel", (PyCFunction)_curses_panel_new_panel, METH_O, _curses_panel_new_panel__doc__}, + +static PyObject * +_curses_panel_new_panel_impl(PyObject *module, PyCursesWindowObject *win); + +static PyObject * +_curses_panel_new_panel(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyCursesWindowObject *win; + + if (!PyArg_Parse(arg, "O!:new_panel", &PyCursesWindow_Type, &win)) { + goto exit; + } + return_value = _curses_panel_new_panel_impl(module, win); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_panel_top_panel__doc__, +"top_panel($module, /)\n" +"--\n" +"\n" +"Return the top panel in the panel stack."); + +#define _CURSES_PANEL_TOP_PANEL_METHODDEF \ + {"top_panel", (PyCFunction)_curses_panel_top_panel, METH_NOARGS, _curses_panel_top_panel__doc__}, + +static PyObject * +_curses_panel_top_panel_impl(PyObject *module); + +static PyObject * +_curses_panel_top_panel(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_panel_top_panel_impl(module); +} + +PyDoc_STRVAR(_curses_panel_update_panels__doc__, +"update_panels($module, /)\n" +"--\n" +"\n" +"Updates the virtual screen after changes in the panel stack.\n" +"\n" +"This does not call curses.doupdate(), so you’ll have to do this yourself."); + +#define _CURSES_PANEL_UPDATE_PANELS_METHODDEF \ + {"update_panels", (PyCFunction)_curses_panel_update_panels, METH_NOARGS, _curses_panel_update_panels__doc__}, + +static PyObject * +_curses_panel_update_panels_impl(PyObject *module); + +static PyObject * +_curses_panel_update_panels(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_panel_update_panels_impl(module); +} +/*[clinic end generated code: output=96f627ca0b08b96d input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_cursesmodule.c.h b/Modules/clinic/_cursesmodule.c.h index 62ff1c8ae18a5a..b32797fc74ee92 100644 --- a/Modules/clinic/_cursesmodule.c.h +++ b/Modules/clinic/_cursesmodule.c.h @@ -2,9 +2,9 @@ preserve [clinic start generated code]*/ -PyDoc_STRVAR(curses_window_addch__doc__, -"addch([y, x,] ch, [attr])\n" -"Paint character ch at (y, x) with attributes attr.\n" +PyDoc_STRVAR(_curses_window_addch__doc__, +"addch([y, x,] ch, [attr=_curses.A_NORMAL])\n" +"Paint the character.\n" "\n" " y\n" " Y-coordinate.\n" @@ -20,15 +20,16 @@ PyDoc_STRVAR(curses_window_addch__doc__, "By default, the character position and attributes are the\n" "current settings for the window object."); -#define CURSES_WINDOW_ADDCH_METHODDEF \ - {"addch", (PyCFunction)curses_window_addch, METH_VARARGS, curses_window_addch__doc__}, +#define _CURSES_WINDOW_ADDCH_METHODDEF \ + {"addch", (PyCFunction)_curses_window_addch, METH_VARARGS, _curses_window_addch__doc__}, static PyObject * -curses_window_addch_impl(PyCursesWindowObject *self, int group_left_1, int y, - int x, 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(PyCursesWindowObject *self, PyObject *args) +_curses_window_addch(PyCursesWindowObject *self, PyObject *args) { PyObject *return_value = NULL; int group_left_1 = 0; @@ -36,7 +37,7 @@ curses_window_addch(PyCursesWindowObject *self, PyObject *args) int x = 0; PyObject *ch; int group_right_1 = 0; - long attr = 0; + long attr = A_NORMAL; switch (PyTuple_GET_SIZE(args)) { case 1: @@ -64,12 +65,3777 @@ curses_window_addch(PyCursesWindowObject *self, PyObject *args) group_left_1 = 1; break; default: - PyErr_SetString(PyExc_TypeError, "curses.window.addch requires 1 to 4 arguments"); + PyErr_SetString(PyExc_TypeError, "_curses.window.addch requires 1 to 4 arguments"); + goto exit; + } + return_value = _curses_window_addch_impl(self, group_left_1, y, x, ch, group_right_1, attr); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_addstr__doc__, +"addstr([y, x,] str, [attr])\n" +"Paint the string.\n" +"\n" +" y\n" +" Y-coordinate.\n" +" x\n" +" X-coordinate.\n" +" str\n" +" String to add.\n" +" attr\n" +" Attributes for characters.\n" +"\n" +"Paint the string str at (y, x) with attributes attr,\n" +"overwriting anything previously on the display.\n" +"By default, the character position and attributes are the\n" +"current settings for the window object."); + +#define _CURSES_WINDOW_ADDSTR_METHODDEF \ + {"addstr", (PyCFunction)_curses_window_addstr, METH_VARARGS, _curses_window_addstr__doc__}, + +static PyObject * +_curses_window_addstr_impl(PyCursesWindowObject *self, int group_left_1, + int y, int x, PyObject *str, int group_right_1, + long attr); + +static PyObject * +_curses_window_addstr(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_left_1 = 0; + int y = 0; + int x = 0; + PyObject *str; + int group_right_1 = 0; + long attr = 0; + + switch (PyTuple_GET_SIZE(args)) { + case 1: + if (!PyArg_ParseTuple(args, "O:addstr", &str)) { + goto exit; + } + break; + case 2: + if (!PyArg_ParseTuple(args, "Ol:addstr", &str, &attr)) { + goto exit; + } + group_right_1 = 1; + break; + case 3: + if (!PyArg_ParseTuple(args, "iiO:addstr", &y, &x, &str)) { + goto exit; + } + group_left_1 = 1; + break; + case 4: + if (!PyArg_ParseTuple(args, "iiOl:addstr", &y, &x, &str, &attr)) { + goto exit; + } + group_right_1 = 1; + group_left_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.addstr requires 1 to 4 arguments"); + goto exit; + } + return_value = _curses_window_addstr_impl(self, group_left_1, y, x, str, group_right_1, attr); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_addnstr__doc__, +"addnstr([y, x,] str, n, [attr])\n" +"Paint at most n characters of the string.\n" +"\n" +" y\n" +" Y-coordinate.\n" +" x\n" +" X-coordinate.\n" +" str\n" +" String to add.\n" +" n\n" +" Maximal number of characters.\n" +" attr\n" +" Attributes for characters.\n" +"\n" +"Paint at most n characters of the string str at (y, x) with\n" +"attributes attr, overwriting anything previously on the display.\n" +"By default, the character position and attributes are the\n" +"current settings for the window object."); + +#define _CURSES_WINDOW_ADDNSTR_METHODDEF \ + {"addnstr", (PyCFunction)_curses_window_addnstr, METH_VARARGS, _curses_window_addnstr__doc__}, + +static PyObject * +_curses_window_addnstr_impl(PyCursesWindowObject *self, int group_left_1, + int y, int x, PyObject *str, int n, + int group_right_1, long attr); + +static PyObject * +_curses_window_addnstr(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_left_1 = 0; + int y = 0; + int x = 0; + PyObject *str; + int n; + int group_right_1 = 0; + long attr = 0; + + switch (PyTuple_GET_SIZE(args)) { + case 2: + if (!PyArg_ParseTuple(args, "Oi:addnstr", &str, &n)) { + goto exit; + } + break; + case 3: + if (!PyArg_ParseTuple(args, "Oil:addnstr", &str, &n, &attr)) { + goto exit; + } + group_right_1 = 1; + break; + case 4: + if (!PyArg_ParseTuple(args, "iiOi:addnstr", &y, &x, &str, &n)) { + goto exit; + } + group_left_1 = 1; + break; + case 5: + if (!PyArg_ParseTuple(args, "iiOil:addnstr", &y, &x, &str, &n, &attr)) { + goto exit; + } + group_right_1 = 1; + group_left_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.addnstr requires 2 to 5 arguments"); + goto exit; + } + return_value = _curses_window_addnstr_impl(self, group_left_1, y, x, str, n, group_right_1, attr); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_bkgd__doc__, +"bkgd($self, ch, attr=_curses.A_NORMAL, /)\n" +"--\n" +"\n" +"Set the background property of the window.\n" +"\n" +" ch\n" +" Background character.\n" +" attr\n" +" Background attributes."); + +#define _CURSES_WINDOW_BKGD_METHODDEF \ + {"bkgd", (PyCFunction)_curses_window_bkgd, METH_FASTCALL, _curses_window_bkgd__doc__}, + +static PyObject * +_curses_window_bkgd_impl(PyCursesWindowObject *self, PyObject *ch, long attr); + +static PyObject * +_curses_window_bkgd(PyCursesWindowObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *ch; + long attr = A_NORMAL; + + if (!_PyArg_ParseStack(args, nargs, "O|l:bkgd", + &ch, &attr)) { + goto exit; + } + return_value = _curses_window_bkgd_impl(self, ch, attr); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_attroff__doc__, +"attroff($self, attr, /)\n" +"--\n" +"\n" +"Remove attribute attr from the \"background\" set."); + +#define _CURSES_WINDOW_ATTROFF_METHODDEF \ + {"attroff", (PyCFunction)_curses_window_attroff, METH_O, _curses_window_attroff__doc__}, + +static PyObject * +_curses_window_attroff_impl(PyCursesWindowObject *self, long attr); + +static PyObject * +_curses_window_attroff(PyCursesWindowObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + long attr; + + if (!PyArg_Parse(arg, "l:attroff", &attr)) { + goto exit; + } + return_value = _curses_window_attroff_impl(self, attr); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_attron__doc__, +"attron($self, attr, /)\n" +"--\n" +"\n" +"Add attribute attr from the \"background\" set."); + +#define _CURSES_WINDOW_ATTRON_METHODDEF \ + {"attron", (PyCFunction)_curses_window_attron, METH_O, _curses_window_attron__doc__}, + +static PyObject * +_curses_window_attron_impl(PyCursesWindowObject *self, long attr); + +static PyObject * +_curses_window_attron(PyCursesWindowObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + long attr; + + if (!PyArg_Parse(arg, "l:attron", &attr)) { + goto exit; + } + return_value = _curses_window_attron_impl(self, attr); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_attrset__doc__, +"attrset($self, attr, /)\n" +"--\n" +"\n" +"Set the \"background\" set of attributes."); + +#define _CURSES_WINDOW_ATTRSET_METHODDEF \ + {"attrset", (PyCFunction)_curses_window_attrset, METH_O, _curses_window_attrset__doc__}, + +static PyObject * +_curses_window_attrset_impl(PyCursesWindowObject *self, long attr); + +static PyObject * +_curses_window_attrset(PyCursesWindowObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + long attr; + + if (!PyArg_Parse(arg, "l:attrset", &attr)) { + goto exit; + } + return_value = _curses_window_attrset_impl(self, attr); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_bkgdset__doc__, +"bkgdset($self, ch, attr=_curses.A_NORMAL, /)\n" +"--\n" +"\n" +"Set the window\'s background.\n" +"\n" +" ch\n" +" Background character.\n" +" attr\n" +" Background attributes."); + +#define _CURSES_WINDOW_BKGDSET_METHODDEF \ + {"bkgdset", (PyCFunction)_curses_window_bkgdset, METH_FASTCALL, _curses_window_bkgdset__doc__}, + +static PyObject * +_curses_window_bkgdset_impl(PyCursesWindowObject *self, PyObject *ch, + long attr); + +static PyObject * +_curses_window_bkgdset(PyCursesWindowObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *ch; + long attr = A_NORMAL; + + if (!_PyArg_ParseStack(args, nargs, "O|l:bkgdset", + &ch, &attr)) { + goto exit; + } + return_value = _curses_window_bkgdset_impl(self, ch, attr); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_border__doc__, +"border($self, ls=_curses.ACS_VLINE, rs=_curses.ACS_VLINE,\n" +" ts=_curses.ACS_HLINE, bs=_curses.ACS_HLINE,\n" +" tl=_curses.ACS_ULCORNER, tr=_curses.ACS_URCORNER,\n" +" bl=_curses.ACS_LLCORNER, br=_curses.ACS_LRCORNER, /)\n" +"--\n" +"\n" +"Draw a border around the edges of the window.\n" +"\n" +" ls\n" +" Left side.\n" +" rs\n" +" Right side.\n" +" ts\n" +" Top side.\n" +" bs\n" +" Bottom side.\n" +" tl\n" +" Upper-left corner.\n" +" tr\n" +" Upper-right corner.\n" +" bl\n" +" Bottom-left corner.\n" +" br\n" +" Bottom-right corner.\n" +"\n" +"Each parameter specifies the character to use for a specific part of the\n" +"border. The characters can be specified as integers or as one-character\n" +"strings. A 0 value for any parameter will cause the default character to be\n" +"used for that parameter."); + +#define _CURSES_WINDOW_BORDER_METHODDEF \ + {"border", (PyCFunction)_curses_window_border, METH_FASTCALL, _curses_window_border__doc__}, + +static PyObject * +_curses_window_border_impl(PyCursesWindowObject *self, PyObject *ls, + PyObject *rs, PyObject *ts, PyObject *bs, + PyObject *tl, PyObject *tr, PyObject *bl, + PyObject *br); + +static PyObject * +_curses_window_border(PyCursesWindowObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *ls = NULL; + PyObject *rs = NULL; + PyObject *ts = NULL; + PyObject *bs = NULL; + PyObject *tl = NULL; + PyObject *tr = NULL; + PyObject *bl = NULL; + PyObject *br = NULL; + + if (!_PyArg_UnpackStack(args, nargs, "border", + 0, 8, + &ls, &rs, &ts, &bs, &tl, &tr, &bl, &br)) { + goto exit; + } + return_value = _curses_window_border_impl(self, ls, rs, ts, bs, tl, tr, bl, br); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_box__doc__, +"box([verch=0, horch=0])\n" +"Draw a border around the edges of the window.\n" +"\n" +" verch\n" +" Left and right side.\n" +" horch\n" +" Top and bottom side.\n" +"\n" +"Similar to border(), but both ls and rs are verch and both ts and bs are\n" +"horch. The default corner characters are always used by this function."); + +#define _CURSES_WINDOW_BOX_METHODDEF \ + {"box", (PyCFunction)_curses_window_box, METH_VARARGS, _curses_window_box__doc__}, + +static PyObject * +_curses_window_box_impl(PyCursesWindowObject *self, int group_right_1, + PyObject *verch, PyObject *horch); + +static PyObject * +_curses_window_box(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_right_1 = 0; + PyObject *verch = _PyLong_Zero; + PyObject *horch = _PyLong_Zero; + + switch (PyTuple_GET_SIZE(args)) { + case 0: + break; + case 2: + if (!PyArg_ParseTuple(args, "OO:box", &verch, &horch)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.box requires 0 to 2 arguments"); goto exit; } - return_value = curses_window_addch_impl(self, group_left_1, y, x, ch, group_right_1, attr); + return_value = _curses_window_box_impl(self, group_right_1, verch, horch); exit: return return_value; } -/*[clinic end generated code: output=13ffc5f8d79cbfbf input=a9049054013a1b77]*/ + +PyDoc_STRVAR(_curses_window_delch__doc__, +"delch([y, x])\n" +"Delete any character at (y, x).\n" +"\n" +" y\n" +" Y-coordinate.\n" +" x\n" +" X-coordinate."); + +#define _CURSES_WINDOW_DELCH_METHODDEF \ + {"delch", (PyCFunction)_curses_window_delch, METH_VARARGS, _curses_window_delch__doc__}, + +static PyObject * +_curses_window_delch_impl(PyCursesWindowObject *self, int group_right_1, + int y, int x); + +static PyObject * +_curses_window_delch(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_right_1 = 0; + int y = 0; + int x = 0; + + switch (PyTuple_GET_SIZE(args)) { + case 0: + break; + case 2: + if (!PyArg_ParseTuple(args, "ii:delch", &y, &x)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.delch requires 0 to 2 arguments"); + goto exit; + } + return_value = _curses_window_delch_impl(self, group_right_1, y, x); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_derwin__doc__, +"derwin([nlines=0, ncols=0,] begin_y, begin_x)\n" +"Create a sub-window (window-relative coordinates).\n" +"\n" +" nlines\n" +" Height.\n" +" ncols\n" +" Width.\n" +" begin_y\n" +" Top side y-coordinate.\n" +" begin_x\n" +" Left side x-coordinate.\n" +"\n" +"derwin() is the same as calling subwin(), except that begin_y and begin_x\n" +"are relative to the origin of the window, rather than relative to the entire\n" +"screen."); + +#define _CURSES_WINDOW_DERWIN_METHODDEF \ + {"derwin", (PyCFunction)_curses_window_derwin, METH_VARARGS, _curses_window_derwin__doc__}, + +static PyObject * +_curses_window_derwin_impl(PyCursesWindowObject *self, int group_left_1, + int nlines, int ncols, int begin_y, int begin_x); + +static PyObject * +_curses_window_derwin(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_left_1 = 0; + int nlines = 0; + int ncols = 0; + int begin_y; + int begin_x; + + switch (PyTuple_GET_SIZE(args)) { + case 2: + if (!PyArg_ParseTuple(args, "ii:derwin", &begin_y, &begin_x)) { + goto exit; + } + break; + case 4: + if (!PyArg_ParseTuple(args, "iiii:derwin", &nlines, &ncols, &begin_y, &begin_x)) { + goto exit; + } + group_left_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.derwin requires 2 to 4 arguments"); + goto exit; + } + return_value = _curses_window_derwin_impl(self, group_left_1, nlines, ncols, begin_y, begin_x); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_echochar__doc__, +"echochar($self, ch, attr=_curses.A_NORMAL, /)\n" +"--\n" +"\n" +"Add character ch with attribute attr, and refresh.\n" +"\n" +" ch\n" +" Character to add.\n" +" attr\n" +" Attributes for the character."); + +#define _CURSES_WINDOW_ECHOCHAR_METHODDEF \ + {"echochar", (PyCFunction)_curses_window_echochar, METH_FASTCALL, _curses_window_echochar__doc__}, + +static PyObject * +_curses_window_echochar_impl(PyCursesWindowObject *self, PyObject *ch, + long attr); + +static PyObject * +_curses_window_echochar(PyCursesWindowObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *ch; + long attr = A_NORMAL; + + if (!_PyArg_ParseStack(args, nargs, "O|l:echochar", + &ch, &attr)) { + goto exit; + } + return_value = _curses_window_echochar_impl(self, ch, attr); + +exit: + return return_value; +} + +#if defined(NCURSES_MOUSE_VERSION) + +PyDoc_STRVAR(_curses_window_enclose__doc__, +"enclose($self, y, x, /)\n" +"--\n" +"\n" +"Return True if the screen-relative coordinates are enclosed by the window.\n" +"\n" +" y\n" +" Y-coordinate.\n" +" x\n" +" X-coordinate."); + +#define _CURSES_WINDOW_ENCLOSE_METHODDEF \ + {"enclose", (PyCFunction)_curses_window_enclose, METH_FASTCALL, _curses_window_enclose__doc__}, + +static long +_curses_window_enclose_impl(PyCursesWindowObject *self, int y, int x); + +static PyObject * +_curses_window_enclose(PyCursesWindowObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int y; + int x; + long _return_value; + + if (!_PyArg_ParseStack(args, nargs, "ii:enclose", + &y, &x)) { + goto exit; + } + _return_value = _curses_window_enclose_impl(self, y, x); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong(_return_value); + +exit: + return return_value; +} + +#endif /* defined(NCURSES_MOUSE_VERSION) */ + +PyDoc_STRVAR(_curses_window_getbkgd__doc__, +"getbkgd($self, /)\n" +"--\n" +"\n" +"Return the window\'s current background character/attribute pair."); + +#define _CURSES_WINDOW_GETBKGD_METHODDEF \ + {"getbkgd", (PyCFunction)_curses_window_getbkgd, METH_NOARGS, _curses_window_getbkgd__doc__}, + +static long +_curses_window_getbkgd_impl(PyCursesWindowObject *self); + +static PyObject * +_curses_window_getbkgd(PyCursesWindowObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + long _return_value; + + _return_value = _curses_window_getbkgd_impl(self); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong(_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_getch__doc__, +"getch([y, x])\n" +"Get a character code from terminal keyboard.\n" +"\n" +" y\n" +" Y-coordinate.\n" +" x\n" +" X-coordinate.\n" +"\n" +"The integer returned does not have to be in ASCII range: function keys,\n" +"keypad keys and so on return numbers higher than 256. In no-delay mode, -1\n" +"is returned if there is no input, else getch() waits until a key is pressed."); + +#define _CURSES_WINDOW_GETCH_METHODDEF \ + {"getch", (PyCFunction)_curses_window_getch, METH_VARARGS, _curses_window_getch__doc__}, + +static int +_curses_window_getch_impl(PyCursesWindowObject *self, int group_right_1, + int y, int x); + +static PyObject * +_curses_window_getch(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_right_1 = 0; + int y = 0; + int x = 0; + int _return_value; + + switch (PyTuple_GET_SIZE(args)) { + case 0: + break; + case 2: + if (!PyArg_ParseTuple(args, "ii:getch", &y, &x)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.getch requires 0 to 2 arguments"); + goto exit; + } + _return_value = _curses_window_getch_impl(self, group_right_1, y, x); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong((long)_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_getkey__doc__, +"getkey([y, x])\n" +"Get a character (string) from terminal keyboard.\n" +"\n" +" y\n" +" Y-coordinate.\n" +" x\n" +" X-coordinate.\n" +"\n" +"Returning a string instead of an integer, as getch() does. Function keys,\n" +"keypad keys and other special keys return a multibyte string containing the\n" +"key name. In no-delay mode, an exception is raised if there is no input."); + +#define _CURSES_WINDOW_GETKEY_METHODDEF \ + {"getkey", (PyCFunction)_curses_window_getkey, METH_VARARGS, _curses_window_getkey__doc__}, + +static PyObject * +_curses_window_getkey_impl(PyCursesWindowObject *self, int group_right_1, + int y, int x); + +static PyObject * +_curses_window_getkey(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_right_1 = 0; + int y = 0; + int x = 0; + + switch (PyTuple_GET_SIZE(args)) { + case 0: + break; + case 2: + if (!PyArg_ParseTuple(args, "ii:getkey", &y, &x)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.getkey requires 0 to 2 arguments"); + goto exit; + } + return_value = _curses_window_getkey_impl(self, group_right_1, y, x); + +exit: + return return_value; +} + +#if defined(HAVE_NCURSESW) + +PyDoc_STRVAR(_curses_window_get_wch__doc__, +"get_wch([y, x])\n" +"Get a wide character from terminal keyboard.\n" +"\n" +" y\n" +" Y-coordinate.\n" +" x\n" +" X-coordinate.\n" +"\n" +"Return a character for most keys, or an integer for function keys,\n" +"keypad keys, and other special keys."); + +#define _CURSES_WINDOW_GET_WCH_METHODDEF \ + {"get_wch", (PyCFunction)_curses_window_get_wch, METH_VARARGS, _curses_window_get_wch__doc__}, + +static PyObject * +_curses_window_get_wch_impl(PyCursesWindowObject *self, int group_right_1, + int y, int x); + +static PyObject * +_curses_window_get_wch(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_right_1 = 0; + int y = 0; + int x = 0; + + switch (PyTuple_GET_SIZE(args)) { + case 0: + break; + case 2: + if (!PyArg_ParseTuple(args, "ii:get_wch", &y, &x)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.get_wch requires 0 to 2 arguments"); + goto exit; + } + return_value = _curses_window_get_wch_impl(self, group_right_1, y, x); + +exit: + return return_value; +} + +#endif /* defined(HAVE_NCURSESW) */ + +PyDoc_STRVAR(_curses_window_hline__doc__, +"hline([y, x,] ch, n, [attr=_curses.A_NORMAL])\n" +"Display a horizontal line.\n" +"\n" +" y\n" +" Starting Y-coordinate.\n" +" x\n" +" Starting X-coordinate.\n" +" ch\n" +" Character to draw.\n" +" n\n" +" Line length.\n" +" attr\n" +" Attributes for the characters."); + +#define _CURSES_WINDOW_HLINE_METHODDEF \ + {"hline", (PyCFunction)_curses_window_hline, METH_VARARGS, _curses_window_hline__doc__}, + +static PyObject * +_curses_window_hline_impl(PyCursesWindowObject *self, int group_left_1, + int y, int x, PyObject *ch, int n, + int group_right_1, long attr); + +static PyObject * +_curses_window_hline(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_left_1 = 0; + int y = 0; + int x = 0; + PyObject *ch; + int n; + int group_right_1 = 0; + long attr = A_NORMAL; + + switch (PyTuple_GET_SIZE(args)) { + case 2: + if (!PyArg_ParseTuple(args, "Oi:hline", &ch, &n)) { + goto exit; + } + break; + case 3: + if (!PyArg_ParseTuple(args, "Oil:hline", &ch, &n, &attr)) { + goto exit; + } + group_right_1 = 1; + break; + case 4: + if (!PyArg_ParseTuple(args, "iiOi:hline", &y, &x, &ch, &n)) { + goto exit; + } + group_left_1 = 1; + break; + case 5: + if (!PyArg_ParseTuple(args, "iiOil:hline", &y, &x, &ch, &n, &attr)) { + goto exit; + } + group_right_1 = 1; + group_left_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.hline requires 2 to 5 arguments"); + goto exit; + } + return_value = _curses_window_hline_impl(self, group_left_1, y, x, ch, n, group_right_1, attr); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_insch__doc__, +"insch([y, x,] ch, [attr=_curses.A_NORMAL])\n" +"Insert a character before the current or specified position.\n" +"\n" +" y\n" +" Y-coordinate.\n" +" x\n" +" X-coordinate.\n" +" ch\n" +" Character to insert.\n" +" attr\n" +" Attributes for the character.\n" +"\n" +"All characters to the right of the cursor are shifted one position right, with\n" +"the rightmost characters on the line being lost."); + +#define _CURSES_WINDOW_INSCH_METHODDEF \ + {"insch", (PyCFunction)_curses_window_insch, METH_VARARGS, _curses_window_insch__doc__}, + +static PyObject * +_curses_window_insch_impl(PyCursesWindowObject *self, int group_left_1, + int y, int x, PyObject *ch, int group_right_1, + long attr); + +static PyObject * +_curses_window_insch(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_left_1 = 0; + int y = 0; + int x = 0; + PyObject *ch; + int group_right_1 = 0; + long attr = A_NORMAL; + + switch (PyTuple_GET_SIZE(args)) { + case 1: + if (!PyArg_ParseTuple(args, "O:insch", &ch)) { + goto exit; + } + break; + case 2: + if (!PyArg_ParseTuple(args, "Ol:insch", &ch, &attr)) { + goto exit; + } + group_right_1 = 1; + break; + case 3: + if (!PyArg_ParseTuple(args, "iiO:insch", &y, &x, &ch)) { + goto exit; + } + group_left_1 = 1; + break; + case 4: + if (!PyArg_ParseTuple(args, "iiOl:insch", &y, &x, &ch, &attr)) { + goto exit; + } + group_right_1 = 1; + group_left_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.insch requires 1 to 4 arguments"); + goto exit; + } + return_value = _curses_window_insch_impl(self, group_left_1, y, x, ch, group_right_1, attr); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_inch__doc__, +"inch([y, x])\n" +"Return the character at the given position in the window.\n" +"\n" +" y\n" +" Y-coordinate.\n" +" x\n" +" X-coordinate.\n" +"\n" +"The bottom 8 bits are the character proper, and upper bits are the attributes."); + +#define _CURSES_WINDOW_INCH_METHODDEF \ + {"inch", (PyCFunction)_curses_window_inch, METH_VARARGS, _curses_window_inch__doc__}, + +static unsigned long +_curses_window_inch_impl(PyCursesWindowObject *self, int group_right_1, + int y, int x); + +static PyObject * +_curses_window_inch(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_right_1 = 0; + int y = 0; + int x = 0; + unsigned long _return_value; + + switch (PyTuple_GET_SIZE(args)) { + case 0: + break; + case 2: + if (!PyArg_ParseTuple(args, "ii:inch", &y, &x)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.inch requires 0 to 2 arguments"); + goto exit; + } + _return_value = _curses_window_inch_impl(self, group_right_1, y, x); + if ((_return_value == (unsigned long)-1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromUnsignedLong(_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_insstr__doc__, +"insstr([y, x,] str, [attr])\n" +"Insert the string before the current or specified position.\n" +"\n" +" y\n" +" Y-coordinate.\n" +" x\n" +" X-coordinate.\n" +" str\n" +" String to insert.\n" +" attr\n" +" Attributes for characters.\n" +"\n" +"Insert a character string (as many characters as will fit on the line)\n" +"before the character under the cursor. All characters to the right of\n" +"the cursor are shifted right, with the rightmost characters on the line\n" +"being lost. The cursor position does not change (after moving to y, x,\n" +"if specified)."); + +#define _CURSES_WINDOW_INSSTR_METHODDEF \ + {"insstr", (PyCFunction)_curses_window_insstr, METH_VARARGS, _curses_window_insstr__doc__}, + +static PyObject * +_curses_window_insstr_impl(PyCursesWindowObject *self, int group_left_1, + int y, int x, PyObject *str, int group_right_1, + long attr); + +static PyObject * +_curses_window_insstr(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_left_1 = 0; + int y = 0; + int x = 0; + PyObject *str; + int group_right_1 = 0; + long attr = 0; + + switch (PyTuple_GET_SIZE(args)) { + case 1: + if (!PyArg_ParseTuple(args, "O:insstr", &str)) { + goto exit; + } + break; + case 2: + if (!PyArg_ParseTuple(args, "Ol:insstr", &str, &attr)) { + goto exit; + } + group_right_1 = 1; + break; + case 3: + if (!PyArg_ParseTuple(args, "iiO:insstr", &y, &x, &str)) { + goto exit; + } + group_left_1 = 1; + break; + case 4: + if (!PyArg_ParseTuple(args, "iiOl:insstr", &y, &x, &str, &attr)) { + goto exit; + } + group_right_1 = 1; + group_left_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.insstr requires 1 to 4 arguments"); + goto exit; + } + return_value = _curses_window_insstr_impl(self, group_left_1, y, x, str, group_right_1, attr); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_insnstr__doc__, +"insnstr([y, x,] str, n, [attr])\n" +"Insert at most n characters of the string.\n" +"\n" +" y\n" +" Y-coordinate.\n" +" x\n" +" X-coordinate.\n" +" str\n" +" String to insert.\n" +" n\n" +" Maximal number of characters.\n" +" attr\n" +" Attributes for characters.\n" +"\n" +"Insert a character string (as many characters as will fit on the line)\n" +"before the character under the cursor, up to n characters. If n is zero\n" +"or negative, the entire string is inserted. All characters to the right\n" +"of the cursor are shifted right, with the rightmost characters on the line\n" +"being lost. The cursor position does not change (after moving to y, x, if\n" +"specified)."); + +#define _CURSES_WINDOW_INSNSTR_METHODDEF \ + {"insnstr", (PyCFunction)_curses_window_insnstr, METH_VARARGS, _curses_window_insnstr__doc__}, + +static PyObject * +_curses_window_insnstr_impl(PyCursesWindowObject *self, int group_left_1, + int y, int x, PyObject *str, int n, + int group_right_1, long attr); + +static PyObject * +_curses_window_insnstr(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_left_1 = 0; + int y = 0; + int x = 0; + PyObject *str; + int n; + int group_right_1 = 0; + long attr = 0; + + switch (PyTuple_GET_SIZE(args)) { + case 2: + if (!PyArg_ParseTuple(args, "Oi:insnstr", &str, &n)) { + goto exit; + } + break; + case 3: + if (!PyArg_ParseTuple(args, "Oil:insnstr", &str, &n, &attr)) { + goto exit; + } + group_right_1 = 1; + break; + case 4: + if (!PyArg_ParseTuple(args, "iiOi:insnstr", &y, &x, &str, &n)) { + goto exit; + } + group_left_1 = 1; + break; + case 5: + if (!PyArg_ParseTuple(args, "iiOil:insnstr", &y, &x, &str, &n, &attr)) { + goto exit; + } + group_right_1 = 1; + group_left_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.insnstr requires 2 to 5 arguments"); + goto exit; + } + return_value = _curses_window_insnstr_impl(self, group_left_1, y, x, str, n, group_right_1, attr); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_is_linetouched__doc__, +"is_linetouched($self, line, /)\n" +"--\n" +"\n" +"Return True if the specified line was modified, otherwise return False.\n" +"\n" +" line\n" +" Line number.\n" +"\n" +"Raise a curses.error exception if line is not valid for the given window."); + +#define _CURSES_WINDOW_IS_LINETOUCHED_METHODDEF \ + {"is_linetouched", (PyCFunction)_curses_window_is_linetouched, METH_O, _curses_window_is_linetouched__doc__}, + +static PyObject * +_curses_window_is_linetouched_impl(PyCursesWindowObject *self, int line); + +static PyObject * +_curses_window_is_linetouched(PyCursesWindowObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + int line; + + if (!PyArg_Parse(arg, "i:is_linetouched", &line)) { + goto exit; + } + return_value = _curses_window_is_linetouched_impl(self, line); + +exit: + return return_value; +} + +#if defined(py_is_pad) + +PyDoc_STRVAR(_curses_window_noutrefresh__doc__, +"noutrefresh([pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol])\n" +"Mark for refresh but wait.\n" +"\n" +"This function updates the data structure representing the desired state of the\n" +"window, but does not force an update of the physical screen. To accomplish\n" +"that, call doupdate()."); + +#define _CURSES_WINDOW_NOUTREFRESH_METHODDEF \ + {"noutrefresh", (PyCFunction)_curses_window_noutrefresh, METH_VARARGS, _curses_window_noutrefresh__doc__}, + +static PyObject * +_curses_window_noutrefresh_impl(PyCursesWindowObject *self, + int group_right_1, int pminrow, int pmincol, + int sminrow, int smincol, int smaxrow, + int smaxcol); + +static PyObject * +_curses_window_noutrefresh(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_right_1 = 0; + int pminrow = 0; + int pmincol = 0; + int sminrow = 0; + int smincol = 0; + int smaxrow = 0; + int smaxcol = 0; + + switch (PyTuple_GET_SIZE(args)) { + case 0: + break; + case 6: + if (!PyArg_ParseTuple(args, "iiiiii:noutrefresh", &pminrow, &pmincol, &sminrow, &smincol, &smaxrow, &smaxcol)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.noutrefresh requires 0 to 6 arguments"); + goto exit; + } + return_value = _curses_window_noutrefresh_impl(self, group_right_1, pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol); + +exit: + return return_value; +} + +#endif /* defined(py_is_pad) */ + +#if !defined(py_is_pad) + +PyDoc_STRVAR(_curses_window_noutrefresh__doc__, +"noutrefresh($self, /)\n" +"--\n" +"\n" +"Mark for refresh but wait.\n" +"\n" +"This function updates the data structure representing the desired state of the\n" +"window, but does not force an update of the physical screen. To accomplish\n" +"that, call doupdate()."); + +#define _CURSES_WINDOW_NOUTREFRESH_METHODDEF \ + {"noutrefresh", (PyCFunction)_curses_window_noutrefresh, METH_NOARGS, _curses_window_noutrefresh__doc__}, + +static PyObject * +_curses_window_noutrefresh_impl(PyCursesWindowObject *self); + +static PyObject * +_curses_window_noutrefresh(PyCursesWindowObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _curses_window_noutrefresh_impl(self); +} + +#endif /* !defined(py_is_pad) */ + +PyDoc_STRVAR(_curses_window_overlay__doc__, +"overlay(destwin, [sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol])\n" +"Overlay the window on top of destwin.\n" +"\n" +"The windows need not be the same size, only the overlapping region is copied.\n" +"This copy is non-destructive, which means that the current background\n" +"character does not overwrite the old contents of destwin.\n" +"\n" +"To get fine-grained control over the copied region, the second form of\n" +"overlay() can be used. sminrow and smincol are the upper-left coordinates\n" +"of the source window, and the other variables mark a rectangle in the\n" +"destination window."); + +#define _CURSES_WINDOW_OVERLAY_METHODDEF \ + {"overlay", (PyCFunction)_curses_window_overlay, METH_VARARGS, _curses_window_overlay__doc__}, + +static PyObject * +_curses_window_overlay_impl(PyCursesWindowObject *self, + PyCursesWindowObject *destwin, int group_right_1, + int sminrow, int smincol, int dminrow, + int dmincol, int dmaxrow, int dmaxcol); + +static PyObject * +_curses_window_overlay(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyCursesWindowObject *destwin; + int group_right_1 = 0; + int sminrow = 0; + int smincol = 0; + int dminrow = 0; + int dmincol = 0; + int dmaxrow = 0; + int dmaxcol = 0; + + switch (PyTuple_GET_SIZE(args)) { + case 1: + if (!PyArg_ParseTuple(args, "O!:overlay", &PyCursesWindow_Type, &destwin)) { + goto exit; + } + break; + case 7: + if (!PyArg_ParseTuple(args, "O!iiiiii:overlay", &PyCursesWindow_Type, &destwin, &sminrow, &smincol, &dminrow, &dmincol, &dmaxrow, &dmaxcol)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.overlay requires 1 to 7 arguments"); + goto exit; + } + return_value = _curses_window_overlay_impl(self, destwin, group_right_1, sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_overwrite__doc__, +"overwrite(destwin, [sminrow, smincol, dminrow, dmincol, dmaxrow,\n" +" dmaxcol])\n" +"Overwrite the window on top of destwin.\n" +"\n" +"The windows need not be the same size, in which case only the overlapping\n" +"region is copied. This copy is destructive, which means that the current\n" +"background character overwrites the old contents of destwin.\n" +"\n" +"To get fine-grained control over the copied region, the second form of\n" +"overwrite() can be used. sminrow and smincol are the upper-left coordinates\n" +"of the source window, the other variables mark a rectangle in the destination\n" +"window."); + +#define _CURSES_WINDOW_OVERWRITE_METHODDEF \ + {"overwrite", (PyCFunction)_curses_window_overwrite, METH_VARARGS, _curses_window_overwrite__doc__}, + +static PyObject * +_curses_window_overwrite_impl(PyCursesWindowObject *self, + PyCursesWindowObject *destwin, + int group_right_1, int sminrow, int smincol, + int dminrow, int dmincol, int dmaxrow, + int dmaxcol); + +static PyObject * +_curses_window_overwrite(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyCursesWindowObject *destwin; + int group_right_1 = 0; + int sminrow = 0; + int smincol = 0; + int dminrow = 0; + int dmincol = 0; + int dmaxrow = 0; + int dmaxcol = 0; + + switch (PyTuple_GET_SIZE(args)) { + case 1: + if (!PyArg_ParseTuple(args, "O!:overwrite", &PyCursesWindow_Type, &destwin)) { + goto exit; + } + break; + case 7: + if (!PyArg_ParseTuple(args, "O!iiiiii:overwrite", &PyCursesWindow_Type, &destwin, &sminrow, &smincol, &dminrow, &dmincol, &dmaxrow, &dmaxcol)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.overwrite requires 1 to 7 arguments"); + goto exit; + } + return_value = _curses_window_overwrite_impl(self, destwin, group_right_1, sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_putwin__doc__, +"putwin($self, file, /)\n" +"--\n" +"\n" +"Write all data associated with the window into the provided file object.\n" +"\n" +"This information can be later retrieved using the getwin() function."); + +#define _CURSES_WINDOW_PUTWIN_METHODDEF \ + {"putwin", (PyCFunction)_curses_window_putwin, METH_O, _curses_window_putwin__doc__}, + +PyDoc_STRVAR(_curses_window_redrawln__doc__, +"redrawln($self, beg, num, /)\n" +"--\n" +"\n" +"Mark the specified lines corrupted.\n" +"\n" +" beg\n" +" Starting line number.\n" +" num\n" +" The number of lines.\n" +"\n" +"They should be completely redrawn on the next refresh() call."); + +#define _CURSES_WINDOW_REDRAWLN_METHODDEF \ + {"redrawln", (PyCFunction)_curses_window_redrawln, METH_FASTCALL, _curses_window_redrawln__doc__}, + +static PyObject * +_curses_window_redrawln_impl(PyCursesWindowObject *self, int beg, int num); + +static PyObject * +_curses_window_redrawln(PyCursesWindowObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int beg; + int num; + + if (!_PyArg_ParseStack(args, nargs, "ii:redrawln", + &beg, &num)) { + goto exit; + } + return_value = _curses_window_redrawln_impl(self, beg, num); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_refresh__doc__, +"refresh([pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol])\n" +"Update the display immediately.\n" +"\n" +"Synchronize actual screen with previous drawing/deleting methods.\n" +"The 6 optional arguments can only be specified when the window is a pad\n" +"created with newpad(). The additional parameters are needed to indicate\n" +"what part of the pad and screen are involved. pminrow and pmincol specify\n" +"the upper left-hand corner of the rectangle to be displayed in the pad.\n" +"sminrow, smincol, smaxrow, and smaxcol specify the edges of the rectangle to\n" +"be displayed on the screen. The lower right-hand corner of the rectangle to\n" +"be displayed in the pad is calculated from the screen coordinates, since the\n" +"rectangles must be the same size. Both rectangles must be entirely contained\n" +"within their respective structures. Negative values of pminrow, pmincol,\n" +"sminrow, or smincol are treated as if they were zero."); + +#define _CURSES_WINDOW_REFRESH_METHODDEF \ + {"refresh", (PyCFunction)_curses_window_refresh, METH_VARARGS, _curses_window_refresh__doc__}, + +static PyObject * +_curses_window_refresh_impl(PyCursesWindowObject *self, int group_right_1, + int pminrow, int pmincol, int sminrow, + int smincol, int smaxrow, int smaxcol); + +static PyObject * +_curses_window_refresh(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_right_1 = 0; + int pminrow = 0; + int pmincol = 0; + int sminrow = 0; + int smincol = 0; + int smaxrow = 0; + int smaxcol = 0; + + switch (PyTuple_GET_SIZE(args)) { + case 0: + break; + case 6: + if (!PyArg_ParseTuple(args, "iiiiii:refresh", &pminrow, &pmincol, &sminrow, &smincol, &smaxrow, &smaxcol)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.refresh requires 0 to 6 arguments"); + goto exit; + } + return_value = _curses_window_refresh_impl(self, group_right_1, pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_setscrreg__doc__, +"setscrreg($self, top, bottom, /)\n" +"--\n" +"\n" +"Define a software scrolling region.\n" +"\n" +" top\n" +" First line number.\n" +" bottom\n" +" Last line number.\n" +"\n" +"All scrolling actions will take place in this region."); + +#define _CURSES_WINDOW_SETSCRREG_METHODDEF \ + {"setscrreg", (PyCFunction)_curses_window_setscrreg, METH_FASTCALL, _curses_window_setscrreg__doc__}, + +static PyObject * +_curses_window_setscrreg_impl(PyCursesWindowObject *self, int top, + int bottom); + +static PyObject * +_curses_window_setscrreg(PyCursesWindowObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int top; + int bottom; + + if (!_PyArg_ParseStack(args, nargs, "ii:setscrreg", + &top, &bottom)) { + goto exit; + } + return_value = _curses_window_setscrreg_impl(self, top, bottom); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_subwin__doc__, +"subwin([nlines=0, ncols=0,] begin_y, begin_x)\n" +"Create a sub-window (screen-relative coordinates).\n" +"\n" +" nlines\n" +" Height.\n" +" ncols\n" +" Width.\n" +" begin_y\n" +" Top side y-coordinate.\n" +" begin_x\n" +" Left side x-coordinate.\n" +"\n" +"By default, the sub-window will extend from the specified position to the\n" +"lower right corner of the window."); + +#define _CURSES_WINDOW_SUBWIN_METHODDEF \ + {"subwin", (PyCFunction)_curses_window_subwin, METH_VARARGS, _curses_window_subwin__doc__}, + +static PyObject * +_curses_window_subwin_impl(PyCursesWindowObject *self, int group_left_1, + int nlines, int ncols, int begin_y, int begin_x); + +static PyObject * +_curses_window_subwin(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_left_1 = 0; + int nlines = 0; + int ncols = 0; + int begin_y; + int begin_x; + + switch (PyTuple_GET_SIZE(args)) { + case 2: + if (!PyArg_ParseTuple(args, "ii:subwin", &begin_y, &begin_x)) { + goto exit; + } + break; + case 4: + if (!PyArg_ParseTuple(args, "iiii:subwin", &nlines, &ncols, &begin_y, &begin_x)) { + goto exit; + } + group_left_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.subwin requires 2 to 4 arguments"); + goto exit; + } + return_value = _curses_window_subwin_impl(self, group_left_1, nlines, ncols, begin_y, begin_x); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_scroll__doc__, +"scroll([lines=1])\n" +"Scroll the screen or scrolling region.\n" +"\n" +" lines\n" +" Number of lines to scroll.\n" +"\n" +"Scroll upward if the argument is positive and downward if it is negative."); + +#define _CURSES_WINDOW_SCROLL_METHODDEF \ + {"scroll", (PyCFunction)_curses_window_scroll, METH_VARARGS, _curses_window_scroll__doc__}, + +static PyObject * +_curses_window_scroll_impl(PyCursesWindowObject *self, int group_right_1, + int lines); + +static PyObject * +_curses_window_scroll(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_right_1 = 0; + int lines = 1; + + switch (PyTuple_GET_SIZE(args)) { + case 0: + break; + case 1: + if (!PyArg_ParseTuple(args, "i:scroll", &lines)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.scroll requires 0 to 1 arguments"); + goto exit; + } + return_value = _curses_window_scroll_impl(self, group_right_1, lines); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_touchline__doc__, +"touchline(start, count, [changed=True])\n" +"Pretend count lines have been changed, starting with line start.\n" +"\n" +"If changed is supplied, it specifies whether the affected lines are marked\n" +"as having been changed (changed=True) or unchanged (changed=False)."); + +#define _CURSES_WINDOW_TOUCHLINE_METHODDEF \ + {"touchline", (PyCFunction)_curses_window_touchline, METH_VARARGS, _curses_window_touchline__doc__}, + +static PyObject * +_curses_window_touchline_impl(PyCursesWindowObject *self, int start, + int count, int group_right_1, int changed); + +static PyObject * +_curses_window_touchline(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int start; + int count; + int group_right_1 = 0; + int changed = 1; + + switch (PyTuple_GET_SIZE(args)) { + case 2: + if (!PyArg_ParseTuple(args, "ii:touchline", &start, &count)) { + goto exit; + } + break; + case 3: + if (!PyArg_ParseTuple(args, "iii:touchline", &start, &count, &changed)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.touchline requires 2 to 3 arguments"); + goto exit; + } + return_value = _curses_window_touchline_impl(self, start, count, group_right_1, changed); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_vline__doc__, +"vline([y, x,] ch, n, [attr=_curses.A_NORMAL])\n" +"Display a vertical line.\n" +"\n" +" y\n" +" Starting Y-coordinate.\n" +" x\n" +" Starting X-coordinate.\n" +" ch\n" +" Character to draw.\n" +" n\n" +" Line length.\n" +" attr\n" +" Attributes for the character."); + +#define _CURSES_WINDOW_VLINE_METHODDEF \ + {"vline", (PyCFunction)_curses_window_vline, METH_VARARGS, _curses_window_vline__doc__}, + +static PyObject * +_curses_window_vline_impl(PyCursesWindowObject *self, int group_left_1, + int y, int x, PyObject *ch, int n, + int group_right_1, long attr); + +static PyObject * +_curses_window_vline(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_left_1 = 0; + int y = 0; + int x = 0; + PyObject *ch; + int n; + int group_right_1 = 0; + long attr = A_NORMAL; + + switch (PyTuple_GET_SIZE(args)) { + case 2: + if (!PyArg_ParseTuple(args, "Oi:vline", &ch, &n)) { + goto exit; + } + break; + case 3: + if (!PyArg_ParseTuple(args, "Oil:vline", &ch, &n, &attr)) { + goto exit; + } + group_right_1 = 1; + break; + case 4: + if (!PyArg_ParseTuple(args, "iiOi:vline", &y, &x, &ch, &n)) { + goto exit; + } + group_left_1 = 1; + break; + case 5: + if (!PyArg_ParseTuple(args, "iiOil:vline", &y, &x, &ch, &n, &attr)) { + goto exit; + } + group_right_1 = 1; + group_left_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.vline requires 2 to 5 arguments"); + goto exit; + } + return_value = _curses_window_vline_impl(self, group_left_1, y, x, ch, n, group_right_1, attr); + +exit: + return return_value; +} + +#if defined(HAVE_CURSES_FILTER) + +PyDoc_STRVAR(_curses_filter__doc__, +"filter($module, /)\n" +"--\n" +"\n"); + +#define _CURSES_FILTER_METHODDEF \ + {"filter", (PyCFunction)_curses_filter, METH_NOARGS, _curses_filter__doc__}, + +static PyObject * +_curses_filter_impl(PyObject *module); + +static PyObject * +_curses_filter(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_filter_impl(module); +} + +#endif /* defined(HAVE_CURSES_FILTER) */ + +PyDoc_STRVAR(_curses_baudrate__doc__, +"baudrate($module, /)\n" +"--\n" +"\n" +"Return the output speed of the terminal in bits per second."); + +#define _CURSES_BAUDRATE_METHODDEF \ + {"baudrate", (PyCFunction)_curses_baudrate, METH_NOARGS, _curses_baudrate__doc__}, + +static PyObject * +_curses_baudrate_impl(PyObject *module); + +static PyObject * +_curses_baudrate(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_baudrate_impl(module); +} + +PyDoc_STRVAR(_curses_beep__doc__, +"beep($module, /)\n" +"--\n" +"\n" +"Emit a short attention sound."); + +#define _CURSES_BEEP_METHODDEF \ + {"beep", (PyCFunction)_curses_beep, METH_NOARGS, _curses_beep__doc__}, + +static PyObject * +_curses_beep_impl(PyObject *module); + +static PyObject * +_curses_beep(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_beep_impl(module); +} + +PyDoc_STRVAR(_curses_can_change_color__doc__, +"can_change_color($module, /)\n" +"--\n" +"\n" +"Return True if the programmer can change the colors displayed by the terminal."); + +#define _CURSES_CAN_CHANGE_COLOR_METHODDEF \ + {"can_change_color", (PyCFunction)_curses_can_change_color, METH_NOARGS, _curses_can_change_color__doc__}, + +static PyObject * +_curses_can_change_color_impl(PyObject *module); + +static PyObject * +_curses_can_change_color(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_can_change_color_impl(module); +} + +PyDoc_STRVAR(_curses_cbreak__doc__, +"cbreak($module, flag=True, /)\n" +"--\n" +"\n" +"Enter cbreak mode.\n" +"\n" +" flag\n" +" If false, the effect is the same as calling nocbreak().\n" +"\n" +"In cbreak mode (sometimes called \"rare\" mode) normal tty line buffering is\n" +"turned off and characters are available to be read one by one. However,\n" +"unlike raw mode, special characters (interrupt, quit, suspend, and flow\n" +"control) retain their effects on the tty driver and calling program.\n" +"Calling first raw() then cbreak() leaves the terminal in cbreak mode."); + +#define _CURSES_CBREAK_METHODDEF \ + {"cbreak", (PyCFunction)_curses_cbreak, METH_FASTCALL, _curses_cbreak__doc__}, + +static PyObject * +_curses_cbreak_impl(PyObject *module, int flag); + +static PyObject * +_curses_cbreak(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int flag = 1; + + if (!_PyArg_ParseStack(args, nargs, "|i:cbreak", + &flag)) { + goto exit; + } + return_value = _curses_cbreak_impl(module, flag); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_color_content__doc__, +"color_content($module, color_number, /)\n" +"--\n" +"\n" +"Return the red, green, and blue (RGB) components of the specified color.\n" +"\n" +" color_number\n" +" The number of the color (0 - COLORS).\n" +"\n" +"A 3-tuple is returned, containing the R, G, B values for the given color,\n" +"which will be between 0 (no component) and 1000 (maximum amount of component)."); + +#define _CURSES_COLOR_CONTENT_METHODDEF \ + {"color_content", (PyCFunction)_curses_color_content, METH_O, _curses_color_content__doc__}, + +static PyObject * +_curses_color_content_impl(PyObject *module, short color_number); + +static PyObject * +_curses_color_content(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + short color_number; + + if (!PyArg_Parse(arg, "h:color_content", &color_number)) { + goto exit; + } + return_value = _curses_color_content_impl(module, color_number); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_color_pair__doc__, +"color_pair($module, color_number, /)\n" +"--\n" +"\n" +"Return the attribute value for displaying text in the specified color.\n" +"\n" +" color_number\n" +" The number of the color (0 - COLORS).\n" +"\n" +"This attribute value can be combined with A_STANDOUT, A_REVERSE, and the\n" +"other A_* attributes. pair_number() is the counterpart to this function."); + +#define _CURSES_COLOR_PAIR_METHODDEF \ + {"color_pair", (PyCFunction)_curses_color_pair, METH_O, _curses_color_pair__doc__}, + +static PyObject * +_curses_color_pair_impl(PyObject *module, short color_number); + +static PyObject * +_curses_color_pair(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + short color_number; + + if (!PyArg_Parse(arg, "h:color_pair", &color_number)) { + goto exit; + } + return_value = _curses_color_pair_impl(module, color_number); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_curs_set__doc__, +"curs_set($module, visibility, /)\n" +"--\n" +"\n" +"Set the cursor state.\n" +"\n" +" visibility\n" +" 0 for invisible, 1 for normal visible, or 2 for very visible.\n" +"\n" +"If the terminal supports the visibility requested, the previous cursor\n" +"state is returned; otherwise, an exception is raised. On many terminals,\n" +"the \"visible\" mode is an underline cursor and the \"very visible\" mode is\n" +"a block cursor."); + +#define _CURSES_CURS_SET_METHODDEF \ + {"curs_set", (PyCFunction)_curses_curs_set, METH_O, _curses_curs_set__doc__}, + +static PyObject * +_curses_curs_set_impl(PyObject *module, int visibility); + +static PyObject * +_curses_curs_set(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int visibility; + + if (!PyArg_Parse(arg, "i:curs_set", &visibility)) { + goto exit; + } + return_value = _curses_curs_set_impl(module, visibility); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_def_prog_mode__doc__, +"def_prog_mode($module, /)\n" +"--\n" +"\n" +"Save the current terminal mode as the \"program\" mode.\n" +"\n" +"The \"program\" mode is the mode when the running program is using curses.\n" +"\n" +"Subsequent calls to reset_prog_mode() will restore this mode."); + +#define _CURSES_DEF_PROG_MODE_METHODDEF \ + {"def_prog_mode", (PyCFunction)_curses_def_prog_mode, METH_NOARGS, _curses_def_prog_mode__doc__}, + +static PyObject * +_curses_def_prog_mode_impl(PyObject *module); + +static PyObject * +_curses_def_prog_mode(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_def_prog_mode_impl(module); +} + +PyDoc_STRVAR(_curses_def_shell_mode__doc__, +"def_shell_mode($module, /)\n" +"--\n" +"\n" +"Save the current terminal mode as the \"shell\" mode.\n" +"\n" +"The \"shell\" mode is the mode when the running program is not using curses.\n" +"\n" +"Subsequent calls to reset_shell_mode() will restore this mode."); + +#define _CURSES_DEF_SHELL_MODE_METHODDEF \ + {"def_shell_mode", (PyCFunction)_curses_def_shell_mode, METH_NOARGS, _curses_def_shell_mode__doc__}, + +static PyObject * +_curses_def_shell_mode_impl(PyObject *module); + +static PyObject * +_curses_def_shell_mode(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_def_shell_mode_impl(module); +} + +PyDoc_STRVAR(_curses_delay_output__doc__, +"delay_output($module, ms, /)\n" +"--\n" +"\n" +"Insert a pause in output.\n" +"\n" +" ms\n" +" Duration in milliseconds."); + +#define _CURSES_DELAY_OUTPUT_METHODDEF \ + {"delay_output", (PyCFunction)_curses_delay_output, METH_O, _curses_delay_output__doc__}, + +static PyObject * +_curses_delay_output_impl(PyObject *module, int ms); + +static PyObject * +_curses_delay_output(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int ms; + + if (!PyArg_Parse(arg, "i:delay_output", &ms)) { + goto exit; + } + return_value = _curses_delay_output_impl(module, ms); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_doupdate__doc__, +"doupdate($module, /)\n" +"--\n" +"\n" +"Update the physical screen to match the virtual screen."); + +#define _CURSES_DOUPDATE_METHODDEF \ + {"doupdate", (PyCFunction)_curses_doupdate, METH_NOARGS, _curses_doupdate__doc__}, + +static PyObject * +_curses_doupdate_impl(PyObject *module); + +static PyObject * +_curses_doupdate(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_doupdate_impl(module); +} + +PyDoc_STRVAR(_curses_echo__doc__, +"echo($module, flag=True, /)\n" +"--\n" +"\n" +"Enter echo mode.\n" +"\n" +" flag\n" +" If false, the effect is the same as calling noecho().\n" +"\n" +"In echo mode, each character input is echoed to the screen as it is entered."); + +#define _CURSES_ECHO_METHODDEF \ + {"echo", (PyCFunction)_curses_echo, METH_FASTCALL, _curses_echo__doc__}, + +static PyObject * +_curses_echo_impl(PyObject *module, int flag); + +static PyObject * +_curses_echo(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int flag = 1; + + if (!_PyArg_ParseStack(args, nargs, "|i:echo", + &flag)) { + goto exit; + } + return_value = _curses_echo_impl(module, flag); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_endwin__doc__, +"endwin($module, /)\n" +"--\n" +"\n" +"De-initialize the library, and return terminal to normal status."); + +#define _CURSES_ENDWIN_METHODDEF \ + {"endwin", (PyCFunction)_curses_endwin, METH_NOARGS, _curses_endwin__doc__}, + +static PyObject * +_curses_endwin_impl(PyObject *module); + +static PyObject * +_curses_endwin(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_endwin_impl(module); +} + +PyDoc_STRVAR(_curses_erasechar__doc__, +"erasechar($module, /)\n" +"--\n" +"\n" +"Return the user\'s current erase character."); + +#define _CURSES_ERASECHAR_METHODDEF \ + {"erasechar", (PyCFunction)_curses_erasechar, METH_NOARGS, _curses_erasechar__doc__}, + +static PyObject * +_curses_erasechar_impl(PyObject *module); + +static PyObject * +_curses_erasechar(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_erasechar_impl(module); +} + +PyDoc_STRVAR(_curses_flash__doc__, +"flash($module, /)\n" +"--\n" +"\n" +"Flash the screen.\n" +"\n" +"That is, change it to reverse-video and then change it back in a short interval."); + +#define _CURSES_FLASH_METHODDEF \ + {"flash", (PyCFunction)_curses_flash, METH_NOARGS, _curses_flash__doc__}, + +static PyObject * +_curses_flash_impl(PyObject *module); + +static PyObject * +_curses_flash(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_flash_impl(module); +} + +PyDoc_STRVAR(_curses_flushinp__doc__, +"flushinp($module, /)\n" +"--\n" +"\n" +"Flush all input buffers.\n" +"\n" +"This throws away any typeahead that has been typed by the user and has not\n" +"yet been processed by the program."); + +#define _CURSES_FLUSHINP_METHODDEF \ + {"flushinp", (PyCFunction)_curses_flushinp, METH_NOARGS, _curses_flushinp__doc__}, + +static PyObject * +_curses_flushinp_impl(PyObject *module); + +static PyObject * +_curses_flushinp(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_flushinp_impl(module); +} + +#if defined(getsyx) + +PyDoc_STRVAR(_curses_getsyx__doc__, +"getsyx($module, /)\n" +"--\n" +"\n" +"Return the current coordinates of the virtual screen cursor.\n" +"\n" +"Return a (y, x) tuple. If leaveok is currently true, return (-1, -1)."); + +#define _CURSES_GETSYX_METHODDEF \ + {"getsyx", (PyCFunction)_curses_getsyx, METH_NOARGS, _curses_getsyx__doc__}, + +static PyObject * +_curses_getsyx_impl(PyObject *module); + +static PyObject * +_curses_getsyx(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_getsyx_impl(module); +} + +#endif /* defined(getsyx) */ + +#if defined(NCURSES_MOUSE_VERSION) + +PyDoc_STRVAR(_curses_getmouse__doc__, +"getmouse($module, /)\n" +"--\n" +"\n" +"Retrieve the queued mouse event.\n" +"\n" +"After getch() returns KEY_MOUSE to signal a mouse event, this function\n" +"returns a 5-tuple (id, x, y, z, bstate)."); + +#define _CURSES_GETMOUSE_METHODDEF \ + {"getmouse", (PyCFunction)_curses_getmouse, METH_NOARGS, _curses_getmouse__doc__}, + +static PyObject * +_curses_getmouse_impl(PyObject *module); + +static PyObject * +_curses_getmouse(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_getmouse_impl(module); +} + +#endif /* defined(NCURSES_MOUSE_VERSION) */ + +#if defined(NCURSES_MOUSE_VERSION) + +PyDoc_STRVAR(_curses_ungetmouse__doc__, +"ungetmouse($module, id, x, y, z, bstate, /)\n" +"--\n" +"\n" +"Push a KEY_MOUSE event onto the input queue.\n" +"\n" +"The following getmouse() will return the given state data."); + +#define _CURSES_UNGETMOUSE_METHODDEF \ + {"ungetmouse", (PyCFunction)_curses_ungetmouse, METH_FASTCALL, _curses_ungetmouse__doc__}, + +static PyObject * +_curses_ungetmouse_impl(PyObject *module, short id, int x, int y, int z, + unsigned long bstate); + +static PyObject * +_curses_ungetmouse(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + short id; + int x; + int y; + int z; + unsigned long bstate; + + if (!_PyArg_ParseStack(args, nargs, "hiiik:ungetmouse", + &id, &x, &y, &z, &bstate)) { + goto exit; + } + return_value = _curses_ungetmouse_impl(module, id, x, y, z, bstate); + +exit: + return return_value; +} + +#endif /* defined(NCURSES_MOUSE_VERSION) */ + +PyDoc_STRVAR(_curses_getwin__doc__, +"getwin($module, file, /)\n" +"--\n" +"\n" +"Read window related data stored in the file by an earlier putwin() call.\n" +"\n" +"The routine then creates and initializes a new window using that data,\n" +"returning the new window object."); + +#define _CURSES_GETWIN_METHODDEF \ + {"getwin", (PyCFunction)_curses_getwin, METH_O, _curses_getwin__doc__}, + +PyDoc_STRVAR(_curses_halfdelay__doc__, +"halfdelay($module, tenths, /)\n" +"--\n" +"\n" +"Enter half-delay mode.\n" +"\n" +" tenths\n" +" Maximal blocking delay in tenths of seconds (1 - 255).\n" +"\n" +"Use nocbreak() to leave half-delay mode."); + +#define _CURSES_HALFDELAY_METHODDEF \ + {"halfdelay", (PyCFunction)_curses_halfdelay, METH_O, _curses_halfdelay__doc__}, + +static PyObject * +_curses_halfdelay_impl(PyObject *module, unsigned char tenths); + +static PyObject * +_curses_halfdelay(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + unsigned char tenths; + + if (!PyArg_Parse(arg, "b:halfdelay", &tenths)) { + goto exit; + } + return_value = _curses_halfdelay_impl(module, tenths); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_has_colors__doc__, +"has_colors($module, /)\n" +"--\n" +"\n" +"Return True if the terminal can display colors; otherwise, return False."); + +#define _CURSES_HAS_COLORS_METHODDEF \ + {"has_colors", (PyCFunction)_curses_has_colors, METH_NOARGS, _curses_has_colors__doc__}, + +static PyObject * +_curses_has_colors_impl(PyObject *module); + +static PyObject * +_curses_has_colors(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_has_colors_impl(module); +} + +PyDoc_STRVAR(_curses_has_ic__doc__, +"has_ic($module, /)\n" +"--\n" +"\n" +"Return True if the terminal has insert- and delete-character capabilities."); + +#define _CURSES_HAS_IC_METHODDEF \ + {"has_ic", (PyCFunction)_curses_has_ic, METH_NOARGS, _curses_has_ic__doc__}, + +static PyObject * +_curses_has_ic_impl(PyObject *module); + +static PyObject * +_curses_has_ic(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_has_ic_impl(module); +} + +PyDoc_STRVAR(_curses_has_il__doc__, +"has_il($module, /)\n" +"--\n" +"\n" +"Return True if the terminal has insert- and delete-line capabilities."); + +#define _CURSES_HAS_IL_METHODDEF \ + {"has_il", (PyCFunction)_curses_has_il, METH_NOARGS, _curses_has_il__doc__}, + +static PyObject * +_curses_has_il_impl(PyObject *module); + +static PyObject * +_curses_has_il(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_has_il_impl(module); +} + +#if defined(HAVE_CURSES_HAS_KEY) + +PyDoc_STRVAR(_curses_has_key__doc__, +"has_key($module, key, /)\n" +"--\n" +"\n" +"Return True if the current terminal type recognizes a key with that value.\n" +"\n" +" key\n" +" Key number."); + +#define _CURSES_HAS_KEY_METHODDEF \ + {"has_key", (PyCFunction)_curses_has_key, METH_O, _curses_has_key__doc__}, + +static PyObject * +_curses_has_key_impl(PyObject *module, int key); + +static PyObject * +_curses_has_key(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int key; + + if (!PyArg_Parse(arg, "i:has_key", &key)) { + goto exit; + } + return_value = _curses_has_key_impl(module, key); + +exit: + return return_value; +} + +#endif /* defined(HAVE_CURSES_HAS_KEY) */ + +PyDoc_STRVAR(_curses_init_color__doc__, +"init_color($module, color_number, r, g, b, /)\n" +"--\n" +"\n" +"Change the definition of a color.\n" +"\n" +" color_number\n" +" The number of the color to be changed (0 - COLORS).\n" +" r\n" +" Red component (0 - 1000).\n" +" g\n" +" Green component (0 - 1000).\n" +" b\n" +" Blue component (0 - 1000).\n" +"\n" +"When init_color() is used, all occurrences of that color on the screen\n" +"immediately change to the new definition. This function is a no-op on\n" +"most terminals; it is active only if can_change_color() returns 1."); + +#define _CURSES_INIT_COLOR_METHODDEF \ + {"init_color", (PyCFunction)_curses_init_color, METH_FASTCALL, _curses_init_color__doc__}, + +static PyObject * +_curses_init_color_impl(PyObject *module, short color_number, short r, + short g, short b); + +static PyObject * +_curses_init_color(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + short color_number; + short r; + short g; + short b; + + if (!_PyArg_ParseStack(args, nargs, "hhhh:init_color", + &color_number, &r, &g, &b)) { + goto exit; + } + return_value = _curses_init_color_impl(module, color_number, r, g, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_init_pair__doc__, +"init_pair($module, pair_number, fg, bg, /)\n" +"--\n" +"\n" +"Change the definition of a color-pair.\n" +"\n" +" pair_number\n" +" The number of the color-pair to be changed (1 - (COLOR_PAIRS-1)).\n" +" fg\n" +" Foreground color number (0 - COLORS).\n" +" bg\n" +" Background color number (0 - COLORS).\n" +"\n" +"If the color-pair was previously initialized, the screen is refreshed and\n" +"all occurrences of that color-pair are changed to the new definition."); + +#define _CURSES_INIT_PAIR_METHODDEF \ + {"init_pair", (PyCFunction)_curses_init_pair, METH_FASTCALL, _curses_init_pair__doc__}, + +static PyObject * +_curses_init_pair_impl(PyObject *module, short pair_number, short fg, + short bg); + +static PyObject * +_curses_init_pair(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + short pair_number; + short fg; + short bg; + + if (!_PyArg_ParseStack(args, nargs, "hhh:init_pair", + &pair_number, &fg, &bg)) { + goto exit; + } + return_value = _curses_init_pair_impl(module, pair_number, fg, bg); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_initscr__doc__, +"initscr($module, /)\n" +"--\n" +"\n" +"Initialize the library.\n" +"\n" +"Return a WindowObject which represents the whole screen."); + +#define _CURSES_INITSCR_METHODDEF \ + {"initscr", (PyCFunction)_curses_initscr, METH_NOARGS, _curses_initscr__doc__}, + +static PyObject * +_curses_initscr_impl(PyObject *module); + +static PyObject * +_curses_initscr(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_initscr_impl(module); +} + +PyDoc_STRVAR(_curses_setupterm__doc__, +"setupterm($module, /, term=None, fd=-1)\n" +"--\n" +"\n" +"Initialize the terminal.\n" +"\n" +" term\n" +" Terminal name.\n" +" If omitted, the value of the TERM environment variable will be used.\n" +" fd\n" +" File descriptor to which any initialization sequences will be sent.\n" +" If not supplied, the file descriptor for sys.stdout will be used."); + +#define _CURSES_SETUPTERM_METHODDEF \ + {"setupterm", (PyCFunction)_curses_setupterm, METH_FASTCALL|METH_KEYWORDS, _curses_setupterm__doc__}, + +static PyObject * +_curses_setupterm_impl(PyObject *module, const char *term, int fd); + +static PyObject * +_curses_setupterm(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"term", "fd", NULL}; + static _PyArg_Parser _parser = {"|zi:setupterm", _keywords, 0}; + const char *term = NULL; + int fd = -1; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &term, &fd)) { + goto exit; + } + return_value = _curses_setupterm_impl(module, term, fd); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_intrflush__doc__, +"intrflush($module, flag, /)\n" +"--\n" +"\n"); + +#define _CURSES_INTRFLUSH_METHODDEF \ + {"intrflush", (PyCFunction)_curses_intrflush, METH_O, _curses_intrflush__doc__}, + +static PyObject * +_curses_intrflush_impl(PyObject *module, int flag); + +static PyObject * +_curses_intrflush(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int flag; + + if (!PyArg_Parse(arg, "i:intrflush", &flag)) { + goto exit; + } + return_value = _curses_intrflush_impl(module, flag); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_isendwin__doc__, +"isendwin($module, /)\n" +"--\n" +"\n" +"Return True if endwin() has been called."); + +#define _CURSES_ISENDWIN_METHODDEF \ + {"isendwin", (PyCFunction)_curses_isendwin, METH_NOARGS, _curses_isendwin__doc__}, + +static PyObject * +_curses_isendwin_impl(PyObject *module); + +static PyObject * +_curses_isendwin(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_isendwin_impl(module); +} + +#if defined(HAVE_CURSES_IS_TERM_RESIZED) + +PyDoc_STRVAR(_curses_is_term_resized__doc__, +"is_term_resized($module, nlines, ncols, /)\n" +"--\n" +"\n" +"Return True if resize_term() would modify the window structure, False otherwise.\n" +"\n" +" nlines\n" +" Height.\n" +" ncols\n" +" Width."); + +#define _CURSES_IS_TERM_RESIZED_METHODDEF \ + {"is_term_resized", (PyCFunction)_curses_is_term_resized, METH_FASTCALL, _curses_is_term_resized__doc__}, + +static PyObject * +_curses_is_term_resized_impl(PyObject *module, int nlines, int ncols); + +static PyObject * +_curses_is_term_resized(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int nlines; + int ncols; + + if (!_PyArg_ParseStack(args, nargs, "ii:is_term_resized", + &nlines, &ncols)) { + goto exit; + } + return_value = _curses_is_term_resized_impl(module, nlines, ncols); + +exit: + return return_value; +} + +#endif /* defined(HAVE_CURSES_IS_TERM_RESIZED) */ + +PyDoc_STRVAR(_curses_keyname__doc__, +"keyname($module, key, /)\n" +"--\n" +"\n" +"Return the name of specified key.\n" +"\n" +" key\n" +" Key number."); + +#define _CURSES_KEYNAME_METHODDEF \ + {"keyname", (PyCFunction)_curses_keyname, METH_O, _curses_keyname__doc__}, + +static PyObject * +_curses_keyname_impl(PyObject *module, int key); + +static PyObject * +_curses_keyname(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int key; + + if (!PyArg_Parse(arg, "i:keyname", &key)) { + goto exit; + } + return_value = _curses_keyname_impl(module, key); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_killchar__doc__, +"killchar($module, /)\n" +"--\n" +"\n" +"Return the user\'s current line kill character."); + +#define _CURSES_KILLCHAR_METHODDEF \ + {"killchar", (PyCFunction)_curses_killchar, METH_NOARGS, _curses_killchar__doc__}, + +static PyObject * +_curses_killchar_impl(PyObject *module); + +static PyObject * +_curses_killchar(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_killchar_impl(module); +} + +PyDoc_STRVAR(_curses_longname__doc__, +"longname($module, /)\n" +"--\n" +"\n" +"Return the terminfo long name field describing the current terminal.\n" +"\n" +"The maximum length of a verbose description is 128 characters. It is defined\n" +"only after the call to initscr()."); + +#define _CURSES_LONGNAME_METHODDEF \ + {"longname", (PyCFunction)_curses_longname, METH_NOARGS, _curses_longname__doc__}, + +static PyObject * +_curses_longname_impl(PyObject *module); + +static PyObject * +_curses_longname(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_longname_impl(module); +} + +PyDoc_STRVAR(_curses_meta__doc__, +"meta($module, yes, /)\n" +"--\n" +"\n" +"Enable/disable meta keys.\n" +"\n" +"If yes is True, allow 8-bit characters to be input. If yes is False,\n" +"allow only 7-bit characters."); + +#define _CURSES_META_METHODDEF \ + {"meta", (PyCFunction)_curses_meta, METH_O, _curses_meta__doc__}, + +static PyObject * +_curses_meta_impl(PyObject *module, int yes); + +static PyObject * +_curses_meta(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int yes; + + if (!PyArg_Parse(arg, "i:meta", &yes)) { + goto exit; + } + return_value = _curses_meta_impl(module, yes); + +exit: + return return_value; +} + +#if defined(NCURSES_MOUSE_VERSION) + +PyDoc_STRVAR(_curses_mouseinterval__doc__, +"mouseinterval($module, interval, /)\n" +"--\n" +"\n" +"Set and retrieve the maximum time between press and release in a click.\n" +"\n" +" interval\n" +" Time in milliseconds.\n" +"\n" +"Set the maximum time that can elapse between press and release events in\n" +"order for them to be recognized as a click, and return the previous interval\n" +"value."); + +#define _CURSES_MOUSEINTERVAL_METHODDEF \ + {"mouseinterval", (PyCFunction)_curses_mouseinterval, METH_O, _curses_mouseinterval__doc__}, + +static PyObject * +_curses_mouseinterval_impl(PyObject *module, int interval); + +static PyObject * +_curses_mouseinterval(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int interval; + + if (!PyArg_Parse(arg, "i:mouseinterval", &interval)) { + goto exit; + } + return_value = _curses_mouseinterval_impl(module, interval); + +exit: + return return_value; +} + +#endif /* defined(NCURSES_MOUSE_VERSION) */ + +#if defined(NCURSES_MOUSE_VERSION) + +PyDoc_STRVAR(_curses_mousemask__doc__, +"mousemask($module, newmask, /)\n" +"--\n" +"\n" +"Set the mouse events to be reported, and return a tuple (availmask, oldmask).\n" +"\n" +"Return a tuple (availmask, oldmask). availmask indicates which of the\n" +"specified mouse events can be reported; on complete failure it returns 0.\n" +"oldmask is the previous value of the given window\'s mouse event mask.\n" +"If this function is never called, no mouse events are ever reported."); + +#define _CURSES_MOUSEMASK_METHODDEF \ + {"mousemask", (PyCFunction)_curses_mousemask, METH_O, _curses_mousemask__doc__}, + +static PyObject * +_curses_mousemask_impl(PyObject *module, unsigned long newmask); + +static PyObject * +_curses_mousemask(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + unsigned long newmask; + + if (!PyArg_Parse(arg, "k:mousemask", &newmask)) { + goto exit; + } + return_value = _curses_mousemask_impl(module, newmask); + +exit: + return return_value; +} + +#endif /* defined(NCURSES_MOUSE_VERSION) */ + +PyDoc_STRVAR(_curses_napms__doc__, +"napms($module, ms, /)\n" +"--\n" +"\n" +"Sleep for specified time.\n" +"\n" +" ms\n" +" Duration in milliseconds."); + +#define _CURSES_NAPMS_METHODDEF \ + {"napms", (PyCFunction)_curses_napms, METH_O, _curses_napms__doc__}, + +static PyObject * +_curses_napms_impl(PyObject *module, int ms); + +static PyObject * +_curses_napms(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int ms; + + if (!PyArg_Parse(arg, "i:napms", &ms)) { + goto exit; + } + return_value = _curses_napms_impl(module, ms); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_newpad__doc__, +"newpad($module, nlines, ncols, /)\n" +"--\n" +"\n" +"Create and return a pointer to a new pad data structure.\n" +"\n" +" nlines\n" +" Height.\n" +" ncols\n" +" Width."); + +#define _CURSES_NEWPAD_METHODDEF \ + {"newpad", (PyCFunction)_curses_newpad, METH_FASTCALL, _curses_newpad__doc__}, + +static PyObject * +_curses_newpad_impl(PyObject *module, int nlines, int ncols); + +static PyObject * +_curses_newpad(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int nlines; + int ncols; + + if (!_PyArg_ParseStack(args, nargs, "ii:newpad", + &nlines, &ncols)) { + goto exit; + } + return_value = _curses_newpad_impl(module, nlines, ncols); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_newwin__doc__, +"newwin(nlines, ncols, [begin_y=0, begin_x=0])\n" +"Return a new window.\n" +"\n" +" nlines\n" +" Height.\n" +" ncols\n" +" Width.\n" +" begin_y\n" +" Top side y-coordinate.\n" +" begin_x\n" +" Left side x-coordinate.\n" +"\n" +"By default, the window will extend from the specified position to the lower\n" +"right corner of the screen."); + +#define _CURSES_NEWWIN_METHODDEF \ + {"newwin", (PyCFunction)_curses_newwin, METH_VARARGS, _curses_newwin__doc__}, + +static PyObject * +_curses_newwin_impl(PyObject *module, int nlines, int ncols, + int group_right_1, int begin_y, int begin_x); + +static PyObject * +_curses_newwin(PyObject *module, PyObject *args) +{ + PyObject *return_value = NULL; + int nlines; + int ncols; + int group_right_1 = 0; + int begin_y = 0; + int begin_x = 0; + + switch (PyTuple_GET_SIZE(args)) { + case 2: + if (!PyArg_ParseTuple(args, "ii:newwin", &nlines, &ncols)) { + goto exit; + } + break; + case 4: + if (!PyArg_ParseTuple(args, "iiii:newwin", &nlines, &ncols, &begin_y, &begin_x)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.newwin requires 2 to 4 arguments"); + goto exit; + } + return_value = _curses_newwin_impl(module, nlines, ncols, group_right_1, begin_y, begin_x); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_nl__doc__, +"nl($module, flag=True, /)\n" +"--\n" +"\n" +"Enter newline mode.\n" +"\n" +" flag\n" +" If false, the effect is the same as calling nonl().\n" +"\n" +"This mode translates the return key into newline on input, and translates\n" +"newline into return and line-feed on output. Newline mode is initially on."); + +#define _CURSES_NL_METHODDEF \ + {"nl", (PyCFunction)_curses_nl, METH_FASTCALL, _curses_nl__doc__}, + +static PyObject * +_curses_nl_impl(PyObject *module, int flag); + +static PyObject * +_curses_nl(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int flag = 1; + + if (!_PyArg_ParseStack(args, nargs, "|i:nl", + &flag)) { + goto exit; + } + return_value = _curses_nl_impl(module, flag); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_nocbreak__doc__, +"nocbreak($module, /)\n" +"--\n" +"\n" +"Leave cbreak mode.\n" +"\n" +"Return to normal \"cooked\" mode with line buffering."); + +#define _CURSES_NOCBREAK_METHODDEF \ + {"nocbreak", (PyCFunction)_curses_nocbreak, METH_NOARGS, _curses_nocbreak__doc__}, + +static PyObject * +_curses_nocbreak_impl(PyObject *module); + +static PyObject * +_curses_nocbreak(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_nocbreak_impl(module); +} + +PyDoc_STRVAR(_curses_noecho__doc__, +"noecho($module, /)\n" +"--\n" +"\n" +"Leave echo mode.\n" +"\n" +"Echoing of input characters is turned off."); + +#define _CURSES_NOECHO_METHODDEF \ + {"noecho", (PyCFunction)_curses_noecho, METH_NOARGS, _curses_noecho__doc__}, + +static PyObject * +_curses_noecho_impl(PyObject *module); + +static PyObject * +_curses_noecho(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_noecho_impl(module); +} + +PyDoc_STRVAR(_curses_nonl__doc__, +"nonl($module, /)\n" +"--\n" +"\n" +"Leave newline mode.\n" +"\n" +"Disable translation of return into newline on input, and disable low-level\n" +"translation of newline into newline/return on output."); + +#define _CURSES_NONL_METHODDEF \ + {"nonl", (PyCFunction)_curses_nonl, METH_NOARGS, _curses_nonl__doc__}, + +static PyObject * +_curses_nonl_impl(PyObject *module); + +static PyObject * +_curses_nonl(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_nonl_impl(module); +} + +PyDoc_STRVAR(_curses_noqiflush__doc__, +"noqiflush($module, /)\n" +"--\n" +"\n" +"Disable queue flushing.\n" +"\n" +"When queue flushing is disabled, normal flush of input and output queues\n" +"associated with the INTR, QUIT and SUSP characters will not be done."); + +#define _CURSES_NOQIFLUSH_METHODDEF \ + {"noqiflush", (PyCFunction)_curses_noqiflush, METH_NOARGS, _curses_noqiflush__doc__}, + +static PyObject * +_curses_noqiflush_impl(PyObject *module); + +static PyObject * +_curses_noqiflush(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_noqiflush_impl(module); +} + +PyDoc_STRVAR(_curses_noraw__doc__, +"noraw($module, /)\n" +"--\n" +"\n" +"Leave raw mode.\n" +"\n" +"Return to normal \"cooked\" mode with line buffering."); + +#define _CURSES_NORAW_METHODDEF \ + {"noraw", (PyCFunction)_curses_noraw, METH_NOARGS, _curses_noraw__doc__}, + +static PyObject * +_curses_noraw_impl(PyObject *module); + +static PyObject * +_curses_noraw(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_noraw_impl(module); +} + +PyDoc_STRVAR(_curses_pair_content__doc__, +"pair_content($module, pair_number, /)\n" +"--\n" +"\n" +"Return a tuple (fg, bg) containing the colors for the requested color pair.\n" +"\n" +" pair_number\n" +" The number of the color pair (1 - (COLOR_PAIRS-1))."); + +#define _CURSES_PAIR_CONTENT_METHODDEF \ + {"pair_content", (PyCFunction)_curses_pair_content, METH_O, _curses_pair_content__doc__}, + +static PyObject * +_curses_pair_content_impl(PyObject *module, short pair_number); + +static PyObject * +_curses_pair_content(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + short pair_number; + + if (!PyArg_Parse(arg, "h:pair_content", &pair_number)) { + goto exit; + } + return_value = _curses_pair_content_impl(module, pair_number); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_pair_number__doc__, +"pair_number($module, attr, /)\n" +"--\n" +"\n" +"Return the number of the color-pair set by the specified attribute value.\n" +"\n" +"color_pair() is the counterpart to this function."); + +#define _CURSES_PAIR_NUMBER_METHODDEF \ + {"pair_number", (PyCFunction)_curses_pair_number, METH_O, _curses_pair_number__doc__}, + +static PyObject * +_curses_pair_number_impl(PyObject *module, int attr); + +static PyObject * +_curses_pair_number(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int attr; + + if (!PyArg_Parse(arg, "i:pair_number", &attr)) { + goto exit; + } + return_value = _curses_pair_number_impl(module, attr); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_putp__doc__, +"putp($module, string, /)\n" +"--\n" +"\n" +"Emit the value of a specified terminfo capability for the current terminal.\n" +"\n" +"Note that the output of putp() always goes to standard output."); + +#define _CURSES_PUTP_METHODDEF \ + {"putp", (PyCFunction)_curses_putp, METH_O, _curses_putp__doc__}, + +static PyObject * +_curses_putp_impl(PyObject *module, const char *string); + +static PyObject * +_curses_putp(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *string; + + if (!PyArg_Parse(arg, "y:putp", &string)) { + goto exit; + } + return_value = _curses_putp_impl(module, string); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_qiflush__doc__, +"qiflush($module, flag=True, /)\n" +"--\n" +"\n" +"Enable queue flushing.\n" +"\n" +" flag\n" +" If false, the effect is the same as calling noqiflush().\n" +"\n" +"If queue flushing is enabled, all output in the display driver queue\n" +"will be flushed when the INTR, QUIT and SUSP characters are read."); + +#define _CURSES_QIFLUSH_METHODDEF \ + {"qiflush", (PyCFunction)_curses_qiflush, METH_FASTCALL, _curses_qiflush__doc__}, + +static PyObject * +_curses_qiflush_impl(PyObject *module, int flag); + +static PyObject * +_curses_qiflush(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int flag = 1; + + if (!_PyArg_ParseStack(args, nargs, "|i:qiflush", + &flag)) { + goto exit; + } + return_value = _curses_qiflush_impl(module, flag); + +exit: + return return_value; +} + +#if (defined(HAVE_CURSES_RESIZETERM) || defined(HAVE_CURSES_RESIZE_TERM)) + +PyDoc_STRVAR(_curses_update_lines_cols__doc__, +"update_lines_cols($module, /)\n" +"--\n" +"\n"); + +#define _CURSES_UPDATE_LINES_COLS_METHODDEF \ + {"update_lines_cols", (PyCFunction)_curses_update_lines_cols, METH_NOARGS, _curses_update_lines_cols__doc__}, + +static int +_curses_update_lines_cols_impl(PyObject *module); + +static PyObject * +_curses_update_lines_cols(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + int _return_value; + + _return_value = _curses_update_lines_cols_impl(module); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong((long)_return_value); + +exit: + return return_value; +} + +#endif /* (defined(HAVE_CURSES_RESIZETERM) || defined(HAVE_CURSES_RESIZE_TERM)) */ + +PyDoc_STRVAR(_curses_raw__doc__, +"raw($module, flag=True, /)\n" +"--\n" +"\n" +"Enter raw mode.\n" +"\n" +" flag\n" +" If false, the effect is the same as calling noraw().\n" +"\n" +"In raw mode, normal line buffering and processing of interrupt, quit,\n" +"suspend, and flow control keys are turned off; characters are presented to\n" +"curses input functions one by one."); + +#define _CURSES_RAW_METHODDEF \ + {"raw", (PyCFunction)_curses_raw, METH_FASTCALL, _curses_raw__doc__}, + +static PyObject * +_curses_raw_impl(PyObject *module, int flag); + +static PyObject * +_curses_raw(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int flag = 1; + + if (!_PyArg_ParseStack(args, nargs, "|i:raw", + &flag)) { + goto exit; + } + return_value = _curses_raw_impl(module, flag); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_reset_prog_mode__doc__, +"reset_prog_mode($module, /)\n" +"--\n" +"\n" +"Restore the terminal to \"program\" mode, as previously saved by def_prog_mode()."); + +#define _CURSES_RESET_PROG_MODE_METHODDEF \ + {"reset_prog_mode", (PyCFunction)_curses_reset_prog_mode, METH_NOARGS, _curses_reset_prog_mode__doc__}, + +static PyObject * +_curses_reset_prog_mode_impl(PyObject *module); + +static PyObject * +_curses_reset_prog_mode(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_reset_prog_mode_impl(module); +} + +PyDoc_STRVAR(_curses_reset_shell_mode__doc__, +"reset_shell_mode($module, /)\n" +"--\n" +"\n" +"Restore the terminal to \"shell\" mode, as previously saved by def_shell_mode()."); + +#define _CURSES_RESET_SHELL_MODE_METHODDEF \ + {"reset_shell_mode", (PyCFunction)_curses_reset_shell_mode, METH_NOARGS, _curses_reset_shell_mode__doc__}, + +static PyObject * +_curses_reset_shell_mode_impl(PyObject *module); + +static PyObject * +_curses_reset_shell_mode(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_reset_shell_mode_impl(module); +} + +PyDoc_STRVAR(_curses_resetty__doc__, +"resetty($module, /)\n" +"--\n" +"\n" +"Restore terminal mode."); + +#define _CURSES_RESETTY_METHODDEF \ + {"resetty", (PyCFunction)_curses_resetty, METH_NOARGS, _curses_resetty__doc__}, + +static PyObject * +_curses_resetty_impl(PyObject *module); + +static PyObject * +_curses_resetty(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_resetty_impl(module); +} + +#if defined(HAVE_CURSES_RESIZETERM) + +PyDoc_STRVAR(_curses_resizeterm__doc__, +"resizeterm($module, nlines, ncols, /)\n" +"--\n" +"\n" +"Resize the standard and current windows to the specified dimensions.\n" +"\n" +" nlines\n" +" Height.\n" +" ncols\n" +" Width.\n" +"\n" +"Adjusts other bookkeeping data used by the curses library that record the\n" +"window dimensions (in particular the SIGWINCH handler)."); + +#define _CURSES_RESIZETERM_METHODDEF \ + {"resizeterm", (PyCFunction)_curses_resizeterm, METH_FASTCALL, _curses_resizeterm__doc__}, + +static PyObject * +_curses_resizeterm_impl(PyObject *module, int nlines, int ncols); + +static PyObject * +_curses_resizeterm(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int nlines; + int ncols; + + if (!_PyArg_ParseStack(args, nargs, "ii:resizeterm", + &nlines, &ncols)) { + goto exit; + } + return_value = _curses_resizeterm_impl(module, nlines, ncols); + +exit: + return return_value; +} + +#endif /* defined(HAVE_CURSES_RESIZETERM) */ + +#if defined(HAVE_CURSES_RESIZE_TERM) + +PyDoc_STRVAR(_curses_resize_term__doc__, +"resize_term($module, nlines, ncols, /)\n" +"--\n" +"\n" +"Backend function used by resizeterm(), performing most of the work.\n" +"\n" +" nlines\n" +" Height.\n" +" ncols\n" +" Width.\n" +"\n" +"When resizing the windows, resize_term() blank-fills the areas that are\n" +"extended. The calling application should fill in these areas with appropriate\n" +"data. The resize_term() function attempts to resize all windows. However,\n" +"due to the calling convention of pads, it is not possible to resize these\n" +"without additional interaction with the application."); + +#define _CURSES_RESIZE_TERM_METHODDEF \ + {"resize_term", (PyCFunction)_curses_resize_term, METH_FASTCALL, _curses_resize_term__doc__}, + +static PyObject * +_curses_resize_term_impl(PyObject *module, int nlines, int ncols); + +static PyObject * +_curses_resize_term(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int nlines; + int ncols; + + if (!_PyArg_ParseStack(args, nargs, "ii:resize_term", + &nlines, &ncols)) { + goto exit; + } + return_value = _curses_resize_term_impl(module, nlines, ncols); + +exit: + return return_value; +} + +#endif /* defined(HAVE_CURSES_RESIZE_TERM) */ + +PyDoc_STRVAR(_curses_savetty__doc__, +"savetty($module, /)\n" +"--\n" +"\n" +"Save terminal mode."); + +#define _CURSES_SAVETTY_METHODDEF \ + {"savetty", (PyCFunction)_curses_savetty, METH_NOARGS, _curses_savetty__doc__}, + +static PyObject * +_curses_savetty_impl(PyObject *module); + +static PyObject * +_curses_savetty(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_savetty_impl(module); +} + +#if defined(getsyx) + +PyDoc_STRVAR(_curses_setsyx__doc__, +"setsyx($module, y, x, /)\n" +"--\n" +"\n" +"Set the virtual screen cursor.\n" +"\n" +" y\n" +" Y-coordinate.\n" +" x\n" +" X-coordinate.\n" +"\n" +"If y and x are both -1, then leaveok is set."); + +#define _CURSES_SETSYX_METHODDEF \ + {"setsyx", (PyCFunction)_curses_setsyx, METH_FASTCALL, _curses_setsyx__doc__}, + +static PyObject * +_curses_setsyx_impl(PyObject *module, int y, int x); + +static PyObject * +_curses_setsyx(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int y; + int x; + + if (!_PyArg_ParseStack(args, nargs, "ii:setsyx", + &y, &x)) { + goto exit; + } + return_value = _curses_setsyx_impl(module, y, x); + +exit: + return return_value; +} + +#endif /* defined(getsyx) */ + +PyDoc_STRVAR(_curses_start_color__doc__, +"start_color($module, /)\n" +"--\n" +"\n" +"Initializes eight basic colors and global variables COLORS and COLOR_PAIRS.\n" +"\n" +"Must be called if the programmer wants to use colors, and before any other\n" +"color manipulation routine is called. It is good practice to call this\n" +"routine right after initscr().\n" +"\n" +"It also restores the colors on the terminal to the values they had when the\n" +"terminal was just turned on."); + +#define _CURSES_START_COLOR_METHODDEF \ + {"start_color", (PyCFunction)_curses_start_color, METH_NOARGS, _curses_start_color__doc__}, + +static PyObject * +_curses_start_color_impl(PyObject *module); + +static PyObject * +_curses_start_color(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_start_color_impl(module); +} + +PyDoc_STRVAR(_curses_termattrs__doc__, +"termattrs($module, /)\n" +"--\n" +"\n" +"Return a logical OR of all video attributes supported by the terminal."); + +#define _CURSES_TERMATTRS_METHODDEF \ + {"termattrs", (PyCFunction)_curses_termattrs, METH_NOARGS, _curses_termattrs__doc__}, + +static PyObject * +_curses_termattrs_impl(PyObject *module); + +static PyObject * +_curses_termattrs(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_termattrs_impl(module); +} + +PyDoc_STRVAR(_curses_termname__doc__, +"termname($module, /)\n" +"--\n" +"\n" +"Return the value of the environment variable TERM, truncated to 14 characters."); + +#define _CURSES_TERMNAME_METHODDEF \ + {"termname", (PyCFunction)_curses_termname, METH_NOARGS, _curses_termname__doc__}, + +static PyObject * +_curses_termname_impl(PyObject *module); + +static PyObject * +_curses_termname(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_termname_impl(module); +} + +PyDoc_STRVAR(_curses_tigetflag__doc__, +"tigetflag($module, capname, /)\n" +"--\n" +"\n" +"Return the value of the Boolean capability.\n" +"\n" +" capname\n" +" The terminfo capability name.\n" +"\n" +"The value -1 is returned if capname is not a Boolean capability, or 0 if\n" +"it is canceled or absent from the terminal description."); + +#define _CURSES_TIGETFLAG_METHODDEF \ + {"tigetflag", (PyCFunction)_curses_tigetflag, METH_O, _curses_tigetflag__doc__}, + +static PyObject * +_curses_tigetflag_impl(PyObject *module, const char *capname); + +static PyObject * +_curses_tigetflag(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *capname; + + if (!PyArg_Parse(arg, "s:tigetflag", &capname)) { + goto exit; + } + return_value = _curses_tigetflag_impl(module, capname); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_tigetnum__doc__, +"tigetnum($module, capname, /)\n" +"--\n" +"\n" +"Return the value of the numeric capability.\n" +"\n" +" capname\n" +" The terminfo capability name.\n" +"\n" +"The value -2 is returned if capname is not a numeric capability, or -1 if\n" +"it is canceled or absent from the terminal description."); + +#define _CURSES_TIGETNUM_METHODDEF \ + {"tigetnum", (PyCFunction)_curses_tigetnum, METH_O, _curses_tigetnum__doc__}, + +static PyObject * +_curses_tigetnum_impl(PyObject *module, const char *capname); + +static PyObject * +_curses_tigetnum(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *capname; + + if (!PyArg_Parse(arg, "s:tigetnum", &capname)) { + goto exit; + } + return_value = _curses_tigetnum_impl(module, capname); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_tigetstr__doc__, +"tigetstr($module, capname, /)\n" +"--\n" +"\n" +"Return the value of the string capability.\n" +"\n" +" capname\n" +" The terminfo capability name.\n" +"\n" +"None is returned if capname is not a string capability, or is canceled or\n" +"absent from the terminal description."); + +#define _CURSES_TIGETSTR_METHODDEF \ + {"tigetstr", (PyCFunction)_curses_tigetstr, METH_O, _curses_tigetstr__doc__}, + +static PyObject * +_curses_tigetstr_impl(PyObject *module, const char *capname); + +static PyObject * +_curses_tigetstr(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *capname; + + if (!PyArg_Parse(arg, "s:tigetstr", &capname)) { + goto exit; + } + return_value = _curses_tigetstr_impl(module, capname); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_tparm__doc__, +"tparm($module, str, i1=0, i2=0, i3=0, i4=0, i5=0, i6=0, i7=0, i8=0,\n" +" i9=0, /)\n" +"--\n" +"\n" +"Instantiate the specified byte string with the supplied parameters.\n" +"\n" +" str\n" +" Parameterized byte string obtained from the terminfo database."); + +#define _CURSES_TPARM_METHODDEF \ + {"tparm", (PyCFunction)_curses_tparm, METH_FASTCALL, _curses_tparm__doc__}, + +static PyObject * +_curses_tparm_impl(PyObject *module, const char *str, int i1, int i2, int i3, + int i4, int i5, int i6, int i7, int i8, int i9); + +static PyObject * +_curses_tparm(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + const char *str; + int i1 = 0; + int i2 = 0; + int i3 = 0; + int i4 = 0; + int i5 = 0; + int i6 = 0; + int i7 = 0; + int i8 = 0; + int i9 = 0; + + if (!_PyArg_ParseStack(args, nargs, "y|iiiiiiiii:tparm", + &str, &i1, &i2, &i3, &i4, &i5, &i6, &i7, &i8, &i9)) { + goto exit; + } + return_value = _curses_tparm_impl(module, str, i1, i2, i3, i4, i5, i6, i7, i8, i9); + +exit: + return return_value; +} + +#if defined(HAVE_CURSES_TYPEAHEAD) + +PyDoc_STRVAR(_curses_typeahead__doc__, +"typeahead($module, fd, /)\n" +"--\n" +"\n" +"Specify that the file descriptor fd be used for typeahead checking.\n" +"\n" +" fd\n" +" File descriptor.\n" +"\n" +"If fd is -1, then no typeahead checking is done."); + +#define _CURSES_TYPEAHEAD_METHODDEF \ + {"typeahead", (PyCFunction)_curses_typeahead, METH_O, _curses_typeahead__doc__}, + +static PyObject * +_curses_typeahead_impl(PyObject *module, int fd); + +static PyObject * +_curses_typeahead(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int fd; + + if (!PyArg_Parse(arg, "i:typeahead", &fd)) { + goto exit; + } + return_value = _curses_typeahead_impl(module, fd); + +exit: + return return_value; +} + +#endif /* defined(HAVE_CURSES_TYPEAHEAD) */ + +PyDoc_STRVAR(_curses_unctrl__doc__, +"unctrl($module, ch, /)\n" +"--\n" +"\n" +"Return a string which is a printable representation of the character ch.\n" +"\n" +"Control characters are displayed as a caret followed by the character,\n" +"for example as ^C. Printing characters are left as they are."); + +#define _CURSES_UNCTRL_METHODDEF \ + {"unctrl", (PyCFunction)_curses_unctrl, METH_O, _curses_unctrl__doc__}, + +PyDoc_STRVAR(_curses_ungetch__doc__, +"ungetch($module, ch, /)\n" +"--\n" +"\n" +"Push ch so the next getch() will return it."); + +#define _CURSES_UNGETCH_METHODDEF \ + {"ungetch", (PyCFunction)_curses_ungetch, METH_O, _curses_ungetch__doc__}, + +#if defined(HAVE_NCURSESW) + +PyDoc_STRVAR(_curses_unget_wch__doc__, +"unget_wch($module, ch, /)\n" +"--\n" +"\n" +"Push ch so the next get_wch() will return it."); + +#define _CURSES_UNGET_WCH_METHODDEF \ + {"unget_wch", (PyCFunction)_curses_unget_wch, METH_O, _curses_unget_wch__doc__}, + +#endif /* defined(HAVE_NCURSESW) */ + +#if defined(HAVE_CURSES_USE_ENV) + +PyDoc_STRVAR(_curses_use_env__doc__, +"use_env($module, flag, /)\n" +"--\n" +"\n" +"Use environment variables LINES and COLUMNS.\n" +"\n" +"If used, this function should be called before initscr() or newterm() are\n" +"called.\n" +"\n" +"When flag is False, the values of lines and columns specified in the terminfo\n" +"database will be used, even if environment variables LINES and COLUMNS (used\n" +"by default) are set, or if curses is running in a window (in which case\n" +"default behavior would be to use the window size if LINES and COLUMNS are\n" +"not set)."); + +#define _CURSES_USE_ENV_METHODDEF \ + {"use_env", (PyCFunction)_curses_use_env, METH_O, _curses_use_env__doc__}, + +static PyObject * +_curses_use_env_impl(PyObject *module, int flag); + +static PyObject * +_curses_use_env(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int flag; + + if (!PyArg_Parse(arg, "i:use_env", &flag)) { + goto exit; + } + return_value = _curses_use_env_impl(module, flag); + +exit: + return return_value; +} + +#endif /* defined(HAVE_CURSES_USE_ENV) */ + +#if !defined(STRICT_SYSV_CURSES) + +PyDoc_STRVAR(_curses_use_default_colors__doc__, +"use_default_colors($module, /)\n" +"--\n" +"\n" +"Allow use of default values for colors on terminals supporting this feature.\n" +"\n" +"Use this to support transparency in your application. The default color\n" +"is assigned to the color number -1."); + +#define _CURSES_USE_DEFAULT_COLORS_METHODDEF \ + {"use_default_colors", (PyCFunction)_curses_use_default_colors, METH_NOARGS, _curses_use_default_colors__doc__}, + +static PyObject * +_curses_use_default_colors_impl(PyObject *module); + +static PyObject * +_curses_use_default_colors(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_use_default_colors_impl(module); +} + +#endif /* !defined(STRICT_SYSV_CURSES) */ + +#ifndef _CURSES_WINDOW_ENCLOSE_METHODDEF + #define _CURSES_WINDOW_ENCLOSE_METHODDEF +#endif /* !defined(_CURSES_WINDOW_ENCLOSE_METHODDEF) */ + +#ifndef _CURSES_WINDOW_GET_WCH_METHODDEF + #define _CURSES_WINDOW_GET_WCH_METHODDEF +#endif /* !defined(_CURSES_WINDOW_GET_WCH_METHODDEF) */ + +#ifndef _CURSES_WINDOW_NOUTREFRESH_METHODDEF + #define _CURSES_WINDOW_NOUTREFRESH_METHODDEF +#endif /* !defined(_CURSES_WINDOW_NOUTREFRESH_METHODDEF) */ + +#ifndef _CURSES_FILTER_METHODDEF + #define _CURSES_FILTER_METHODDEF +#endif /* !defined(_CURSES_FILTER_METHODDEF) */ + +#ifndef _CURSES_GETSYX_METHODDEF + #define _CURSES_GETSYX_METHODDEF +#endif /* !defined(_CURSES_GETSYX_METHODDEF) */ + +#ifndef _CURSES_GETMOUSE_METHODDEF + #define _CURSES_GETMOUSE_METHODDEF +#endif /* !defined(_CURSES_GETMOUSE_METHODDEF) */ + +#ifndef _CURSES_UNGETMOUSE_METHODDEF + #define _CURSES_UNGETMOUSE_METHODDEF +#endif /* !defined(_CURSES_UNGETMOUSE_METHODDEF) */ + +#ifndef _CURSES_HAS_KEY_METHODDEF + #define _CURSES_HAS_KEY_METHODDEF +#endif /* !defined(_CURSES_HAS_KEY_METHODDEF) */ + +#ifndef _CURSES_IS_TERM_RESIZED_METHODDEF + #define _CURSES_IS_TERM_RESIZED_METHODDEF +#endif /* !defined(_CURSES_IS_TERM_RESIZED_METHODDEF) */ + +#ifndef _CURSES_MOUSEINTERVAL_METHODDEF + #define _CURSES_MOUSEINTERVAL_METHODDEF +#endif /* !defined(_CURSES_MOUSEINTERVAL_METHODDEF) */ + +#ifndef _CURSES_MOUSEMASK_METHODDEF + #define _CURSES_MOUSEMASK_METHODDEF +#endif /* !defined(_CURSES_MOUSEMASK_METHODDEF) */ + +#ifndef _CURSES_UPDATE_LINES_COLS_METHODDEF + #define _CURSES_UPDATE_LINES_COLS_METHODDEF +#endif /* !defined(_CURSES_UPDATE_LINES_COLS_METHODDEF) */ + +#ifndef _CURSES_RESIZETERM_METHODDEF + #define _CURSES_RESIZETERM_METHODDEF +#endif /* !defined(_CURSES_RESIZETERM_METHODDEF) */ + +#ifndef _CURSES_RESIZE_TERM_METHODDEF + #define _CURSES_RESIZE_TERM_METHODDEF +#endif /* !defined(_CURSES_RESIZE_TERM_METHODDEF) */ + +#ifndef _CURSES_SETSYX_METHODDEF + #define _CURSES_SETSYX_METHODDEF +#endif /* !defined(_CURSES_SETSYX_METHODDEF) */ + +#ifndef _CURSES_TYPEAHEAD_METHODDEF + #define _CURSES_TYPEAHEAD_METHODDEF +#endif /* !defined(_CURSES_TYPEAHEAD_METHODDEF) */ + +#ifndef _CURSES_UNGET_WCH_METHODDEF + #define _CURSES_UNGET_WCH_METHODDEF +#endif /* !defined(_CURSES_UNGET_WCH_METHODDEF) */ + +#ifndef _CURSES_USE_ENV_METHODDEF + #define _CURSES_USE_ENV_METHODDEF +#endif /* !defined(_CURSES_USE_ENV_METHODDEF) */ + +#ifndef _CURSES_USE_DEFAULT_COLORS_METHODDEF + #define _CURSES_USE_DEFAULT_COLORS_METHODDEF +#endif /* !defined(_CURSES_USE_DEFAULT_COLORS_METHODDEF) */ +/*[clinic end generated code: output=763ffe3abc3a97c7 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_pickle.c.h b/Modules/clinic/_pickle.c.h index 7fc00a00479c7e..6d9072832ceaa8 100644 --- a/Modules/clinic/_pickle.c.h +++ b/Modules/clinic/_pickle.c.h @@ -367,8 +367,9 @@ PyDoc_STRVAR(_pickle_dump__doc__, "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" +"protocol; supported protocols are 0, 1, 2, 3 and 4. The default\n" +"protocol is 4. It was introduced in Python 3.4, it is incompatible\n" +"with previous versions.\n" "\n" "Specifying a negative protocol version selects the highest protocol\n" "version supported. The higher the protocol used, the more recent the\n" @@ -419,7 +420,8 @@ PyDoc_STRVAR(_pickle_dumps__doc__, "\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" +"protocol is 4. It was introduced in Python 3.4, it is incompatible\n" +"with previous versions.\n" "\n" "Specifying a negative protocol version selects the highest protocol\n" "version supported. The higher the protocol used, the more recent the\n" @@ -560,4 +562,4 @@ _pickle_loads(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec exit: return return_value; } -/*[clinic end generated code: output=e995dd494045d876 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=6fc104b8299c82dd input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_struct.c.h b/Modules/clinic/_struct.c.h index 6e43215b737a08..2ecadfb1de97cc 100644 --- a/Modules/clinic/_struct.c.h +++ b/Modules/clinic/_struct.c.h @@ -79,7 +79,8 @@ PyDoc_STRVAR(Struct_unpack_from__doc__, "\n" "Values are unpacked according to the format string Struct.format.\n" "\n" -"The buffer\'s size in bytes, minus offset, must be at least Struct.size.\n" +"The buffer\'s size in bytes, starting at position offset, must be\n" +"at least Struct.size.\n" "\n" "See help(struct) for more on format strings."); @@ -302,4 +303,4 @@ iter_unpack(PyObject *module, PyObject *const *args, Py_ssize_t nargs) return return_value; } -/*[clinic end generated code: output=9119f213a951e4cc input=a9049054013a1b77]*/ +/*[clinic end generated code: output=d79b009652ae0b89 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index ab1f75350340d9..583da2e7664ffd 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -1727,6 +1727,54 @@ os_execve(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k #endif /* defined(HAVE_EXECV) */ +#if defined(HAVE_POSIX_SPAWN) + +PyDoc_STRVAR(os_posix_spawn__doc__, +"posix_spawn($module, path, argv, env, file_actions=None, /)\n" +"--\n" +"\n" +"Execute the program specified by path in a new 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.\n" +" file_actions\n" +" A sequence of file action tuples."); + +#define OS_POSIX_SPAWN_METHODDEF \ + {"posix_spawn", (PyCFunction)os_posix_spawn, METH_FASTCALL, os_posix_spawn__doc__}, + +static PyObject * +os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv, + PyObject *env, PyObject *file_actions); + +static PyObject * +os_posix_spawn(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + path_t path = PATH_T_INITIALIZE("posix_spawn", "path", 0, 0); + PyObject *argv; + PyObject *env; + PyObject *file_actions = Py_None; + + if (!_PyArg_ParseStack(args, nargs, "O&OO|O:posix_spawn", + path_converter, &path, &argv, &env, &file_actions)) { + goto exit; + } + return_value = os_posix_spawn_impl(module, &path, argv, env, file_actions); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +#endif /* defined(HAVE_POSIX_SPAWN) */ + #if (defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)) PyDoc_STRVAR(os_spawnv__doc__, @@ -3805,6 +3853,40 @@ os_write(PyObject *module, PyObject *const *args, Py_ssize_t nargs) return return_value; } +#if defined(__APPLE__) + +PyDoc_STRVAR(os__fcopyfile__doc__, +"_fcopyfile($module, infd, outfd, flags, /)\n" +"--\n" +"\n" +"Efficiently copy content or metadata of 2 regular file descriptors (macOS)."); + +#define OS__FCOPYFILE_METHODDEF \ + {"_fcopyfile", (PyCFunction)os__fcopyfile, METH_FASTCALL, os__fcopyfile__doc__}, + +static PyObject * +os__fcopyfile_impl(PyObject *module, int infd, int outfd, int flags); + +static PyObject * +os__fcopyfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int infd; + int outfd; + int flags; + + if (!_PyArg_ParseStack(args, nargs, "iii:_fcopyfile", + &infd, &outfd, &flags)) { + goto exit; + } + return_value = os__fcopyfile_impl(module, infd, outfd, flags); + +exit: + return return_value; +} + +#endif /* defined(__APPLE__) */ + PyDoc_STRVAR(os_fstat__doc__, "fstat($module, /, fd)\n" "--\n" @@ -6362,6 +6444,10 @@ os_getrandom(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject #define OS_PREADV_METHODDEF #endif /* !defined(OS_PREADV_METHODDEF) */ +#ifndef OS__FCOPYFILE_METHODDEF + #define OS__FCOPYFILE_METHODDEF +#endif /* !defined(OS__FCOPYFILE_METHODDEF) */ + #ifndef OS_PIPE_METHODDEF #define OS_PIPE_METHODDEF #endif /* !defined(OS_PIPE_METHODDEF) */ @@ -6537,4 +6623,4 @@ os_getrandom(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject #ifndef OS_GETRANDOM_METHODDEF #define OS_GETRANDOM_METHODDEF #endif /* !defined(OS_GETRANDOM_METHODDEF) */ -/*[clinic end generated code: output=c966c821d557b7c0 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=47fb6a3e88cba6d9 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/selectmodule.c.h b/Modules/clinic/selectmodule.c.h new file mode 100644 index 00000000000000..f66ceaab3ccb18 --- /dev/null +++ b/Modules/clinic/selectmodule.c.h @@ -0,0 +1,1050 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(select_select__doc__, +"select($module, rlist, wlist, xlist, timeout=None, /)\n" +"--\n" +"\n" +"Wait until one or more file descriptors are ready for some kind of I/O.\n" +"\n" +"The first three arguments are sequences of file descriptors to be waited for:\n" +"rlist -- wait until ready for reading\n" +"wlist -- wait until ready for writing\n" +"xlist -- wait for an \"exceptional condition\"\n" +"If only one kind of condition is required, pass [] for the other lists.\n" +"\n" +"A file descriptor is either a socket or file object, or a small integer\n" +"gotten from a fileno() method call on one of those.\n" +"\n" +"The optional 4th argument specifies a timeout in seconds; it may be\n" +"a floating point number to specify fractions of seconds. If it is absent\n" +"or None, the call will never time out.\n" +"\n" +"The return value is a tuple of three lists corresponding to the first three\n" +"arguments; each contains the subset of the corresponding file descriptors\n" +"that are ready.\n" +"\n" +"*** IMPORTANT NOTICE ***\n" +"On Windows, only sockets are supported; on Unix, all file\n" +"descriptors can be used."); + +#define SELECT_SELECT_METHODDEF \ + {"select", (PyCFunction)select_select, METH_FASTCALL, select_select__doc__}, + +static PyObject * +select_select_impl(PyObject *module, PyObject *rlist, PyObject *wlist, + PyObject *xlist, PyObject *timeout_obj); + +static PyObject * +select_select(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *rlist; + PyObject *wlist; + PyObject *xlist; + PyObject *timeout_obj = Py_None; + + if (!_PyArg_UnpackStack(args, nargs, "select", + 3, 4, + &rlist, &wlist, &xlist, &timeout_obj)) { + goto exit; + } + return_value = select_select_impl(module, rlist, wlist, xlist, timeout_obj); + +exit: + return return_value; +} + +#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) + +PyDoc_STRVAR(select_poll_register__doc__, +"register($self, fd, eventmask=POLLIN | POLLPRI | POLLOUT, /)\n" +"--\n" +"\n" +"Register a file descriptor with the polling object.\n" +"\n" +" fd\n" +" either an integer, or an object with a fileno() method returning an int\n" +" eventmask\n" +" an optional bitmask describing the type of events to check for"); + +#define SELECT_POLL_REGISTER_METHODDEF \ + {"register", (PyCFunction)select_poll_register, METH_FASTCALL, select_poll_register__doc__}, + +static PyObject * +select_poll_register_impl(pollObject *self, int fd, unsigned short eventmask); + +static PyObject * +select_poll_register(pollObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int fd; + unsigned short eventmask = POLLIN | POLLPRI | POLLOUT; + + if (!_PyArg_ParseStack(args, nargs, "O&|O&:register", + fildes_converter, &fd, ushort_converter, &eventmask)) { + goto exit; + } + return_value = select_poll_register_impl(self, fd, eventmask); + +exit: + return return_value; +} + +#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) */ + +#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) + +PyDoc_STRVAR(select_poll_modify__doc__, +"modify($self, fd, eventmask, /)\n" +"--\n" +"\n" +"Modify an already registered file descriptor.\n" +"\n" +" fd\n" +" either an integer, or an object with a fileno() method returning\n" +" an int\n" +" eventmask\n" +" a bitmask describing the type of events to check for"); + +#define SELECT_POLL_MODIFY_METHODDEF \ + {"modify", (PyCFunction)select_poll_modify, METH_FASTCALL, select_poll_modify__doc__}, + +static PyObject * +select_poll_modify_impl(pollObject *self, int fd, unsigned short eventmask); + +static PyObject * +select_poll_modify(pollObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int fd; + unsigned short eventmask; + + if (!_PyArg_ParseStack(args, nargs, "O&O&:modify", + fildes_converter, &fd, ushort_converter, &eventmask)) { + goto exit; + } + return_value = select_poll_modify_impl(self, fd, eventmask); + +exit: + return return_value; +} + +#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) */ + +#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) + +PyDoc_STRVAR(select_poll_unregister__doc__, +"unregister($self, fd, /)\n" +"--\n" +"\n" +"Remove a file descriptor being tracked by the polling object."); + +#define SELECT_POLL_UNREGISTER_METHODDEF \ + {"unregister", (PyCFunction)select_poll_unregister, METH_O, select_poll_unregister__doc__}, + +static PyObject * +select_poll_unregister_impl(pollObject *self, int fd); + +static PyObject * +select_poll_unregister(pollObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + int fd; + + if (!PyArg_Parse(arg, "O&:unregister", fildes_converter, &fd)) { + goto exit; + } + return_value = select_poll_unregister_impl(self, fd); + +exit: + return return_value; +} + +#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) */ + +#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) + +PyDoc_STRVAR(select_poll_poll__doc__, +"poll($self, timeout=None, /)\n" +"--\n" +"\n" +"Polls the set of registered file descriptors.\n" +"\n" +"Returns a list containing any descriptors that have events or errors to\n" +"report, as a list of (fd, event) 2-tuples."); + +#define SELECT_POLL_POLL_METHODDEF \ + {"poll", (PyCFunction)select_poll_poll, METH_FASTCALL, select_poll_poll__doc__}, + +static PyObject * +select_poll_poll_impl(pollObject *self, PyObject *timeout_obj); + +static PyObject * +select_poll_poll(pollObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *timeout_obj = Py_None; + + if (!_PyArg_UnpackStack(args, nargs, "poll", + 0, 1, + &timeout_obj)) { + goto exit; + } + return_value = select_poll_poll_impl(self, timeout_obj); + +exit: + return return_value; +} + +#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) */ + +#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) + +PyDoc_STRVAR(select_devpoll_register__doc__, +"register($self, fd, eventmask=POLLIN | POLLPRI | POLLOUT, /)\n" +"--\n" +"\n" +"Register a file descriptor with the polling object.\n" +"\n" +" fd\n" +" either an integer, or an object with a fileno() method returning\n" +" an int\n" +" eventmask\n" +" an optional bitmask describing the type of events to check for"); + +#define SELECT_DEVPOLL_REGISTER_METHODDEF \ + {"register", (PyCFunction)select_devpoll_register, METH_FASTCALL, select_devpoll_register__doc__}, + +static PyObject * +select_devpoll_register_impl(devpollObject *self, int fd, + unsigned short eventmask); + +static PyObject * +select_devpoll_register(devpollObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int fd; + unsigned short eventmask = POLLIN | POLLPRI | POLLOUT; + + if (!_PyArg_ParseStack(args, nargs, "O&|O&:register", + fildes_converter, &fd, ushort_converter, &eventmask)) { + goto exit; + } + return_value = select_devpoll_register_impl(self, fd, eventmask); + +exit: + return return_value; +} + +#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) */ + +#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) + +PyDoc_STRVAR(select_devpoll_modify__doc__, +"modify($self, fd, eventmask=POLLIN | POLLPRI | POLLOUT, /)\n" +"--\n" +"\n" +"Modify a possible already registered file descriptor.\n" +"\n" +" fd\n" +" either an integer, or an object with a fileno() method returning\n" +" an int\n" +" eventmask\n" +" an optional bitmask describing the type of events to check for"); + +#define SELECT_DEVPOLL_MODIFY_METHODDEF \ + {"modify", (PyCFunction)select_devpoll_modify, METH_FASTCALL, select_devpoll_modify__doc__}, + +static PyObject * +select_devpoll_modify_impl(devpollObject *self, int fd, + unsigned short eventmask); + +static PyObject * +select_devpoll_modify(devpollObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int fd; + unsigned short eventmask = POLLIN | POLLPRI | POLLOUT; + + if (!_PyArg_ParseStack(args, nargs, "O&|O&:modify", + fildes_converter, &fd, ushort_converter, &eventmask)) { + goto exit; + } + return_value = select_devpoll_modify_impl(self, fd, eventmask); + +exit: + return return_value; +} + +#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) */ + +#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) + +PyDoc_STRVAR(select_devpoll_unregister__doc__, +"unregister($self, fd, /)\n" +"--\n" +"\n" +"Remove a file descriptor being tracked by the polling object."); + +#define SELECT_DEVPOLL_UNREGISTER_METHODDEF \ + {"unregister", (PyCFunction)select_devpoll_unregister, METH_O, select_devpoll_unregister__doc__}, + +static PyObject * +select_devpoll_unregister_impl(devpollObject *self, int fd); + +static PyObject * +select_devpoll_unregister(devpollObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + int fd; + + if (!PyArg_Parse(arg, "O&:unregister", fildes_converter, &fd)) { + goto exit; + } + return_value = select_devpoll_unregister_impl(self, fd); + +exit: + return return_value; +} + +#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) */ + +#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) + +PyDoc_STRVAR(select_devpoll_poll__doc__, +"poll($self, timeout=None, /)\n" +"--\n" +"\n" +"Polls the set of registered file descriptors.\n" +"\n" +"Returns a list containing any descriptors that have events or errors to\n" +"report, as a list of (fd, event) 2-tuples."); + +#define SELECT_DEVPOLL_POLL_METHODDEF \ + {"poll", (PyCFunction)select_devpoll_poll, METH_FASTCALL, select_devpoll_poll__doc__}, + +static PyObject * +select_devpoll_poll_impl(devpollObject *self, PyObject *timeout_obj); + +static PyObject * +select_devpoll_poll(devpollObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *timeout_obj = Py_None; + + if (!_PyArg_UnpackStack(args, nargs, "poll", + 0, 1, + &timeout_obj)) { + goto exit; + } + return_value = select_devpoll_poll_impl(self, timeout_obj); + +exit: + return return_value; +} + +#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) */ + +#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) + +PyDoc_STRVAR(select_devpoll_close__doc__, +"close($self, /)\n" +"--\n" +"\n" +"Close the devpoll file descriptor.\n" +"\n" +"Further operations on the devpoll object will raise an exception."); + +#define SELECT_DEVPOLL_CLOSE_METHODDEF \ + {"close", (PyCFunction)select_devpoll_close, METH_NOARGS, select_devpoll_close__doc__}, + +static PyObject * +select_devpoll_close_impl(devpollObject *self); + +static PyObject * +select_devpoll_close(devpollObject *self, PyObject *Py_UNUSED(ignored)) +{ + return select_devpoll_close_impl(self); +} + +#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) */ + +#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) + +PyDoc_STRVAR(select_devpoll_fileno__doc__, +"fileno($self, /)\n" +"--\n" +"\n" +"Return the file descriptor."); + +#define SELECT_DEVPOLL_FILENO_METHODDEF \ + {"fileno", (PyCFunction)select_devpoll_fileno, METH_NOARGS, select_devpoll_fileno__doc__}, + +static PyObject * +select_devpoll_fileno_impl(devpollObject *self); + +static PyObject * +select_devpoll_fileno(devpollObject *self, PyObject *Py_UNUSED(ignored)) +{ + return select_devpoll_fileno_impl(self); +} + +#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) */ + +#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) + +PyDoc_STRVAR(select_poll__doc__, +"poll($module, /)\n" +"--\n" +"\n" +"Returns a polling object.\n" +"\n" +"This object supports registering and unregistering file descriptors, and then\n" +"polling them for I/O events."); + +#define SELECT_POLL_METHODDEF \ + {"poll", (PyCFunction)select_poll, METH_NOARGS, select_poll__doc__}, + +static PyObject * +select_poll_impl(PyObject *module); + +static PyObject * +select_poll(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return select_poll_impl(module); +} + +#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) */ + +#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) + +PyDoc_STRVAR(select_devpoll__doc__, +"devpoll($module, /)\n" +"--\n" +"\n" +"Returns a polling object.\n" +"\n" +"This object supports registering and unregistering file descriptors, and then\n" +"polling them for I/O events."); + +#define SELECT_DEVPOLL_METHODDEF \ + {"devpoll", (PyCFunction)select_devpoll, METH_NOARGS, select_devpoll__doc__}, + +static PyObject * +select_devpoll_impl(PyObject *module); + +static PyObject * +select_devpoll(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return select_devpoll_impl(module); +} + +#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) */ + +#if defined(HAVE_EPOLL) + +PyDoc_STRVAR(select_epoll__doc__, +"epoll(sizehint=-1, flags=0)\n" +"--\n" +"\n" +"Returns an epolling object.\n" +"\n" +" sizehint\n" +" The expected number of events to be registered. It must be positive,\n" +" or -1 to use the default. It is only used on older systems where\n" +" epoll_create1() is not available; otherwise it has no effect (though its\n" +" value is still checked).\n" +" flags\n" +" Deprecated and completely ignored. However, when supplied, its value\n" +" must be 0 or select.EPOLL_CLOEXEC, otherwise OSError is raised."); + +static PyObject * +select_epoll_impl(PyTypeObject *type, int sizehint, int flags); + +static PyObject * +select_epoll(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"sizehint", "flags", NULL}; + static _PyArg_Parser _parser = {"|ii:epoll", _keywords, 0}; + int sizehint = -1; + int flags = 0; + + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &sizehint, &flags)) { + goto exit; + } + return_value = select_epoll_impl(type, sizehint, flags); + +exit: + return return_value; +} + +#endif /* defined(HAVE_EPOLL) */ + +#if defined(HAVE_EPOLL) + +PyDoc_STRVAR(select_epoll_close__doc__, +"close($self, /)\n" +"--\n" +"\n" +"Close the epoll control file descriptor.\n" +"\n" +"Further operations on the epoll object will raise an exception."); + +#define SELECT_EPOLL_CLOSE_METHODDEF \ + {"close", (PyCFunction)select_epoll_close, METH_NOARGS, select_epoll_close__doc__}, + +static PyObject * +select_epoll_close_impl(pyEpoll_Object *self); + +static PyObject * +select_epoll_close(pyEpoll_Object *self, PyObject *Py_UNUSED(ignored)) +{ + return select_epoll_close_impl(self); +} + +#endif /* defined(HAVE_EPOLL) */ + +#if defined(HAVE_EPOLL) + +PyDoc_STRVAR(select_epoll_fileno__doc__, +"fileno($self, /)\n" +"--\n" +"\n" +"Return the epoll control file descriptor."); + +#define SELECT_EPOLL_FILENO_METHODDEF \ + {"fileno", (PyCFunction)select_epoll_fileno, METH_NOARGS, select_epoll_fileno__doc__}, + +static PyObject * +select_epoll_fileno_impl(pyEpoll_Object *self); + +static PyObject * +select_epoll_fileno(pyEpoll_Object *self, PyObject *Py_UNUSED(ignored)) +{ + return select_epoll_fileno_impl(self); +} + +#endif /* defined(HAVE_EPOLL) */ + +#if defined(HAVE_EPOLL) + +PyDoc_STRVAR(select_epoll_fromfd__doc__, +"fromfd($type, fd, /)\n" +"--\n" +"\n" +"Create an epoll object from a given control fd."); + +#define SELECT_EPOLL_FROMFD_METHODDEF \ + {"fromfd", (PyCFunction)select_epoll_fromfd, METH_O|METH_CLASS, select_epoll_fromfd__doc__}, + +static PyObject * +select_epoll_fromfd_impl(PyTypeObject *type, int fd); + +static PyObject * +select_epoll_fromfd(PyTypeObject *type, PyObject *arg) +{ + PyObject *return_value = NULL; + int fd; + + if (!PyArg_Parse(arg, "i:fromfd", &fd)) { + goto exit; + } + return_value = select_epoll_fromfd_impl(type, fd); + +exit: + return return_value; +} + +#endif /* defined(HAVE_EPOLL) */ + +#if defined(HAVE_EPOLL) + +PyDoc_STRVAR(select_epoll_register__doc__, +"register($self, /, fd, eventmask=EPOLLIN | EPOLLPRI | EPOLLOUT)\n" +"--\n" +"\n" +"Registers a new fd or raises an OSError if the fd is already registered.\n" +"\n" +" fd\n" +" the target file descriptor of the operation\n" +" eventmask\n" +" a bit set composed of the various EPOLL constants\n" +"\n" +"The epoll interface supports all file descriptors that support poll."); + +#define SELECT_EPOLL_REGISTER_METHODDEF \ + {"register", (PyCFunction)select_epoll_register, METH_FASTCALL|METH_KEYWORDS, select_epoll_register__doc__}, + +static PyObject * +select_epoll_register_impl(pyEpoll_Object *self, int fd, + unsigned int eventmask); + +static PyObject * +select_epoll_register(pyEpoll_Object *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"fd", "eventmask", NULL}; + static _PyArg_Parser _parser = {"O&|I:register", _keywords, 0}; + int fd; + unsigned int eventmask = EPOLLIN | EPOLLPRI | EPOLLOUT; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + fildes_converter, &fd, &eventmask)) { + goto exit; + } + return_value = select_epoll_register_impl(self, fd, eventmask); + +exit: + return return_value; +} + +#endif /* defined(HAVE_EPOLL) */ + +#if defined(HAVE_EPOLL) + +PyDoc_STRVAR(select_epoll_modify__doc__, +"modify($self, /, fd, eventmask)\n" +"--\n" +"\n" +"Modify event mask for a registered file descriptor.\n" +"\n" +" fd\n" +" the target file descriptor of the operation\n" +" eventmask\n" +" a bit set composed of the various EPOLL constants"); + +#define SELECT_EPOLL_MODIFY_METHODDEF \ + {"modify", (PyCFunction)select_epoll_modify, METH_FASTCALL|METH_KEYWORDS, select_epoll_modify__doc__}, + +static PyObject * +select_epoll_modify_impl(pyEpoll_Object *self, int fd, + unsigned int eventmask); + +static PyObject * +select_epoll_modify(pyEpoll_Object *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"fd", "eventmask", NULL}; + static _PyArg_Parser _parser = {"O&I:modify", _keywords, 0}; + int fd; + unsigned int eventmask; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + fildes_converter, &fd, &eventmask)) { + goto exit; + } + return_value = select_epoll_modify_impl(self, fd, eventmask); + +exit: + return return_value; +} + +#endif /* defined(HAVE_EPOLL) */ + +#if defined(HAVE_EPOLL) + +PyDoc_STRVAR(select_epoll_unregister__doc__, +"unregister($self, /, fd)\n" +"--\n" +"\n" +"Remove a registered file descriptor from the epoll object.\n" +"\n" +" fd\n" +" the target file descriptor of the operation"); + +#define SELECT_EPOLL_UNREGISTER_METHODDEF \ + {"unregister", (PyCFunction)select_epoll_unregister, METH_FASTCALL|METH_KEYWORDS, select_epoll_unregister__doc__}, + +static PyObject * +select_epoll_unregister_impl(pyEpoll_Object *self, int fd); + +static PyObject * +select_epoll_unregister(pyEpoll_Object *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"fd", NULL}; + static _PyArg_Parser _parser = {"O&:unregister", _keywords, 0}; + int fd; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + fildes_converter, &fd)) { + goto exit; + } + return_value = select_epoll_unregister_impl(self, fd); + +exit: + return return_value; +} + +#endif /* defined(HAVE_EPOLL) */ + +#if defined(HAVE_EPOLL) + +PyDoc_STRVAR(select_epoll_poll__doc__, +"poll($self, /, timeout=None, maxevents=-1)\n" +"--\n" +"\n" +"Wait for events on the epoll file descriptor.\n" +"\n" +" timeout\n" +" the maximum time to wait in seconds (as float);\n" +" a timeout of None or -1 makes poll wait indefinitely\n" +" maxevents\n" +" the maximum number of events returned; -1 means no limit\n" +"\n" +"Returns a list containing any descriptors that have events to report,\n" +"as a list of (fd, events) 2-tuples."); + +#define SELECT_EPOLL_POLL_METHODDEF \ + {"poll", (PyCFunction)select_epoll_poll, METH_FASTCALL|METH_KEYWORDS, select_epoll_poll__doc__}, + +static PyObject * +select_epoll_poll_impl(pyEpoll_Object *self, PyObject *timeout_obj, + int maxevents); + +static PyObject * +select_epoll_poll(pyEpoll_Object *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"timeout", "maxevents", NULL}; + static _PyArg_Parser _parser = {"|Oi:poll", _keywords, 0}; + PyObject *timeout_obj = Py_None; + int maxevents = -1; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &timeout_obj, &maxevents)) { + goto exit; + } + return_value = select_epoll_poll_impl(self, timeout_obj, maxevents); + +exit: + return return_value; +} + +#endif /* defined(HAVE_EPOLL) */ + +#if defined(HAVE_EPOLL) + +PyDoc_STRVAR(select_epoll___enter____doc__, +"__enter__($self, /)\n" +"--\n" +"\n"); + +#define SELECT_EPOLL___ENTER___METHODDEF \ + {"__enter__", (PyCFunction)select_epoll___enter__, METH_NOARGS, select_epoll___enter____doc__}, + +static PyObject * +select_epoll___enter___impl(pyEpoll_Object *self); + +static PyObject * +select_epoll___enter__(pyEpoll_Object *self, PyObject *Py_UNUSED(ignored)) +{ + return select_epoll___enter___impl(self); +} + +#endif /* defined(HAVE_EPOLL) */ + +#if defined(HAVE_EPOLL) + +PyDoc_STRVAR(select_epoll___exit____doc__, +"__exit__($self, exc_type=None, exc_value=None, exc_tb=None, /)\n" +"--\n" +"\n"); + +#define SELECT_EPOLL___EXIT___METHODDEF \ + {"__exit__", (PyCFunction)select_epoll___exit__, METH_FASTCALL, select_epoll___exit____doc__}, + +static PyObject * +select_epoll___exit___impl(pyEpoll_Object *self, PyObject *exc_type, + PyObject *exc_value, PyObject *exc_tb); + +static PyObject * +select_epoll___exit__(pyEpoll_Object *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *exc_type = Py_None; + PyObject *exc_value = Py_None; + PyObject *exc_tb = Py_None; + + if (!_PyArg_UnpackStack(args, nargs, "__exit__", + 0, 3, + &exc_type, &exc_value, &exc_tb)) { + goto exit; + } + return_value = select_epoll___exit___impl(self, exc_type, exc_value, exc_tb); + +exit: + return return_value; +} + +#endif /* defined(HAVE_EPOLL) */ + +#if defined(HAVE_KQUEUE) + +PyDoc_STRVAR(select_kqueue__doc__, +"kqueue()\n" +"--\n" +"\n" +"Kqueue syscall wrapper.\n" +"\n" +"For example, to start watching a socket for input:\n" +">>> kq = kqueue()\n" +">>> sock = socket()\n" +">>> sock.connect((host, port))\n" +">>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n" +"\n" +"To wait one second for it to become writeable:\n" +">>> kq.control(None, 1, 1000)\n" +"\n" +"To stop listening:\n" +">>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)"); + +static PyObject * +select_kqueue_impl(PyTypeObject *type); + +static PyObject * +select_kqueue(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + + if ((type == &kqueue_queue_Type) && + !_PyArg_NoPositional("kqueue", args)) { + goto exit; + } + if ((type == &kqueue_queue_Type) && + !_PyArg_NoKeywords("kqueue", kwargs)) { + goto exit; + } + return_value = select_kqueue_impl(type); + +exit: + return return_value; +} + +#endif /* defined(HAVE_KQUEUE) */ + +#if defined(HAVE_KQUEUE) + +PyDoc_STRVAR(select_kqueue_close__doc__, +"close($self, /)\n" +"--\n" +"\n" +"Close the kqueue control file descriptor.\n" +"\n" +"Further operations on the kqueue object will raise an exception."); + +#define SELECT_KQUEUE_CLOSE_METHODDEF \ + {"close", (PyCFunction)select_kqueue_close, METH_NOARGS, select_kqueue_close__doc__}, + +static PyObject * +select_kqueue_close_impl(kqueue_queue_Object *self); + +static PyObject * +select_kqueue_close(kqueue_queue_Object *self, PyObject *Py_UNUSED(ignored)) +{ + return select_kqueue_close_impl(self); +} + +#endif /* defined(HAVE_KQUEUE) */ + +#if defined(HAVE_KQUEUE) + +PyDoc_STRVAR(select_kqueue_fileno__doc__, +"fileno($self, /)\n" +"--\n" +"\n" +"Return the kqueue control file descriptor."); + +#define SELECT_KQUEUE_FILENO_METHODDEF \ + {"fileno", (PyCFunction)select_kqueue_fileno, METH_NOARGS, select_kqueue_fileno__doc__}, + +static PyObject * +select_kqueue_fileno_impl(kqueue_queue_Object *self); + +static PyObject * +select_kqueue_fileno(kqueue_queue_Object *self, PyObject *Py_UNUSED(ignored)) +{ + return select_kqueue_fileno_impl(self); +} + +#endif /* defined(HAVE_KQUEUE) */ + +#if defined(HAVE_KQUEUE) + +PyDoc_STRVAR(select_kqueue_fromfd__doc__, +"fromfd($type, fd, /)\n" +"--\n" +"\n" +"Create a kqueue object from a given control fd."); + +#define SELECT_KQUEUE_FROMFD_METHODDEF \ + {"fromfd", (PyCFunction)select_kqueue_fromfd, METH_O|METH_CLASS, select_kqueue_fromfd__doc__}, + +static PyObject * +select_kqueue_fromfd_impl(PyTypeObject *type, int fd); + +static PyObject * +select_kqueue_fromfd(PyTypeObject *type, PyObject *arg) +{ + PyObject *return_value = NULL; + int fd; + + if (!PyArg_Parse(arg, "i:fromfd", &fd)) { + goto exit; + } + return_value = select_kqueue_fromfd_impl(type, fd); + +exit: + return return_value; +} + +#endif /* defined(HAVE_KQUEUE) */ + +#if defined(HAVE_KQUEUE) + +PyDoc_STRVAR(select_kqueue_control__doc__, +"control($self, changelist, maxevents, timeout=None, /)\n" +"--\n" +"\n" +"Calls the kernel kevent function.\n" +"\n" +" changelist\n" +" Must be an iterable of kevent objects describing the changes to be made\n" +" to the kernel\'s watch list or None.\n" +" maxevents\n" +" The maximum number of events that the kernel will return.\n" +" timeout\n" +" The maximum time to wait in seconds, or else None to wait forever.\n" +" This accepts floats for smaller timeouts, too."); + +#define SELECT_KQUEUE_CONTROL_METHODDEF \ + {"control", (PyCFunction)select_kqueue_control, METH_FASTCALL, select_kqueue_control__doc__}, + +static PyObject * +select_kqueue_control_impl(kqueue_queue_Object *self, PyObject *changelist, + int maxevents, PyObject *otimeout); + +static PyObject * +select_kqueue_control(kqueue_queue_Object *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *changelist; + int maxevents; + PyObject *otimeout = Py_None; + + if (!_PyArg_ParseStack(args, nargs, "Oi|O:control", + &changelist, &maxevents, &otimeout)) { + goto exit; + } + return_value = select_kqueue_control_impl(self, changelist, maxevents, otimeout); + +exit: + return return_value; +} + +#endif /* defined(HAVE_KQUEUE) */ + +#ifndef SELECT_POLL_REGISTER_METHODDEF + #define SELECT_POLL_REGISTER_METHODDEF +#endif /* !defined(SELECT_POLL_REGISTER_METHODDEF) */ + +#ifndef SELECT_POLL_MODIFY_METHODDEF + #define SELECT_POLL_MODIFY_METHODDEF +#endif /* !defined(SELECT_POLL_MODIFY_METHODDEF) */ + +#ifndef SELECT_POLL_UNREGISTER_METHODDEF + #define SELECT_POLL_UNREGISTER_METHODDEF +#endif /* !defined(SELECT_POLL_UNREGISTER_METHODDEF) */ + +#ifndef SELECT_POLL_POLL_METHODDEF + #define SELECT_POLL_POLL_METHODDEF +#endif /* !defined(SELECT_POLL_POLL_METHODDEF) */ + +#ifndef SELECT_DEVPOLL_REGISTER_METHODDEF + #define SELECT_DEVPOLL_REGISTER_METHODDEF +#endif /* !defined(SELECT_DEVPOLL_REGISTER_METHODDEF) */ + +#ifndef SELECT_DEVPOLL_MODIFY_METHODDEF + #define SELECT_DEVPOLL_MODIFY_METHODDEF +#endif /* !defined(SELECT_DEVPOLL_MODIFY_METHODDEF) */ + +#ifndef SELECT_DEVPOLL_UNREGISTER_METHODDEF + #define SELECT_DEVPOLL_UNREGISTER_METHODDEF +#endif /* !defined(SELECT_DEVPOLL_UNREGISTER_METHODDEF) */ + +#ifndef SELECT_DEVPOLL_POLL_METHODDEF + #define SELECT_DEVPOLL_POLL_METHODDEF +#endif /* !defined(SELECT_DEVPOLL_POLL_METHODDEF) */ + +#ifndef SELECT_DEVPOLL_CLOSE_METHODDEF + #define SELECT_DEVPOLL_CLOSE_METHODDEF +#endif /* !defined(SELECT_DEVPOLL_CLOSE_METHODDEF) */ + +#ifndef SELECT_DEVPOLL_FILENO_METHODDEF + #define SELECT_DEVPOLL_FILENO_METHODDEF +#endif /* !defined(SELECT_DEVPOLL_FILENO_METHODDEF) */ + +#ifndef SELECT_POLL_METHODDEF + #define SELECT_POLL_METHODDEF +#endif /* !defined(SELECT_POLL_METHODDEF) */ + +#ifndef SELECT_DEVPOLL_METHODDEF + #define SELECT_DEVPOLL_METHODDEF +#endif /* !defined(SELECT_DEVPOLL_METHODDEF) */ + +#ifndef SELECT_EPOLL_CLOSE_METHODDEF + #define SELECT_EPOLL_CLOSE_METHODDEF +#endif /* !defined(SELECT_EPOLL_CLOSE_METHODDEF) */ + +#ifndef SELECT_EPOLL_FILENO_METHODDEF + #define SELECT_EPOLL_FILENO_METHODDEF +#endif /* !defined(SELECT_EPOLL_FILENO_METHODDEF) */ + +#ifndef SELECT_EPOLL_FROMFD_METHODDEF + #define SELECT_EPOLL_FROMFD_METHODDEF +#endif /* !defined(SELECT_EPOLL_FROMFD_METHODDEF) */ + +#ifndef SELECT_EPOLL_REGISTER_METHODDEF + #define SELECT_EPOLL_REGISTER_METHODDEF +#endif /* !defined(SELECT_EPOLL_REGISTER_METHODDEF) */ + +#ifndef SELECT_EPOLL_MODIFY_METHODDEF + #define SELECT_EPOLL_MODIFY_METHODDEF +#endif /* !defined(SELECT_EPOLL_MODIFY_METHODDEF) */ + +#ifndef SELECT_EPOLL_UNREGISTER_METHODDEF + #define SELECT_EPOLL_UNREGISTER_METHODDEF +#endif /* !defined(SELECT_EPOLL_UNREGISTER_METHODDEF) */ + +#ifndef SELECT_EPOLL_POLL_METHODDEF + #define SELECT_EPOLL_POLL_METHODDEF +#endif /* !defined(SELECT_EPOLL_POLL_METHODDEF) */ + +#ifndef SELECT_EPOLL___ENTER___METHODDEF + #define SELECT_EPOLL___ENTER___METHODDEF +#endif /* !defined(SELECT_EPOLL___ENTER___METHODDEF) */ + +#ifndef SELECT_EPOLL___EXIT___METHODDEF + #define SELECT_EPOLL___EXIT___METHODDEF +#endif /* !defined(SELECT_EPOLL___EXIT___METHODDEF) */ + +#ifndef SELECT_KQUEUE_CLOSE_METHODDEF + #define SELECT_KQUEUE_CLOSE_METHODDEF +#endif /* !defined(SELECT_KQUEUE_CLOSE_METHODDEF) */ + +#ifndef SELECT_KQUEUE_FILENO_METHODDEF + #define SELECT_KQUEUE_FILENO_METHODDEF +#endif /* !defined(SELECT_KQUEUE_FILENO_METHODDEF) */ + +#ifndef SELECT_KQUEUE_FROMFD_METHODDEF + #define SELECT_KQUEUE_FROMFD_METHODDEF +#endif /* !defined(SELECT_KQUEUE_FROMFD_METHODDEF) */ + +#ifndef SELECT_KQUEUE_CONTROL_METHODDEF + #define SELECT_KQUEUE_CONTROL_METHODDEF +#endif /* !defined(SELECT_KQUEUE_CONTROL_METHODDEF) */ +/*[clinic end generated code: output=3e425445d49c49e2 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/signalmodule.c.h b/Modules/clinic/signalmodule.c.h index dc3aadf878b2f2..4d7ac38372f2f2 100644 --- a/Modules/clinic/signalmodule.c.h +++ b/Modules/clinic/signalmodule.c.h @@ -129,6 +129,36 @@ signal_getsignal(PyObject *module, PyObject *arg) return return_value; } +PyDoc_STRVAR(signal_strsignal__doc__, +"strsignal($module, signalnum, /)\n" +"--\n" +"\n" +"Return the system description of the given signal.\n" +"\n" +"The return values can be such as \"Interrupt\", \"Segmentation fault\", etc.\n" +"Returns None if the signal is not recognized."); + +#define SIGNAL_STRSIGNAL_METHODDEF \ + {"strsignal", (PyCFunction)signal_strsignal, METH_O, signal_strsignal__doc__}, + +static PyObject * +signal_strsignal_impl(PyObject *module, int signalnum); + +static PyObject * +signal_strsignal(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int signalnum; + + if (!PyArg_Parse(arg, "i:strsignal", &signalnum)) { + goto exit; + } + return_value = signal_strsignal_impl(module, signalnum); + +exit: + return return_value; +} + #if defined(HAVE_SIGINTERRUPT) PyDoc_STRVAR(signal_siginterrupt__doc__, @@ -248,17 +278,17 @@ PyDoc_STRVAR(signal_pthread_sigmask__doc__, {"pthread_sigmask", (PyCFunction)signal_pthread_sigmask, METH_FASTCALL, signal_pthread_sigmask__doc__}, static PyObject * -signal_pthread_sigmask_impl(PyObject *module, int how, PyObject *mask); +signal_pthread_sigmask_impl(PyObject *module, int how, sigset_t mask); static PyObject * signal_pthread_sigmask(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; int how; - PyObject *mask; + sigset_t mask; - if (!_PyArg_ParseStack(args, nargs, "iO:pthread_sigmask", - &how, &mask)) { + if (!_PyArg_ParseStack(args, nargs, "iO&:pthread_sigmask", + &how, _Py_Sigset_Converter, &mask)) { goto exit; } return_value = signal_pthread_sigmask_impl(module, how, mask); @@ -309,8 +339,51 @@ PyDoc_STRVAR(signal_sigwait__doc__, #define SIGNAL_SIGWAIT_METHODDEF \ {"sigwait", (PyCFunction)signal_sigwait, METH_O, signal_sigwait__doc__}, +static PyObject * +signal_sigwait_impl(PyObject *module, sigset_t sigset); + +static PyObject * +signal_sigwait(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + sigset_t sigset; + + if (!PyArg_Parse(arg, "O&:sigwait", _Py_Sigset_Converter, &sigset)) { + goto exit; + } + return_value = signal_sigwait_impl(module, sigset); + +exit: + return return_value; +} + #endif /* defined(HAVE_SIGWAIT) */ +#if (defined(HAVE_SIGFILLSET) || defined(MS_WINDOWS)) + +PyDoc_STRVAR(signal_valid_signals__doc__, +"valid_signals($module, /)\n" +"--\n" +"\n" +"Return a set of valid signal numbers on this platform.\n" +"\n" +"The signal numbers returned by this function can be safely passed to\n" +"functions like `pthread_sigmask`."); + +#define SIGNAL_VALID_SIGNALS_METHODDEF \ + {"valid_signals", (PyCFunction)signal_valid_signals, METH_NOARGS, signal_valid_signals__doc__}, + +static PyObject * +signal_valid_signals_impl(PyObject *module); + +static PyObject * +signal_valid_signals(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return signal_valid_signals_impl(module); +} + +#endif /* (defined(HAVE_SIGFILLSET) || defined(MS_WINDOWS)) */ + #if defined(HAVE_SIGWAITINFO) PyDoc_STRVAR(signal_sigwaitinfo__doc__, @@ -324,6 +397,24 @@ PyDoc_STRVAR(signal_sigwaitinfo__doc__, #define SIGNAL_SIGWAITINFO_METHODDEF \ {"sigwaitinfo", (PyCFunction)signal_sigwaitinfo, METH_O, signal_sigwaitinfo__doc__}, +static PyObject * +signal_sigwaitinfo_impl(PyObject *module, sigset_t sigset); + +static PyObject * +signal_sigwaitinfo(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + sigset_t sigset; + + if (!PyArg_Parse(arg, "O&:sigwaitinfo", _Py_Sigset_Converter, &sigset)) { + goto exit; + } + return_value = signal_sigwaitinfo_impl(module, sigset); + +exit: + return return_value; +} + #endif /* defined(HAVE_SIGWAITINFO) */ #if defined(HAVE_SIGTIMEDWAIT) @@ -340,19 +431,18 @@ PyDoc_STRVAR(signal_sigtimedwait__doc__, {"sigtimedwait", (PyCFunction)signal_sigtimedwait, METH_FASTCALL, signal_sigtimedwait__doc__}, static PyObject * -signal_sigtimedwait_impl(PyObject *module, PyObject *sigset, +signal_sigtimedwait_impl(PyObject *module, sigset_t sigset, PyObject *timeout_obj); static PyObject * signal_sigtimedwait(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - PyObject *sigset; + sigset_t sigset; PyObject *timeout_obj; - if (!_PyArg_UnpackStack(args, nargs, "sigtimedwait", - 2, 2, - &sigset, &timeout_obj)) { + if (!_PyArg_ParseStack(args, nargs, "O&O:sigtimedwait", + _Py_Sigset_Converter, &sigset, &timeout_obj)) { goto exit; } return_value = signal_sigtimedwait_impl(module, sigset, timeout_obj); @@ -429,6 +519,10 @@ signal_pthread_kill(PyObject *module, PyObject *const *args, Py_ssize_t nargs) #define SIGNAL_SIGWAIT_METHODDEF #endif /* !defined(SIGNAL_SIGWAIT_METHODDEF) */ +#ifndef SIGNAL_VALID_SIGNALS_METHODDEF + #define SIGNAL_VALID_SIGNALS_METHODDEF +#endif /* !defined(SIGNAL_VALID_SIGNALS_METHODDEF) */ + #ifndef SIGNAL_SIGWAITINFO_METHODDEF #define SIGNAL_SIGWAITINFO_METHODDEF #endif /* !defined(SIGNAL_SIGWAITINFO_METHODDEF) */ @@ -440,4 +534,4 @@ signal_pthread_kill(PyObject *module, PyObject *const *args, Py_ssize_t nargs) #ifndef SIGNAL_PTHREAD_KILL_METHODDEF #define SIGNAL_PTHREAD_KILL_METHODDEF #endif /* !defined(SIGNAL_PTHREAD_KILL_METHODDEF) */ -/*[clinic end generated code: output=36132f4189381fe0 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=549f0efdc7405834 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/zlibmodule.c.h b/Modules/clinic/zlibmodule.c.h index c68c4a1078508c..99db052bf2faa9 100644 --- a/Modules/clinic/zlibmodule.c.h +++ b/Modules/clinic/zlibmodule.c.h @@ -335,6 +335,39 @@ zlib_Compress_copy(compobject *self, PyObject *Py_UNUSED(ignored)) #if defined(HAVE_ZLIB_COPY) +PyDoc_STRVAR(zlib_Compress___copy____doc__, +"__copy__($self, /)\n" +"--\n" +"\n"); + +#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) */ + +#if defined(HAVE_ZLIB_COPY) + +PyDoc_STRVAR(zlib_Compress___deepcopy____doc__, +"__deepcopy__($self, memo, /)\n" +"--\n" +"\n"); + +#define ZLIB_COMPRESS___DEEPCOPY___METHODDEF \ + {"__deepcopy__", (PyCFunction)zlib_Compress___deepcopy__, METH_O, zlib_Compress___deepcopy____doc__}, + +#endif /* defined(HAVE_ZLIB_COPY) */ + +#if defined(HAVE_ZLIB_COPY) + PyDoc_STRVAR(zlib_Decompress_copy__doc__, "copy($self, /)\n" "--\n" @@ -355,6 +388,39 @@ zlib_Decompress_copy(compobject *self, PyObject *Py_UNUSED(ignored)) #endif /* defined(HAVE_ZLIB_COPY) */ +#if defined(HAVE_ZLIB_COPY) + +PyDoc_STRVAR(zlib_Decompress___copy____doc__, +"__copy__($self, /)\n" +"--\n" +"\n"); + +#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) */ + +#if defined(HAVE_ZLIB_COPY) + +PyDoc_STRVAR(zlib_Decompress___deepcopy____doc__, +"__deepcopy__($self, memo, /)\n" +"--\n" +"\n"); + +#define ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF \ + {"__deepcopy__", (PyCFunction)zlib_Decompress___deepcopy__, METH_O, zlib_Decompress___deepcopy____doc__}, + +#endif /* defined(HAVE_ZLIB_COPY) */ + PyDoc_STRVAR(zlib_Decompress_flush__doc__, "flush($self, length=zlib.DEF_BUF_SIZE, /)\n" "--\n" @@ -468,7 +534,23 @@ zlib_crc32(PyObject *module, PyObject *const *args, Py_ssize_t nargs) #define ZLIB_COMPRESS_COPY_METHODDEF #endif /* !defined(ZLIB_COMPRESS_COPY_METHODDEF) */ +#ifndef ZLIB_COMPRESS___COPY___METHODDEF + #define ZLIB_COMPRESS___COPY___METHODDEF +#endif /* !defined(ZLIB_COMPRESS___COPY___METHODDEF) */ + +#ifndef ZLIB_COMPRESS___DEEPCOPY___METHODDEF + #define ZLIB_COMPRESS___DEEPCOPY___METHODDEF +#endif /* !defined(ZLIB_COMPRESS___DEEPCOPY___METHODDEF) */ + #ifndef ZLIB_DECOMPRESS_COPY_METHODDEF #define ZLIB_DECOMPRESS_COPY_METHODDEF #endif /* !defined(ZLIB_DECOMPRESS_COPY_METHODDEF) */ -/*[clinic end generated code: output=43dd29b8977765f9 input=a9049054013a1b77]*/ + +#ifndef ZLIB_DECOMPRESS___COPY___METHODDEF + #define ZLIB_DECOMPRESS___COPY___METHODDEF +#endif /* !defined(ZLIB_DECOMPRESS___COPY___METHODDEF) */ + +#ifndef ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF + #define ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF +#endif /* !defined(ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF) */ +/*[clinic end generated code: output=d46c646770146ade input=a9049054013a1b77]*/ diff --git a/Modules/expat/expat.h b/Modules/expat/expat.h index d0735bb5c61676..1f608c02d6fdbf 100644 --- a/Modules/expat/expat.h +++ b/Modules/expat/expat.h @@ -1076,7 +1076,7 @@ XML_GetFeatureList(void); */ #define XML_MAJOR_VERSION 2 #define XML_MINOR_VERSION 2 -#define XML_MICRO_VERSION 4 +#define XML_MICRO_VERSION 5 #ifdef __cplusplus } diff --git a/Modules/expat/expat_external.h b/Modules/expat/expat_external.h index 81102856496965..629483a91b27f4 100644 --- a/Modules/expat/expat_external.h +++ b/Modules/expat/expat_external.h @@ -35,12 +35,8 @@ /* 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 +# define XML_USE_MSC_EXTENSIONS 1 #endif /* Expat tries very hard to make the API boundary very specifically @@ -66,11 +62,11 @@ system headers may assume the cdecl convention. */ #ifndef XMLCALL -#if defined(_MSC_VER) -#define XMLCALL __cdecl -#elif defined(__GNUC__) && defined(__i386) && !defined(__INTEL_COMPILER) -#define XMLCALL __attribute__((cdecl)) -#else +# if defined(_MSC_VER) +# define XMLCALL __cdecl +# elif defined(__GNUC__) && defined(__i386) && !defined(__INTEL_COMPILER) +# define XMLCALL __attribute__((cdecl)) +# else /* For any platform which uses this definition and supports more than one calling convention, we need to extend this definition to declare the convention used on that platform, if it's possible to @@ -81,41 +77,41 @@ pre-processor and how to specify the same calling convention as the platform's malloc() implementation. */ -#define XMLCALL -#endif +# define XMLCALL +# endif #endif /* not defined XMLCALL */ #if !defined(XML_STATIC) && !defined(XMLIMPORT) -#ifndef XML_BUILDING_EXPAT +# ifndef XML_BUILDING_EXPAT /* using Expat from an application */ -#ifdef XML_USE_MSC_EXTENSIONS -#define XMLIMPORT __declspec(dllimport) -#endif +# ifdef XML_USE_MSC_EXTENSIONS +# define XMLIMPORT __declspec(dllimport) +# endif -#endif +# endif #endif /* not defined XML_STATIC */ #if !defined(XMLIMPORT) && defined(__GNUC__) && (__GNUC__ >= 4) -#define XMLIMPORT __attribute__ ((visibility ("default"))) +# define XMLIMPORT __attribute__ ((visibility ("default"))) #endif /* If we didn't define it above, define it away: */ #ifndef XMLIMPORT -#define XMLIMPORT +# define XMLIMPORT #endif #if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96)) -#define XML_ATTR_MALLOC __attribute__((__malloc__)) +# define XML_ATTR_MALLOC __attribute__((__malloc__)) #else -#define XML_ATTR_MALLOC +# define XML_ATTR_MALLOC #endif #if defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) -#define XML_ATTR_ALLOC_SIZE(x) __attribute__((__alloc_size__(x))) +# define XML_ATTR_ALLOC_SIZE(x) __attribute__((__alloc_size__(x))) #else -#define XML_ATTR_ALLOC_SIZE(x) +# define XML_ATTR_ALLOC_SIZE(x) #endif #define XMLPARSEAPI(type) XMLIMPORT type XMLCALL @@ -125,33 +121,35 @@ extern "C" { #endif #ifdef XML_UNICODE_WCHAR_T -# define XML_UNICODE +# ifndef XML_UNICODE +# define XML_UNICODE +# endif # if defined(__SIZEOF_WCHAR_T__) && (__SIZEOF_WCHAR_T__ != 2) # error "sizeof(wchar_t) != 2; Need -fshort-wchar for both Expat and libc" # endif #endif #ifdef XML_UNICODE /* Information is UTF-16 encoded. */ -#ifdef XML_UNICODE_WCHAR_T +# ifdef XML_UNICODE_WCHAR_T typedef wchar_t XML_Char; typedef wchar_t XML_LChar; -#else +# else typedef unsigned short XML_Char; typedef char XML_LChar; -#endif /* XML_UNICODE_WCHAR_T */ +# endif /* XML_UNICODE_WCHAR_T */ #else /* Information is UTF-8 encoded. */ typedef char XML_Char; typedef char XML_LChar; #endif /* XML_UNICODE */ #ifdef XML_LARGE_SIZE /* Use large integers for file/stream positions. */ -#if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400 +# if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400 typedef __int64 XML_Index; typedef unsigned __int64 XML_Size; -#else +# else typedef long long XML_Index; typedef unsigned long long XML_Size; -#endif +# endif #else typedef long XML_Index; typedef unsigned long XML_Size; diff --git a/Modules/expat/internal.h b/Modules/expat/internal.h index 3c5d6e913d6db3..e33fdcb0238d72 100644 --- a/Modules/expat/internal.h +++ b/Modules/expat/internal.h @@ -116,7 +116,7 @@ extern "C" { void -align_limit_to_full_utf8_characters(const char * from, const char ** fromLimRef); +_INTERNAL_trim_to_complete_utf8_characters(const char * from, const char ** fromLimRef); #ifdef __cplusplus diff --git a/Modules/expat/loadlibrary.c b/Modules/expat/loadlibrary.c index 452ae92db2673c..35fdf98bce6cea 100644 --- a/Modules/expat/loadlibrary.c +++ b/Modules/expat/loadlibrary.c @@ -84,7 +84,7 @@ HMODULE _Expat_LoadLibrary(LPCTSTR filename) /* Get a handle to kernel32 so we can access it's functions at runtime */ HMODULE hKernel32 = GetModuleHandle(TEXT("kernel32")); if(!hKernel32) - return NULL; + return NULL; /* LCOV_EXCL_LINE */ /* Attempt to find LoadLibraryEx() which is only available on Windows 2000 and above */ diff --git a/Modules/expat/xmlparse.c b/Modules/expat/xmlparse.c index 0df68830f05e3a..90a237f30eb8cd 100644 --- a/Modules/expat/xmlparse.c +++ b/Modules/expat/xmlparse.c @@ -1,4 +1,4 @@ -/* 8c6b2be7c6281da65ce05218fc15c339f02a811706340824ab596aa86e1fd51a (2.2.4+) +/* 4b74aa710b4ed5ce464b0ce544852cb47bf905c85a49c7bae2749f5885cb966d (2.2.5+) __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| @@ -470,7 +470,7 @@ setContext(XML_Parser parser, const XML_Char *context); static void FASTCALL normalizePublicId(XML_Char *s); static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms); -/* do not call if parentParser != NULL */ +/* do not call if m_parentParser != NULL */ static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms); static void dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms); @@ -542,7 +542,7 @@ parserInit(XML_Parser parser, const XML_Char *encodingName); : ((*((pool)->ptr)++ = c), 1)) struct XML_ParserStruct { - /* The first member must be userData so that the XML_GetUserData + /* The first member must be m_userData so that the XML_GetUserData macro works. */ void *m_userData; void *m_handlerArg; @@ -552,7 +552,7 @@ struct XML_ParserStruct { const char *m_bufferPtr; /* past last character to be parsed */ char *m_bufferEnd; - /* allocated end of buffer */ + /* allocated end of m_buffer */ const char *m_bufferLim; XML_Index m_parseEndByteIndex; const char *m_parseEndPtr; @@ -644,113 +644,10 @@ struct XML_ParserStruct { unsigned long m_hash_secret_salt; }; -#define MALLOC(s) (parser->m_mem.malloc_fcn((s))) -#define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s))) -#define FREE(p) (parser->m_mem.free_fcn((p))) - -#define userData (parser->m_userData) -#define handlerArg (parser->m_handlerArg) -#define startElementHandler (parser->m_startElementHandler) -#define endElementHandler (parser->m_endElementHandler) -#define characterDataHandler (parser->m_characterDataHandler) -#define processingInstructionHandler \ - (parser->m_processingInstructionHandler) -#define commentHandler (parser->m_commentHandler) -#define startCdataSectionHandler \ - (parser->m_startCdataSectionHandler) -#define endCdataSectionHandler (parser->m_endCdataSectionHandler) -#define defaultHandler (parser->m_defaultHandler) -#define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler) -#define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler) -#define unparsedEntityDeclHandler \ - (parser->m_unparsedEntityDeclHandler) -#define notationDeclHandler (parser->m_notationDeclHandler) -#define startNamespaceDeclHandler \ - (parser->m_startNamespaceDeclHandler) -#define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler) -#define notStandaloneHandler (parser->m_notStandaloneHandler) -#define externalEntityRefHandler \ - (parser->m_externalEntityRefHandler) -#define externalEntityRefHandlerArg \ - (parser->m_externalEntityRefHandlerArg) -#define internalEntityRefHandler \ - (parser->m_internalEntityRefHandler) -#define skippedEntityHandler (parser->m_skippedEntityHandler) -#define unknownEncodingHandler (parser->m_unknownEncodingHandler) -#define elementDeclHandler (parser->m_elementDeclHandler) -#define attlistDeclHandler (parser->m_attlistDeclHandler) -#define entityDeclHandler (parser->m_entityDeclHandler) -#define xmlDeclHandler (parser->m_xmlDeclHandler) -#define encoding (parser->m_encoding) -#define initEncoding (parser->m_initEncoding) -#define internalEncoding (parser->m_internalEncoding) -#define unknownEncodingMem (parser->m_unknownEncodingMem) -#define unknownEncodingData (parser->m_unknownEncodingData) -#define unknownEncodingHandlerData \ - (parser->m_unknownEncodingHandlerData) -#define unknownEncodingRelease (parser->m_unknownEncodingRelease) -#define protocolEncodingName (parser->m_protocolEncodingName) -#define ns (parser->m_ns) -#define ns_triplets (parser->m_ns_triplets) -#define prologState (parser->m_prologState) -#define processor (parser->m_processor) -#define errorCode (parser->m_errorCode) -#define eventPtr (parser->m_eventPtr) -#define eventEndPtr (parser->m_eventEndPtr) -#define positionPtr (parser->m_positionPtr) -#define position (parser->m_position) -#define openInternalEntities (parser->m_openInternalEntities) -#define freeInternalEntities (parser->m_freeInternalEntities) -#define defaultExpandInternalEntities \ - (parser->m_defaultExpandInternalEntities) -#define tagLevel (parser->m_tagLevel) -#define buffer (parser->m_buffer) -#define bufferPtr (parser->m_bufferPtr) -#define bufferEnd (parser->m_bufferEnd) -#define parseEndByteIndex (parser->m_parseEndByteIndex) -#define parseEndPtr (parser->m_parseEndPtr) -#define bufferLim (parser->m_bufferLim) -#define dataBuf (parser->m_dataBuf) -#define dataBufEnd (parser->m_dataBufEnd) -#define _dtd (parser->m_dtd) -#define curBase (parser->m_curBase) -#define declEntity (parser->m_declEntity) -#define doctypeName (parser->m_doctypeName) -#define doctypeSysid (parser->m_doctypeSysid) -#define doctypePubid (parser->m_doctypePubid) -#define declAttributeType (parser->m_declAttributeType) -#define declNotationName (parser->m_declNotationName) -#define declNotationPublicId (parser->m_declNotationPublicId) -#define declElementType (parser->m_declElementType) -#define declAttributeId (parser->m_declAttributeId) -#define declAttributeIsCdata (parser->m_declAttributeIsCdata) -#define declAttributeIsId (parser->m_declAttributeIsId) -#define freeTagList (parser->m_freeTagList) -#define freeBindingList (parser->m_freeBindingList) -#define inheritedBindings (parser->m_inheritedBindings) -#define tagStack (parser->m_tagStack) -#define atts (parser->m_atts) -#define attsSize (parser->m_attsSize) -#define nSpecifiedAtts (parser->m_nSpecifiedAtts) -#define idAttIndex (parser->m_idAttIndex) -#define nsAtts (parser->m_nsAtts) -#define nsAttsVersion (parser->m_nsAttsVersion) -#define nsAttsPower (parser->m_nsAttsPower) -#define attInfo (parser->m_attInfo) -#define tempPool (parser->m_tempPool) -#define temp2Pool (parser->m_temp2Pool) -#define groupConnector (parser->m_groupConnector) -#define groupSize (parser->m_groupSize) -#define namespaceSeparator (parser->m_namespaceSeparator) -#define parentParser (parser->m_parentParser) -#define ps_parsing (parser->m_parsingStatus.parsing) -#define ps_finalBuffer (parser->m_parsingStatus.finalBuffer) -#ifdef XML_DTD -#define isParamEntity (parser->m_isParamEntity) -#define useForeignDTD (parser->m_useForeignDTD) -#define paramEntityParsing (parser->m_paramEntityParsing) -#endif /* XML_DTD */ -#define hash_secret_salt (parser->m_hash_secret_salt) +#define MALLOC(parser, s) (parser->m_mem.malloc_fcn((s))) +#define REALLOC(parser, p, s) (parser->m_mem.realloc_fcn((p),(s))) +#define FREE(parser, p) (parser->m_mem.free_fcn((p))) + XML_Parser XMLCALL XML_ParserCreate(const XML_Char *encodingName) @@ -776,6 +673,9 @@ static const XML_Char implicitContext[] = { }; +/* To avoid warnings about unused functions: */ +#if ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) + #if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) /* Obtain entropy on Linux 3.17+ */ @@ -841,6 +741,8 @@ writeRandomBytes_dev_urandom(void * target, size_t count) { #endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */ +#endif /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */ + #if defined(HAVE_ARC4RANDOM) @@ -942,6 +844,8 @@ generate_hash_secret_salt(XML_Parser parser) { unsigned long entropy; (void)parser; + + /* "Failproof" high quality providers: */ #if defined(HAVE_ARC4RANDOM_BUF) arc4random_buf(&entropy, sizeof(entropy)); return ENTROPY_DEBUG("arc4random_buf", entropy); @@ -990,9 +894,9 @@ static XML_Bool /* only valid for root parser */ startParsing(XML_Parser parser) { /* hash functions must be initialized before setContext() is called */ - if (hash_secret_salt == 0) - hash_secret_salt = generate_hash_secret_salt(parser); - if (ns) { + if (parser->m_hash_secret_salt == 0) + parser->m_hash_secret_salt = generate_hash_secret_salt(parser); + if (parser->m_ns) { /* implicit context only set for root parser, since child parsers (i.e. external entity parsers) will inherit it */ @@ -1042,85 +946,85 @@ parserCreate(const XML_Char *encodingName, if (!parser) return parser; - buffer = NULL; - bufferLim = NULL; + parser->m_buffer = NULL; + parser->m_bufferLim = NULL; - attsSize = INIT_ATTS_SIZE; - atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE)); - if (atts == NULL) { - FREE(parser); + parser->m_attsSize = INIT_ATTS_SIZE; + parser->m_atts = (ATTRIBUTE *)MALLOC(parser, parser->m_attsSize * sizeof(ATTRIBUTE)); + if (parser->m_atts == NULL) { + FREE(parser, parser); return NULL; } #ifdef XML_ATTR_INFO - attInfo = (XML_AttrInfo*)MALLOC(attsSize * sizeof(XML_AttrInfo)); - if (attInfo == NULL) { - FREE(atts); - FREE(parser); + parser->m_attInfo = (XML_AttrInfo*)MALLOC(parser, parser->m_attsSize * sizeof(XML_AttrInfo)); + if (parser->m_attInfo == NULL) { + FREE(parser, parser->m_atts); + FREE(parser, parser); return NULL; } #endif - dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char)); - if (dataBuf == NULL) { - FREE(atts); + parser->m_dataBuf = (XML_Char *)MALLOC(parser, INIT_DATA_BUF_SIZE * sizeof(XML_Char)); + if (parser->m_dataBuf == NULL) { + FREE(parser, parser->m_atts); #ifdef XML_ATTR_INFO - FREE(attInfo); + FREE(parser, parser->m_attInfo); #endif - FREE(parser); + FREE(parser, parser); return NULL; } - dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE; + parser->m_dataBufEnd = parser->m_dataBuf + INIT_DATA_BUF_SIZE; if (dtd) - _dtd = dtd; + parser->m_dtd = dtd; else { - _dtd = dtdCreate(&parser->m_mem); - if (_dtd == NULL) { - FREE(dataBuf); - FREE(atts); + parser->m_dtd = dtdCreate(&parser->m_mem); + if (parser->m_dtd == NULL) { + FREE(parser, parser->m_dataBuf); + FREE(parser, parser->m_atts); #ifdef XML_ATTR_INFO - FREE(attInfo); + FREE(parser, parser->m_attInfo); #endif - FREE(parser); + FREE(parser, parser); return NULL; } } - freeBindingList = NULL; - freeTagList = NULL; - freeInternalEntities = NULL; + parser->m_freeBindingList = NULL; + parser->m_freeTagList = NULL; + parser->m_freeInternalEntities = NULL; - groupSize = 0; - groupConnector = NULL; + parser->m_groupSize = 0; + parser->m_groupConnector = NULL; - unknownEncodingHandler = NULL; - unknownEncodingHandlerData = NULL; + parser->m_unknownEncodingHandler = NULL; + parser->m_unknownEncodingHandlerData = NULL; - namespaceSeparator = ASCII_EXCL; - ns = XML_FALSE; - ns_triplets = XML_FALSE; + parser->m_namespaceSeparator = ASCII_EXCL; + parser->m_ns = XML_FALSE; + parser->m_ns_triplets = XML_FALSE; - nsAtts = NULL; - nsAttsVersion = 0; - nsAttsPower = 0; + parser->m_nsAtts = NULL; + parser->m_nsAttsVersion = 0; + parser->m_nsAttsPower = 0; - protocolEncodingName = NULL; + parser->m_protocolEncodingName = NULL; - poolInit(&tempPool, &(parser->m_mem)); - poolInit(&temp2Pool, &(parser->m_mem)); + poolInit(&parser->m_tempPool, &(parser->m_mem)); + poolInit(&parser->m_temp2Pool, &(parser->m_mem)); parserInit(parser, encodingName); - if (encodingName && !protocolEncodingName) { + if (encodingName && !parser->m_protocolEncodingName) { XML_ParserFree(parser); return NULL; } if (nameSep) { - ns = XML_TRUE; - internalEncoding = XmlGetInternalEncodingNS(); - namespaceSeparator = *nameSep; + parser->m_ns = XML_TRUE; + parser->m_internalEncoding = XmlGetInternalEncodingNS(); + parser->m_namespaceSeparator = *nameSep; } else { - internalEncoding = XmlGetInternalEncoding(); + parser->m_internalEncoding = XmlGetInternalEncoding(); } return parser; @@ -1129,85 +1033,85 @@ parserCreate(const XML_Char *encodingName, static void parserInit(XML_Parser parser, const XML_Char *encodingName) { - processor = prologInitProcessor; - XmlPrologStateInit(&prologState); + parser->m_processor = prologInitProcessor; + XmlPrologStateInit(&parser->m_prologState); if (encodingName != NULL) { - protocolEncodingName = copyString(encodingName, &(parser->m_mem)); - } - curBase = NULL; - XmlInitEncoding(&initEncoding, &encoding, 0); - userData = NULL; - handlerArg = NULL; - startElementHandler = NULL; - endElementHandler = NULL; - characterDataHandler = NULL; - processingInstructionHandler = NULL; - commentHandler = NULL; - startCdataSectionHandler = NULL; - endCdataSectionHandler = NULL; - defaultHandler = NULL; - startDoctypeDeclHandler = NULL; - endDoctypeDeclHandler = NULL; - unparsedEntityDeclHandler = NULL; - notationDeclHandler = NULL; - startNamespaceDeclHandler = NULL; - endNamespaceDeclHandler = NULL; - notStandaloneHandler = NULL; - externalEntityRefHandler = NULL; - externalEntityRefHandlerArg = parser; - skippedEntityHandler = NULL; - elementDeclHandler = NULL; - attlistDeclHandler = NULL; - entityDeclHandler = NULL; - xmlDeclHandler = NULL; - bufferPtr = buffer; - bufferEnd = buffer; - parseEndByteIndex = 0; - parseEndPtr = NULL; - declElementType = NULL; - declAttributeId = NULL; - declEntity = NULL; - doctypeName = NULL; - doctypeSysid = NULL; - doctypePubid = NULL; - declAttributeType = NULL; - declNotationName = NULL; - declNotationPublicId = NULL; - declAttributeIsCdata = XML_FALSE; - declAttributeIsId = XML_FALSE; - memset(&position, 0, sizeof(POSITION)); - errorCode = XML_ERROR_NONE; - eventPtr = NULL; - eventEndPtr = NULL; - positionPtr = NULL; - openInternalEntities = NULL; - defaultExpandInternalEntities = XML_TRUE; - tagLevel = 0; - tagStack = NULL; - inheritedBindings = NULL; - nSpecifiedAtts = 0; - unknownEncodingMem = NULL; - unknownEncodingRelease = NULL; - unknownEncodingData = NULL; - parentParser = NULL; - ps_parsing = XML_INITIALIZED; + parser->m_protocolEncodingName = copyString(encodingName, &(parser->m_mem)); + } + parser->m_curBase = NULL; + XmlInitEncoding(&parser->m_initEncoding, &parser->m_encoding, 0); + parser->m_userData = NULL; + parser->m_handlerArg = NULL; + parser->m_startElementHandler = NULL; + parser->m_endElementHandler = NULL; + parser->m_characterDataHandler = NULL; + parser->m_processingInstructionHandler = NULL; + parser->m_commentHandler = NULL; + parser->m_startCdataSectionHandler = NULL; + parser->m_endCdataSectionHandler = NULL; + parser->m_defaultHandler = NULL; + parser->m_startDoctypeDeclHandler = NULL; + parser->m_endDoctypeDeclHandler = NULL; + parser->m_unparsedEntityDeclHandler = NULL; + parser->m_notationDeclHandler = NULL; + parser->m_startNamespaceDeclHandler = NULL; + parser->m_endNamespaceDeclHandler = NULL; + parser->m_notStandaloneHandler = NULL; + parser->m_externalEntityRefHandler = NULL; + parser->m_externalEntityRefHandlerArg = parser; + parser->m_skippedEntityHandler = NULL; + parser->m_elementDeclHandler = NULL; + parser->m_attlistDeclHandler = NULL; + parser->m_entityDeclHandler = NULL; + parser->m_xmlDeclHandler = NULL; + parser->m_bufferPtr = parser->m_buffer; + parser->m_bufferEnd = parser->m_buffer; + parser->m_parseEndByteIndex = 0; + parser->m_parseEndPtr = NULL; + parser->m_declElementType = NULL; + parser->m_declAttributeId = NULL; + parser->m_declEntity = NULL; + parser->m_doctypeName = NULL; + parser->m_doctypeSysid = NULL; + parser->m_doctypePubid = NULL; + parser->m_declAttributeType = NULL; + parser->m_declNotationName = NULL; + parser->m_declNotationPublicId = NULL; + parser->m_declAttributeIsCdata = XML_FALSE; + parser->m_declAttributeIsId = XML_FALSE; + memset(&parser->m_position, 0, sizeof(POSITION)); + parser->m_errorCode = XML_ERROR_NONE; + parser->m_eventPtr = NULL; + parser->m_eventEndPtr = NULL; + parser->m_positionPtr = NULL; + parser->m_openInternalEntities = NULL; + parser->m_defaultExpandInternalEntities = XML_TRUE; + parser->m_tagLevel = 0; + parser->m_tagStack = NULL; + parser->m_inheritedBindings = NULL; + parser->m_nSpecifiedAtts = 0; + parser->m_unknownEncodingMem = NULL; + parser->m_unknownEncodingRelease = NULL; + parser->m_unknownEncodingData = NULL; + parser->m_parentParser = NULL; + parser->m_parsingStatus.parsing = XML_INITIALIZED; #ifdef XML_DTD - isParamEntity = XML_FALSE; - useForeignDTD = XML_FALSE; - paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; + parser->m_isParamEntity = XML_FALSE; + parser->m_useForeignDTD = XML_FALSE; + parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; #endif - hash_secret_salt = 0; + parser->m_hash_secret_salt = 0; } -/* moves list of bindings to freeBindingList */ +/* moves list of bindings to m_freeBindingList */ static void FASTCALL moveToFreeBindingList(XML_Parser parser, BINDING *bindings) { while (bindings) { BINDING *b = bindings; bindings = bindings->nextTagBinding; - b->nextTagBinding = freeBindingList; - freeBindingList = b; + b->nextTagBinding = parser->m_freeBindingList; + parser->m_freeBindingList = b; } } @@ -1220,36 +1124,36 @@ XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) if (parser == NULL) return XML_FALSE; - if (parentParser) + if (parser->m_parentParser) return XML_FALSE; - /* move tagStack to freeTagList */ - tStk = tagStack; + /* move m_tagStack to m_freeTagList */ + tStk = parser->m_tagStack; while (tStk) { TAG *tag = tStk; tStk = tStk->parent; - tag->parent = freeTagList; + tag->parent = parser->m_freeTagList; moveToFreeBindingList(parser, tag->bindings); tag->bindings = NULL; - freeTagList = tag; + parser->m_freeTagList = tag; } - /* move openInternalEntities to freeInternalEntities */ - openEntityList = openInternalEntities; + /* move m_openInternalEntities to m_freeInternalEntities */ + openEntityList = parser->m_openInternalEntities; while (openEntityList) { OPEN_INTERNAL_ENTITY *openEntity = openEntityList; openEntityList = openEntity->next; - openEntity->next = freeInternalEntities; - freeInternalEntities = openEntity; - } - moveToFreeBindingList(parser, inheritedBindings); - FREE(unknownEncodingMem); - if (unknownEncodingRelease) - unknownEncodingRelease(unknownEncodingData); - poolClear(&tempPool); - poolClear(&temp2Pool); - FREE((void *)protocolEncodingName); - protocolEncodingName = NULL; + openEntity->next = parser->m_freeInternalEntities; + parser->m_freeInternalEntities = openEntity; + } + moveToFreeBindingList(parser, parser->m_inheritedBindings); + FREE(parser, parser->m_unknownEncodingMem); + if (parser->m_unknownEncodingRelease) + parser->m_unknownEncodingRelease(parser->m_unknownEncodingData); + poolClear(&parser->m_tempPool); + poolClear(&parser->m_temp2Pool); + FREE(parser, (void *)parser->m_protocolEncodingName); + parser->m_protocolEncodingName = NULL; parserInit(parser, encodingName); - dtdReset(_dtd, &parser->m_mem); + dtdReset(parser->m_dtd, &parser->m_mem); return XML_TRUE; } @@ -1262,19 +1166,19 @@ XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName) XXX There's no way for the caller to determine which of the XXX possible error cases caused the XML_STATUS_ERROR return. */ - if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED) + if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED) return XML_STATUS_ERROR; /* Get rid of any previous encoding name */ - FREE((void *)protocolEncodingName); + FREE(parser, (void *)parser->m_protocolEncodingName); if (encodingName == NULL) /* No new encoding name */ - protocolEncodingName = NULL; + parser->m_protocolEncodingName = NULL; else { /* Copy the new encoding name into allocated memory */ - protocolEncodingName = copyString(encodingName, &(parser->m_mem)); - if (!protocolEncodingName) + parser->m_protocolEncodingName = copyString(encodingName, &(parser->m_mem)); + if (!parser->m_protocolEncodingName) return XML_STATUS_ERROR; } return XML_STATUS_OK; @@ -1331,44 +1235,44 @@ XML_ExternalEntityParserCreate(XML_Parser oldParser, return NULL; /* Stash the original parser contents on the stack */ - oldDtd = _dtd; - oldStartElementHandler = startElementHandler; - oldEndElementHandler = endElementHandler; - oldCharacterDataHandler = characterDataHandler; - oldProcessingInstructionHandler = processingInstructionHandler; - oldCommentHandler = commentHandler; - oldStartCdataSectionHandler = startCdataSectionHandler; - oldEndCdataSectionHandler = endCdataSectionHandler; - oldDefaultHandler = defaultHandler; - oldUnparsedEntityDeclHandler = unparsedEntityDeclHandler; - oldNotationDeclHandler = notationDeclHandler; - oldStartNamespaceDeclHandler = startNamespaceDeclHandler; - oldEndNamespaceDeclHandler = endNamespaceDeclHandler; - oldNotStandaloneHandler = notStandaloneHandler; - oldExternalEntityRefHandler = externalEntityRefHandler; - oldSkippedEntityHandler = skippedEntityHandler; - oldUnknownEncodingHandler = unknownEncodingHandler; - oldElementDeclHandler = elementDeclHandler; - oldAttlistDeclHandler = attlistDeclHandler; - oldEntityDeclHandler = entityDeclHandler; - oldXmlDeclHandler = xmlDeclHandler; - oldDeclElementType = declElementType; - - oldUserData = userData; - oldHandlerArg = handlerArg; - oldDefaultExpandInternalEntities = defaultExpandInternalEntities; - oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg; + oldDtd = parser->m_dtd; + oldStartElementHandler = parser->m_startElementHandler; + oldEndElementHandler = parser->m_endElementHandler; + oldCharacterDataHandler = parser->m_characterDataHandler; + oldProcessingInstructionHandler = parser->m_processingInstructionHandler; + oldCommentHandler = parser->m_commentHandler; + oldStartCdataSectionHandler = parser->m_startCdataSectionHandler; + oldEndCdataSectionHandler = parser->m_endCdataSectionHandler; + oldDefaultHandler = parser->m_defaultHandler; + oldUnparsedEntityDeclHandler = parser->m_unparsedEntityDeclHandler; + oldNotationDeclHandler = parser->m_notationDeclHandler; + oldStartNamespaceDeclHandler = parser->m_startNamespaceDeclHandler; + oldEndNamespaceDeclHandler = parser->m_endNamespaceDeclHandler; + oldNotStandaloneHandler = parser->m_notStandaloneHandler; + oldExternalEntityRefHandler = parser->m_externalEntityRefHandler; + oldSkippedEntityHandler = parser->m_skippedEntityHandler; + oldUnknownEncodingHandler = parser->m_unknownEncodingHandler; + oldElementDeclHandler = parser->m_elementDeclHandler; + oldAttlistDeclHandler = parser->m_attlistDeclHandler; + oldEntityDeclHandler = parser->m_entityDeclHandler; + oldXmlDeclHandler = parser->m_xmlDeclHandler; + oldDeclElementType = parser->m_declElementType; + + oldUserData = parser->m_userData; + oldHandlerArg = parser->m_handlerArg; + oldDefaultExpandInternalEntities = parser->m_defaultExpandInternalEntities; + oldExternalEntityRefHandlerArg = parser->m_externalEntityRefHandlerArg; #ifdef XML_DTD - oldParamEntityParsing = paramEntityParsing; - oldInEntityValue = prologState.inEntityValue; + oldParamEntityParsing = parser->m_paramEntityParsing; + oldInEntityValue = parser->m_prologState.inEntityValue; #endif - oldns_triplets = ns_triplets; + oldns_triplets = parser->m_ns_triplets; /* Note that the new parser shares the same hash secret as the old parser, so that dtdCopy and copyEntityTable can lookup values from hash tables associated with either parser without us having to worry which hash secrets each table has. */ - oldhash_secret_salt = hash_secret_salt; + oldhash_secret_salt = parser->m_hash_secret_salt; #ifdef XML_DTD if (!context) @@ -1380,9 +1284,9 @@ XML_ExternalEntityParserCreate(XML_Parser oldParser, here. This makes this function more painful to follow than it would be otherwise. */ - if (ns) { + if (parser->m_ns) { XML_Char tmp[2]; - *tmp = namespaceSeparator; + *tmp = parser->m_namespaceSeparator; parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd); } else { @@ -1392,62 +1296,62 @@ XML_ExternalEntityParserCreate(XML_Parser oldParser, if (!parser) return NULL; - startElementHandler = oldStartElementHandler; - endElementHandler = oldEndElementHandler; - characterDataHandler = oldCharacterDataHandler; - processingInstructionHandler = oldProcessingInstructionHandler; - commentHandler = oldCommentHandler; - startCdataSectionHandler = oldStartCdataSectionHandler; - endCdataSectionHandler = oldEndCdataSectionHandler; - defaultHandler = oldDefaultHandler; - unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler; - notationDeclHandler = oldNotationDeclHandler; - startNamespaceDeclHandler = oldStartNamespaceDeclHandler; - endNamespaceDeclHandler = oldEndNamespaceDeclHandler; - notStandaloneHandler = oldNotStandaloneHandler; - externalEntityRefHandler = oldExternalEntityRefHandler; - skippedEntityHandler = oldSkippedEntityHandler; - unknownEncodingHandler = oldUnknownEncodingHandler; - elementDeclHandler = oldElementDeclHandler; - attlistDeclHandler = oldAttlistDeclHandler; - entityDeclHandler = oldEntityDeclHandler; - xmlDeclHandler = oldXmlDeclHandler; - declElementType = oldDeclElementType; - userData = oldUserData; + parser->m_startElementHandler = oldStartElementHandler; + parser->m_endElementHandler = oldEndElementHandler; + parser->m_characterDataHandler = oldCharacterDataHandler; + parser->m_processingInstructionHandler = oldProcessingInstructionHandler; + parser->m_commentHandler = oldCommentHandler; + parser->m_startCdataSectionHandler = oldStartCdataSectionHandler; + parser->m_endCdataSectionHandler = oldEndCdataSectionHandler; + parser->m_defaultHandler = oldDefaultHandler; + parser->m_unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler; + parser->m_notationDeclHandler = oldNotationDeclHandler; + parser->m_startNamespaceDeclHandler = oldStartNamespaceDeclHandler; + parser->m_endNamespaceDeclHandler = oldEndNamespaceDeclHandler; + parser->m_notStandaloneHandler = oldNotStandaloneHandler; + parser->m_externalEntityRefHandler = oldExternalEntityRefHandler; + parser->m_skippedEntityHandler = oldSkippedEntityHandler; + parser->m_unknownEncodingHandler = oldUnknownEncodingHandler; + parser->m_elementDeclHandler = oldElementDeclHandler; + parser->m_attlistDeclHandler = oldAttlistDeclHandler; + parser->m_entityDeclHandler = oldEntityDeclHandler; + parser->m_xmlDeclHandler = oldXmlDeclHandler; + parser->m_declElementType = oldDeclElementType; + parser->m_userData = oldUserData; if (oldUserData == oldHandlerArg) - handlerArg = userData; + parser->m_handlerArg = parser->m_userData; else - handlerArg = parser; + parser->m_handlerArg = parser; if (oldExternalEntityRefHandlerArg != oldParser) - externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg; - defaultExpandInternalEntities = oldDefaultExpandInternalEntities; - ns_triplets = oldns_triplets; - hash_secret_salt = oldhash_secret_salt; - parentParser = oldParser; + parser->m_externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg; + parser->m_defaultExpandInternalEntities = oldDefaultExpandInternalEntities; + parser->m_ns_triplets = oldns_triplets; + parser->m_hash_secret_salt = oldhash_secret_salt; + parser->m_parentParser = oldParser; #ifdef XML_DTD - paramEntityParsing = oldParamEntityParsing; - prologState.inEntityValue = oldInEntityValue; + parser->m_paramEntityParsing = oldParamEntityParsing; + parser->m_prologState.inEntityValue = oldInEntityValue; if (context) { #endif /* XML_DTD */ - if (!dtdCopy(oldParser, _dtd, oldDtd, &parser->m_mem) + if (!dtdCopy(oldParser, parser->m_dtd, oldDtd, &parser->m_mem) || !setContext(parser, context)) { XML_ParserFree(parser); return NULL; } - processor = externalEntityInitProcessor; + parser->m_processor = externalEntityInitProcessor; #ifdef XML_DTD } else { - /* The DTD instance referenced by _dtd is shared between the document's + /* The DTD instance referenced by parser->m_dtd is shared between the document's root parser and external PE parsers, therefore one does not need to call setContext. In addition, one also *must* not call setContext, because this would overwrite existing prefix->binding pointers in - _dtd with ones that get destroyed with the external PE parser. + parser->m_dtd with ones that get destroyed with the external PE parser. This would leave those prefixes with dangling pointers. */ - isParamEntity = XML_TRUE; - XmlPrologStateInitExternalEntity(&prologState); - processor = externalParEntInitProcessor; + parser->m_isParamEntity = XML_TRUE; + XmlPrologStateInitExternalEntity(&parser->m_prologState); + parser->m_processor = externalParEntInitProcessor; } #endif /* XML_DTD */ return parser; @@ -1461,8 +1365,8 @@ destroyBindings(BINDING *bindings, XML_Parser parser) if (!b) break; bindings = b->nextTagBinding; - FREE(b->uri); - FREE(b); + FREE(parser, b->uri); + FREE(parser, b); } } @@ -1473,70 +1377,70 @@ XML_ParserFree(XML_Parser parser) OPEN_INTERNAL_ENTITY *entityList; if (parser == NULL) return; - /* free tagStack and freeTagList */ - tagList = tagStack; + /* free m_tagStack and m_freeTagList */ + tagList = parser->m_tagStack; for (;;) { TAG *p; if (tagList == NULL) { - if (freeTagList == NULL) + if (parser->m_freeTagList == NULL) break; - tagList = freeTagList; - freeTagList = NULL; + tagList = parser->m_freeTagList; + parser->m_freeTagList = NULL; } p = tagList; tagList = tagList->parent; - FREE(p->buf); + FREE(parser, p->buf); destroyBindings(p->bindings, parser); - FREE(p); + FREE(parser, p); } - /* free openInternalEntities and freeInternalEntities */ - entityList = openInternalEntities; + /* free m_openInternalEntities and m_freeInternalEntities */ + entityList = parser->m_openInternalEntities; for (;;) { OPEN_INTERNAL_ENTITY *openEntity; if (entityList == NULL) { - if (freeInternalEntities == NULL) + if (parser->m_freeInternalEntities == NULL) break; - entityList = freeInternalEntities; - freeInternalEntities = NULL; + entityList = parser->m_freeInternalEntities; + parser->m_freeInternalEntities = NULL; } openEntity = entityList; entityList = entityList->next; - FREE(openEntity); + FREE(parser, openEntity); } - destroyBindings(freeBindingList, parser); - destroyBindings(inheritedBindings, parser); - poolDestroy(&tempPool); - poolDestroy(&temp2Pool); - FREE((void *)protocolEncodingName); + destroyBindings(parser->m_freeBindingList, parser); + destroyBindings(parser->m_inheritedBindings, parser); + poolDestroy(&parser->m_tempPool); + poolDestroy(&parser->m_temp2Pool); + FREE(parser, (void *)parser->m_protocolEncodingName); #ifdef XML_DTD /* external parameter entity parsers share the DTD structure parser->m_dtd with the root parser, so we must not destroy it */ - if (!isParamEntity && _dtd) + if (!parser->m_isParamEntity && parser->m_dtd) #else - if (_dtd) + if (parser->m_dtd) #endif /* XML_DTD */ - dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem); - FREE((void *)atts); + dtdDestroy(parser->m_dtd, (XML_Bool)!parser->m_parentParser, &parser->m_mem); + FREE(parser, (void *)parser->m_atts); #ifdef XML_ATTR_INFO - FREE((void *)attInfo); + FREE(parser, (void *)parser->m_attInfo); #endif - FREE(groupConnector); - FREE(buffer); - FREE(dataBuf); - FREE(nsAtts); - FREE(unknownEncodingMem); - if (unknownEncodingRelease) - unknownEncodingRelease(unknownEncodingData); - FREE(parser); + FREE(parser, parser->m_groupConnector); + FREE(parser, parser->m_buffer); + FREE(parser, parser->m_dataBuf); + FREE(parser, parser->m_nsAtts); + FREE(parser, parser->m_unknownEncodingMem); + if (parser->m_unknownEncodingRelease) + parser->m_unknownEncodingRelease(parser->m_unknownEncodingData); + FREE(parser, parser); } void XMLCALL XML_UseParserAsHandlerArg(XML_Parser parser) { if (parser != NULL) - handlerArg = parser; + parser->m_handlerArg = parser; } enum XML_Error XMLCALL @@ -1546,9 +1450,9 @@ XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD) return XML_ERROR_INVALID_ARGUMENT; #ifdef XML_DTD /* block after XML_Parse()/XML_ParseBuffer() has been called */ - if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED) + if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED) return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING; - useForeignDTD = useDTD; + parser->m_useForeignDTD = useDTD; return XML_ERROR_NONE; #else return XML_ERROR_FEATURE_REQUIRES_XML_DTD; @@ -1561,9 +1465,9 @@ XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) if (parser == NULL) return; /* block after XML_Parse()/XML_ParseBuffer() has been called */ - if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED) + if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED) return; - ns_triplets = do_nst ? XML_TRUE : XML_FALSE; + parser->m_ns_triplets = do_nst ? XML_TRUE : XML_FALSE; } void XMLCALL @@ -1571,10 +1475,10 @@ XML_SetUserData(XML_Parser parser, void *p) { if (parser == NULL) return; - if (handlerArg == userData) - handlerArg = userData = p; + if (parser->m_handlerArg == parser->m_userData) + parser->m_handlerArg = parser->m_userData = p; else - userData = p; + parser->m_userData = p; } enum XML_Status XMLCALL @@ -1583,13 +1487,13 @@ XML_SetBase(XML_Parser parser, const XML_Char *p) if (parser == NULL) return XML_STATUS_ERROR; if (p) { - p = poolCopyString(&_dtd->pool, p); + p = poolCopyString(&parser->m_dtd->pool, p); if (!p) return XML_STATUS_ERROR; - curBase = p; + parser->m_curBase = p; } else - curBase = NULL; + parser->m_curBase = NULL; return XML_STATUS_OK; } @@ -1598,7 +1502,7 @@ XML_GetBase(XML_Parser parser) { if (parser == NULL) return NULL; - return curBase; + return parser->m_curBase; } int XMLCALL @@ -1606,7 +1510,7 @@ XML_GetSpecifiedAttributeCount(XML_Parser parser) { if (parser == NULL) return -1; - return nSpecifiedAtts; + return parser->m_nSpecifiedAtts; } int XMLCALL @@ -1614,7 +1518,7 @@ XML_GetIdAttributeIndex(XML_Parser parser) { if (parser == NULL) return -1; - return idAttIndex; + return parser->m_idAttIndex; } #ifdef XML_ATTR_INFO @@ -1623,7 +1527,7 @@ XML_GetAttributeInfo(XML_Parser parser) { if (parser == NULL) return NULL; - return attInfo; + return parser->m_attInfo; } #endif @@ -1634,22 +1538,22 @@ XML_SetElementHandler(XML_Parser parser, { if (parser == NULL) return; - startElementHandler = start; - endElementHandler = end; + parser->m_startElementHandler = start; + parser->m_endElementHandler = end; } void XMLCALL XML_SetStartElementHandler(XML_Parser parser, XML_StartElementHandler start) { if (parser != NULL) - startElementHandler = start; + parser->m_startElementHandler = start; } void XMLCALL XML_SetEndElementHandler(XML_Parser parser, XML_EndElementHandler end) { if (parser != NULL) - endElementHandler = end; + parser->m_endElementHandler = end; } void XMLCALL @@ -1657,7 +1561,7 @@ XML_SetCharacterDataHandler(XML_Parser parser, XML_CharacterDataHandler handler) { if (parser != NULL) - characterDataHandler = handler; + parser->m_characterDataHandler = handler; } void XMLCALL @@ -1665,7 +1569,7 @@ XML_SetProcessingInstructionHandler(XML_Parser parser, XML_ProcessingInstructionHandler handler) { if (parser != NULL) - processingInstructionHandler = handler; + parser->m_processingInstructionHandler = handler; } void XMLCALL @@ -1673,7 +1577,7 @@ XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler handler) { if (parser != NULL) - commentHandler = handler; + parser->m_commentHandler = handler; } void XMLCALL @@ -1683,22 +1587,22 @@ XML_SetCdataSectionHandler(XML_Parser parser, { if (parser == NULL) return; - startCdataSectionHandler = start; - endCdataSectionHandler = end; + parser->m_startCdataSectionHandler = start; + parser->m_endCdataSectionHandler = end; } void XMLCALL XML_SetStartCdataSectionHandler(XML_Parser parser, XML_StartCdataSectionHandler start) { if (parser != NULL) - startCdataSectionHandler = start; + parser->m_startCdataSectionHandler = start; } void XMLCALL XML_SetEndCdataSectionHandler(XML_Parser parser, XML_EndCdataSectionHandler end) { if (parser != NULL) - endCdataSectionHandler = end; + parser->m_endCdataSectionHandler = end; } void XMLCALL @@ -1707,8 +1611,8 @@ XML_SetDefaultHandler(XML_Parser parser, { if (parser == NULL) return; - defaultHandler = handler; - defaultExpandInternalEntities = XML_FALSE; + parser->m_defaultHandler = handler; + parser->m_defaultExpandInternalEntities = XML_FALSE; } void XMLCALL @@ -1717,8 +1621,8 @@ XML_SetDefaultHandlerExpand(XML_Parser parser, { if (parser == NULL) return; - defaultHandler = handler; - defaultExpandInternalEntities = XML_TRUE; + parser->m_defaultHandler = handler; + parser->m_defaultExpandInternalEntities = XML_TRUE; } void XMLCALL @@ -1728,22 +1632,22 @@ XML_SetDoctypeDeclHandler(XML_Parser parser, { if (parser == NULL) return; - startDoctypeDeclHandler = start; - endDoctypeDeclHandler = end; + parser->m_startDoctypeDeclHandler = start; + parser->m_endDoctypeDeclHandler = end; } void XMLCALL XML_SetStartDoctypeDeclHandler(XML_Parser parser, XML_StartDoctypeDeclHandler start) { if (parser != NULL) - startDoctypeDeclHandler = start; + parser->m_startDoctypeDeclHandler = start; } void XMLCALL XML_SetEndDoctypeDeclHandler(XML_Parser parser, XML_EndDoctypeDeclHandler end) { if (parser != NULL) - endDoctypeDeclHandler = end; + parser->m_endDoctypeDeclHandler = end; } void XMLCALL @@ -1751,7 +1655,7 @@ XML_SetUnparsedEntityDeclHandler(XML_Parser parser, XML_UnparsedEntityDeclHandler handler) { if (parser != NULL) - unparsedEntityDeclHandler = handler; + parser->m_unparsedEntityDeclHandler = handler; } void XMLCALL @@ -1759,7 +1663,7 @@ XML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler handler) { if (parser != NULL) - notationDeclHandler = handler; + parser->m_notationDeclHandler = handler; } void XMLCALL @@ -1769,22 +1673,22 @@ XML_SetNamespaceDeclHandler(XML_Parser parser, { if (parser == NULL) return; - startNamespaceDeclHandler = start; - endNamespaceDeclHandler = end; + parser->m_startNamespaceDeclHandler = start; + parser->m_endNamespaceDeclHandler = end; } void XMLCALL XML_SetStartNamespaceDeclHandler(XML_Parser parser, XML_StartNamespaceDeclHandler start) { if (parser != NULL) - startNamespaceDeclHandler = start; + parser->m_startNamespaceDeclHandler = start; } void XMLCALL XML_SetEndNamespaceDeclHandler(XML_Parser parser, XML_EndNamespaceDeclHandler end) { if (parser != NULL) - endNamespaceDeclHandler = end; + parser->m_endNamespaceDeclHandler = end; } void XMLCALL @@ -1792,7 +1696,7 @@ XML_SetNotStandaloneHandler(XML_Parser parser, XML_NotStandaloneHandler handler) { if (parser != NULL) - notStandaloneHandler = handler; + parser->m_notStandaloneHandler = handler; } void XMLCALL @@ -1800,7 +1704,7 @@ XML_SetExternalEntityRefHandler(XML_Parser parser, XML_ExternalEntityRefHandler handler) { if (parser != NULL) - externalEntityRefHandler = handler; + parser->m_externalEntityRefHandler = handler; } void XMLCALL @@ -1809,9 +1713,9 @@ XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg) if (parser == NULL) return; if (arg) - externalEntityRefHandlerArg = (XML_Parser)arg; + parser->m_externalEntityRefHandlerArg = (XML_Parser)arg; else - externalEntityRefHandlerArg = parser; + parser->m_externalEntityRefHandlerArg = parser; } void XMLCALL @@ -1819,7 +1723,7 @@ XML_SetSkippedEntityHandler(XML_Parser parser, XML_SkippedEntityHandler handler) { if (parser != NULL) - skippedEntityHandler = handler; + parser->m_skippedEntityHandler = handler; } void XMLCALL @@ -1829,8 +1733,8 @@ XML_SetUnknownEncodingHandler(XML_Parser parser, { if (parser == NULL) return; - unknownEncodingHandler = handler; - unknownEncodingHandlerData = data; + parser->m_unknownEncodingHandler = handler; + parser->m_unknownEncodingHandlerData = data; } void XMLCALL @@ -1838,7 +1742,7 @@ XML_SetElementDeclHandler(XML_Parser parser, XML_ElementDeclHandler eldecl) { if (parser != NULL) - elementDeclHandler = eldecl; + parser->m_elementDeclHandler = eldecl; } void XMLCALL @@ -1846,7 +1750,7 @@ XML_SetAttlistDeclHandler(XML_Parser parser, XML_AttlistDeclHandler attdecl) { if (parser != NULL) - attlistDeclHandler = attdecl; + parser->m_attlistDeclHandler = attdecl; } void XMLCALL @@ -1854,14 +1758,14 @@ XML_SetEntityDeclHandler(XML_Parser parser, XML_EntityDeclHandler handler) { if (parser != NULL) - entityDeclHandler = handler; + parser->m_entityDeclHandler = handler; } void XMLCALL XML_SetXmlDeclHandler(XML_Parser parser, XML_XmlDeclHandler handler) { if (parser != NULL) - xmlDeclHandler = handler; + parser->m_xmlDeclHandler = handler; } int XMLCALL @@ -1871,10 +1775,10 @@ XML_SetParamEntityParsing(XML_Parser parser, if (parser == NULL) return 0; /* block after XML_Parse()/XML_ParseBuffer() has been called */ - if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED) + if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED) return 0; #ifdef XML_DTD - paramEntityParsing = peParsing; + parser->m_paramEntityParsing = peParsing; return 1; #else return peParsing == XML_PARAM_ENTITY_PARSING_NEVER; @@ -1890,9 +1794,9 @@ XML_SetHashSalt(XML_Parser parser, if (parser->m_parentParser) return XML_SetHashSalt(parser->m_parentParser, hash_salt); /* block after XML_Parse()/XML_ParseBuffer() has been called */ - if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED) + if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED) return 0; - hash_secret_salt = hash_salt; + parser->m_hash_secret_salt = hash_salt; return 1; } @@ -1904,37 +1808,37 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) parser->m_errorCode = XML_ERROR_INVALID_ARGUMENT; return XML_STATUS_ERROR; } - switch (ps_parsing) { + switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: - errorCode = XML_ERROR_SUSPENDED; + parser->m_errorCode = XML_ERROR_SUSPENDED; return XML_STATUS_ERROR; case XML_FINISHED: - errorCode = XML_ERROR_FINISHED; + parser->m_errorCode = XML_ERROR_FINISHED; return XML_STATUS_ERROR; case XML_INITIALIZED: - if (parentParser == NULL && !startParsing(parser)) { - errorCode = XML_ERROR_NO_MEMORY; + if (parser->m_parentParser == NULL && !startParsing(parser)) { + parser->m_errorCode = XML_ERROR_NO_MEMORY; return XML_STATUS_ERROR; } default: - ps_parsing = XML_PARSING; + parser->m_parsingStatus.parsing = XML_PARSING; } if (len == 0) { - ps_finalBuffer = (XML_Bool)isFinal; + parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal; if (!isFinal) return XML_STATUS_OK; - positionPtr = bufferPtr; - parseEndPtr = bufferEnd; + parser->m_positionPtr = parser->m_bufferPtr; + parser->m_parseEndPtr = parser->m_bufferEnd; /* If data are left over from last buffer, and we now know that these data are the final chunk of input, then we have to check them again to detect errors based on that fact. */ - errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr); + parser->m_errorCode = parser->m_processor(parser, parser->m_bufferPtr, parser->m_parseEndPtr, &parser->m_bufferPtr); - if (errorCode == XML_ERROR_NONE) { - switch (ps_parsing) { + if (parser->m_errorCode == XML_ERROR_NONE) { + switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: /* It is hard to be certain, but it seems that this case * cannot occur. This code is cleaning up a previous parse @@ -1948,54 +1852,54 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) * * LCOV_EXCL_START */ - XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position); - positionPtr = bufferPtr; + XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_bufferPtr, &parser->m_position); + parser->m_positionPtr = parser->m_bufferPtr; return XML_STATUS_SUSPENDED; /* LCOV_EXCL_STOP */ case XML_INITIALIZED: case XML_PARSING: - ps_parsing = XML_FINISHED; + parser->m_parsingStatus.parsing = XML_FINISHED; /* fall through */ default: return XML_STATUS_OK; } } - eventEndPtr = eventPtr; - processor = errorProcessor; + parser->m_eventEndPtr = parser->m_eventPtr; + parser->m_processor = errorProcessor; return XML_STATUS_ERROR; } #ifndef XML_CONTEXT_BYTES - else if (bufferPtr == bufferEnd) { + else if (parser->m_bufferPtr == parser->m_bufferEnd) { const char *end; int nLeftOver; enum XML_Status result; /* Detect overflow (a+b > MAX <==> b > MAX-a) */ - if (len > ((XML_Size)-1) / 2 - parseEndByteIndex) { - errorCode = XML_ERROR_NO_MEMORY; - eventPtr = eventEndPtr = NULL; - processor = errorProcessor; + if (len > ((XML_Size)-1) / 2 - parser->m_parseEndByteIndex) { + parser->m_errorCode = XML_ERROR_NO_MEMORY; + parser->m_eventPtr = parser->m_eventEndPtr = NULL; + parser->m_processor = errorProcessor; return XML_STATUS_ERROR; } - parseEndByteIndex += len; - positionPtr = s; - ps_finalBuffer = (XML_Bool)isFinal; + parser->m_parseEndByteIndex += len; + parser->m_positionPtr = s; + parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal; - errorCode = processor(parser, s, parseEndPtr = s + len, &end); + parser->m_errorCode = parser->m_processor(parser, s, parser->m_parseEndPtr = s + len, &end); - if (errorCode != XML_ERROR_NONE) { - eventEndPtr = eventPtr; - processor = errorProcessor; + if (parser->m_errorCode != XML_ERROR_NONE) { + parser->m_eventEndPtr = parser->m_eventPtr; + parser->m_processor = errorProcessor; return XML_STATUS_ERROR; } else { - switch (ps_parsing) { + switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: result = XML_STATUS_SUSPENDED; break; case XML_INITIALIZED: case XML_PARSING: if (isFinal) { - ps_parsing = XML_FINISHED; + parser->m_parsingStatus.parsing = XML_FINISHED; return XML_STATUS_OK; } /* fall through */ @@ -2004,35 +1908,33 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) } } - XmlUpdatePosition(encoding, positionPtr, end, &position); + XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, end, &parser->m_position); nLeftOver = s + len - end; if (nLeftOver) { - if (buffer == NULL || nLeftOver > bufferLim - buffer) { + if (parser->m_buffer == NULL || nLeftOver > parser->m_bufferLim - parser->m_buffer) { /* avoid _signed_ integer overflow */ char *temp = NULL; const int bytesToAllocate = (int)((unsigned)len * 2U); if (bytesToAllocate > 0) { - temp = (buffer == NULL - ? (char *)MALLOC(bytesToAllocate) - : (char *)REALLOC(buffer, bytesToAllocate)); + temp = (char *)REALLOC(parser, parser->m_buffer, bytesToAllocate); } if (temp == NULL) { - errorCode = XML_ERROR_NO_MEMORY; - eventPtr = eventEndPtr = NULL; - processor = errorProcessor; + parser->m_errorCode = XML_ERROR_NO_MEMORY; + parser->m_eventPtr = parser->m_eventEndPtr = NULL; + parser->m_processor = errorProcessor; return XML_STATUS_ERROR; } - buffer = temp; - bufferLim = buffer + bytesToAllocate; + parser->m_buffer = temp; + parser->m_bufferLim = parser->m_buffer + bytesToAllocate; } - memcpy(buffer, end, nLeftOver); + memcpy(parser->m_buffer, end, nLeftOver); } - bufferPtr = buffer; - bufferEnd = buffer + nLeftOver; - positionPtr = bufferPtr; - parseEndPtr = bufferEnd; - eventPtr = bufferPtr; - eventEndPtr = bufferPtr; + parser->m_bufferPtr = parser->m_buffer; + parser->m_bufferEnd = parser->m_buffer + nLeftOver; + parser->m_positionPtr = parser->m_bufferPtr; + parser->m_parseEndPtr = parser->m_bufferEnd; + parser->m_eventPtr = parser->m_bufferPtr; + parser->m_eventEndPtr = parser->m_bufferPtr; return result; } #endif /* not defined XML_CONTEXT_BYTES */ @@ -2055,53 +1957,53 @@ XML_ParseBuffer(XML_Parser parser, int len, int isFinal) if (parser == NULL) return XML_STATUS_ERROR; - switch (ps_parsing) { + switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: - errorCode = XML_ERROR_SUSPENDED; + parser->m_errorCode = XML_ERROR_SUSPENDED; return XML_STATUS_ERROR; case XML_FINISHED: - errorCode = XML_ERROR_FINISHED; + parser->m_errorCode = XML_ERROR_FINISHED; return XML_STATUS_ERROR; case XML_INITIALIZED: - if (parentParser == NULL && !startParsing(parser)) { - errorCode = XML_ERROR_NO_MEMORY; + if (parser->m_parentParser == NULL && !startParsing(parser)) { + parser->m_errorCode = XML_ERROR_NO_MEMORY; return XML_STATUS_ERROR; } default: - ps_parsing = XML_PARSING; + parser->m_parsingStatus.parsing = XML_PARSING; } - start = bufferPtr; - positionPtr = start; - bufferEnd += len; - parseEndPtr = bufferEnd; - parseEndByteIndex += len; - ps_finalBuffer = (XML_Bool)isFinal; + start = parser->m_bufferPtr; + parser->m_positionPtr = start; + parser->m_bufferEnd += len; + parser->m_parseEndPtr = parser->m_bufferEnd; + parser->m_parseEndByteIndex += len; + parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal; - errorCode = processor(parser, start, parseEndPtr, &bufferPtr); + parser->m_errorCode = parser->m_processor(parser, start, parser->m_parseEndPtr, &parser->m_bufferPtr); - if (errorCode != XML_ERROR_NONE) { - eventEndPtr = eventPtr; - processor = errorProcessor; + if (parser->m_errorCode != XML_ERROR_NONE) { + parser->m_eventEndPtr = parser->m_eventPtr; + parser->m_processor = errorProcessor; return XML_STATUS_ERROR; } else { - switch (ps_parsing) { + switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: result = XML_STATUS_SUSPENDED; break; case XML_INITIALIZED: case XML_PARSING: if (isFinal) { - ps_parsing = XML_FINISHED; + parser->m_parsingStatus.parsing = XML_FINISHED; return result; } default: ; /* should not happen */ } } - XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position); - positionPtr = bufferPtr; + XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_bufferPtr, &parser->m_position); + parser->m_positionPtr = parser->m_bufferPtr; return result; } @@ -2111,52 +2013,52 @@ XML_GetBuffer(XML_Parser parser, int len) if (parser == NULL) return NULL; if (len < 0) { - errorCode = XML_ERROR_NO_MEMORY; + parser->m_errorCode = XML_ERROR_NO_MEMORY; return NULL; } - switch (ps_parsing) { + switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: - errorCode = XML_ERROR_SUSPENDED; + parser->m_errorCode = XML_ERROR_SUSPENDED; return NULL; case XML_FINISHED: - errorCode = XML_ERROR_FINISHED; + parser->m_errorCode = XML_ERROR_FINISHED; return NULL; default: ; } - if (len > bufferLim - bufferEnd) { + if (len > parser->m_bufferLim - parser->m_bufferEnd) { #ifdef XML_CONTEXT_BYTES int keep; #endif /* defined XML_CONTEXT_BYTES */ /* Do not invoke signed arithmetic overflow: */ - int neededSize = (int) ((unsigned)len + (unsigned)(bufferEnd - bufferPtr)); + int neededSize = (int) ((unsigned)len + (unsigned)(parser->m_bufferEnd - parser->m_bufferPtr)); if (neededSize < 0) { - errorCode = XML_ERROR_NO_MEMORY; + parser->m_errorCode = XML_ERROR_NO_MEMORY; return NULL; } #ifdef XML_CONTEXT_BYTES - keep = (int)(bufferPtr - buffer); + keep = (int)(parser->m_bufferPtr - parser->m_buffer); if (keep > XML_CONTEXT_BYTES) keep = XML_CONTEXT_BYTES; neededSize += keep; #endif /* defined XML_CONTEXT_BYTES */ - if (neededSize <= bufferLim - buffer) { + if (neededSize <= parser->m_bufferLim - parser->m_buffer) { #ifdef XML_CONTEXT_BYTES - if (keep < bufferPtr - buffer) { - int offset = (int)(bufferPtr - buffer) - keep; - memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep); - bufferEnd -= offset; - bufferPtr -= offset; + if (keep < parser->m_bufferPtr - parser->m_buffer) { + int offset = (int)(parser->m_bufferPtr - parser->m_buffer) - keep; + memmove(parser->m_buffer, &parser->m_buffer[offset], parser->m_bufferEnd - parser->m_bufferPtr + keep); + parser->m_bufferEnd -= offset; + parser->m_bufferPtr -= offset; } #else - memmove(buffer, bufferPtr, bufferEnd - bufferPtr); - bufferEnd = buffer + (bufferEnd - bufferPtr); - bufferPtr = buffer; + memmove(parser->m_buffer, parser->m_bufferPtr, parser->m_bufferEnd - parser->m_bufferPtr); + parser->m_bufferEnd = parser->m_buffer + (parser->m_bufferEnd - parser->m_bufferPtr); + parser->m_bufferPtr = parser->m_buffer; #endif /* not defined XML_CONTEXT_BYTES */ } else { char *newBuf; - int bufferSize = (int)(bufferLim - bufferPtr); + int bufferSize = (int)(parser->m_bufferLim - parser->m_bufferPtr); if (bufferSize == 0) bufferSize = INIT_BUFFER_SIZE; do { @@ -2164,43 +2066,43 @@ XML_GetBuffer(XML_Parser parser, int len) bufferSize = (int) (2U * (unsigned) bufferSize); } while (bufferSize < neededSize && bufferSize > 0); if (bufferSize <= 0) { - errorCode = XML_ERROR_NO_MEMORY; + parser->m_errorCode = XML_ERROR_NO_MEMORY; return NULL; } - newBuf = (char *)MALLOC(bufferSize); + newBuf = (char *)MALLOC(parser, bufferSize); if (newBuf == 0) { - errorCode = XML_ERROR_NO_MEMORY; + parser->m_errorCode = XML_ERROR_NO_MEMORY; return NULL; } - bufferLim = newBuf + bufferSize; + parser->m_bufferLim = newBuf + bufferSize; #ifdef XML_CONTEXT_BYTES - if (bufferPtr) { - int keep = (int)(bufferPtr - buffer); + if (parser->m_bufferPtr) { + int keep = (int)(parser->m_bufferPtr - parser->m_buffer); if (keep > XML_CONTEXT_BYTES) keep = XML_CONTEXT_BYTES; - memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep); - FREE(buffer); - buffer = newBuf; - bufferEnd = buffer + (bufferEnd - bufferPtr) + keep; - bufferPtr = buffer + keep; + memcpy(newBuf, &parser->m_bufferPtr[-keep], parser->m_bufferEnd - parser->m_bufferPtr + keep); + FREE(parser, parser->m_buffer); + parser->m_buffer = newBuf; + parser->m_bufferEnd = parser->m_buffer + (parser->m_bufferEnd - parser->m_bufferPtr) + keep; + parser->m_bufferPtr = parser->m_buffer + keep; } else { - bufferEnd = newBuf + (bufferEnd - bufferPtr); - bufferPtr = buffer = newBuf; + parser->m_bufferEnd = newBuf + (parser->m_bufferEnd - parser->m_bufferPtr); + parser->m_bufferPtr = parser->m_buffer = newBuf; } #else - if (bufferPtr) { - memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr); - FREE(buffer); + if (parser->m_bufferPtr) { + memcpy(newBuf, parser->m_bufferPtr, parser->m_bufferEnd - parser->m_bufferPtr); + FREE(parser, parser->m_buffer); } - bufferEnd = newBuf + (bufferEnd - bufferPtr); - bufferPtr = buffer = newBuf; + parser->m_bufferEnd = newBuf + (parser->m_bufferEnd - parser->m_bufferPtr); + parser->m_bufferPtr = parser->m_buffer = newBuf; #endif /* not defined XML_CONTEXT_BYTES */ } - eventPtr = eventEndPtr = NULL; - positionPtr = NULL; + parser->m_eventPtr = parser->m_eventEndPtr = NULL; + parser->m_positionPtr = NULL; } - return bufferEnd; + return parser->m_bufferEnd; } enum XML_Status XMLCALL @@ -2208,29 +2110,29 @@ XML_StopParser(XML_Parser parser, XML_Bool resumable) { if (parser == NULL) return XML_STATUS_ERROR; - switch (ps_parsing) { + switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: if (resumable) { - errorCode = XML_ERROR_SUSPENDED; + parser->m_errorCode = XML_ERROR_SUSPENDED; return XML_STATUS_ERROR; } - ps_parsing = XML_FINISHED; + parser->m_parsingStatus.parsing = XML_FINISHED; break; case XML_FINISHED: - errorCode = XML_ERROR_FINISHED; + parser->m_errorCode = XML_ERROR_FINISHED; return XML_STATUS_ERROR; default: if (resumable) { #ifdef XML_DTD - if (isParamEntity) { - errorCode = XML_ERROR_SUSPEND_PE; + if (parser->m_isParamEntity) { + parser->m_errorCode = XML_ERROR_SUSPEND_PE; return XML_STATUS_ERROR; } #endif - ps_parsing = XML_SUSPENDED; + parser->m_parsingStatus.parsing = XML_SUSPENDED; } else - ps_parsing = XML_FINISHED; + parser->m_parsingStatus.parsing = XML_FINISHED; } return XML_STATUS_OK; } @@ -2242,36 +2144,36 @@ XML_ResumeParser(XML_Parser parser) if (parser == NULL) return XML_STATUS_ERROR; - if (ps_parsing != XML_SUSPENDED) { - errorCode = XML_ERROR_NOT_SUSPENDED; + if (parser->m_parsingStatus.parsing != XML_SUSPENDED) { + parser->m_errorCode = XML_ERROR_NOT_SUSPENDED; return XML_STATUS_ERROR; } - ps_parsing = XML_PARSING; + parser->m_parsingStatus.parsing = XML_PARSING; - errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr); + parser->m_errorCode = parser->m_processor(parser, parser->m_bufferPtr, parser->m_parseEndPtr, &parser->m_bufferPtr); - if (errorCode != XML_ERROR_NONE) { - eventEndPtr = eventPtr; - processor = errorProcessor; + if (parser->m_errorCode != XML_ERROR_NONE) { + parser->m_eventEndPtr = parser->m_eventPtr; + parser->m_processor = errorProcessor; return XML_STATUS_ERROR; } else { - switch (ps_parsing) { + switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: result = XML_STATUS_SUSPENDED; break; case XML_INITIALIZED: case XML_PARSING: - if (ps_finalBuffer) { - ps_parsing = XML_FINISHED; + if (parser->m_parsingStatus.finalBuffer) { + parser->m_parsingStatus.parsing = XML_FINISHED; return result; } default: ; } } - XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position); - positionPtr = bufferPtr; + XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_bufferPtr, &parser->m_position); + parser->m_positionPtr = parser->m_bufferPtr; return result; } @@ -2289,7 +2191,7 @@ XML_GetErrorCode(XML_Parser parser) { if (parser == NULL) return XML_ERROR_INVALID_ARGUMENT; - return errorCode; + return parser->m_errorCode; } XML_Index XMLCALL @@ -2297,8 +2199,8 @@ XML_GetCurrentByteIndex(XML_Parser parser) { if (parser == NULL) return -1; - if (eventPtr) - return (XML_Index)(parseEndByteIndex - (parseEndPtr - eventPtr)); + if (parser->m_eventPtr) + return (XML_Index)(parser->m_parseEndByteIndex - (parser->m_parseEndPtr - parser->m_eventPtr)); return -1; } @@ -2307,8 +2209,8 @@ XML_GetCurrentByteCount(XML_Parser parser) { if (parser == NULL) return 0; - if (eventEndPtr && eventPtr) - return (int)(eventEndPtr - eventPtr); + if (parser->m_eventEndPtr && parser->m_eventPtr) + return (int)(parser->m_eventEndPtr - parser->m_eventPtr); return 0; } @@ -2318,12 +2220,12 @@ XML_GetInputContext(XML_Parser parser, int *offset, int *size) #ifdef XML_CONTEXT_BYTES if (parser == NULL) return NULL; - if (eventPtr && buffer) { + if (parser->m_eventPtr && parser->m_buffer) { if (offset != NULL) - *offset = (int)(eventPtr - buffer); + *offset = (int)(parser->m_eventPtr - parser->m_buffer); if (size != NULL) - *size = (int)(bufferEnd - buffer); - return buffer; + *size = (int)(parser->m_bufferEnd - parser->m_buffer); + return parser->m_buffer; } #else (void)parser; @@ -2338,11 +2240,11 @@ XML_GetCurrentLineNumber(XML_Parser parser) { if (parser == NULL) return 0; - if (eventPtr && eventPtr >= positionPtr) { - XmlUpdatePosition(encoding, positionPtr, eventPtr, &position); - positionPtr = eventPtr; + if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) { + XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_eventPtr, &parser->m_position); + parser->m_positionPtr = parser->m_eventPtr; } - return position.lineNumber + 1; + return parser->m_position.lineNumber + 1; } XML_Size XMLCALL @@ -2350,18 +2252,18 @@ XML_GetCurrentColumnNumber(XML_Parser parser) { if (parser == NULL) return 0; - if (eventPtr && eventPtr >= positionPtr) { - XmlUpdatePosition(encoding, positionPtr, eventPtr, &position); - positionPtr = eventPtr; + if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) { + XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_eventPtr, &parser->m_position); + parser->m_positionPtr = parser->m_eventPtr; } - return position.columnNumber; + return parser->m_position.columnNumber; } void XMLCALL XML_FreeContentModel(XML_Parser parser, XML_Content *model) { if (parser != NULL) - FREE(model); + FREE(parser, model); } void * XMLCALL @@ -2369,7 +2271,7 @@ XML_MemMalloc(XML_Parser parser, size_t size) { if (parser == NULL) return NULL; - return MALLOC(size); + return MALLOC(parser, size); } void * XMLCALL @@ -2377,14 +2279,14 @@ XML_MemRealloc(XML_Parser parser, void *ptr, size_t size) { if (parser == NULL) return NULL; - return REALLOC(ptr, size); + return REALLOC(parser, ptr, size); } void XMLCALL XML_MemFree(XML_Parser parser, void *ptr) { if (parser != NULL) - FREE(ptr); + FREE(parser, ptr); } void XMLCALL @@ -2392,65 +2294,110 @@ XML_DefaultCurrent(XML_Parser parser) { if (parser == NULL) return; - if (defaultHandler) { - if (openInternalEntities) + if (parser->m_defaultHandler) { + if (parser->m_openInternalEntities) reportDefault(parser, - internalEncoding, - openInternalEntities->internalEventPtr, - openInternalEntities->internalEventEndPtr); + parser->m_internalEncoding, + parser->m_openInternalEntities->internalEventPtr, + parser->m_openInternalEntities->internalEventEndPtr); else - reportDefault(parser, encoding, eventPtr, eventEndPtr); + reportDefault(parser, parser->m_encoding, parser->m_eventPtr, parser->m_eventEndPtr); } } const XML_LChar * XMLCALL XML_ErrorString(enum XML_Error code) { - static const XML_LChar* const message[] = { - 0, - XML_L("out of memory"), - XML_L("syntax error"), - XML_L("no element found"), - XML_L("not well-formed (invalid token)"), - XML_L("unclosed token"), - XML_L("partial character"), - XML_L("mismatched tag"), - XML_L("duplicate attribute"), - XML_L("junk after document element"), - XML_L("illegal parameter entity reference"), - XML_L("undefined entity"), - XML_L("recursive entity reference"), - XML_L("asynchronous entity"), - XML_L("reference to invalid character number"), - XML_L("reference to binary entity"), - XML_L("reference to external entity in attribute"), - XML_L("XML or text declaration not at start of entity"), - XML_L("unknown encoding"), - XML_L("encoding specified in XML declaration is incorrect"), - XML_L("unclosed CDATA section"), - XML_L("error in processing external entity reference"), - XML_L("document is not standalone"), - XML_L("unexpected parser state - please send a bug report"), - XML_L("entity declared in parameter entity"), - XML_L("requested feature requires XML_DTD support in Expat"), - XML_L("cannot change setting once parsing has begun"), - XML_L("unbound prefix"), - XML_L("must not undeclare prefix"), - XML_L("incomplete markup in parameter entity"), - XML_L("XML declaration not well-formed"), - XML_L("text declaration not well-formed"), - XML_L("illegal character(s) in public id"), - XML_L("parser suspended"), - XML_L("parser not suspended"), - XML_L("parsing aborted"), - XML_L("parsing finished"), - XML_L("cannot suspend in external parameter entity"), - XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"), - XML_L("reserved prefix (xmlns) must not be declared or undeclared"), - XML_L("prefix must not be bound to one of the reserved namespace names") - }; - if (code > 0 && code < sizeof(message)/sizeof(message[0])) - return message[code]; + switch (code) { + case XML_ERROR_NONE: + return NULL; + case XML_ERROR_NO_MEMORY: + return XML_L("out of memory"); + case XML_ERROR_SYNTAX: + return XML_L("syntax error"); + case XML_ERROR_NO_ELEMENTS: + return XML_L("no element found"); + case XML_ERROR_INVALID_TOKEN: + return XML_L("not well-formed (invalid token)"); + case XML_ERROR_UNCLOSED_TOKEN: + return XML_L("unclosed token"); + case XML_ERROR_PARTIAL_CHAR: + return XML_L("partial character"); + case XML_ERROR_TAG_MISMATCH: + return XML_L("mismatched tag"); + case XML_ERROR_DUPLICATE_ATTRIBUTE: + return XML_L("duplicate attribute"); + case XML_ERROR_JUNK_AFTER_DOC_ELEMENT: + return XML_L("junk after document element"); + case XML_ERROR_PARAM_ENTITY_REF: + return XML_L("illegal parameter entity reference"); + case XML_ERROR_UNDEFINED_ENTITY: + return XML_L("undefined entity"); + case XML_ERROR_RECURSIVE_ENTITY_REF: + return XML_L("recursive entity reference"); + case XML_ERROR_ASYNC_ENTITY: + return XML_L("asynchronous entity"); + case XML_ERROR_BAD_CHAR_REF: + return XML_L("reference to invalid character number"); + case XML_ERROR_BINARY_ENTITY_REF: + return XML_L("reference to binary entity"); + case XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF: + return XML_L("reference to external entity in attribute"); + case XML_ERROR_MISPLACED_XML_PI: + return XML_L("XML or text declaration not at start of entity"); + case XML_ERROR_UNKNOWN_ENCODING: + return XML_L("unknown encoding"); + case XML_ERROR_INCORRECT_ENCODING: + return XML_L("encoding specified in XML declaration is incorrect"); + case XML_ERROR_UNCLOSED_CDATA_SECTION: + return XML_L("unclosed CDATA section"); + case XML_ERROR_EXTERNAL_ENTITY_HANDLING: + return XML_L("error in processing external entity reference"); + case XML_ERROR_NOT_STANDALONE: + return XML_L("document is not standalone"); + case XML_ERROR_UNEXPECTED_STATE: + return XML_L("unexpected parser state - please send a bug report"); + case XML_ERROR_ENTITY_DECLARED_IN_PE: + return XML_L("entity declared in parameter entity"); + case XML_ERROR_FEATURE_REQUIRES_XML_DTD: + return XML_L("requested feature requires XML_DTD support in Expat"); + case XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING: + return XML_L("cannot change setting once parsing has begun"); + /* Added in 1.95.7. */ + case XML_ERROR_UNBOUND_PREFIX: + return XML_L("unbound prefix"); + /* Added in 1.95.8. */ + case XML_ERROR_UNDECLARING_PREFIX: + return XML_L("must not undeclare prefix"); + case XML_ERROR_INCOMPLETE_PE: + return XML_L("incomplete markup in parameter entity"); + case XML_ERROR_XML_DECL: + return XML_L("XML declaration not well-formed"); + case XML_ERROR_TEXT_DECL: + return XML_L("text declaration not well-formed"); + case XML_ERROR_PUBLICID: + return XML_L("illegal character(s) in public id"); + case XML_ERROR_SUSPENDED: + return XML_L("parser suspended"); + case XML_ERROR_NOT_SUSPENDED: + return XML_L("parser not suspended"); + case XML_ERROR_ABORTED: + return XML_L("parsing aborted"); + case XML_ERROR_FINISHED: + return XML_L("parsing finished"); + case XML_ERROR_SUSPEND_PE: + return XML_L("cannot suspend in external parameter entity"); + /* Added in 2.0.0. */ + case XML_ERROR_RESERVED_PREFIX_XML: + return XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"); + case XML_ERROR_RESERVED_PREFIX_XMLNS: + return XML_L("reserved prefix (xmlns) must not be declared or undeclared"); + case XML_ERROR_RESERVED_NAMESPACE_URI: + return XML_L("prefix must not be bound to one of the reserved namespace names"); + /* Added in 2.2.5. */ + case XML_ERROR_INVALID_ARGUMENT: /* Constant added in 2.2.1, already */ + return XML_L("invalid argument"); + } return NULL; } @@ -2533,12 +2480,12 @@ XML_GetFeatureList(void) static XML_Bool storeRawNames(XML_Parser parser) { - TAG *tag = tagStack; + TAG *tag = parser->m_tagStack; while (tag) { int bufSize; int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1); char *rawNameBuf = tag->buf + nameLen; - /* Stop if already stored. Since tagStack is a stack, we can stop + /* Stop if already stored. Since m_tagStack is a stack, we can stop at the first entry that has already been copied; everything below it in the stack is already been accounted for in a previous call to this function. @@ -2550,7 +2497,7 @@ storeRawNames(XML_Parser parser) */ bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)); if (bufSize > tag->bufEnd - tag->buf) { - char *temp = (char *)REALLOC(tag->buf, bufSize); + char *temp = (char *)REALLOC(parser, tag->buf, bufSize); if (temp == NULL) return XML_FALSE; /* if tag->name.str points to tag->buf (only when namespace @@ -2581,8 +2528,8 @@ contentProcessor(XML_Parser parser, const char *end, const char **endPtr) { - enum XML_Error result = doContent(parser, 0, encoding, start, end, - endPtr, (XML_Bool)!ps_finalBuffer); + enum XML_Error result = doContent(parser, 0, parser->m_encoding, start, end, + endPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer); if (result == XML_ERROR_NONE) { if (!storeRawNames(parser)) return XML_ERROR_NO_MEMORY; @@ -2599,7 +2546,7 @@ externalEntityInitProcessor(XML_Parser parser, enum XML_Error result = initializeEncoding(parser); if (result != XML_ERROR_NONE) return result; - processor = externalEntityInitProcessor2; + parser->m_processor = externalEntityInitProcessor2; return externalEntityInitProcessor2(parser, start, end, endPtr); } @@ -2610,7 +2557,7 @@ externalEntityInitProcessor2(XML_Parser parser, const char **endPtr) { const char *next = start; /* XmlContentTok doesn't always set the last arg */ - int tok = XmlContentTok(encoding, start, end, &next); + int tok = XmlContentTok(parser->m_encoding, start, end, &next); switch (tok) { case XML_TOK_BOM: /* If we are at the end of the buffer, this would cause the next stage, @@ -2618,28 +2565,28 @@ externalEntityInitProcessor2(XML_Parser parser, doContent (by detecting XML_TOK_NONE) without processing any xml text declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent. */ - if (next == end && !ps_finalBuffer) { + if (next == end && !parser->m_parsingStatus.finalBuffer) { *endPtr = next; return XML_ERROR_NONE; } start = next; break; case XML_TOK_PARTIAL: - if (!ps_finalBuffer) { + if (!parser->m_parsingStatus.finalBuffer) { *endPtr = start; return XML_ERROR_NONE; } - eventPtr = start; + parser->m_eventPtr = start; return XML_ERROR_UNCLOSED_TOKEN; case XML_TOK_PARTIAL_CHAR: - if (!ps_finalBuffer) { + if (!parser->m_parsingStatus.finalBuffer) { *endPtr = start; return XML_ERROR_NONE; } - eventPtr = start; + parser->m_eventPtr = start; return XML_ERROR_PARTIAL_CHAR; } - processor = externalEntityInitProcessor3; + parser->m_processor = externalEntityInitProcessor3; return externalEntityInitProcessor3(parser, start, end, endPtr); } @@ -2651,9 +2598,9 @@ externalEntityInitProcessor3(XML_Parser parser, { int tok; const char *next = start; /* XmlContentTok doesn't always set the last arg */ - eventPtr = start; - tok = XmlContentTok(encoding, start, end, &next); - eventEndPtr = next; + parser->m_eventPtr = start; + tok = XmlContentTok(parser->m_encoding, start, end, &next); + parser->m_eventEndPtr = next; switch (tok) { case XML_TOK_XML_DECL: @@ -2662,7 +2609,7 @@ externalEntityInitProcessor3(XML_Parser parser, result = processXmlDecl(parser, 1, start, next); if (result != XML_ERROR_NONE) return result; - switch (ps_parsing) { + switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: *endPtr = next; return XML_ERROR_NONE; @@ -2674,20 +2621,20 @@ externalEntityInitProcessor3(XML_Parser parser, } break; case XML_TOK_PARTIAL: - if (!ps_finalBuffer) { + if (!parser->m_parsingStatus.finalBuffer) { *endPtr = start; return XML_ERROR_NONE; } return XML_ERROR_UNCLOSED_TOKEN; case XML_TOK_PARTIAL_CHAR: - if (!ps_finalBuffer) { + if (!parser->m_parsingStatus.finalBuffer) { *endPtr = start; return XML_ERROR_NONE; } return XML_ERROR_PARTIAL_CHAR; } - processor = externalEntityContentProcessor; - tagLevel = 1; + parser->m_processor = externalEntityContentProcessor; + parser->m_tagLevel = 1; return externalEntityContentProcessor(parser, start, end, endPtr); } @@ -2697,8 +2644,8 @@ externalEntityContentProcessor(XML_Parser parser, const char *end, const char **endPtr) { - enum XML_Error result = doContent(parser, 1, encoding, start, end, - endPtr, (XML_Bool)!ps_finalBuffer); + enum XML_Error result = doContent(parser, 1, parser->m_encoding, start, end, + endPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer); if (result == XML_ERROR_NONE) { if (!storeRawNames(parser)) return XML_ERROR_NO_MEMORY; @@ -2716,17 +2663,17 @@ doContent(XML_Parser parser, XML_Bool haveMore) { /* save one level of indirection */ - DTD * const dtd = _dtd; + DTD * const dtd = parser->m_dtd; const char **eventPP; const char **eventEndPP; - if (enc == encoding) { - eventPP = &eventPtr; - eventEndPP = &eventEndPtr; + if (enc == parser->m_encoding) { + eventPP = &parser->m_eventPtr; + eventEndPP = &parser->m_eventEndPtr; } else { - eventPP = &(openInternalEntities->internalEventPtr); - eventEndPP = &(openInternalEntities->internalEventEndPtr); + eventPP = &(parser->m_openInternalEntities->internalEventPtr); + eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); } *eventPP = s; @@ -2741,18 +2688,18 @@ doContent(XML_Parser parser, return XML_ERROR_NONE; } *eventEndPP = end; - if (characterDataHandler) { + if (parser->m_characterDataHandler) { XML_Char c = 0xA; - characterDataHandler(handlerArg, &c, 1); + parser->m_characterDataHandler(parser->m_handlerArg, &c, 1); } - else if (defaultHandler) + else if (parser->m_defaultHandler) reportDefault(parser, enc, s, end); /* We are at the end of the final buffer, should we check for XML_SUSPENDED, XML_FINISHED? */ if (startTagLevel == 0) return XML_ERROR_NO_ELEMENTS; - if (tagLevel != startTagLevel) + if (parser->m_tagLevel != startTagLevel) return XML_ERROR_ASYNC_ENTITY; *nextPtr = end; return XML_ERROR_NONE; @@ -2762,7 +2709,7 @@ doContent(XML_Parser parser, return XML_ERROR_NONE; } if (startTagLevel > 0) { - if (tagLevel != startTagLevel) + if (parser->m_tagLevel != startTagLevel) return XML_ERROR_ASYNC_ENTITY; *nextPtr = s; return XML_ERROR_NONE; @@ -2791,9 +2738,9 @@ doContent(XML_Parser parser, s + enc->minBytesPerChar, next - enc->minBytesPerChar); if (ch) { - if (characterDataHandler) - characterDataHandler(handlerArg, &ch, 1); - else if (defaultHandler) + if (parser->m_characterDataHandler) + parser->m_characterDataHandler(parser->m_handlerArg, &ch, 1); + else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); break; } @@ -2815,9 +2762,9 @@ doContent(XML_Parser parser, return XML_ERROR_ENTITY_DECLARED_IN_PE; } else if (!entity) { - if (skippedEntityHandler) - skippedEntityHandler(handlerArg, name, 0); - else if (defaultHandler) + if (parser->m_skippedEntityHandler) + parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0); + else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); break; } @@ -2827,10 +2774,10 @@ doContent(XML_Parser parser, return XML_ERROR_BINARY_ENTITY_REF; if (entity->textPtr) { enum XML_Error result; - if (!defaultExpandInternalEntities) { - if (skippedEntityHandler) - skippedEntityHandler(handlerArg, entity->name, 0); - else if (defaultHandler) + if (!parser->m_defaultExpandInternalEntities) { + if (parser->m_skippedEntityHandler) + parser->m_skippedEntityHandler(parser->m_handlerArg, entity->name, 0); + else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); break; } @@ -2838,22 +2785,22 @@ doContent(XML_Parser parser, if (result != XML_ERROR_NONE) return result; } - else if (externalEntityRefHandler) { + else if (parser->m_externalEntityRefHandler) { const XML_Char *context; entity->open = XML_TRUE; context = getContext(parser); entity->open = XML_FALSE; if (!context) return XML_ERROR_NO_MEMORY; - if (!externalEntityRefHandler(externalEntityRefHandlerArg, + if (!parser->m_externalEntityRefHandler(parser->m_externalEntityRefHandlerArg, context, entity->base, entity->systemId, entity->publicId)) return XML_ERROR_EXTERNAL_ENTITY_HANDLING; - poolDiscard(&tempPool); + poolDiscard(&parser->m_tempPool); } - else if (defaultHandler) + else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); break; } @@ -2864,29 +2811,29 @@ doContent(XML_Parser parser, TAG *tag; enum XML_Error result; XML_Char *toPtr; - if (freeTagList) { - tag = freeTagList; - freeTagList = freeTagList->parent; + if (parser->m_freeTagList) { + tag = parser->m_freeTagList; + parser->m_freeTagList = parser->m_freeTagList->parent; } else { - tag = (TAG *)MALLOC(sizeof(TAG)); + tag = (TAG *)MALLOC(parser, sizeof(TAG)); if (!tag) return XML_ERROR_NO_MEMORY; - tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE); + tag->buf = (char *)MALLOC(parser, INIT_TAG_BUF_SIZE); if (!tag->buf) { - FREE(tag); + FREE(parser, tag); return XML_ERROR_NO_MEMORY; } tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE; } tag->bindings = NULL; - tag->parent = tagStack; - tagStack = tag; + tag->parent = parser->m_tagStack; + parser->m_tagStack = tag; tag->name.localPart = NULL; tag->name.prefix = NULL; tag->rawName = s + enc->minBytesPerChar; tag->rawNameLength = XmlNameLength(enc, tag->rawName); - ++tagLevel; + ++parser->m_tagLevel; { const char *rawNameEnd = tag->rawName + tag->rawNameLength; const char *fromPtr = tag->rawName; @@ -2904,7 +2851,7 @@ doContent(XML_Parser parser, } bufSize = (int)(tag->bufEnd - tag->buf) << 1; { - char *temp = (char *)REALLOC(tag->buf, bufSize); + char *temp = (char *)REALLOC(parser, tag->buf, bufSize); if (temp == NULL) return XML_ERROR_NO_MEMORY; tag->buf = temp; @@ -2918,12 +2865,12 @@ doContent(XML_Parser parser, result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings)); if (result) return result; - if (startElementHandler) - startElementHandler(handlerArg, tag->name.str, - (const XML_Char **)atts); - else if (defaultHandler) + if (parser->m_startElementHandler) + parser->m_startElementHandler(parser->m_handlerArg, tag->name.str, + (const XML_Char **)parser->m_atts); + else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); - poolClear(&tempPool); + poolClear(&parser->m_tempPool); break; } case XML_TOK_EMPTY_ELEMENT_NO_ATTS: @@ -2935,45 +2882,47 @@ doContent(XML_Parser parser, BINDING *bindings = NULL; XML_Bool noElmHandlers = XML_TRUE; TAG_NAME name; - name.str = poolStoreString(&tempPool, enc, rawName, + name.str = poolStoreString(&parser->m_tempPool, enc, rawName, rawName + XmlNameLength(enc, rawName)); if (!name.str) return XML_ERROR_NO_MEMORY; - poolFinish(&tempPool); + poolFinish(&parser->m_tempPool); result = storeAtts(parser, enc, s, &name, &bindings); if (result != XML_ERROR_NONE) { freeBindings(parser, bindings); return result; } - poolFinish(&tempPool); - if (startElementHandler) { - startElementHandler(handlerArg, name.str, (const XML_Char **)atts); + poolFinish(&parser->m_tempPool); + if (parser->m_startElementHandler) { + parser->m_startElementHandler(parser->m_handlerArg, name.str, (const XML_Char **)parser->m_atts); noElmHandlers = XML_FALSE; } - if (endElementHandler) { - if (startElementHandler) + if (parser->m_endElementHandler) { + if (parser->m_startElementHandler) *eventPP = *eventEndPP; - endElementHandler(handlerArg, name.str); + parser->m_endElementHandler(parser->m_handlerArg, name.str); noElmHandlers = XML_FALSE; } - if (noElmHandlers && defaultHandler) + if (noElmHandlers && parser->m_defaultHandler) reportDefault(parser, enc, s, next); - poolClear(&tempPool); + poolClear(&parser->m_tempPool); freeBindings(parser, bindings); } - if (tagLevel == 0) + if ((parser->m_tagLevel == 0) && + !((parser->m_parsingStatus.parsing == XML_FINISHED) || (parser->m_parsingStatus.parsing == XML_SUSPENDED))) { return epilogProcessor(parser, next, end, nextPtr); + } break; case XML_TOK_END_TAG: - if (tagLevel == startTagLevel) + if (parser->m_tagLevel == startTagLevel) return XML_ERROR_ASYNC_ENTITY; else { int len; const char *rawName; - TAG *tag = tagStack; - tagStack = tag->parent; - tag->parent = freeTagList; - freeTagList = tag; + TAG *tag = parser->m_tagStack; + parser->m_tagStack = tag->parent; + tag->parent = parser->m_freeTagList; + parser->m_freeTagList = tag; rawName = s + enc->minBytesPerChar*2; len = XmlNameLength(enc, rawName); if (len != tag->rawNameLength @@ -2981,13 +2930,13 @@ doContent(XML_Parser parser, *eventPP = rawName; return XML_ERROR_TAG_MISMATCH; } - --tagLevel; - if (endElementHandler) { + --parser->m_tagLevel; + if (parser->m_endElementHandler) { const XML_Char *localPart; const XML_Char *prefix; XML_Char *uri; localPart = tag->name.localPart; - if (ns && localPart) { + if (parser->m_ns && localPart) { /* localPart and prefix may have been overwritten in tag->name.str, since this points to the binding->uri buffer which gets re-used; so we have to add them again @@ -2996,26 +2945,26 @@ doContent(XML_Parser parser, /* don't need to check for space - already done in storeAtts() */ while (*localPart) *uri++ = *localPart++; prefix = (XML_Char *)tag->name.prefix; - if (ns_triplets && prefix) { - *uri++ = namespaceSeparator; + if (parser->m_ns_triplets && prefix) { + *uri++ = parser->m_namespaceSeparator; while (*prefix) *uri++ = *prefix++; } *uri = XML_T('\0'); } - endElementHandler(handlerArg, tag->name.str); + parser->m_endElementHandler(parser->m_handlerArg, tag->name.str); } - else if (defaultHandler) + else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); while (tag->bindings) { BINDING *b = tag->bindings; - if (endNamespaceDeclHandler) - endNamespaceDeclHandler(handlerArg, b->prefix->name); + if (parser->m_endNamespaceDeclHandler) + parser->m_endNamespaceDeclHandler(parser->m_handlerArg, b->prefix->name); tag->bindings = tag->bindings->nextTagBinding; - b->nextTagBinding = freeBindingList; - freeBindingList = b; + b->nextTagBinding = parser->m_freeBindingList; + parser->m_freeBindingList = b; b->prefix->binding = b->prevPrefixBinding; } - if (tagLevel == 0) + if (parser->m_tagLevel == 0) return epilogProcessor(parser, next, end, nextPtr); } break; @@ -3024,29 +2973,29 @@ doContent(XML_Parser parser, int n = XmlCharRefNumber(enc, s); if (n < 0) return XML_ERROR_BAD_CHAR_REF; - if (characterDataHandler) { + if (parser->m_characterDataHandler) { XML_Char buf[XML_ENCODE_MAX]; - characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf)); + parser->m_characterDataHandler(parser->m_handlerArg, buf, XmlEncode(n, (ICHAR *)buf)); } - else if (defaultHandler) + else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); } break; case XML_TOK_XML_DECL: return XML_ERROR_MISPLACED_XML_PI; case XML_TOK_DATA_NEWLINE: - if (characterDataHandler) { + if (parser->m_characterDataHandler) { XML_Char c = 0xA; - characterDataHandler(handlerArg, &c, 1); + parser->m_characterDataHandler(parser->m_handlerArg, &c, 1); } - else if (defaultHandler) + else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); break; case XML_TOK_CDATA_SECT_OPEN: { enum XML_Error result; - if (startCdataSectionHandler) - startCdataSectionHandler(handlerArg); + if (parser->m_startCdataSectionHandler) + parser->m_startCdataSectionHandler(parser->m_handlerArg); #if 0 /* Suppose you doing a transformation on a document that involves changing only the character data. You set up a defaultHandler @@ -3060,16 +3009,16 @@ doContent(XML_Parser parser, However, now we have a start/endCdataSectionHandler, so it seems easier to let the user deal with this. */ - else if (characterDataHandler) - characterDataHandler(handlerArg, dataBuf, 0); + else if (parser->m_characterDataHandler) + parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf, 0); #endif - else if (defaultHandler) + else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore); if (result != XML_ERROR_NONE) return result; else if (!next) { - processor = cdataSectionProcessor; + parser->m_processor = cdataSectionProcessor; return result; } } @@ -3079,19 +3028,19 @@ doContent(XML_Parser parser, *nextPtr = s; return XML_ERROR_NONE; } - if (characterDataHandler) { + if (parser->m_characterDataHandler) { if (MUST_CONVERT(enc, s)) { - ICHAR *dataPtr = (ICHAR *)dataBuf; - XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd); - characterDataHandler(handlerArg, dataBuf, - (int)(dataPtr - (ICHAR *)dataBuf)); + ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf; + XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd); + parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf, + (int)(dataPtr - (ICHAR *)parser->m_dataBuf)); } else - characterDataHandler(handlerArg, + parser->m_characterDataHandler(parser->m_handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s)); } - else if (defaultHandler) + else if (parser->m_defaultHandler) reportDefault(parser, enc, s, end); /* We are at the end of the final buffer, should we check for XML_SUSPENDED, XML_FINISHED? @@ -3100,7 +3049,7 @@ doContent(XML_Parser parser, *eventPP = end; return XML_ERROR_NO_ELEMENTS; } - if (tagLevel != startTagLevel) { + if (parser->m_tagLevel != startTagLevel) { *eventPP = end; return XML_ERROR_ASYNC_ENTITY; } @@ -3108,26 +3057,26 @@ doContent(XML_Parser parser, return XML_ERROR_NONE; case XML_TOK_DATA_CHARS: { - XML_CharacterDataHandler charDataHandler = characterDataHandler; + XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler; if (charDataHandler) { if (MUST_CONVERT(enc, s)) { for (;;) { - ICHAR *dataPtr = (ICHAR *)dataBuf; - const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd); + ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf; + const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd); *eventEndPP = s; - charDataHandler(handlerArg, dataBuf, - (int)(dataPtr - (ICHAR *)dataBuf)); + charDataHandler(parser->m_handlerArg, parser->m_dataBuf, + (int)(dataPtr - (ICHAR *)parser->m_dataBuf)); if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) break; *eventPP = s; } } else - charDataHandler(handlerArg, + charDataHandler(parser->m_handlerArg, (XML_Char *)s, (int)((XML_Char *)next - (XML_Char *)s)); } - else if (defaultHandler) + else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); } break; @@ -3147,13 +3096,13 @@ doContent(XML_Parser parser, * * LCOV_EXCL_START */ - if (defaultHandler) + if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); break; /* LCOV_EXCL_STOP */ } *eventPP = s = next; - switch (ps_parsing) { + switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: *nextPtr = next; return XML_ERROR_NONE; @@ -3166,7 +3115,7 @@ doContent(XML_Parser parser, } /* This function does not call free() on the allocated memory, merely - * moving it to the parser's freeBindingList where it can be freed or + * moving it to the parser's m_freeBindingList where it can be freed or * reused as appropriate. */ static void @@ -3175,15 +3124,15 @@ freeBindings(XML_Parser parser, BINDING *bindings) while (bindings) { BINDING *b = bindings; - /* startNamespaceDeclHandler will have been called for this + /* m_startNamespaceDeclHandler will have been called for this * binding in addBindings(), so call the end handler now. */ - if (endNamespaceDeclHandler) - endNamespaceDeclHandler(handlerArg, b->prefix->name); + if (parser->m_endNamespaceDeclHandler) + parser->m_endNamespaceDeclHandler(parser->m_handlerArg, b->prefix->name); bindings = bindings->nextTagBinding; - b->nextTagBinding = freeBindingList; - freeBindingList = b; + b->nextTagBinding = parser->m_freeBindingList; + parser->m_freeBindingList = b; b->prefix->binding = b->prevPrefixBinding; } } @@ -3203,7 +3152,7 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr, TAG_NAME *tagNamePtr, BINDING **bindingsPtr) { - DTD * const dtd = _dtd; /* save one level of indirection */ + DTD * const dtd = parser->m_dtd; /* save one level of indirection */ ELEMENT_TYPE *elementType; int nDefaultAtts; const XML_Char **appAtts; /* the attribute list for the application */ @@ -3226,43 +3175,43 @@ storeAtts(XML_Parser parser, const ENCODING *enc, sizeof(ELEMENT_TYPE)); if (!elementType) return XML_ERROR_NO_MEMORY; - if (ns && !setElementTypePrefix(parser, elementType)) + if (parser->m_ns && !setElementTypePrefix(parser, elementType)) return XML_ERROR_NO_MEMORY; } nDefaultAtts = elementType->nDefaultAtts; /* get the attributes from the tokenizer */ - n = XmlGetAttributes(enc, attStr, attsSize, atts); - if (n + nDefaultAtts > attsSize) { - int oldAttsSize = attsSize; + n = XmlGetAttributes(enc, attStr, parser->m_attsSize, parser->m_atts); + if (n + nDefaultAtts > parser->m_attsSize) { + int oldAttsSize = parser->m_attsSize; ATTRIBUTE *temp; #ifdef XML_ATTR_INFO XML_AttrInfo *temp2; #endif - attsSize = n + nDefaultAtts + INIT_ATTS_SIZE; - temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE)); + parser->m_attsSize = n + nDefaultAtts + INIT_ATTS_SIZE; + temp = (ATTRIBUTE *)REALLOC(parser, (void *)parser->m_atts, parser->m_attsSize * sizeof(ATTRIBUTE)); if (temp == NULL) { - attsSize = oldAttsSize; + parser->m_attsSize = oldAttsSize; return XML_ERROR_NO_MEMORY; } - atts = temp; + parser->m_atts = temp; #ifdef XML_ATTR_INFO - temp2 = (XML_AttrInfo *)REALLOC((void *)attInfo, attsSize * sizeof(XML_AttrInfo)); + temp2 = (XML_AttrInfo *)REALLOC(parser, (void *)parser->m_attInfo, parser->m_attsSize * sizeof(XML_AttrInfo)); if (temp2 == NULL) { - attsSize = oldAttsSize; + parser->m_attsSize = oldAttsSize; return XML_ERROR_NO_MEMORY; } - attInfo = temp2; + parser->m_attInfo = temp2; #endif if (n > oldAttsSize) - XmlGetAttributes(enc, attStr, n, atts); + XmlGetAttributes(enc, attStr, n, parser->m_atts); } - appAtts = (const XML_Char **)atts; + appAtts = (const XML_Char **)parser->m_atts; for (i = 0; i < n; i++) { - ATTRIBUTE *currAtt = &atts[i]; + ATTRIBUTE *currAtt = &parser->m_atts[i]; #ifdef XML_ATTR_INFO - XML_AttrInfo *currAttInfo = &attInfo[i]; + XML_AttrInfo *currAttInfo = &parser->m_attInfo[i]; #endif /* add the name and value to the attribute list */ ATTRIBUTE_ID *attId = getAttributeId(parser, enc, currAtt->name, @@ -3271,25 +3220,25 @@ storeAtts(XML_Parser parser, const ENCODING *enc, if (!attId) return XML_ERROR_NO_MEMORY; #ifdef XML_ATTR_INFO - currAttInfo->nameStart = parseEndByteIndex - (parseEndPtr - currAtt->name); + currAttInfo->nameStart = parser->m_parseEndByteIndex - (parser->m_parseEndPtr - currAtt->name); currAttInfo->nameEnd = currAttInfo->nameStart + XmlNameLength(enc, currAtt->name); - currAttInfo->valueStart = parseEndByteIndex - - (parseEndPtr - currAtt->valuePtr); - currAttInfo->valueEnd = parseEndByteIndex - (parseEndPtr - currAtt->valueEnd); + currAttInfo->valueStart = parser->m_parseEndByteIndex - + (parser->m_parseEndPtr - currAtt->valuePtr); + currAttInfo->valueEnd = parser->m_parseEndByteIndex - (parser->m_parseEndPtr - currAtt->valueEnd); #endif /* Detect duplicate attributes by their QNames. This does not work when namespace processing is turned on and different prefixes for the same namespace are used. For this case we have a check further down. */ if ((attId->name)[-1]) { - if (enc == encoding) - eventPtr = atts[i].name; + if (enc == parser->m_encoding) + parser->m_eventPtr = parser->m_atts[i].name; return XML_ERROR_DUPLICATE_ATTRIBUTE; } (attId->name)[-1] = 1; appAtts[attIndex++] = attId->name; - if (!atts[i].normalized) { + if (!parser->m_atts[i].normalized) { enum XML_Error result; XML_Bool isCdata = XML_TRUE; @@ -3306,20 +3255,20 @@ storeAtts(XML_Parser parser, const ENCODING *enc, /* normalize the attribute value */ result = storeAttributeValue(parser, enc, isCdata, - atts[i].valuePtr, atts[i].valueEnd, - &tempPool); + parser->m_atts[i].valuePtr, parser->m_atts[i].valueEnd, + &parser->m_tempPool); if (result) return result; - appAtts[attIndex] = poolStart(&tempPool); - poolFinish(&tempPool); + appAtts[attIndex] = poolStart(&parser->m_tempPool); + poolFinish(&parser->m_tempPool); } else { /* the value did not need normalizing */ - appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr, - atts[i].valueEnd); + appAtts[attIndex] = poolStoreString(&parser->m_tempPool, enc, parser->m_atts[i].valuePtr, + parser->m_atts[i].valueEnd); if (appAtts[attIndex] == 0) return XML_ERROR_NO_MEMORY; - poolFinish(&tempPool); + poolFinish(&parser->m_tempPool); } /* handle prefixed attribute names */ if (attId->prefix) { @@ -3343,16 +3292,16 @@ storeAtts(XML_Parser parser, const ENCODING *enc, } /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */ - nSpecifiedAtts = attIndex; + parser->m_nSpecifiedAtts = attIndex; if (elementType->idAtt && (elementType->idAtt->name)[-1]) { for (i = 0; i < attIndex; i += 2) if (appAtts[i] == elementType->idAtt->name) { - idAttIndex = i; + parser->m_idAttIndex = i; break; } } else - idAttIndex = -1; + parser->m_idAttIndex = -1; /* do attribute defaulting */ for (i = 0; i < nDefaultAtts; i++) { @@ -3386,33 +3335,33 @@ storeAtts(XML_Parser parser, const ENCODING *enc, i = 0; if (nPrefixes) { int j; /* hash table index */ - unsigned long version = nsAttsVersion; - int nsAttsSize = (int)1 << nsAttsPower; - unsigned char oldNsAttsPower = nsAttsPower; + unsigned long version = parser->m_nsAttsVersion; + int nsAttsSize = (int)1 << parser->m_nsAttsPower; + unsigned char oldNsAttsPower = parser->m_nsAttsPower; /* size of hash table must be at least 2 * (# of prefixed attributes) */ - if ((nPrefixes << 1) >> nsAttsPower) { /* true for nsAttsPower = 0 */ + if ((nPrefixes << 1) >> parser->m_nsAttsPower) { /* true for m_nsAttsPower = 0 */ NS_ATT *temp; /* hash table size must also be a power of 2 and >= 8 */ - while (nPrefixes >> nsAttsPower++); - if (nsAttsPower < 3) - nsAttsPower = 3; - nsAttsSize = (int)1 << nsAttsPower; - temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT)); + while (nPrefixes >> parser->m_nsAttsPower++); + if (parser->m_nsAttsPower < 3) + parser->m_nsAttsPower = 3; + nsAttsSize = (int)1 << parser->m_nsAttsPower; + temp = (NS_ATT *)REALLOC(parser, parser->m_nsAtts, nsAttsSize * sizeof(NS_ATT)); if (!temp) { - /* Restore actual size of memory in nsAtts */ - nsAttsPower = oldNsAttsPower; + /* Restore actual size of memory in m_nsAtts */ + parser->m_nsAttsPower = oldNsAttsPower; return XML_ERROR_NO_MEMORY; } - nsAtts = temp; - version = 0; /* force re-initialization of nsAtts hash table */ + parser->m_nsAtts = temp; + version = 0; /* force re-initialization of m_nsAtts hash table */ } - /* using a version flag saves us from initializing nsAtts every time */ + /* using a version flag saves us from initializing m_nsAtts every time */ if (!version) { /* initialize version flags when version wraps around */ version = INIT_ATTS_VERSION; for (j = nsAttsSize; j != 0; ) - nsAtts[--j].version = version; + parser->m_nsAtts[--j].version = version; } - nsAttsVersion = --version; + parser->m_nsAttsVersion = --version; /* expand prefixed names and check for duplicates */ for (; i < attIndex; i += 2) { @@ -3452,7 +3401,7 @@ storeAtts(XML_Parser parser, const ENCODING *enc, for (j = 0; j < b->uriLen; j++) { const XML_Char c = b->uri[j]; - if (!poolAppendChar(&tempPool, c)) + if (!poolAppendChar(&parser->m_tempPool, c)) return XML_ERROR_NO_MEMORY; } @@ -3464,7 +3413,7 @@ storeAtts(XML_Parser parser, const ENCODING *enc, sip24_update(&sip_state, s, keylen(s) * sizeof(XML_Char)); do { /* copies null terminator */ - if (!poolAppendChar(&tempPool, *s)) + if (!poolAppendChar(&parser->m_tempPool, *s)) return XML_ERROR_NO_MEMORY; } while (*s++); @@ -3476,40 +3425,40 @@ storeAtts(XML_Parser parser, const ENCODING *enc, unsigned char step = 0; unsigned long mask = nsAttsSize - 1; j = uriHash & mask; /* index into hash table */ - while (nsAtts[j].version == version) { + while (parser->m_nsAtts[j].version == version) { /* for speed we compare stored hash values first */ - if (uriHash == nsAtts[j].hash) { - const XML_Char *s1 = poolStart(&tempPool); - const XML_Char *s2 = nsAtts[j].uriName; + if (uriHash == parser->m_nsAtts[j].hash) { + const XML_Char *s1 = poolStart(&parser->m_tempPool); + const XML_Char *s2 = parser->m_nsAtts[j].uriName; /* s1 is null terminated, but not s2 */ for (; *s1 == *s2 && *s1 != 0; s1++, s2++); if (*s1 == 0) return XML_ERROR_DUPLICATE_ATTRIBUTE; } if (!step) - step = PROBE_STEP(uriHash, mask, nsAttsPower); + step = PROBE_STEP(uriHash, mask, parser->m_nsAttsPower); j < step ? (j += nsAttsSize - step) : (j -= step); } } - if (ns_triplets) { /* append namespace separator and prefix */ - tempPool.ptr[-1] = namespaceSeparator; + if (parser->m_ns_triplets) { /* append namespace separator and prefix */ + parser->m_tempPool.ptr[-1] = parser->m_namespaceSeparator; s = b->prefix->name; do { - if (!poolAppendChar(&tempPool, *s)) + if (!poolAppendChar(&parser->m_tempPool, *s)) return XML_ERROR_NO_MEMORY; } while (*s++); } /* store expanded name in attribute list */ - s = poolStart(&tempPool); - poolFinish(&tempPool); + s = poolStart(&parser->m_tempPool); + poolFinish(&parser->m_tempPool); appAtts[i] = s; /* fill empty slot with new version, uriName and hash value */ - nsAtts[j].version = version; - nsAtts[j].hash = uriHash; - nsAtts[j].uriName = s; + parser->m_nsAtts[j].version = version; + parser->m_nsAtts[j].hash = uriHash; + parser->m_nsAtts[j].uriName = s; if (!--nPrefixes) { i += 2; @@ -3526,7 +3475,7 @@ storeAtts(XML_Parser parser, const ENCODING *enc, for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding) binding->attId->name[-1] = 0; - if (!ns) + if (!parser->m_ns) return XML_ERROR_NONE; /* expand the element type name */ @@ -3545,7 +3494,7 @@ storeAtts(XML_Parser parser, const ENCODING *enc, else return XML_ERROR_NONE; prefixLen = 0; - if (ns_triplets && binding->prefix->name) { + if (parser->m_ns_triplets && binding->prefix->name) { for (; binding->prefix->name[prefixLen++];) ; /* prefixLen includes null terminator */ } @@ -3558,24 +3507,24 @@ storeAtts(XML_Parser parser, const ENCODING *enc, n = i + binding->uriLen + prefixLen; if (n > binding->uriAlloc) { TAG *p; - uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char)); + uri = (XML_Char *)MALLOC(parser, (n + EXPAND_SPARE) * sizeof(XML_Char)); if (!uri) return XML_ERROR_NO_MEMORY; binding->uriAlloc = n + EXPAND_SPARE; memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char)); - for (p = tagStack; p; p = p->parent) + for (p = parser->m_tagStack; p; p = p->parent) if (p->name.str == binding->uri) p->name.str = uri; - FREE(binding->uri); + FREE(parser, binding->uri); binding->uri = uri; } - /* if namespaceSeparator != '\0' then uri includes it already */ + /* if m_namespaceSeparator != '\0' then uri includes it already */ uri = binding->uri + binding->uriLen; memcpy(uri, localPart, i * sizeof(XML_Char)); /* we always have a namespace separator between localPart and prefix */ if (prefixLen) { uri += i - 1; - *uri = namespaceSeparator; /* replace null terminator */ + *uri = parser->m_namespaceSeparator; /* replace null terminator */ memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char)); } tagNamePtr->str = binding->uri; @@ -3653,48 +3602,48 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, if (isXMLNS) return XML_ERROR_RESERVED_NAMESPACE_URI; - if (namespaceSeparator) + if (parser->m_namespaceSeparator) len++; - if (freeBindingList) { - b = freeBindingList; + if (parser->m_freeBindingList) { + b = parser->m_freeBindingList; if (len > b->uriAlloc) { - XML_Char *temp = (XML_Char *)REALLOC(b->uri, + XML_Char *temp = (XML_Char *)REALLOC(parser, b->uri, sizeof(XML_Char) * (len + EXPAND_SPARE)); if (temp == NULL) return XML_ERROR_NO_MEMORY; b->uri = temp; b->uriAlloc = len + EXPAND_SPARE; } - freeBindingList = b->nextTagBinding; + parser->m_freeBindingList = b->nextTagBinding; } else { - b = (BINDING *)MALLOC(sizeof(BINDING)); + b = (BINDING *)MALLOC(parser, sizeof(BINDING)); if (!b) return XML_ERROR_NO_MEMORY; - b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE)); + b->uri = (XML_Char *)MALLOC(parser, sizeof(XML_Char) * (len + EXPAND_SPARE)); if (!b->uri) { - FREE(b); + FREE(parser, b); return XML_ERROR_NO_MEMORY; } b->uriAlloc = len + EXPAND_SPARE; } b->uriLen = len; memcpy(b->uri, uri, len * sizeof(XML_Char)); - if (namespaceSeparator) - b->uri[len - 1] = namespaceSeparator; + if (parser->m_namespaceSeparator) + b->uri[len - 1] = parser->m_namespaceSeparator; b->prefix = prefix; b->attId = attId; b->prevPrefixBinding = prefix->binding; /* NULL binding when default namespace undeclared */ - if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix) + if (*uri == XML_T('\0') && prefix == &parser->m_dtd->defaultPrefix) prefix->binding = NULL; else prefix->binding = b; b->nextTagBinding = *bindingsPtr; *bindingsPtr = b; /* if attId == NULL then we are not starting a namespace scope */ - if (attId && startNamespaceDeclHandler) - startNamespaceDeclHandler(handlerArg, prefix->name, + if (attId && parser->m_startNamespaceDeclHandler) + parser->m_startNamespaceDeclHandler(parser->m_handlerArg, prefix->name, prefix->binding ? uri : 0); return XML_ERROR_NONE; } @@ -3708,17 +3657,17 @@ cdataSectionProcessor(XML_Parser parser, const char *end, const char **endPtr) { - enum XML_Error result = doCdataSection(parser, encoding, &start, end, - endPtr, (XML_Bool)!ps_finalBuffer); + enum XML_Error result = doCdataSection(parser, parser->m_encoding, &start, end, + endPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer); if (result != XML_ERROR_NONE) return result; if (start) { - if (parentParser) { /* we are parsing an external entity */ - processor = externalEntityContentProcessor; + if (parser->m_parentParser) { /* we are parsing an external entity */ + parser->m_processor = externalEntityContentProcessor; return externalEntityContentProcessor(parser, start, end, endPtr); } else { - processor = contentProcessor; + parser->m_processor = contentProcessor; return contentProcessor(parser, start, end, endPtr); } } @@ -3739,14 +3688,14 @@ doCdataSection(XML_Parser parser, const char *s = *startPtr; const char **eventPP; const char **eventEndPP; - if (enc == encoding) { - eventPP = &eventPtr; + if (enc == parser->m_encoding) { + eventPP = &parser->m_eventPtr; *eventPP = s; - eventEndPP = &eventEndPtr; + eventEndPP = &parser->m_eventEndPtr; } else { - eventPP = &(openInternalEntities->internalEventPtr); - eventEndPP = &(openInternalEntities->internalEventEndPtr); + eventPP = &(parser->m_openInternalEntities->internalEventPtr); + eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); } *eventPP = s; *startPtr = NULL; @@ -3757,51 +3706,51 @@ doCdataSection(XML_Parser parser, *eventEndPP = next; switch (tok) { case XML_TOK_CDATA_SECT_CLOSE: - if (endCdataSectionHandler) - endCdataSectionHandler(handlerArg); + if (parser->m_endCdataSectionHandler) + parser->m_endCdataSectionHandler(parser->m_handlerArg); #if 0 /* see comment under XML_TOK_CDATA_SECT_OPEN */ - else if (characterDataHandler) - characterDataHandler(handlerArg, dataBuf, 0); + else if (parser->m_characterDataHandler) + parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf, 0); #endif - else if (defaultHandler) + else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); *startPtr = next; *nextPtr = next; - if (ps_parsing == XML_FINISHED) + if (parser->m_parsingStatus.parsing == XML_FINISHED) return XML_ERROR_ABORTED; else return XML_ERROR_NONE; case XML_TOK_DATA_NEWLINE: - if (characterDataHandler) { + if (parser->m_characterDataHandler) { XML_Char c = 0xA; - characterDataHandler(handlerArg, &c, 1); + parser->m_characterDataHandler(parser->m_handlerArg, &c, 1); } - else if (defaultHandler) + else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); break; case XML_TOK_DATA_CHARS: { - XML_CharacterDataHandler charDataHandler = characterDataHandler; + XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler; if (charDataHandler) { if (MUST_CONVERT(enc, s)) { for (;;) { - ICHAR *dataPtr = (ICHAR *)dataBuf; - const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd); + ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf; + const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd); *eventEndPP = next; - charDataHandler(handlerArg, dataBuf, - (int)(dataPtr - (ICHAR *)dataBuf)); + charDataHandler(parser->m_handlerArg, parser->m_dataBuf, + (int)(dataPtr - (ICHAR *)parser->m_dataBuf)); if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) break; *eventPP = s; } } else - charDataHandler(handlerArg, + charDataHandler(parser->m_handlerArg, (XML_Char *)s, (int)((XML_Char *)next - (XML_Char *)s)); } - else if (defaultHandler) + else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); } break; @@ -3835,7 +3784,7 @@ doCdataSection(XML_Parser parser, } *eventPP = s = next; - switch (ps_parsing) { + switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: *nextPtr = next; return XML_ERROR_NONE; @@ -3858,12 +3807,12 @@ ignoreSectionProcessor(XML_Parser parser, const char *end, const char **endPtr) { - enum XML_Error result = doIgnoreSection(parser, encoding, &start, end, - endPtr, (XML_Bool)!ps_finalBuffer); + enum XML_Error result = doIgnoreSection(parser, parser->m_encoding, &start, end, + endPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer); if (result != XML_ERROR_NONE) return result; if (start) { - processor = prologProcessor; + parser->m_processor = prologProcessor; return prologProcessor(parser, start, end, endPtr); } return result; @@ -3885,15 +3834,15 @@ doIgnoreSection(XML_Parser parser, const char *s = *startPtr; const char **eventPP; const char **eventEndPP; - if (enc == encoding) { - eventPP = &eventPtr; + if (enc == parser->m_encoding) { + eventPP = &parser->m_eventPtr; *eventPP = s; - eventEndPP = &eventEndPtr; + eventEndPP = &parser->m_eventEndPtr; } else { /* It's not entirely clear, but it seems the following two lines * of code cannot be executed. The only occasions on which 'enc' - * is not 'parser->m_encoding' are when this function is called + * is not 'encoding' are when this function is called * from the internal entity processing, and IGNORE sections are an * error in internal entities. * @@ -3902,8 +3851,8 @@ doIgnoreSection(XML_Parser parser, * * LCOV_EXCL_START */ - eventPP = &(openInternalEntities->internalEventPtr); - eventEndPP = &(openInternalEntities->internalEventEndPtr); + eventPP = &(parser->m_openInternalEntities->internalEventPtr); + eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); /* LCOV_EXCL_STOP */ } *eventPP = s; @@ -3912,11 +3861,11 @@ doIgnoreSection(XML_Parser parser, *eventEndPP = next; switch (tok) { case XML_TOK_IGNORE_SECT: - if (defaultHandler) + if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); *startPtr = next; *nextPtr = next; - if (ps_parsing == XML_FINISHED) + if (parser->m_parsingStatus.parsing == XML_FINISHED) return XML_ERROR_ABORTED; else return XML_ERROR_NONE; @@ -3960,27 +3909,27 @@ initializeEncoding(XML_Parser parser) #ifdef XML_UNICODE char encodingBuf[128]; /* See comments abount `protoclEncodingName` in parserInit() */ - if (!protocolEncodingName) + if (!parser->m_protocolEncodingName) s = NULL; else { int i; - for (i = 0; protocolEncodingName[i]; i++) { + for (i = 0; parser->m_protocolEncodingName[i]; i++) { if (i == sizeof(encodingBuf) - 1 - || (protocolEncodingName[i] & ~0x7f) != 0) { + || (parser->m_protocolEncodingName[i] & ~0x7f) != 0) { encodingBuf[0] = '\0'; break; } - encodingBuf[i] = (char)protocolEncodingName[i]; + encodingBuf[i] = (char)parser->m_protocolEncodingName[i]; } encodingBuf[i] = '\0'; s = encodingBuf; } #else - s = protocolEncodingName; + s = parser->m_protocolEncodingName; #endif - if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s)) + if ((parser->m_ns ? XmlInitEncodingNS : XmlInitEncoding)(&parser->m_initEncoding, &parser->m_encoding, s)) return XML_ERROR_NONE; - return handleUnknownEncoding(parser, protocolEncodingName); + return handleUnknownEncoding(parser, parser->m_protocolEncodingName); } static enum XML_Error @@ -3994,13 +3943,13 @@ processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *versionend; const XML_Char *storedversion = NULL; int standalone = -1; - if (!(ns + if (!(parser->m_ns ? XmlParseXmlDeclNS : XmlParseXmlDecl)(isGeneralTextEntity, - encoding, + parser->m_encoding, s, next, - &eventPtr, + &parser->m_eventPtr, &version, &versionend, &encodingName, @@ -4012,69 +3961,69 @@ processXmlDecl(XML_Parser parser, int isGeneralTextEntity, return XML_ERROR_XML_DECL; } if (!isGeneralTextEntity && standalone == 1) { - _dtd->standalone = XML_TRUE; + parser->m_dtd->standalone = XML_TRUE; #ifdef XML_DTD - if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE) - paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; + if (parser->m_paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE) + parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; #endif /* XML_DTD */ } - if (xmlDeclHandler) { + if (parser->m_xmlDeclHandler) { if (encodingName != NULL) { - storedEncName = poolStoreString(&temp2Pool, - encoding, + storedEncName = poolStoreString(&parser->m_temp2Pool, + parser->m_encoding, encodingName, encodingName - + XmlNameLength(encoding, encodingName)); + + XmlNameLength(parser->m_encoding, encodingName)); if (!storedEncName) return XML_ERROR_NO_MEMORY; - poolFinish(&temp2Pool); + poolFinish(&parser->m_temp2Pool); } if (version) { - storedversion = poolStoreString(&temp2Pool, - encoding, + storedversion = poolStoreString(&parser->m_temp2Pool, + parser->m_encoding, version, - versionend - encoding->minBytesPerChar); + versionend - parser->m_encoding->minBytesPerChar); if (!storedversion) return XML_ERROR_NO_MEMORY; } - xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone); + parser->m_xmlDeclHandler(parser->m_handlerArg, storedversion, storedEncName, standalone); } - else if (defaultHandler) - reportDefault(parser, encoding, s, next); - if (protocolEncodingName == NULL) { + else if (parser->m_defaultHandler) + reportDefault(parser, parser->m_encoding, s, next); + if (parser->m_protocolEncodingName == NULL) { if (newEncoding) { /* Check that the specified encoding does not conflict with what * the parser has already deduced. Do we have the same number * of bytes in the smallest representation of a character? If * this is UTF-16, is it the same endianness? */ - if (newEncoding->minBytesPerChar != encoding->minBytesPerChar + if (newEncoding->minBytesPerChar != parser->m_encoding->minBytesPerChar || (newEncoding->minBytesPerChar == 2 && - newEncoding != encoding)) { - eventPtr = encodingName; + newEncoding != parser->m_encoding)) { + parser->m_eventPtr = encodingName; return XML_ERROR_INCORRECT_ENCODING; } - encoding = newEncoding; + parser->m_encoding = newEncoding; } else if (encodingName) { enum XML_Error result; if (!storedEncName) { storedEncName = poolStoreString( - &temp2Pool, encoding, encodingName, - encodingName + XmlNameLength(encoding, encodingName)); + &parser->m_temp2Pool, parser->m_encoding, encodingName, + encodingName + XmlNameLength(parser->m_encoding, encodingName)); if (!storedEncName) return XML_ERROR_NO_MEMORY; } result = handleUnknownEncoding(parser, storedEncName); - poolClear(&temp2Pool); + poolClear(&parser->m_temp2Pool); if (result == XML_ERROR_UNKNOWN_ENCODING) - eventPtr = encodingName; + parser->m_eventPtr = encodingName; return result; } } if (storedEncName || storedversion) - poolClear(&temp2Pool); + poolClear(&parser->m_temp2Pool); return XML_ERROR_NONE; } @@ -4082,7 +4031,7 @@ processXmlDecl(XML_Parser parser, int isGeneralTextEntity, static enum XML_Error handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName) { - if (unknownEncodingHandler) { + if (parser->m_unknownEncodingHandler) { XML_Encoding info; int i; for (i = 0; i < 256; i++) @@ -4090,25 +4039,25 @@ handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName) info.convert = NULL; info.data = NULL; info.release = NULL; - if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName, + if (parser->m_unknownEncodingHandler(parser->m_unknownEncodingHandlerData, encodingName, &info)) { ENCODING *enc; - unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding()); - if (!unknownEncodingMem) { + parser->m_unknownEncodingMem = MALLOC(parser, XmlSizeOfUnknownEncoding()); + if (!parser->m_unknownEncodingMem) { if (info.release) info.release(info.data); return XML_ERROR_NO_MEMORY; } - enc = (ns + enc = (parser->m_ns ? XmlInitUnknownEncodingNS - : XmlInitUnknownEncoding)(unknownEncodingMem, + : XmlInitUnknownEncoding)(parser->m_unknownEncodingMem, info.map, info.convert, info.data); if (enc) { - unknownEncodingData = info.data; - unknownEncodingRelease = info.release; - encoding = enc; + parser->m_unknownEncodingData = info.data; + parser->m_unknownEncodingRelease = info.release; + parser->m_encoding = enc; return XML_ERROR_NONE; } } @@ -4127,7 +4076,7 @@ prologInitProcessor(XML_Parser parser, enum XML_Error result = initializeEncoding(parser); if (result != XML_ERROR_NONE) return result; - processor = prologProcessor; + parser->m_processor = prologProcessor; return prologProcessor(parser, s, end, nextPtr); } @@ -4145,14 +4094,14 @@ externalParEntInitProcessor(XML_Parser parser, /* we know now that XML_Parse(Buffer) has been called, so we consider the external parameter entity read */ - _dtd->paramEntityRead = XML_TRUE; + parser->m_dtd->paramEntityRead = XML_TRUE; - if (prologState.inEntityValue) { - processor = entityValueInitProcessor; + if (parser->m_prologState.inEntityValue) { + parser->m_processor = entityValueInitProcessor; return entityValueInitProcessor(parser, s, end, nextPtr); } else { - processor = externalParEntProcessor; + parser->m_processor = externalParEntProcessor; return externalParEntProcessor(parser, s, end, nextPtr); } } @@ -4166,13 +4115,13 @@ entityValueInitProcessor(XML_Parser parser, int tok; const char *start = s; const char *next = start; - eventPtr = start; + parser->m_eventPtr = start; for (;;) { - tok = XmlPrologTok(encoding, start, end, &next); - eventEndPtr = next; + tok = XmlPrologTok(parser->m_encoding, start, end, &next); + parser->m_eventEndPtr = next; if (tok <= 0) { - if (!ps_finalBuffer && tok != XML_TOK_INVALID) { + if (!parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) { *nextPtr = s; return XML_ERROR_NONE; } @@ -4188,23 +4137,23 @@ entityValueInitProcessor(XML_Parser parser, break; } /* found end of entity value - can store it now */ - return storeEntityValue(parser, encoding, s, end); + return storeEntityValue(parser, parser->m_encoding, s, end); } else if (tok == XML_TOK_XML_DECL) { enum XML_Error result; result = processXmlDecl(parser, 0, start, next); if (result != XML_ERROR_NONE) return result; - /* At this point, ps_parsing cannot be XML_SUSPENDED. For that + /* At this point, m_parsingStatus.parsing cannot be XML_SUSPENDED. For that * to happen, a parameter entity parsing handler must have * attempted to suspend the parser, which fails and raises an * error. The parser can be aborted, but can't be suspended. */ - if (ps_parsing == XML_FINISHED) + if (parser->m_parsingStatus.parsing == XML_FINISHED) return XML_ERROR_ABORTED; *nextPtr = next; /* stop scanning for text declaration - we found one */ - processor = entityValueProcessor; + parser->m_processor = entityValueProcessor; return entityValueProcessor(parser, next, end, nextPtr); } /* If we are at the end of the buffer, this would cause XmlPrologTok to @@ -4214,7 +4163,7 @@ entityValueInitProcessor(XML_Parser parser, then, when this routine is entered the next time, XmlPrologTok will return XML_TOK_INVALID, since the BOM is still in the buffer */ - else if (tok == XML_TOK_BOM && next == end && !ps_finalBuffer) { + else if (tok == XML_TOK_BOM && next == end && !parser->m_parsingStatus.finalBuffer) { *nextPtr = next; return XML_ERROR_NONE; } @@ -4227,7 +4176,7 @@ entityValueInitProcessor(XML_Parser parser, return XML_ERROR_SYNTAX; } start = next; - eventPtr = start; + parser->m_eventPtr = start; } } @@ -4240,9 +4189,9 @@ externalParEntProcessor(XML_Parser parser, const char *next = s; int tok; - tok = XmlPrologTok(encoding, s, end, &next); + tok = XmlPrologTok(parser->m_encoding, s, end, &next); if (tok <= 0) { - if (!ps_finalBuffer && tok != XML_TOK_INVALID) { + if (!parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) { *nextPtr = s; return XML_ERROR_NONE; } @@ -4264,12 +4213,12 @@ externalParEntProcessor(XML_Parser parser, */ else if (tok == XML_TOK_BOM) { s = next; - tok = XmlPrologTok(encoding, s, end, &next); + tok = XmlPrologTok(parser->m_encoding, s, end, &next); } - processor = prologProcessor; - return doProlog(parser, encoding, s, end, tok, next, - nextPtr, (XML_Bool)!ps_finalBuffer); + parser->m_processor = prologProcessor; + return doProlog(parser, parser->m_encoding, s, end, tok, next, + nextPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer); } static enum XML_Error PTRCALL @@ -4280,13 +4229,13 @@ entityValueProcessor(XML_Parser parser, { const char *start = s; const char *next = s; - const ENCODING *enc = encoding; + const ENCODING *enc = parser->m_encoding; int tok; for (;;) { tok = XmlPrologTok(enc, start, end, &next); if (tok <= 0) { - if (!ps_finalBuffer && tok != XML_TOK_INVALID) { + if (!parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) { *nextPtr = s; return XML_ERROR_NONE; } @@ -4317,9 +4266,9 @@ prologProcessor(XML_Parser parser, const char **nextPtr) { const char *next = s; - int tok = XmlPrologTok(encoding, s, end, &next); - return doProlog(parser, encoding, s, end, tok, next, - nextPtr, (XML_Bool)!ps_finalBuffer); + int tok = XmlPrologTok(parser->m_encoding, s, end, &next); + return doProlog(parser, parser->m_encoding, s, end, tok, next, + nextPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer); } static enum XML_Error @@ -4356,19 +4305,19 @@ doProlog(XML_Parser parser, static const XML_Char enumValueStart[] = { ASCII_LPAREN, '\0' }; /* save one level of indirection */ - DTD * const dtd = _dtd; + DTD * const dtd = parser->m_dtd; const char **eventPP; const char **eventEndPP; enum XML_Content_Quant quant; - if (enc == encoding) { - eventPP = &eventPtr; - eventEndPP = &eventEndPtr; + if (enc == parser->m_encoding) { + eventPP = &parser->m_eventPtr; + eventEndPP = &parser->m_eventEndPtr; } else { - eventPP = &(openInternalEntities->internalEventPtr); - eventEndPP = &(openInternalEntities->internalEventEndPtr); + eventPP = &(parser->m_openInternalEntities->internalEventPtr); + eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); } for (;;) { @@ -4395,7 +4344,7 @@ doProlog(XML_Parser parser, case XML_TOK_NONE: #ifdef XML_DTD /* for internal PE NOT referenced between declarations */ - if (enc != encoding && !openInternalEntities->betweenDecl) { + if (enc != parser->m_encoding && !parser->m_openInternalEntities->betweenDecl) { *nextPtr = s; return XML_ERROR_NONE; } @@ -4403,8 +4352,8 @@ doProlog(XML_Parser parser, complete markup, not only for external PEs, but also for internal PEs if the reference occurs between declarations. */ - if (isParamEntity || enc != encoding) { - if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc) + if (parser->m_isParamEntity || enc != parser->m_encoding) { + if (XmlTokenRole(&parser->m_prologState, XML_TOK_NONE, end, end, enc) == XML_ROLE_ERROR) return XML_ERROR_INCOMPLETE_PE; *nextPtr = s; @@ -4418,34 +4367,34 @@ doProlog(XML_Parser parser, break; } } - role = XmlTokenRole(&prologState, tok, s, next, enc); + role = XmlTokenRole(&parser->m_prologState, tok, s, next, enc); switch (role) { case XML_ROLE_XML_DECL: { enum XML_Error result = processXmlDecl(parser, 0, s, next); if (result != XML_ERROR_NONE) return result; - enc = encoding; + enc = parser->m_encoding; handleDefault = XML_FALSE; } break; case XML_ROLE_DOCTYPE_NAME: - if (startDoctypeDeclHandler) { - doctypeName = poolStoreString(&tempPool, enc, s, next); - if (!doctypeName) + if (parser->m_startDoctypeDeclHandler) { + parser->m_doctypeName = poolStoreString(&parser->m_tempPool, enc, s, next); + if (!parser->m_doctypeName) return XML_ERROR_NO_MEMORY; - poolFinish(&tempPool); - doctypePubid = NULL; + poolFinish(&parser->m_tempPool); + parser->m_doctypePubid = NULL; handleDefault = XML_FALSE; } - doctypeSysid = NULL; /* always initialize to NULL */ + parser->m_doctypeSysid = NULL; /* always initialize to NULL */ break; case XML_ROLE_DOCTYPE_INTERNAL_SUBSET: - if (startDoctypeDeclHandler) { - startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid, - doctypePubid, 1); - doctypeName = NULL; - poolClear(&tempPool); + if (parser->m_startDoctypeDeclHandler) { + parser->m_startDoctypeDeclHandler(parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid, + parser->m_doctypePubid, 1); + parser->m_doctypeName = NULL; + poolClear(&parser->m_tempPool); handleDefault = XML_FALSE; } break; @@ -4455,34 +4404,34 @@ doProlog(XML_Parser parser, enum XML_Error result = processXmlDecl(parser, 1, s, next); if (result != XML_ERROR_NONE) return result; - enc = encoding; + enc = parser->m_encoding; handleDefault = XML_FALSE; } break; #endif /* XML_DTD */ case XML_ROLE_DOCTYPE_PUBLIC_ID: #ifdef XML_DTD - useForeignDTD = XML_FALSE; - declEntity = (ENTITY *)lookup(parser, + parser->m_useForeignDTD = XML_FALSE; + parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities, externalSubsetName, sizeof(ENTITY)); - if (!declEntity) + if (!parser->m_declEntity) return XML_ERROR_NO_MEMORY; #endif /* XML_DTD */ dtd->hasParamEntityRefs = XML_TRUE; - if (startDoctypeDeclHandler) { + if (parser->m_startDoctypeDeclHandler) { XML_Char *pubId; if (!XmlIsPublicId(enc, s, next, eventPP)) return XML_ERROR_PUBLICID; - pubId = poolStoreString(&tempPool, enc, + pubId = poolStoreString(&parser->m_tempPool, enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar); if (!pubId) return XML_ERROR_NO_MEMORY; normalizePublicId(pubId); - poolFinish(&tempPool); - doctypePubid = pubId; + poolFinish(&parser->m_tempPool); + parser->m_doctypePubid = pubId; handleDefault = XML_FALSE; goto alreadyChecked; } @@ -4491,7 +4440,7 @@ doProlog(XML_Parser parser, if (!XmlIsPublicId(enc, s, next, eventPP)) return XML_ERROR_PUBLICID; alreadyChecked: - if (dtd->keepProcessing && declEntity) { + if (dtd->keepProcessing && parser->m_declEntity) { XML_Char *tem = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar, @@ -4499,28 +4448,31 @@ doProlog(XML_Parser parser, if (!tem) return XML_ERROR_NO_MEMORY; normalizePublicId(tem); - declEntity->publicId = tem; + parser->m_declEntity->publicId = tem; poolFinish(&dtd->pool); - if (entityDeclHandler) + /* Don't suppress the default handler if we fell through from + * the XML_ROLE_DOCTYPE_PUBLIC_ID case. + */ + if (parser->m_entityDeclHandler && role == XML_ROLE_ENTITY_PUBLIC_ID) handleDefault = XML_FALSE; } break; case XML_ROLE_DOCTYPE_CLOSE: - if (doctypeName) { - startDoctypeDeclHandler(handlerArg, doctypeName, - doctypeSysid, doctypePubid, 0); - poolClear(&tempPool); + if (parser->m_doctypeName) { + parser->m_startDoctypeDeclHandler(parser->m_handlerArg, parser->m_doctypeName, + parser->m_doctypeSysid, parser->m_doctypePubid, 0); + poolClear(&parser->m_tempPool); handleDefault = XML_FALSE; } - /* doctypeSysid will be non-NULL in the case of a previous - XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler + /* parser->m_doctypeSysid will be non-NULL in the case of a previous + XML_ROLE_DOCTYPE_SYSTEM_ID, even if parser->m_startDoctypeDeclHandler was not set, indicating an external subset */ #ifdef XML_DTD - if (doctypeSysid || useForeignDTD) { + if (parser->m_doctypeSysid || parser->m_useForeignDTD) { XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs; dtd->hasParamEntityRefs = XML_TRUE; - if (paramEntityParsing && externalEntityRefHandler) { + if (parser->m_paramEntityParsing && parser->m_externalEntityRefHandler) { ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities, externalSubsetName, @@ -4533,10 +4485,10 @@ doProlog(XML_Parser parser, */ return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */ } - if (useForeignDTD) - entity->base = curBase; + if (parser->m_useForeignDTD) + entity->base = parser->m_curBase; dtd->paramEntityRead = XML_FALSE; - if (!externalEntityRefHandler(externalEntityRefHandlerArg, + if (!parser->m_externalEntityRefHandler(parser->m_externalEntityRefHandlerArg, 0, entity->base, entity->systemId, @@ -4544,22 +4496,22 @@ doProlog(XML_Parser parser, return XML_ERROR_EXTERNAL_ENTITY_HANDLING; if (dtd->paramEntityRead) { if (!dtd->standalone && - notStandaloneHandler && - !notStandaloneHandler(handlerArg)) + parser->m_notStandaloneHandler && + !parser->m_notStandaloneHandler(parser->m_handlerArg)) return XML_ERROR_NOT_STANDALONE; } /* if we didn't read the foreign DTD then this means that there is no external subset and we must reset dtd->hasParamEntityRefs */ - else if (!doctypeSysid) + else if (!parser->m_doctypeSysid) dtd->hasParamEntityRefs = hadParamEntityRefs; /* end of DTD - no need to update dtd->keepProcessing */ } - useForeignDTD = XML_FALSE; + parser->m_useForeignDTD = XML_FALSE; } #endif /* XML_DTD */ - if (endDoctypeDeclHandler) { - endDoctypeDeclHandler(handlerArg); + if (parser->m_endDoctypeDeclHandler) { + parser->m_endDoctypeDeclHandler(parser->m_handlerArg); handleDefault = XML_FALSE; } break; @@ -4568,18 +4520,18 @@ doProlog(XML_Parser parser, /* if there is no DOCTYPE declaration then now is the last chance to read the foreign DTD */ - if (useForeignDTD) { + if (parser->m_useForeignDTD) { XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs; dtd->hasParamEntityRefs = XML_TRUE; - if (paramEntityParsing && externalEntityRefHandler) { + if (parser->m_paramEntityParsing && parser->m_externalEntityRefHandler) { ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities, externalSubsetName, sizeof(ENTITY)); if (!entity) return XML_ERROR_NO_MEMORY; - entity->base = curBase; + entity->base = parser->m_curBase; dtd->paramEntityRead = XML_FALSE; - if (!externalEntityRefHandler(externalEntityRefHandlerArg, + if (!parser->m_externalEntityRefHandler(parser->m_externalEntityRefHandlerArg, 0, entity->base, entity->systemId, @@ -4587,8 +4539,8 @@ doProlog(XML_Parser parser, return XML_ERROR_EXTERNAL_ENTITY_HANDLING; if (dtd->paramEntityRead) { if (!dtd->standalone && - notStandaloneHandler && - !notStandaloneHandler(handlerArg)) + parser->m_notStandaloneHandler && + !parser->m_notStandaloneHandler(parser->m_handlerArg)) return XML_ERROR_NOT_STANDALONE; } /* if we didn't read the foreign DTD then this means that there @@ -4600,55 +4552,55 @@ doProlog(XML_Parser parser, } } #endif /* XML_DTD */ - processor = contentProcessor; + parser->m_processor = contentProcessor; return contentProcessor(parser, s, end, nextPtr); case XML_ROLE_ATTLIST_ELEMENT_NAME: - declElementType = getElementType(parser, enc, s, next); - if (!declElementType) + parser->m_declElementType = getElementType(parser, enc, s, next); + if (!parser->m_declElementType) return XML_ERROR_NO_MEMORY; goto checkAttListDeclHandler; case XML_ROLE_ATTRIBUTE_NAME: - declAttributeId = getAttributeId(parser, enc, s, next); - if (!declAttributeId) + parser->m_declAttributeId = getAttributeId(parser, enc, s, next); + if (!parser->m_declAttributeId) return XML_ERROR_NO_MEMORY; - declAttributeIsCdata = XML_FALSE; - declAttributeType = NULL; - declAttributeIsId = XML_FALSE; + parser->m_declAttributeIsCdata = XML_FALSE; + parser->m_declAttributeType = NULL; + parser->m_declAttributeIsId = XML_FALSE; goto checkAttListDeclHandler; case XML_ROLE_ATTRIBUTE_TYPE_CDATA: - declAttributeIsCdata = XML_TRUE; - declAttributeType = atypeCDATA; + parser->m_declAttributeIsCdata = XML_TRUE; + parser->m_declAttributeType = atypeCDATA; goto checkAttListDeclHandler; case XML_ROLE_ATTRIBUTE_TYPE_ID: - declAttributeIsId = XML_TRUE; - declAttributeType = atypeID; + parser->m_declAttributeIsId = XML_TRUE; + parser->m_declAttributeType = atypeID; goto checkAttListDeclHandler; case XML_ROLE_ATTRIBUTE_TYPE_IDREF: - declAttributeType = atypeIDREF; + parser->m_declAttributeType = atypeIDREF; goto checkAttListDeclHandler; case XML_ROLE_ATTRIBUTE_TYPE_IDREFS: - declAttributeType = atypeIDREFS; + parser->m_declAttributeType = atypeIDREFS; goto checkAttListDeclHandler; case XML_ROLE_ATTRIBUTE_TYPE_ENTITY: - declAttributeType = atypeENTITY; + parser->m_declAttributeType = atypeENTITY; goto checkAttListDeclHandler; case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES: - declAttributeType = atypeENTITIES; + parser->m_declAttributeType = atypeENTITIES; goto checkAttListDeclHandler; case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN: - declAttributeType = atypeNMTOKEN; + parser->m_declAttributeType = atypeNMTOKEN; goto checkAttListDeclHandler; case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS: - declAttributeType = atypeNMTOKENS; + parser->m_declAttributeType = atypeNMTOKENS; checkAttListDeclHandler: - if (dtd->keepProcessing && attlistDeclHandler) + if (dtd->keepProcessing && parser->m_attlistDeclHandler) handleDefault = XML_FALSE; break; case XML_ROLE_ATTRIBUTE_ENUM_VALUE: case XML_ROLE_ATTRIBUTE_NOTATION_VALUE: - if (dtd->keepProcessing && attlistDeclHandler) { + if (dtd->keepProcessing && parser->m_attlistDeclHandler) { const XML_Char *prefix; - if (declAttributeType) { + if (parser->m_declAttributeType) { prefix = enumValueSep; } else { @@ -4656,37 +4608,37 @@ doProlog(XML_Parser parser, ? notationPrefix : enumValueStart); } - if (!poolAppendString(&tempPool, prefix)) + if (!poolAppendString(&parser->m_tempPool, prefix)) return XML_ERROR_NO_MEMORY; - if (!poolAppend(&tempPool, enc, s, next)) + if (!poolAppend(&parser->m_tempPool, enc, s, next)) return XML_ERROR_NO_MEMORY; - declAttributeType = tempPool.start; + parser->m_declAttributeType = parser->m_tempPool.start; handleDefault = XML_FALSE; } break; case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE: case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE: if (dtd->keepProcessing) { - if (!defineAttribute(declElementType, declAttributeId, - declAttributeIsCdata, declAttributeIsId, + if (!defineAttribute(parser->m_declElementType, parser->m_declAttributeId, + parser->m_declAttributeIsCdata, parser->m_declAttributeIsId, 0, parser)) return XML_ERROR_NO_MEMORY; - if (attlistDeclHandler && declAttributeType) { - if (*declAttributeType == XML_T(ASCII_LPAREN) - || (*declAttributeType == XML_T(ASCII_N) - && declAttributeType[1] == XML_T(ASCII_O))) { + if (parser->m_attlistDeclHandler && parser->m_declAttributeType) { + if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN) + || (*parser->m_declAttributeType == XML_T(ASCII_N) + && parser->m_declAttributeType[1] == XML_T(ASCII_O))) { /* Enumerated or Notation type */ - if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN)) - || !poolAppendChar(&tempPool, XML_T('\0'))) + if (!poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN)) + || !poolAppendChar(&parser->m_tempPool, XML_T('\0'))) return XML_ERROR_NO_MEMORY; - declAttributeType = tempPool.start; - poolFinish(&tempPool); + parser->m_declAttributeType = parser->m_tempPool.start; + poolFinish(&parser->m_tempPool); } *eventEndPP = s; - attlistDeclHandler(handlerArg, declElementType->name, - declAttributeId->name, declAttributeType, + parser->m_attlistDeclHandler(parser->m_handlerArg, parser->m_declElementType->name, + parser->m_declAttributeId->name, parser->m_declAttributeType, 0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE); - poolClear(&tempPool); + poolClear(&parser->m_tempPool); handleDefault = XML_FALSE; } } @@ -4696,7 +4648,7 @@ doProlog(XML_Parser parser, if (dtd->keepProcessing) { const XML_Char *attVal; enum XML_Error result = - storeAttributeValue(parser, enc, declAttributeIsCdata, + storeAttributeValue(parser, enc, parser->m_declAttributeIsCdata, s + enc->minBytesPerChar, next - enc->minBytesPerChar, &dtd->pool); @@ -4705,26 +4657,26 @@ doProlog(XML_Parser parser, attVal = poolStart(&dtd->pool); poolFinish(&dtd->pool); /* ID attributes aren't allowed to have a default */ - if (!defineAttribute(declElementType, declAttributeId, - declAttributeIsCdata, XML_FALSE, attVal, parser)) + if (!defineAttribute(parser->m_declElementType, parser->m_declAttributeId, + parser->m_declAttributeIsCdata, XML_FALSE, attVal, parser)) return XML_ERROR_NO_MEMORY; - if (attlistDeclHandler && declAttributeType) { - if (*declAttributeType == XML_T(ASCII_LPAREN) - || (*declAttributeType == XML_T(ASCII_N) - && declAttributeType[1] == XML_T(ASCII_O))) { + if (parser->m_attlistDeclHandler && parser->m_declAttributeType) { + if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN) + || (*parser->m_declAttributeType == XML_T(ASCII_N) + && parser->m_declAttributeType[1] == XML_T(ASCII_O))) { /* Enumerated or Notation type */ - if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN)) - || !poolAppendChar(&tempPool, XML_T('\0'))) + if (!poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN)) + || !poolAppendChar(&parser->m_tempPool, XML_T('\0'))) return XML_ERROR_NO_MEMORY; - declAttributeType = tempPool.start; - poolFinish(&tempPool); + parser->m_declAttributeType = parser->m_tempPool.start; + poolFinish(&parser->m_tempPool); } *eventEndPP = s; - attlistDeclHandler(handlerArg, declElementType->name, - declAttributeId->name, declAttributeType, + parser->m_attlistDeclHandler(parser->m_handlerArg, parser->m_declElementType->name, + parser->m_declAttributeId->name, parser->m_declAttributeType, attVal, role == XML_ROLE_FIXED_ATTRIBUTE_VALUE); - poolClear(&tempPool); + poolClear(&parser->m_tempPool); handleDefault = XML_FALSE; } } @@ -4734,18 +4686,18 @@ doProlog(XML_Parser parser, enum XML_Error result = storeEntityValue(parser, enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar); - if (declEntity) { - declEntity->textPtr = poolStart(&dtd->entityValuePool); - declEntity->textLen = (int)(poolLength(&dtd->entityValuePool)); + if (parser->m_declEntity) { + parser->m_declEntity->textPtr = poolStart(&dtd->entityValuePool); + parser->m_declEntity->textLen = (int)(poolLength(&dtd->entityValuePool)); poolFinish(&dtd->entityValuePool); - if (entityDeclHandler) { + if (parser->m_entityDeclHandler) { *eventEndPP = s; - entityDeclHandler(handlerArg, - declEntity->name, - declEntity->is_param, - declEntity->textPtr, - declEntity->textLen, - curBase, 0, 0, 0); + parser->m_entityDeclHandler(parser->m_handlerArg, + parser->m_declEntity->name, + parser->m_declEntity->is_param, + parser->m_declEntity->textPtr, + parser->m_declEntity->textLen, + parser->m_curBase, 0, 0, 0); handleDefault = XML_FALSE; } } @@ -4757,97 +4709,100 @@ doProlog(XML_Parser parser, break; case XML_ROLE_DOCTYPE_SYSTEM_ID: #ifdef XML_DTD - useForeignDTD = XML_FALSE; + parser->m_useForeignDTD = XML_FALSE; #endif /* XML_DTD */ dtd->hasParamEntityRefs = XML_TRUE; - if (startDoctypeDeclHandler) { - doctypeSysid = poolStoreString(&tempPool, enc, + if (parser->m_startDoctypeDeclHandler) { + parser->m_doctypeSysid = poolStoreString(&parser->m_tempPool, enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar); - if (doctypeSysid == NULL) + if (parser->m_doctypeSysid == NULL) return XML_ERROR_NO_MEMORY; - poolFinish(&tempPool); + poolFinish(&parser->m_tempPool); handleDefault = XML_FALSE; } #ifdef XML_DTD else - /* use externalSubsetName to make doctypeSysid non-NULL - for the case where no startDoctypeDeclHandler is set */ - doctypeSysid = externalSubsetName; + /* use externalSubsetName to make parser->m_doctypeSysid non-NULL + for the case where no parser->m_startDoctypeDeclHandler is set */ + parser->m_doctypeSysid = externalSubsetName; #endif /* XML_DTD */ if (!dtd->standalone #ifdef XML_DTD - && !paramEntityParsing + && !parser->m_paramEntityParsing #endif /* XML_DTD */ - && notStandaloneHandler - && !notStandaloneHandler(handlerArg)) + && parser->m_notStandaloneHandler + && !parser->m_notStandaloneHandler(parser->m_handlerArg)) return XML_ERROR_NOT_STANDALONE; #ifndef XML_DTD break; #else /* XML_DTD */ - if (!declEntity) { - declEntity = (ENTITY *)lookup(parser, + if (!parser->m_declEntity) { + parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities, externalSubsetName, sizeof(ENTITY)); - if (!declEntity) + if (!parser->m_declEntity) return XML_ERROR_NO_MEMORY; - declEntity->publicId = NULL; + parser->m_declEntity->publicId = NULL; } /* fall through */ #endif /* XML_DTD */ case XML_ROLE_ENTITY_SYSTEM_ID: - if (dtd->keepProcessing && declEntity) { - declEntity->systemId = poolStoreString(&dtd->pool, enc, + if (dtd->keepProcessing && parser->m_declEntity) { + parser->m_declEntity->systemId = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar); - if (!declEntity->systemId) + if (!parser->m_declEntity->systemId) return XML_ERROR_NO_MEMORY; - declEntity->base = curBase; + parser->m_declEntity->base = parser->m_curBase; poolFinish(&dtd->pool); - if (entityDeclHandler) + /* Don't suppress the default handler if we fell through from + * the XML_ROLE_DOCTYPE_SYSTEM_ID case. + */ + if (parser->m_entityDeclHandler && role == XML_ROLE_ENTITY_SYSTEM_ID) handleDefault = XML_FALSE; } break; case XML_ROLE_ENTITY_COMPLETE: - if (dtd->keepProcessing && declEntity && entityDeclHandler) { + if (dtd->keepProcessing && parser->m_declEntity && parser->m_entityDeclHandler) { *eventEndPP = s; - entityDeclHandler(handlerArg, - declEntity->name, - declEntity->is_param, + parser->m_entityDeclHandler(parser->m_handlerArg, + parser->m_declEntity->name, + parser->m_declEntity->is_param, 0,0, - declEntity->base, - declEntity->systemId, - declEntity->publicId, + parser->m_declEntity->base, + parser->m_declEntity->systemId, + parser->m_declEntity->publicId, 0); handleDefault = XML_FALSE; } break; case XML_ROLE_ENTITY_NOTATION_NAME: - if (dtd->keepProcessing && declEntity) { - declEntity->notation = poolStoreString(&dtd->pool, enc, s, next); - if (!declEntity->notation) + if (dtd->keepProcessing && parser->m_declEntity) { + parser->m_declEntity->notation = poolStoreString(&dtd->pool, enc, s, next); + if (!parser->m_declEntity->notation) return XML_ERROR_NO_MEMORY; poolFinish(&dtd->pool); - if (unparsedEntityDeclHandler) { + if (parser->m_unparsedEntityDeclHandler) { *eventEndPP = s; - unparsedEntityDeclHandler(handlerArg, - declEntity->name, - declEntity->base, - declEntity->systemId, - declEntity->publicId, - declEntity->notation); + parser->m_unparsedEntityDeclHandler(parser->m_handlerArg, + parser->m_declEntity->name, + parser->m_declEntity->base, + parser->m_declEntity->systemId, + parser->m_declEntity->publicId, + parser->m_declEntity->notation); handleDefault = XML_FALSE; } - else if (entityDeclHandler) { + else if (parser->m_entityDeclHandler) { *eventEndPP = s; - entityDeclHandler(handlerArg, - declEntity->name, + parser->m_entityDeclHandler(parser->m_handlerArg, + parser->m_declEntity->name, 0,0,0, - declEntity->base, - declEntity->systemId, - declEntity->publicId, - declEntity->notation); + parser->m_declEntity->base, + parser->m_declEntity->systemId, + parser->m_declEntity->publicId, + parser->m_declEntity->notation); handleDefault = XML_FALSE; } } @@ -4855,36 +4810,36 @@ doProlog(XML_Parser parser, case XML_ROLE_GENERAL_ENTITY_NAME: { if (XmlPredefinedEntityName(enc, s, next)) { - declEntity = NULL; + parser->m_declEntity = NULL; break; } if (dtd->keepProcessing) { const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next); if (!name) return XML_ERROR_NO_MEMORY; - declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, + parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, sizeof(ENTITY)); - if (!declEntity) + if (!parser->m_declEntity) return XML_ERROR_NO_MEMORY; - if (declEntity->name != name) { + if (parser->m_declEntity->name != name) { poolDiscard(&dtd->pool); - declEntity = NULL; + parser->m_declEntity = NULL; } else { poolFinish(&dtd->pool); - declEntity->publicId = NULL; - declEntity->is_param = XML_FALSE; + parser->m_declEntity->publicId = NULL; + parser->m_declEntity->is_param = XML_FALSE; /* if we have a parent parser or are reading an internal parameter entity, then the entity declaration is not considered "internal" */ - declEntity->is_internal = !(parentParser || openInternalEntities); - if (entityDeclHandler) + parser->m_declEntity->is_internal = !(parser->m_parentParser || parser->m_openInternalEntities); + if (parser->m_entityDeclHandler) handleDefault = XML_FALSE; } } else { poolDiscard(&dtd->pool); - declEntity = NULL; + parser->m_declEntity = NULL; } } break; @@ -4894,90 +4849,90 @@ doProlog(XML_Parser parser, const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next); if (!name) return XML_ERROR_NO_MEMORY; - declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities, + parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, sizeof(ENTITY)); - if (!declEntity) + if (!parser->m_declEntity) return XML_ERROR_NO_MEMORY; - if (declEntity->name != name) { + if (parser->m_declEntity->name != name) { poolDiscard(&dtd->pool); - declEntity = NULL; + parser->m_declEntity = NULL; } else { poolFinish(&dtd->pool); - declEntity->publicId = NULL; - declEntity->is_param = XML_TRUE; + parser->m_declEntity->publicId = NULL; + parser->m_declEntity->is_param = XML_TRUE; /* if we have a parent parser or are reading an internal parameter entity, then the entity declaration is not considered "internal" */ - declEntity->is_internal = !(parentParser || openInternalEntities); - if (entityDeclHandler) + parser->m_declEntity->is_internal = !(parser->m_parentParser || parser->m_openInternalEntities); + if (parser->m_entityDeclHandler) handleDefault = XML_FALSE; } } else { poolDiscard(&dtd->pool); - declEntity = NULL; + parser->m_declEntity = NULL; } #else /* not XML_DTD */ - declEntity = NULL; + parser->m_declEntity = NULL; #endif /* XML_DTD */ break; case XML_ROLE_NOTATION_NAME: - declNotationPublicId = NULL; - declNotationName = NULL; - if (notationDeclHandler) { - declNotationName = poolStoreString(&tempPool, enc, s, next); - if (!declNotationName) + parser->m_declNotationPublicId = NULL; + parser->m_declNotationName = NULL; + if (parser->m_notationDeclHandler) { + parser->m_declNotationName = poolStoreString(&parser->m_tempPool, enc, s, next); + if (!parser->m_declNotationName) return XML_ERROR_NO_MEMORY; - poolFinish(&tempPool); + poolFinish(&parser->m_tempPool); handleDefault = XML_FALSE; } break; case XML_ROLE_NOTATION_PUBLIC_ID: if (!XmlIsPublicId(enc, s, next, eventPP)) return XML_ERROR_PUBLICID; - if (declNotationName) { /* means notationDeclHandler != NULL */ - XML_Char *tem = poolStoreString(&tempPool, + if (parser->m_declNotationName) { /* means m_notationDeclHandler != NULL */ + XML_Char *tem = poolStoreString(&parser->m_tempPool, enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar); if (!tem) return XML_ERROR_NO_MEMORY; normalizePublicId(tem); - declNotationPublicId = tem; - poolFinish(&tempPool); + parser->m_declNotationPublicId = tem; + poolFinish(&parser->m_tempPool); handleDefault = XML_FALSE; } break; case XML_ROLE_NOTATION_SYSTEM_ID: - if (declNotationName && notationDeclHandler) { + if (parser->m_declNotationName && parser->m_notationDeclHandler) { const XML_Char *systemId - = poolStoreString(&tempPool, enc, + = poolStoreString(&parser->m_tempPool, enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar); if (!systemId) return XML_ERROR_NO_MEMORY; *eventEndPP = s; - notationDeclHandler(handlerArg, - declNotationName, - curBase, + parser->m_notationDeclHandler(parser->m_handlerArg, + parser->m_declNotationName, + parser->m_curBase, systemId, - declNotationPublicId); + parser->m_declNotationPublicId); handleDefault = XML_FALSE; } - poolClear(&tempPool); + poolClear(&parser->m_tempPool); break; case XML_ROLE_NOTATION_NO_SYSTEM_ID: - if (declNotationPublicId && notationDeclHandler) { + if (parser->m_declNotationPublicId && parser->m_notationDeclHandler) { *eventEndPP = s; - notationDeclHandler(handlerArg, - declNotationName, - curBase, + parser->m_notationDeclHandler(parser->m_handlerArg, + parser->m_declNotationName, + parser->m_curBase, 0, - declNotationPublicId); + parser->m_declNotationPublicId); handleDefault = XML_FALSE; } - poolClear(&tempPool); + poolClear(&parser->m_tempPool); break; case XML_ROLE_ERROR: switch (tok) { @@ -4994,45 +4949,45 @@ doProlog(XML_Parser parser, case XML_ROLE_IGNORE_SECT: { enum XML_Error result; - if (defaultHandler) + if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); handleDefault = XML_FALSE; result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore); if (result != XML_ERROR_NONE) return result; else if (!next) { - processor = ignoreSectionProcessor; + parser->m_processor = ignoreSectionProcessor; return result; } } break; #endif /* XML_DTD */ case XML_ROLE_GROUP_OPEN: - if (prologState.level >= groupSize) { - if (groupSize) { - char *temp = (char *)REALLOC(groupConnector, groupSize *= 2); + if (parser->m_prologState.level >= parser->m_groupSize) { + if (parser->m_groupSize) { + char *temp = (char *)REALLOC(parser, parser->m_groupConnector, parser->m_groupSize *= 2); if (temp == NULL) { - groupSize /= 2; + parser->m_groupSize /= 2; return XML_ERROR_NO_MEMORY; } - groupConnector = temp; + parser->m_groupConnector = temp; if (dtd->scaffIndex) { - int *temp = (int *)REALLOC(dtd->scaffIndex, - groupSize * sizeof(int)); + int *temp = (int *)REALLOC(parser, dtd->scaffIndex, + parser->m_groupSize * sizeof(int)); if (temp == NULL) return XML_ERROR_NO_MEMORY; dtd->scaffIndex = temp; } } else { - groupConnector = (char *)MALLOC(groupSize = 32); - if (!groupConnector) { - groupSize = 0; + parser->m_groupConnector = (char *)MALLOC(parser, parser->m_groupSize = 32); + if (!parser->m_groupConnector) { + parser->m_groupSize = 0; return XML_ERROR_NO_MEMORY; } } } - groupConnector[prologState.level] = 0; + parser->m_groupConnector[parser->m_prologState.level] = 0; if (dtd->in_eldecl) { int myindex = nextScaffoldPart(parser); if (myindex < 0) @@ -5040,37 +4995,37 @@ doProlog(XML_Parser parser, dtd->scaffIndex[dtd->scaffLevel] = myindex; dtd->scaffLevel++; dtd->scaffold[myindex].type = XML_CTYPE_SEQ; - if (elementDeclHandler) + if (parser->m_elementDeclHandler) handleDefault = XML_FALSE; } break; case XML_ROLE_GROUP_SEQUENCE: - if (groupConnector[prologState.level] == ASCII_PIPE) + if (parser->m_groupConnector[parser->m_prologState.level] == ASCII_PIPE) return XML_ERROR_SYNTAX; - groupConnector[prologState.level] = ASCII_COMMA; - if (dtd->in_eldecl && elementDeclHandler) + parser->m_groupConnector[parser->m_prologState.level] = ASCII_COMMA; + if (dtd->in_eldecl && parser->m_elementDeclHandler) handleDefault = XML_FALSE; break; case XML_ROLE_GROUP_CHOICE: - if (groupConnector[prologState.level] == ASCII_COMMA) + if (parser->m_groupConnector[parser->m_prologState.level] == ASCII_COMMA) return XML_ERROR_SYNTAX; if (dtd->in_eldecl - && !groupConnector[prologState.level] + && !parser->m_groupConnector[parser->m_prologState.level] && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type != XML_CTYPE_MIXED) ) { dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type = XML_CTYPE_CHOICE; - if (elementDeclHandler) + if (parser->m_elementDeclHandler) handleDefault = XML_FALSE; } - groupConnector[prologState.level] = ASCII_PIPE; + parser->m_groupConnector[parser->m_prologState.level] = ASCII_PIPE; break; case XML_ROLE_PARAM_ENTITY_REF: #ifdef XML_DTD case XML_ROLE_INNER_PARAM_ENTITY_REF: dtd->hasParamEntityRefs = XML_TRUE; - if (!paramEntityParsing) + if (!parser->m_paramEntityParsing) dtd->keepProcessing = dtd->standalone; else { const XML_Char *name; @@ -5086,9 +5041,9 @@ doProlog(XML_Parser parser, if yes, check that the entity exists, and that it is internal, otherwise call the skipped entity handler */ - if (prologState.documentEntity && + if (parser->m_prologState.documentEntity && (dtd->standalone - ? !openInternalEntities + ? !parser->m_openInternalEntities : !dtd->hasParamEntityRefs)) { if (!entity) return XML_ERROR_UNDEFINED_ENTITY; @@ -5119,8 +5074,8 @@ doProlog(XML_Parser parser, else if (!entity) { dtd->keepProcessing = dtd->standalone; /* cannot report skipped entities in declarations */ - if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) { - skippedEntityHandler(handlerArg, name, 1); + if ((role == XML_ROLE_PARAM_ENTITY_REF) && parser->m_skippedEntityHandler) { + parser->m_skippedEntityHandler(parser->m_handlerArg, name, 1); handleDefault = XML_FALSE; } break; @@ -5137,10 +5092,10 @@ doProlog(XML_Parser parser, handleDefault = XML_FALSE; break; } - if (externalEntityRefHandler) { + if (parser->m_externalEntityRefHandler) { dtd->paramEntityRead = XML_FALSE; entity->open = XML_TRUE; - if (!externalEntityRefHandler(externalEntityRefHandlerArg, + if (!parser->m_externalEntityRefHandler(parser->m_externalEntityRefHandlerArg, 0, entity->base, entity->systemId, @@ -5162,17 +5117,17 @@ doProlog(XML_Parser parser, } #endif /* XML_DTD */ if (!dtd->standalone && - notStandaloneHandler && - !notStandaloneHandler(handlerArg)) + parser->m_notStandaloneHandler && + !parser->m_notStandaloneHandler(parser->m_handlerArg)) return XML_ERROR_NOT_STANDALONE; break; /* Element declaration stuff */ case XML_ROLE_ELEMENT_NAME: - if (elementDeclHandler) { - declElementType = getElementType(parser, enc, s, next); - if (!declElementType) + if (parser->m_elementDeclHandler) { + parser->m_declElementType = getElementType(parser, enc, s, next); + if (!parser->m_declElementType) return XML_ERROR_NO_MEMORY; dtd->scaffLevel = 0; dtd->scaffCount = 0; @@ -5184,8 +5139,8 @@ doProlog(XML_Parser parser, case XML_ROLE_CONTENT_ANY: case XML_ROLE_CONTENT_EMPTY: if (dtd->in_eldecl) { - if (elementDeclHandler) { - XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content)); + if (parser->m_elementDeclHandler) { + XML_Content * content = (XML_Content *) MALLOC(parser, sizeof(XML_Content)); if (!content) return XML_ERROR_NO_MEMORY; content->quant = XML_CQUANT_NONE; @@ -5196,7 +5151,7 @@ doProlog(XML_Parser parser, XML_CTYPE_ANY : XML_CTYPE_EMPTY); *eventEndPP = s; - elementDeclHandler(handlerArg, declElementType->name, content); + parser->m_elementDeclHandler(parser->m_handlerArg, parser->m_declElementType->name, content); handleDefault = XML_FALSE; } dtd->in_eldecl = XML_FALSE; @@ -5207,7 +5162,7 @@ doProlog(XML_Parser parser, if (dtd->in_eldecl) { dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type = XML_CTYPE_MIXED; - if (elementDeclHandler) + if (parser->m_elementDeclHandler) handleDefault = XML_FALSE; } break; @@ -5244,7 +5199,7 @@ doProlog(XML_Parser parser, nameLen = 0; for (; name[nameLen++]; ); dtd->contentStringLen += nameLen; - if (elementDeclHandler) + if (parser->m_elementDeclHandler) handleDefault = XML_FALSE; } break; @@ -5262,7 +5217,7 @@ doProlog(XML_Parser parser, quant = XML_CQUANT_PLUS; closeGroup: if (dtd->in_eldecl) { - if (elementDeclHandler) + if (parser->m_elementDeclHandler) handleDefault = XML_FALSE; dtd->scaffLevel--; dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant; @@ -5272,7 +5227,7 @@ doProlog(XML_Parser parser, if (!model) return XML_ERROR_NO_MEMORY; *eventEndPP = s; - elementDeclHandler(handlerArg, declElementType->name, model); + parser->m_elementDeclHandler(parser->m_handlerArg, parser->m_declElementType->name, model); } dtd->in_eldecl = XML_FALSE; dtd->contentStringLen = 0; @@ -5299,31 +5254,31 @@ doProlog(XML_Parser parser, } break; case XML_ROLE_DOCTYPE_NONE: - if (startDoctypeDeclHandler) + if (parser->m_startDoctypeDeclHandler) handleDefault = XML_FALSE; break; case XML_ROLE_ENTITY_NONE: - if (dtd->keepProcessing && entityDeclHandler) + if (dtd->keepProcessing && parser->m_entityDeclHandler) handleDefault = XML_FALSE; break; case XML_ROLE_NOTATION_NONE: - if (notationDeclHandler) + if (parser->m_notationDeclHandler) handleDefault = XML_FALSE; break; case XML_ROLE_ATTLIST_NONE: - if (dtd->keepProcessing && attlistDeclHandler) + if (dtd->keepProcessing && parser->m_attlistDeclHandler) handleDefault = XML_FALSE; break; case XML_ROLE_ELEMENT_NONE: - if (elementDeclHandler) + if (parser->m_elementDeclHandler) handleDefault = XML_FALSE; break; } /* end of big switch */ - if (handleDefault && defaultHandler) + if (handleDefault && parser->m_defaultHandler) reportDefault(parser, enc, s, next); - switch (ps_parsing) { + switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: *nextPtr = next; return XML_ERROR_NONE; @@ -5343,18 +5298,18 @@ epilogProcessor(XML_Parser parser, const char *end, const char **nextPtr) { - processor = epilogProcessor; - eventPtr = s; + parser->m_processor = epilogProcessor; + parser->m_eventPtr = s; for (;;) { const char *next = NULL; - int tok = XmlPrologTok(encoding, s, end, &next); - eventEndPtr = next; + int tok = XmlPrologTok(parser->m_encoding, s, end, &next); + parser->m_eventEndPtr = next; switch (tok) { /* report partial linebreak - it might be the last token */ case -XML_TOK_PROLOG_S: - if (defaultHandler) { - reportDefault(parser, encoding, s, next); - if (ps_parsing == XML_FINISHED) + if (parser->m_defaultHandler) { + reportDefault(parser, parser->m_encoding, s, next); + if (parser->m_parsingStatus.parsing == XML_FINISHED) return XML_ERROR_ABORTED; } *nextPtr = next; @@ -5363,28 +5318,28 @@ epilogProcessor(XML_Parser parser, *nextPtr = s; return XML_ERROR_NONE; case XML_TOK_PROLOG_S: - if (defaultHandler) - reportDefault(parser, encoding, s, next); + if (parser->m_defaultHandler) + reportDefault(parser, parser->m_encoding, s, next); break; case XML_TOK_PI: - if (!reportProcessingInstruction(parser, encoding, s, next)) + if (!reportProcessingInstruction(parser, parser->m_encoding, s, next)) return XML_ERROR_NO_MEMORY; break; case XML_TOK_COMMENT: - if (!reportComment(parser, encoding, s, next)) + if (!reportComment(parser, parser->m_encoding, s, next)) return XML_ERROR_NO_MEMORY; break; case XML_TOK_INVALID: - eventPtr = next; + parser->m_eventPtr = next; return XML_ERROR_INVALID_TOKEN; case XML_TOK_PARTIAL: - if (!ps_finalBuffer) { + if (!parser->m_parsingStatus.finalBuffer) { *nextPtr = s; return XML_ERROR_NONE; } return XML_ERROR_UNCLOSED_TOKEN; case XML_TOK_PARTIAL_CHAR: - if (!ps_finalBuffer) { + if (!parser->m_parsingStatus.finalBuffer) { *nextPtr = s; return XML_ERROR_NONE; } @@ -5392,8 +5347,8 @@ epilogProcessor(XML_Parser parser, default: return XML_ERROR_JUNK_AFTER_DOC_ELEMENT; } - eventPtr = s = next; - switch (ps_parsing) { + parser->m_eventPtr = s = next; + switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: *nextPtr = next; return XML_ERROR_NONE; @@ -5413,21 +5368,21 @@ processInternalEntity(XML_Parser parser, ENTITY *entity, enum XML_Error result; OPEN_INTERNAL_ENTITY *openEntity; - if (freeInternalEntities) { - openEntity = freeInternalEntities; - freeInternalEntities = openEntity->next; + if (parser->m_freeInternalEntities) { + openEntity = parser->m_freeInternalEntities; + parser->m_freeInternalEntities = openEntity->next; } else { - openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(sizeof(OPEN_INTERNAL_ENTITY)); + openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(parser, sizeof(OPEN_INTERNAL_ENTITY)); if (!openEntity) return XML_ERROR_NO_MEMORY; } entity->open = XML_TRUE; entity->processed = 0; - openEntity->next = openInternalEntities; - openInternalEntities = openEntity; + openEntity->next = parser->m_openInternalEntities; + parser->m_openInternalEntities = openEntity; openEntity->entity = entity; - openEntity->startTagLevel = tagLevel; + openEntity->startTagLevel = parser->m_tagLevel; openEntity->betweenDecl = betweenDecl; openEntity->internalEventPtr = NULL; openEntity->internalEventEndPtr = NULL; @@ -5438,26 +5393,26 @@ processInternalEntity(XML_Parser parser, ENTITY *entity, #ifdef XML_DTD if (entity->is_param) { - int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next); - result = doProlog(parser, internalEncoding, textStart, textEnd, tok, + int tok = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next); + result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd, tok, next, &next, XML_FALSE); } else #endif /* XML_DTD */ - result = doContent(parser, tagLevel, internalEncoding, textStart, + result = doContent(parser, parser->m_tagLevel, parser->m_internalEncoding, textStart, textEnd, &next, XML_FALSE); if (result == XML_ERROR_NONE) { - if (textEnd != next && ps_parsing == XML_SUSPENDED) { + if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) { entity->processed = (int)(next - textStart); - processor = internalEntityProcessor; + parser->m_processor = internalEntityProcessor; } else { entity->open = XML_FALSE; - openInternalEntities = openEntity->next; + parser->m_openInternalEntities = openEntity->next; /* put openEntity back in list of free instances */ - openEntity->next = freeInternalEntities; - freeInternalEntities = openEntity; + openEntity->next = parser->m_freeInternalEntities; + parser->m_freeInternalEntities = openEntity; } } return result; @@ -5473,7 +5428,7 @@ internalEntityProcessor(XML_Parser parser, const char *textStart, *textEnd; const char *next; enum XML_Error result; - OPEN_INTERNAL_ENTITY *openEntity = openInternalEntities; + OPEN_INTERNAL_ENTITY *openEntity = parser->m_openInternalEntities; if (!openEntity) return XML_ERROR_UNEXPECTED_STATE; @@ -5485,44 +5440,44 @@ internalEntityProcessor(XML_Parser parser, #ifdef XML_DTD if (entity->is_param) { - int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next); - result = doProlog(parser, internalEncoding, textStart, textEnd, tok, + int tok = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next); + result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd, tok, next, &next, XML_FALSE); } else #endif /* XML_DTD */ - result = doContent(parser, openEntity->startTagLevel, internalEncoding, + result = doContent(parser, openEntity->startTagLevel, parser->m_internalEncoding, textStart, textEnd, &next, XML_FALSE); if (result != XML_ERROR_NONE) return result; - else if (textEnd != next && ps_parsing == XML_SUSPENDED) { + else if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) { entity->processed = (int)(next - (char *)entity->textPtr); return result; } else { entity->open = XML_FALSE; - openInternalEntities = openEntity->next; + parser->m_openInternalEntities = openEntity->next; /* put openEntity back in list of free instances */ - openEntity->next = freeInternalEntities; - freeInternalEntities = openEntity; + openEntity->next = parser->m_freeInternalEntities; + parser->m_freeInternalEntities = openEntity; } #ifdef XML_DTD if (entity->is_param) { int tok; - processor = prologProcessor; - tok = XmlPrologTok(encoding, s, end, &next); - return doProlog(parser, encoding, s, end, tok, next, nextPtr, - (XML_Bool)!ps_finalBuffer); + parser->m_processor = prologProcessor; + tok = XmlPrologTok(parser->m_encoding, s, end, &next); + return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr, + (XML_Bool)!parser->m_parsingStatus.finalBuffer); } else #endif /* XML_DTD */ { - processor = contentProcessor; + parser->m_processor = contentProcessor; /* see externalEntityContentProcessor vs contentProcessor */ - return doContent(parser, parentParser ? 1 : 0, encoding, s, end, - nextPtr, (XML_Bool)!ps_finalBuffer); + return doContent(parser, parser->m_parentParser ? 1 : 0, parser->m_encoding, s, end, + nextPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer); } } @@ -5532,7 +5487,7 @@ errorProcessor(XML_Parser parser, const char *UNUSED_P(end), const char **UNUSED_P(nextPtr)) { - return errorCode; + return parser->m_errorCode; } static enum XML_Error @@ -5556,7 +5511,7 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, const char *ptr, const char *end, STRING_POOL *pool) { - DTD * const dtd = _dtd; /* save one level of indirection */ + DTD * const dtd = parser->m_dtd; /* save one level of indirection */ for (;;) { const char *next; int tok = XmlAttributeValueTok(enc, ptr, end, &next); @@ -5564,12 +5519,12 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, case XML_TOK_NONE: return XML_ERROR_NONE; case XML_TOK_INVALID: - if (enc == encoding) - eventPtr = next; + if (enc == parser->m_encoding) + parser->m_eventPtr = next; return XML_ERROR_INVALID_TOKEN; case XML_TOK_PARTIAL: - if (enc == encoding) - eventPtr = ptr; + if (enc == parser->m_encoding) + parser->m_eventPtr = ptr; return XML_ERROR_INVALID_TOKEN; case XML_TOK_CHAR_REF: { @@ -5577,8 +5532,8 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, int i; int n = XmlCharRefNumber(enc, ptr); if (n < 0) { - if (enc == encoding) - eventPtr = ptr; + if (enc == parser->m_encoding) + parser->m_eventPtr = ptr; return XML_ERROR_BAD_CHAR_REF; } if (!isCdata @@ -5628,25 +5583,25 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, return XML_ERROR_NO_MEMORY; break; } - name = poolStoreString(&temp2Pool, enc, + name = poolStoreString(&parser->m_temp2Pool, enc, ptr + enc->minBytesPerChar, next - enc->minBytesPerChar); if (!name) return XML_ERROR_NO_MEMORY; entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0); - poolDiscard(&temp2Pool); + poolDiscard(&parser->m_temp2Pool); /* First, determine if a check for an existing declaration is needed; if yes, check that the entity exists, and that it is internal. */ if (pool == &dtd->pool) /* are we called from prolog? */ checkEntityDecl = #ifdef XML_DTD - prologState.documentEntity && + parser->m_prologState.documentEntity && #endif /* XML_DTD */ (dtd->standalone - ? !openInternalEntities + ? !parser->m_openInternalEntities : !dtd->hasParamEntityRefs); - else /* if (pool == &tempPool): we are called from content */ + else /* if (pool == &parser->m_tempPool): we are called from content */ checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone; if (checkEntityDecl) { if (!entity) @@ -5656,19 +5611,19 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, } else if (!entity) { /* Cannot report skipped entity here - see comments on - skippedEntityHandler. - if (skippedEntityHandler) - skippedEntityHandler(handlerArg, name, 0); + parser->m_skippedEntityHandler. + if (parser->m_skippedEntityHandler) + parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0); */ /* Cannot call the default handler because this would be out of sync with the call to the startElementHandler. - if ((pool == &tempPool) && defaultHandler) + if ((pool == &parser->m_tempPool) && parser->m_defaultHandler) reportDefault(parser, enc, ptr, next); */ break; } if (entity->open) { - if (enc == encoding) { + if (enc == parser->m_encoding) { /* It does not appear that this line can be executed. * * The "if (entity->open)" check catches recursive entity @@ -5686,25 +5641,25 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, * we keep the line and merely exclude it from coverage * tests. */ - eventPtr = ptr; /* LCOV_EXCL_LINE */ + parser->m_eventPtr = ptr; /* LCOV_EXCL_LINE */ } return XML_ERROR_RECURSIVE_ENTITY_REF; } if (entity->notation) { - if (enc == encoding) - eventPtr = ptr; + if (enc == parser->m_encoding) + parser->m_eventPtr = ptr; return XML_ERROR_BINARY_ENTITY_REF; } if (!entity->textPtr) { - if (enc == encoding) - eventPtr = ptr; + if (enc == parser->m_encoding) + parser->m_eventPtr = ptr; return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF; } else { enum XML_Error result; const XML_Char *textEnd = entity->textPtr + entity->textLen; entity->open = XML_TRUE; - result = appendAttributeValue(parser, internalEncoding, isCdata, + result = appendAttributeValue(parser, parser->m_internalEncoding, isCdata, (char *)entity->textPtr, (char *)textEnd, pool); entity->open = XML_FALSE; @@ -5725,8 +5680,8 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, * * LCOV_EXCL_START */ - if (enc == encoding) - eventPtr = ptr; + if (enc == parser->m_encoding) + parser->m_eventPtr = ptr; return XML_ERROR_UNEXPECTED_STATE; /* LCOV_EXCL_STOP */ } @@ -5741,12 +5696,12 @@ storeEntityValue(XML_Parser parser, const char *entityTextPtr, const char *entityTextEnd) { - DTD * const dtd = _dtd; /* save one level of indirection */ + DTD * const dtd = parser->m_dtd; /* save one level of indirection */ STRING_POOL *pool = &(dtd->entityValuePool); enum XML_Error result = XML_ERROR_NONE; #ifdef XML_DTD - int oldInEntityValue = prologState.inEntityValue; - prologState.inEntityValue = 1; + int oldInEntityValue = parser->m_prologState.inEntityValue; + parser->m_prologState.inEntityValue = 1; #endif /* XML_DTD */ /* never return Null for the value argument in EntityDeclHandler, since this would indicate an external entity; therefore we @@ -5762,10 +5717,10 @@ storeEntityValue(XML_Parser parser, switch (tok) { case XML_TOK_PARAM_ENTITY_REF: #ifdef XML_DTD - if (isParamEntity || enc != encoding) { + if (parser->m_isParamEntity || enc != parser->m_encoding) { const XML_Char *name; ENTITY *entity; - name = poolStoreString(&tempPool, enc, + name = poolStoreString(&parser->m_tempPool, enc, entityTextPtr + enc->minBytesPerChar, next - enc->minBytesPerChar); if (!name) { @@ -5773,28 +5728,28 @@ storeEntityValue(XML_Parser parser, goto endEntityValue; } entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0); - poolDiscard(&tempPool); + poolDiscard(&parser->m_tempPool); if (!entity) { /* not a well-formedness error - see XML 1.0: WFC Entity Declared */ /* cannot report skipped entity here - see comments on - skippedEntityHandler - if (skippedEntityHandler) - skippedEntityHandler(handlerArg, name, 0); + parser->m_skippedEntityHandler + if (parser->m_skippedEntityHandler) + parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0); */ dtd->keepProcessing = dtd->standalone; goto endEntityValue; } if (entity->open) { - if (enc == encoding) - eventPtr = entityTextPtr; + if (enc == parser->m_encoding) + parser->m_eventPtr = entityTextPtr; result = XML_ERROR_RECURSIVE_ENTITY_REF; goto endEntityValue; } if (entity->systemId) { - if (externalEntityRefHandler) { + if (parser->m_externalEntityRefHandler) { dtd->paramEntityRead = XML_FALSE; entity->open = XML_TRUE; - if (!externalEntityRefHandler(externalEntityRefHandlerArg, + if (!parser->m_externalEntityRefHandler(parser->m_externalEntityRefHandlerArg, 0, entity->base, entity->systemId, @@ -5813,7 +5768,7 @@ storeEntityValue(XML_Parser parser, else { entity->open = XML_TRUE; result = storeEntityValue(parser, - internalEncoding, + parser->m_internalEncoding, (char *)entity->textPtr, (char *)(entity->textPtr + entity->textLen)); @@ -5826,7 +5781,7 @@ storeEntityValue(XML_Parser parser, #endif /* XML_DTD */ /* In the internal subset, PE references are not legal within markup declarations, e.g entity values in this case. */ - eventPtr = entityTextPtr; + parser->m_eventPtr = entityTextPtr; result = XML_ERROR_PARAM_ENTITY_REF; goto endEntityValue; case XML_TOK_NONE: @@ -5855,8 +5810,8 @@ storeEntityValue(XML_Parser parser, int i; int n = XmlCharRefNumber(enc, entityTextPtr); if (n < 0) { - if (enc == encoding) - eventPtr = entityTextPtr; + if (enc == parser->m_encoding) + parser->m_eventPtr = entityTextPtr; result = XML_ERROR_BAD_CHAR_REF; goto endEntityValue; } @@ -5880,13 +5835,13 @@ storeEntityValue(XML_Parser parser, } break; case XML_TOK_PARTIAL: - if (enc == encoding) - eventPtr = entityTextPtr; + if (enc == parser->m_encoding) + parser->m_eventPtr = entityTextPtr; result = XML_ERROR_INVALID_TOKEN; goto endEntityValue; case XML_TOK_INVALID: - if (enc == encoding) - eventPtr = next; + if (enc == parser->m_encoding) + parser->m_eventPtr = next; result = XML_ERROR_INVALID_TOKEN; goto endEntityValue; default: @@ -5897,8 +5852,8 @@ storeEntityValue(XML_Parser parser, * * LCOV_EXCL_START */ - if (enc == encoding) - eventPtr = entityTextPtr; + if (enc == parser->m_encoding) + parser->m_eventPtr = entityTextPtr; result = XML_ERROR_UNEXPECTED_STATE; goto endEntityValue; /* LCOV_EXCL_STOP */ @@ -5907,7 +5862,7 @@ storeEntityValue(XML_Parser parser, } endEntityValue: #ifdef XML_DTD - prologState.inEntityValue = oldInEntityValue; + parser->m_prologState.inEntityValue = oldInEntityValue; #endif /* XML_DTD */ return result; } @@ -5942,25 +5897,25 @@ reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const XML_Char *target; XML_Char *data; const char *tem; - if (!processingInstructionHandler) { - if (defaultHandler) + if (!parser->m_processingInstructionHandler) { + if (parser->m_defaultHandler) reportDefault(parser, enc, start, end); return 1; } start += enc->minBytesPerChar * 2; tem = start + XmlNameLength(enc, start); - target = poolStoreString(&tempPool, enc, start, tem); + target = poolStoreString(&parser->m_tempPool, enc, start, tem); if (!target) return 0; - poolFinish(&tempPool); - data = poolStoreString(&tempPool, enc, + poolFinish(&parser->m_tempPool); + data = poolStoreString(&parser->m_tempPool, enc, XmlSkipS(enc, tem), end - enc->minBytesPerChar*2); if (!data) return 0; normalizeLines(data); - processingInstructionHandler(handlerArg, target, data); - poolClear(&tempPool); + parser->m_processingInstructionHandler(parser->m_handlerArg, target, data); + poolClear(&parser->m_tempPool); return 1; } @@ -5969,20 +5924,20 @@ reportComment(XML_Parser parser, const ENCODING *enc, const char *start, const char *end) { XML_Char *data; - if (!commentHandler) { - if (defaultHandler) + if (!parser->m_commentHandler) { + if (parser->m_defaultHandler) reportDefault(parser, enc, start, end); return 1; } - data = poolStoreString(&tempPool, + data = poolStoreString(&parser->m_tempPool, enc, start + enc->minBytesPerChar * 4, end - enc->minBytesPerChar * 3); if (!data) return 0; normalizeLines(data); - commentHandler(handlerArg, data); - poolClear(&tempPool); + parser->m_commentHandler(parser->m_handlerArg, data); + poolClear(&parser->m_tempPool); return 1; } @@ -5994,9 +5949,9 @@ reportDefault(XML_Parser parser, const ENCODING *enc, enum XML_Convert_Result convert_res; const char **eventPP; const char **eventEndPP; - if (enc == encoding) { - eventPP = &eventPtr; - eventEndPP = &eventEndPtr; + if (enc == parser->m_encoding) { + eventPP = &parser->m_eventPtr; + eventEndPP = &parser->m_eventEndPtr; } else { /* To get here, two things must be true; the parser must be @@ -6015,20 +5970,20 @@ reportDefault(XML_Parser parser, const ENCODING *enc, * * LCOV_EXCL_START */ - eventPP = &(openInternalEntities->internalEventPtr); - eventEndPP = &(openInternalEntities->internalEventEndPtr); + eventPP = &(parser->m_openInternalEntities->internalEventPtr); + eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); /* LCOV_EXCL_STOP */ } do { - ICHAR *dataPtr = (ICHAR *)dataBuf; - convert_res = XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd); + ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf; + convert_res = XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd); *eventEndPP = s; - defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf)); + parser->m_defaultHandler(parser->m_handlerArg, parser->m_dataBuf, (int)(dataPtr - (ICHAR *)parser->m_dataBuf)); *eventPP = s; } while ((convert_res != XML_CONVERT_COMPLETED) && (convert_res != XML_CONVERT_INPUT_INCOMPLETE)); } else - defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s)); + parser->m_defaultHandler(parser->m_handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s)); } @@ -6050,16 +6005,18 @@ defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata, if (type->nDefaultAtts == type->allocDefaultAtts) { if (type->allocDefaultAtts == 0) { type->allocDefaultAtts = 8; - type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts + type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(parser, type->allocDefaultAtts * sizeof(DEFAULT_ATTRIBUTE)); - if (!type->defaultAtts) + if (!type->defaultAtts) { + type->allocDefaultAtts = 0; return 0; + } } else { DEFAULT_ATTRIBUTE *temp; int count = type->allocDefaultAtts * 2; temp = (DEFAULT_ATTRIBUTE *) - REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE))); + REALLOC(parser, type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE))); if (temp == NULL) return 0; type->allocDefaultAtts = count; @@ -6079,7 +6036,7 @@ defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata, static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType) { - DTD * const dtd = _dtd; /* save one level of indirection */ + DTD * const dtd = parser->m_dtd; /* save one level of indirection */ const XML_Char *name; for (name = elementType->name; *name; name++) { if (*name == XML_T(ASCII_COLON)) { @@ -6110,7 +6067,7 @@ static ATTRIBUTE_ID * getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end) { - DTD * const dtd = _dtd; /* save one level of indirection */ + DTD * const dtd = parser->m_dtd; /* save one level of indirection */ ATTRIBUTE_ID *id; const XML_Char *name; if (!poolAppendChar(&dtd->pool, XML_T('\0'))) @@ -6127,7 +6084,7 @@ getAttributeId(XML_Parser parser, const ENCODING *enc, poolDiscard(&dtd->pool); else { poolFinish(&dtd->pool); - if (!ns) + if (!parser->m_ns) ; else if (name[0] == XML_T(ASCII_x) && name[1] == XML_T(ASCII_m) @@ -6174,20 +6131,20 @@ getAttributeId(XML_Parser parser, const ENCODING *enc, static const XML_Char * getContext(XML_Parser parser) { - DTD * const dtd = _dtd; /* save one level of indirection */ + DTD * const dtd = parser->m_dtd; /* save one level of indirection */ HASH_TABLE_ITER iter; XML_Bool needSep = XML_FALSE; if (dtd->defaultPrefix.binding) { int i; int len; - if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS))) + if (!poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS))) return NULL; len = dtd->defaultPrefix.binding->uriLen; - if (namespaceSeparator) + if (parser->m_namespaceSeparator) len--; for (i = 0; i < len; i++) { - if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i])) { + if (!poolAppendChar(&parser->m_tempPool, dtd->defaultPrefix.binding->uri[i])) { /* Because of memory caching, I don't believe this line can be * executed. * @@ -6230,18 +6187,18 @@ getContext(XML_Parser parser) */ continue; /* LCOV_EXCL_LINE */ } - if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP)) + if (needSep && !poolAppendChar(&parser->m_tempPool, CONTEXT_SEP)) return NULL; for (s = prefix->name; *s; s++) - if (!poolAppendChar(&tempPool, *s)) + if (!poolAppendChar(&parser->m_tempPool, *s)) return NULL; - if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS))) + if (!poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS))) return NULL; len = prefix->binding->uriLen; - if (namespaceSeparator) + if (parser->m_namespaceSeparator) len--; for (i = 0; i < len; i++) - if (!poolAppendChar(&tempPool, prefix->binding->uri[i])) + if (!poolAppendChar(&parser->m_tempPool, prefix->binding->uri[i])) return NULL; needSep = XML_TRUE; } @@ -6255,73 +6212,73 @@ getContext(XML_Parser parser) break; if (!e->open) continue; - if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP)) + if (needSep && !poolAppendChar(&parser->m_tempPool, CONTEXT_SEP)) return NULL; for (s = e->name; *s; s++) - if (!poolAppendChar(&tempPool, *s)) + if (!poolAppendChar(&parser->m_tempPool, *s)) return 0; needSep = XML_TRUE; } - if (!poolAppendChar(&tempPool, XML_T('\0'))) + if (!poolAppendChar(&parser->m_tempPool, XML_T('\0'))) return NULL; - return tempPool.start; + return parser->m_tempPool.start; } static XML_Bool setContext(XML_Parser parser, const XML_Char *context) { - DTD * const dtd = _dtd; /* save one level of indirection */ + DTD * const dtd = parser->m_dtd; /* save one level of indirection */ const XML_Char *s = context; while (*context != XML_T('\0')) { if (*s == CONTEXT_SEP || *s == XML_T('\0')) { ENTITY *e; - if (!poolAppendChar(&tempPool, XML_T('\0'))) + if (!poolAppendChar(&parser->m_tempPool, XML_T('\0'))) return XML_FALSE; - e = (ENTITY *)lookup(parser, &dtd->generalEntities, poolStart(&tempPool), 0); + e = (ENTITY *)lookup(parser, &dtd->generalEntities, poolStart(&parser->m_tempPool), 0); if (e) e->open = XML_TRUE; if (*s != XML_T('\0')) s++; context = s; - poolDiscard(&tempPool); + poolDiscard(&parser->m_tempPool); } else if (*s == XML_T(ASCII_EQUALS)) { PREFIX *prefix; - if (poolLength(&tempPool) == 0) + if (poolLength(&parser->m_tempPool) == 0) prefix = &dtd->defaultPrefix; else { - if (!poolAppendChar(&tempPool, XML_T('\0'))) + if (!poolAppendChar(&parser->m_tempPool, XML_T('\0'))) return XML_FALSE; - prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&tempPool), + prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&parser->m_tempPool), sizeof(PREFIX)); if (!prefix) return XML_FALSE; - if (prefix->name == poolStart(&tempPool)) { + if (prefix->name == poolStart(&parser->m_tempPool)) { prefix->name = poolCopyString(&dtd->pool, prefix->name); if (!prefix->name) return XML_FALSE; } - poolDiscard(&tempPool); + poolDiscard(&parser->m_tempPool); } for (context = s + 1; *context != CONTEXT_SEP && *context != XML_T('\0'); context++) - if (!poolAppendChar(&tempPool, *context)) + if (!poolAppendChar(&parser->m_tempPool, *context)) return XML_FALSE; - if (!poolAppendChar(&tempPool, XML_T('\0'))) + if (!poolAppendChar(&parser->m_tempPool, XML_T('\0'))) return XML_FALSE; - if (addBinding(parser, prefix, NULL, poolStart(&tempPool), - &inheritedBindings) != XML_ERROR_NONE) + if (addBinding(parser, prefix, NULL, poolStart(&parser->m_tempPool), + &parser->m_inheritedBindings) != XML_ERROR_NONE) return XML_FALSE; - poolDiscard(&tempPool); + poolDiscard(&parser->m_tempPool); if (*context != XML_T('\0')) ++context; s = context; } else { - if (!poolAppendChar(&tempPool, *s)) + if (!poolAppendChar(&parser->m_tempPool, *s)) return XML_FALSE; s++; } @@ -7006,8 +6963,8 @@ poolGrow(STRING_POOL *pool) int blockSize = (int)((unsigned)(pool->end - pool->start)*2U); size_t bytesToAllocate; - // NOTE: Needs to be calculated prior to calling `realloc` - // to avoid dangling pointers: + /* NOTE: Needs to be calculated prior to calling `realloc` + to avoid dangling pointers: */ const ptrdiff_t offsetInsideBlock = pool->ptr - pool->start; if (blockSize < 0) { @@ -7085,12 +7042,12 @@ poolGrow(STRING_POOL *pool) static int FASTCALL nextScaffoldPart(XML_Parser parser) { - DTD * const dtd = _dtd; /* save one level of indirection */ + DTD * const dtd = parser->m_dtd; /* save one level of indirection */ CONTENT_SCAFFOLD * me; int next; if (!dtd->scaffIndex) { - dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int)); + dtd->scaffIndex = (int *)MALLOC(parser, parser->m_groupSize * sizeof(int)); if (!dtd->scaffIndex) return -1; dtd->scaffIndex[0] = 0; @@ -7100,13 +7057,13 @@ nextScaffoldPart(XML_Parser parser) CONTENT_SCAFFOLD *temp; if (dtd->scaffold) { temp = (CONTENT_SCAFFOLD *) - REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD)); + REALLOC(parser, dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD)); if (temp == NULL) return -1; dtd->scaffSize *= 2; } else { - temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS + temp = (CONTENT_SCAFFOLD *)MALLOC(parser, INIT_SCAFFOLD_ELEMENTS * sizeof(CONTENT_SCAFFOLD)); if (temp == NULL) return -1; @@ -7137,7 +7094,7 @@ build_node(XML_Parser parser, XML_Content **contpos, XML_Char **strpos) { - DTD * const dtd = _dtd; /* save one level of indirection */ + DTD * const dtd = parser->m_dtd; /* save one level of indirection */ dest->type = dtd->scaffold[src_node].type; dest->quant = dtd->scaffold[src_node].quant; if (dest->type == XML_CTYPE_NAME) { @@ -7171,14 +7128,14 @@ build_node(XML_Parser parser, static XML_Content * build_model (XML_Parser parser) { - DTD * const dtd = _dtd; /* save one level of indirection */ + DTD * const dtd = parser->m_dtd; /* save one level of indirection */ XML_Content *ret; XML_Content *cpos; XML_Char * str; int allocsize = (dtd->scaffCount * sizeof(XML_Content) + (dtd->contentStringLen * sizeof(XML_Char))); - ret = (XML_Content *)MALLOC(allocsize); + ret = (XML_Content *)MALLOC(parser, allocsize); if (!ret) return NULL; @@ -7195,7 +7152,7 @@ getElementType(XML_Parser parser, const char *ptr, const char *end) { - DTD * const dtd = _dtd; /* save one level of indirection */ + DTD * const dtd = parser->m_dtd; /* save one level of indirection */ const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end); ELEMENT_TYPE *ret; diff --git a/Modules/expat/xmltok.c b/Modules/expat/xmltok.c index 007aed0640a2ef..6b415d83972ca6 100644 --- a/Modules/expat/xmltok.c +++ b/Modules/expat/xmltok.c @@ -31,8 +31,17 @@ */ #include <stddef.h> -#include <stdbool.h> -#include <string.h> // memcpy +#include <string.h> /* memcpy */ + +#if defined(_MSC_VER) && (_MSC_VER <= 1700) + /* for vs2012/11.0/1700 and earlier Visual Studio compilers */ +# define bool int +# define false 0 +# define true 1 +#else +# include <stdbool.h> +#endif + #ifdef _WIN32 #include "winconfig.h" @@ -57,7 +66,6 @@ { PREFIX(prologTok), PREFIX(contentTok), \ PREFIX(cdataSectionTok) IGNORE_SECTION_TOK_VTABLE }, \ { PREFIX(attributeValueTok), PREFIX(entityValueTok) }, \ - PREFIX(sameName), \ PREFIX(nameMatchesAscii), \ PREFIX(nameLength), \ PREFIX(skipS), \ @@ -354,7 +362,7 @@ enum { /* UTF8_cvalN is value of masked first byte of N byte sequence */ }; void -align_limit_to_full_utf8_characters(const char * from, const char ** fromLimRef) +_INTERNAL_trim_to_complete_utf8_characters(const char * from, const char ** fromLimRef) { const char * fromLim = *fromLimRef; size_t walked = 0; @@ -405,18 +413,22 @@ utf8_toUtf8(const ENCODING *UNUSED_P(enc), } /* Avoid copying partial characters (from incomplete input). */ - const char * const fromLimBefore = fromLim; - align_limit_to_full_utf8_characters(*fromP, &fromLim); - if (fromLim < fromLimBefore) { - input_incomplete = true; + { + const char * const fromLimBefore = fromLim; + _INTERNAL_trim_to_complete_utf8_characters(*fromP, &fromLim); + if (fromLim < fromLimBefore) { + input_incomplete = true; + } } - const ptrdiff_t bytesToCopy = fromLim - *fromP; - memcpy((void *)*toP, (const void *)*fromP, (size_t)bytesToCopy); - *fromP += bytesToCopy; - *toP += bytesToCopy; + { + const ptrdiff_t bytesToCopy = fromLim - *fromP; + memcpy(*toP, *fromP, bytesToCopy); + *fromP += bytesToCopy; + *toP += bytesToCopy; + } - if (output_exhausted) // needs to go first + if (output_exhausted) /* needs to go first */ return XML_CONVERT_OUTPUT_EXHAUSTED; else if (input_incomplete) return XML_CONVERT_INPUT_INCOMPLETE; @@ -1452,9 +1464,8 @@ unknown_toUtf8(const ENCODING *enc, return XML_CONVERT_OUTPUT_EXHAUSTED; (*fromP)++; } - do { - *(*toP)++ = *utf8++; - } while (--n != 0); + memcpy(*toP, utf8, n); + *toP += n; } } diff --git a/Modules/expat/xmltok.h b/Modules/expat/xmltok.h index 6d31879b331d83..50926f38ab323e 100644 --- a/Modules/expat/xmltok.h +++ b/Modules/expat/xmltok.h @@ -167,9 +167,6 @@ enum XML_Convert_Result { struct encoding { SCANNER scanners[XML_N_STATES]; SCANNER literalScanners[XML_N_LITERAL_TYPES]; - int (PTRCALL *sameName)(const ENCODING *, - const char *, - const char *); int (PTRCALL *nameMatchesAscii)(const ENCODING *, const char *, const char *, @@ -260,8 +257,6 @@ struct encoding { #define XmlEntityValueTok(enc, ptr, end, nextTokPtr) \ XmlLiteralTok(enc, XML_ENTITY_VALUE_LITERAL, ptr, end, nextTokPtr) -#define XmlSameName(enc, ptr1, ptr2) (((enc)->sameName)(enc, ptr1, ptr2)) - #define XmlNameMatchesAscii(enc, ptr1, end1, ptr2) \ (((enc)->nameMatchesAscii)(enc, ptr1, end1, ptr2)) diff --git a/Modules/expat/xmltok_impl.c b/Modules/expat/xmltok_impl.c index 2874bb343f0588..0403dd3d09a0b6 100644 --- a/Modules/expat/xmltok_impl.c +++ b/Modules/expat/xmltok_impl.c @@ -1653,79 +1653,6 @@ PREFIX(predefinedEntityName)(const ENCODING *UNUSED_P(enc), const char *ptr, return 0; } -/* This function does not appear to be called from anywhere within the - * library code. It is used via the macro XmlSameName(), which is - * defined but never used. Since it appears in the encoding function - * table, removing it is not a thing to be undertaken lightly. For - * the moment, we simply exclude it from coverage tests. - * - * LCOV_EXCL_START - */ -static int PTRCALL -PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2) -{ - for (;;) { - switch (BYTE_TYPE(enc, ptr1)) { -#define LEAD_CASE(n) \ - case BT_LEAD ## n: \ - if (*ptr1++ != *ptr2++) \ - return 0; - LEAD_CASE(4) LEAD_CASE(3) LEAD_CASE(2) -#undef LEAD_CASE - /* fall through */ - if (*ptr1++ != *ptr2++) - return 0; - break; - case BT_NONASCII: - case BT_NMSTRT: -#ifdef XML_NS - case BT_COLON: -#endif - case BT_HEX: - case BT_DIGIT: - case BT_NAME: - case BT_MINUS: - if (*ptr2++ != *ptr1++) - return 0; - if (MINBPC(enc) > 1) { - if (*ptr2++ != *ptr1++) - return 0; - if (MINBPC(enc) > 2) { - if (*ptr2++ != *ptr1++) - return 0; - if (MINBPC(enc) > 3) { - if (*ptr2++ != *ptr1++) - return 0; - } - } - } - break; - default: - if (MINBPC(enc) == 1 && *ptr1 == *ptr2) - return 1; - switch (BYTE_TYPE(enc, ptr2)) { - case BT_LEAD2: - case BT_LEAD3: - case BT_LEAD4: - case BT_NONASCII: - case BT_NMSTRT: -#ifdef XML_NS - case BT_COLON: -#endif - case BT_HEX: - case BT_DIGIT: - case BT_NAME: - case BT_MINUS: - return 0; - default: - return 1; - } - } - } - /* not reached */ -} -/* LCOV_EXCL_STOP */ - static int PTRCALL PREFIX(nameMatchesAscii)(const ENCODING *UNUSED_P(enc), const char *ptr1, const char *end1, const char *ptr2) @@ -1733,7 +1660,7 @@ PREFIX(nameMatchesAscii)(const ENCODING *UNUSED_P(enc), const char *ptr1, for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) { if (end1 - ptr1 < MINBPC(enc)) { /* This line cannot be executed. THe incoming data has already - * been tokenized once, so incomplete characters like this have + * been tokenized once, so imcomplete characters like this have * already been eliminated from the input. Retaining the * paranoia check is still valuable, however. */ diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c index f1da9f7a839fdb..2f9c2f675836b8 100644 --- a/Modules/faulthandler.c +++ b/Modules/faulthandler.c @@ -533,7 +533,7 @@ faulthandler_disable(void) } static PyObject* -faulthandler_disable_py(PyObject *self) +faulthandler_disable_py(PyObject *self, PyObject *Py_UNUSED(ignored)) { if (!fatal_error.enabled) { Py_RETURN_FALSE; @@ -543,7 +543,7 @@ faulthandler_disable_py(PyObject *self) } static PyObject* -faulthandler_is_enabled(PyObject *self) +faulthandler_is_enabled(PyObject *self, PyObject *Py_UNUSED(ignored)) { return PyBool_FromLong(fatal_error.enabled); } @@ -718,7 +718,8 @@ faulthandler_dump_traceback_later(PyObject *self, } static PyObject* -faulthandler_cancel_dump_traceback_later_py(PyObject *self) +faulthandler_cancel_dump_traceback_later_py(PyObject *self, + PyObject *Py_UNUSED(ignored)) { cancel_dump_traceback_later(); Py_RETURN_NONE; @@ -1116,7 +1117,7 @@ stack_overflow(uintptr_t min_sp, uintptr_t max_sp, size_t *depth) } static PyObject * -faulthandler_stack_overflow(PyObject *self) +faulthandler_stack_overflow(PyObject *self, PyObject *Py_UNUSED(ignored)) { size_t depth, size; uintptr_t sp = (uintptr_t)&depth; @@ -1177,9 +1178,9 @@ static PyMethodDef module_methods[] = { (PyCFunction)faulthandler_py_enable, METH_VARARGS|METH_KEYWORDS, PyDoc_STR("enable(file=sys.stderr, all_threads=True): " "enable the fault handler")}, - {"disable", (PyCFunction)faulthandler_disable_py, METH_NOARGS, + {"disable", faulthandler_disable_py, METH_NOARGS, PyDoc_STR("disable(): disable the fault handler")}, - {"is_enabled", (PyCFunction)faulthandler_is_enabled, METH_NOARGS, + {"is_enabled", faulthandler_is_enabled, METH_NOARGS, PyDoc_STR("is_enabled()->bool: check if the handler is enabled")}, {"dump_traceback", (PyCFunction)faulthandler_dump_traceback_py, METH_VARARGS|METH_KEYWORDS, @@ -1194,7 +1195,7 @@ static PyMethodDef module_methods[] = { "or each timeout seconds if repeat is True. If exit is True, " "call _exit(1) which is not safe.")}, {"cancel_dump_traceback_later", - (PyCFunction)faulthandler_cancel_dump_traceback_later_py, METH_NOARGS, + faulthandler_cancel_dump_traceback_later_py, METH_NOARGS, PyDoc_STR("cancel_dump_traceback_later():\ncancel the previous call " "to dump_traceback_later().")}, #endif @@ -1227,7 +1228,7 @@ static PyMethodDef module_methods[] = { {"_fatal_error", faulthandler_fatal_error_py, METH_VARARGS, PyDoc_STR("_fatal_error(message): call Py_FatalError(message)")}, #ifdef FAULTHANDLER_STACK_OVERFLOW - {"_stack_overflow", (PyCFunction)faulthandler_stack_overflow, METH_NOARGS, + {"_stack_overflow", faulthandler_stack_overflow, METH_NOARGS, PyDoc_STR("_stack_overflow(): recursive call to raise a stack overflow")}, #endif #ifdef MS_WINDOWS diff --git a/Modules/fcntlmodule.c b/Modules/fcntlmodule.c index 0baaa83d2acae5..77ddebf3ee0d22 100644 --- a/Modules/fcntlmodule.c +++ b/Modules/fcntlmodule.c @@ -430,7 +430,7 @@ static PyMethodDef fcntl_methods[] = { PyDoc_STRVAR(module_doc, -"This module performs file control and I/O control on file \n\ +"This module performs file control and I/O control on file\n\ descriptors. It is an interface to the fcntl() and ioctl() Unix\n\ routines. File descriptors can be obtained with the fileno() method of\n\ a file or socket object."); diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index 4d701cb72e8c5d..7d23fc22c81dd0 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -654,6 +654,7 @@ handle_legacy_finalizers(PyGC_Head *finalizers, PyGC_Head *old) { PyGC_Head *gc = finalizers->gc.gc_next; + assert(!PyErr_Occurred()); if (_PyRuntime.gc.garbage == NULL) { _PyRuntime.gc.garbage = PyList_New(0); if (_PyRuntime.gc.garbage == NULL) @@ -663,8 +664,10 @@ handle_legacy_finalizers(PyGC_Head *finalizers, PyGC_Head *old) PyObject *op = FROM_GC(gc); if ((_PyRuntime.gc.debug & DEBUG_SAVEALL) || has_legacy_finalizer(op)) { - if (PyList_Append(_PyRuntime.gc.garbage, op) < 0) + if (PyList_Append(_PyRuntime.gc.garbage, op) < 0) { + PyErr_Clear(); break; + } } } @@ -701,6 +704,7 @@ finalize_garbage(PyGC_Head *collectable) _PyGCHead_SET_FINALIZED(gc, 1); Py_INCREF(op); finalize(op); + assert(!PyErr_Occurred()); Py_DECREF(op); } } @@ -748,17 +752,26 @@ delete_garbage(PyGC_Head *collectable, PyGC_Head *old) { inquiry clear; + assert(!PyErr_Occurred()); while (!gc_list_is_empty(collectable)) { PyGC_Head *gc = collectable->gc.gc_next; PyObject *op = FROM_GC(gc); if (_PyRuntime.gc.debug & DEBUG_SAVEALL) { - PyList_Append(_PyRuntime.gc.garbage, op); + assert(_PyRuntime.gc.garbage != NULL); + if (PyList_Append(_PyRuntime.gc.garbage, op) < 0) { + PyErr_Clear(); + } } else { if ((clear = Py_TYPE(op)->tp_clear) != NULL) { Py_INCREF(op); - clear(op); + (void) clear(op); + if (PyErr_Occurred()) { + PySys_WriteStderr("Exception ignored in tp_clear of " + "%.50s\n", Py_TYPE(op)->tp_name); + PyErr_WriteUnraisable(NULL); + } Py_DECREF(op); } } @@ -974,6 +987,7 @@ collect(int generation, Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable, if (PyDTrace_GC_DONE_ENABLED()) PyDTrace_GC_DONE(n+m); + assert(!PyErr_Occurred()); return n+m; } @@ -987,11 +1001,12 @@ invoke_gc_callback(const char *phase, int generation, Py_ssize_t i; PyObject *info = NULL; + assert(!PyErr_Occurred()); /* we may get called very early */ if (_PyRuntime.gc.callbacks == NULL) return; /* The local variable cannot be rebound, check it for sanity */ - assert(_PyRuntime.gc.callbacks != NULL && PyList_CheckExact(_PyRuntime.gc.callbacks)); + assert(PyList_CheckExact(_PyRuntime.gc.callbacks)); if (PyList_GET_SIZE(_PyRuntime.gc.callbacks) != 0) { info = Py_BuildValue("{sisnsn}", "generation", generation, @@ -1015,6 +1030,7 @@ invoke_gc_callback(const char *phase, int generation, Py_DECREF(cb); } Py_XDECREF(info); + assert(!PyErr_Occurred()); } /* Perform garbage collection of a generation and invoke @@ -1024,9 +1040,11 @@ static Py_ssize_t collect_with_callback(int generation) { Py_ssize_t result, collected, uncollectable; + assert(!PyErr_Occurred()); invoke_gc_callback("start", generation, 0, 0); result = collect(generation, &collected, &uncollectable, 0); invoke_gc_callback("stop", generation, collected, uncollectable); + assert(!PyErr_Occurred()); return result; } @@ -1592,6 +1610,7 @@ _PyGC_CollectNoFail(void) { Py_ssize_t n; + assert(!PyErr_Occurred()); /* Ideally, this function is only called on interpreter shutdown, and therefore not recursively. Unfortunately, when there are daemon threads, a daemon thread can start a cyclic garbage collection diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index 1113fb6b76c03d..8a36755bfa7265 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -138,7 +138,7 @@ groupby_next(groupbyobject *gbo) } static PyObject * -groupby_reduce(groupbyobject *lz) +groupby_reduce(groupbyobject *lz, PyObject *Py_UNUSED(ignored)) { /* reduce as a 'new' call with an optional 'setstate' if groupby * has started @@ -320,7 +320,7 @@ _grouper_next(_grouperobject *igo) } static PyObject * -_grouper_reduce(_grouperobject *lz) +_grouper_reduce(_grouperobject *lz, PyObject *Py_UNUSED(ignored)) { if (((groupbyobject *)lz->parent)->currgrouper != lz) { return Py_BuildValue("N(())", _PyObject_GetBuiltin("iter")); @@ -504,7 +504,7 @@ teedataobject_dealloc(teedataobject *tdo) } static PyObject * -teedataobject_reduce(teedataobject *tdo) +teedataobject_reduce(teedataobject *tdo, PyObject *Py_UNUSED(ignored)) { int i; /* create a temporary list of already iterated values */ @@ -649,7 +649,7 @@ tee_traverse(teeobject *to, visitproc visit, void *arg) } static PyObject * -tee_copy(teeobject *to) +tee_copy(teeobject *to, PyObject *Py_UNUSED(ignored)) { teeobject *newto; @@ -676,7 +676,7 @@ tee_fromiterable(PyObject *iterable) if (it == NULL) return NULL; if (PyObject_TypeCheck(it, &tee_type)) { - to = (teeobject *)tee_copy((teeobject *)it); + to = (teeobject *)tee_copy((teeobject *)it, NULL); goto done; } @@ -726,7 +726,7 @@ tee_dealloc(teeobject *to) } static PyObject * -tee_reduce(teeobject *to) +tee_reduce(teeobject *to, PyObject *Py_UNUSED(ignored)) { return Py_BuildValue("O(())(Oi)", Py_TYPE(to), to->dataobj, to->index); } @@ -973,7 +973,7 @@ cycle_next(cycleobject *lz) } static PyObject * -cycle_reduce(cycleobject *lz) +cycle_reduce(cycleobject *lz, PyObject *Py_UNUSED(ignored)) { /* Create a new cycle with the iterator tuple, then set the saved state */ if (lz->it == NULL) { @@ -1168,7 +1168,7 @@ dropwhile_next(dropwhileobject *lz) } static PyObject * -dropwhile_reduce(dropwhileobject *lz) +dropwhile_reduce(dropwhileobject *lz, PyObject *Py_UNUSED(ignored)) { return Py_BuildValue("O(OO)l", Py_TYPE(lz), lz->func, lz->it, lz->start); } @@ -1332,7 +1332,7 @@ takewhile_next(takewhileobject *lz) } static PyObject * -takewhile_reduce(takewhileobject *lz) +takewhile_reduce(takewhileobject *lz, PyObject *Py_UNUSED(ignored)) { return Py_BuildValue("O(OO)l", Py_TYPE(lz), lz->func, lz->it, lz->stop); } @@ -1358,7 +1358,7 @@ static PyMethodDef takewhile_reduce_methods[] = { PyDoc_STRVAR(takewhile_doc, "takewhile(predicate, iterable) --> takewhile object\n\ \n\ -Return successive entries from an iterable as long as the \n\ +Return successive entries from an iterable as long as the\n\ predicate evaluates to true for each entry."); static PyTypeObject takewhile_type = { @@ -1558,7 +1558,7 @@ islice_next(isliceobject *lz) } static PyObject * -islice_reduce(isliceobject *lz) +islice_reduce(isliceobject *lz, PyObject *Py_UNUSED(ignored)) { /* When unpickled, generate a new object with the same bounds, * then 'setstate' with the next and count @@ -1616,7 +1616,7 @@ islice(iterable, start, stop[, step]) --> islice object\n\ Return an iterator whose next() method returns selected values from an\n\ iterable. If start is specified, will skip all preceding elements;\n\ otherwise, start defaults to zero. Step defaults to one. If\n\ -specified as another value, step determines how many values are \n\ +specified as another value, step determines how many values are\n\ skipped between successive calls. Works like a slice() on a list\n\ but returns an iterator."); @@ -1746,7 +1746,7 @@ starmap_next(starmapobject *lz) } static PyObject * -starmap_reduce(starmapobject *lz) +starmap_reduce(starmapobject *lz, PyObject *Py_UNUSED(ignored)) { /* Just pickle the iterator */ return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->func, lz->it); @@ -1918,7 +1918,7 @@ chain_next(chainobject *lz) } static PyObject * -chain_reduce(chainobject *lz) +chain_reduce(chainobject *lz, PyObject *Py_UNUSED(ignored)) { if (lz->source) { /* we can't pickle function objects (itertools.from_iterable) so @@ -2242,7 +2242,7 @@ product_next(productobject *lz) } static PyObject * -product_reduce(productobject *lz) +product_reduce(productobject *lz, PyObject *Py_UNUSED(ignored)) { if (lz->stopped) { return Py_BuildValue("O(())", Py_TYPE(lz)); @@ -2569,7 +2569,7 @@ combinations_next(combinationsobject *co) } static PyObject * -combinations_reduce(combinationsobject *lz) +combinations_reduce(combinationsobject *lz, PyObject *Py_UNUSED(ignored)) { if (lz->result == NULL) { return Py_BuildValue("O(On)", Py_TYPE(lz), lz->pool, lz->r); @@ -2903,7 +2903,7 @@ cwr_next(cwrobject *co) } static PyObject * -cwr_reduce(cwrobject *lz) +cwr_reduce(cwrobject *lz, PyObject *Py_UNUSED(ignored)) { if (lz->result == NULL) { return Py_BuildValue("O(On)", Py_TYPE(lz), lz->pool, lz->r); @@ -3262,7 +3262,7 @@ permutations_next(permutationsobject *po) } static PyObject * -permutations_reduce(permutationsobject *po) +permutations_reduce(permutationsobject *po, PyObject *Py_UNUSED(ignored)) { if (po->result == NULL) { return Py_BuildValue("O(On)", Py_TYPE(po), po->pool, po->r); @@ -3514,7 +3514,7 @@ accumulate_next(accumulateobject *lz) } static PyObject * -accumulate_reduce(accumulateobject *lz) +accumulate_reduce(accumulateobject *lz, PyObject *Py_UNUSED(ignored)) { if (lz->total == Py_None) { PyObject *it; @@ -3707,7 +3707,7 @@ compress_next(compressobject *lz) } static PyObject * -compress_reduce(compressobject *lz) +compress_reduce(compressobject *lz, PyObject *Py_UNUSED(ignored)) { return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->data, lz->selectors); @@ -3865,7 +3865,7 @@ filterfalse_next(filterfalseobject *lz) } static PyObject * -filterfalse_reduce(filterfalseobject *lz) +filterfalse_reduce(filterfalseobject *lz, PyObject *Py_UNUSED(ignored)) { return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->func, lz->it); } @@ -4108,7 +4108,7 @@ count_repr(countobject *lz) } static PyObject * -count_reduce(countobject *lz) +count_reduce(countobject *lz, PyObject *Py_UNUSED(ignored)) { if (lz->cnt == PY_SSIZE_T_MAX) return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->long_cnt, lz->long_step); @@ -4253,7 +4253,7 @@ repeat_repr(repeatobject *ro) } static PyObject * -repeat_len(repeatobject *ro) +repeat_len(repeatobject *ro, PyObject *Py_UNUSED(ignored)) { if (ro->cnt == -1) { PyErr_SetString(PyExc_TypeError, "len() of unsized object"); @@ -4265,7 +4265,7 @@ repeat_len(repeatobject *ro) PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); static PyObject * -repeat_reduce(repeatobject *ro) +repeat_reduce(repeatobject *ro, PyObject *Py_UNUSED(ignored)) { /* unpickle this so that a new repeat iterator is constructed with an * object, then call __setstate__ on it to set cnt @@ -4504,7 +4504,7 @@ zip_longest_next(ziplongestobject *lz) } static PyObject * -zip_longest_reduce(ziplongestobject *lz) +zip_longest_reduce(ziplongestobject *lz, PyObject *Py_UNUSED(ignored)) { /* Create a new tuple with empty sequences where appropriate to pickle. @@ -4613,8 +4613,8 @@ repeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times\n\ \n\ Iterators terminating on the shortest input sequence:\n\ accumulate(p[, func]) --> p0, p0+p1, p0+p1+p2\n\ -chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ... \n\ -chain.from_iterable([p, q, ...]) --> p0, p1, ... plast, q0, q1, ... \n\ +chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ...\n\ +chain.from_iterable([p, q, ...]) --> p0, p1, ... plast, q0, q1, ...\n\ compress(data, selectors) --> (d[0] if s[0]), (d[1] if s[1]), ...\n\ dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails\n\ groupby(iterable[, keyfunc]) --> sub-iterators grouped by value of keyfunc(v)\n\ @@ -4624,7 +4624,7 @@ islice(seq, [start,] stop [, step]) --> elements from\n\ starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ...\n\ tee(it, n=2) --> (it1, it2 , ... itn) splits one iterator into n\n\ takewhile(pred, seq) --> seq[0], seq[1], until pred fails\n\ -zip_longest(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ... \n\ +zip_longest(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ...\n\ \n\ Combinatoric generators:\n\ product(p, q, ... [repeat=1]) --> cartesian product\n\ diff --git a/Modules/main.c b/Modules/main.c index 286ad418fe13a5..6067d5eccffdef 100644 --- a/Modules/main.c +++ b/Modules/main.c @@ -144,7 +144,8 @@ static const char usage_6[] = "PYTHONCOERCECLOCALE: if this variable is set to 0, it disables the locale\n" " coercion behavior. Use PYTHONCOERCECLOCALE=warn to request display of\n" " locale coercion and locale compatibility warnings on stderr.\n" -"PYTHONDEVMODE: enable the development mode.\n"; +"PYTHONDEVMODE: enable the development mode.\n" +"PYTHONPYCACHEPREFIX: root directory for bytecode cache (pyc) files.\n"; static void pymain_usage(int error, const wchar_t* program) @@ -1675,6 +1676,37 @@ pymain_init_tracemalloc(_PyCoreConfig *config) } +static _PyInitError +pymain_init_pycache_prefix(_PyCoreConfig *config) +{ + wchar_t *env; + + int res = config_get_env_var_dup( + &env, L"PYTHONPYCACHEPREFIX", "PYTHONPYCACHEPREFIX"); + if (res < 0) { + return DECODE_LOCALE_ERR("PYTHONPYCACHEPREFIX", res); + } else if (env) { + config->pycache_prefix = env; + } + + const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix"); + if (xoption) { + const wchar_t *sep = wcschr(xoption, L'='); + if (sep && wcslen(sep) > 1) { + config->pycache_prefix = _PyMem_RawWcsdup(sep + 1); + if (config->pycache_prefix == NULL) { + return _Py_INIT_NO_MEMORY(); + } + } else { + // -X pycache_prefix= can cancel the env var + config->pycache_prefix = NULL; + } + } + + return _Py_INIT_OK(); +} + + static void get_env_flag(int *flag, const char *name) { @@ -1868,6 +1900,12 @@ config_read_complex_options(_PyCoreConfig *config) if (_Py_INIT_FAILED(err)) { return err; } + + err = pymain_init_pycache_prefix(config); + if (_Py_INIT_FAILED(err)) { + return err; + } + return _Py_INIT_OK(); } @@ -2015,6 +2053,7 @@ pymain_read_conf(_PyMain *pymain, _Py_CommandLineDetails *cmdline) Py_IgnoreEnvironmentFlag = init_ignore_env; _PyCoreConfig_Clear(&pymain->config); pymain_clear_cmdline(pymain, cmdline); + memset(cmdline, 0, sizeof(*cmdline)); pymain_get_global_config(pymain, cmdline); /* The encoding changed: read again the configuration @@ -2237,6 +2276,7 @@ _PyCoreConfig_Clear(_PyCoreConfig *config) LIST = NULL; \ } while (0) + CLEAR(config->pycache_prefix); CLEAR(config->module_search_path_env); CLEAR(config->home); CLEAR(config->program_name); @@ -2301,6 +2341,7 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2) COPY_ATTR(malloc_stats); COPY_ATTR(utf8_mode); + COPY_STR_ATTR(pycache_prefix); COPY_STR_ATTR(module_search_path_env); COPY_STR_ATTR(home); COPY_STR_ATTR(program_name); @@ -2336,6 +2377,7 @@ _PyMainInterpreterConfig_Clear(_PyMainInterpreterConfig *config) Py_CLEAR(config->warnoptions); Py_CLEAR(config->xoptions); Py_CLEAR(config->module_search_path); + Py_CLEAR(config->pycache_prefix); } @@ -2388,6 +2430,7 @@ _PyMainInterpreterConfig_Copy(_PyMainInterpreterConfig *config, COPY_ATTR(warnoptions); COPY_ATTR(xoptions); COPY_ATTR(module_search_path); + COPY_ATTR(pycache_prefix); #undef COPY_ATTR return 0; } @@ -2445,6 +2488,13 @@ _PyMainInterpreterConfig_Read(_PyMainInterpreterConfig *main_config, COPY_WSTRLIST(main_config->module_search_path, config->nmodule_search_path, config->module_search_paths); + + if (config->pycache_prefix != NULL) { + COPY_WSTR(pycache_prefix); + } else { + main_config->pycache_prefix = NULL; + } + } return _Py_INIT_OK(); diff --git a/Modules/nismodule.c b/Modules/nismodule.c index a9028bbfe54c6c..1a538dc3b2332d 100644 --- a/Modules/nismodule.c +++ b/Modules/nismodule.c @@ -137,7 +137,7 @@ nis_foreach (int instatus, char *inkey, int inkeylen, char *inval, } static PyObject * -nis_get_default_domain (PyObject *self) +nis_get_default_domain (PyObject *self, PyObject *Py_UNUSED(ignored)) { char *domain; int err; @@ -432,7 +432,7 @@ static PyMethodDef nis_methods[] = { {"maps", (PyCFunction)nis_maps, METH_VARARGS | METH_KEYWORDS, maps__doc__}, - {"get_default_domain", (PyCFunction)nis_get_default_domain, + {"get_default_domain", nis_get_default_domain, METH_NOARGS, get_default_domain__doc__}, {NULL, NULL} /* Sentinel */ diff --git a/Modules/overlapped.c b/Modules/overlapped.c index ae7cddadd02df7..69875a7f37da51 100644 --- a/Modules/overlapped.c +++ b/Modules/overlapped.c @@ -618,7 +618,7 @@ PyDoc_STRVAR( "Cancel overlapped operation"); static PyObject * -Overlapped_cancel(OverlappedObject *self) +Overlapped_cancel(OverlappedObject *self, PyObject *Py_UNUSED(ignored)) { BOOL ret = TRUE; diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index d41bc97b78edb6..3aebcb0b21a522 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -97,6 +97,10 @@ corresponding Unix manual entries for more information on calls."); #include <sys/sendfile.h> #endif +#if defined(__APPLE__) +#include <copyfile.h> +#endif + #ifdef HAVE_SCHED_H #include <sched.h> #endif @@ -1263,6 +1267,65 @@ PyLong_FromPy_off_t(Py_off_t offset) #endif } +#ifdef HAVE_SIGSET_T +/* Convert an iterable of integers to a sigset. + Return 1 on success, return 0 and raise an exception on error. */ +int +_Py_Sigset_Converter(PyObject *obj, void *addr) +{ + sigset_t *mask = (sigset_t *)addr; + PyObject *iterator, *item; + long signum; + int overflow; + + if (sigemptyset(mask)) { + /* Probably only if mask == NULL. */ + PyErr_SetFromErrno(PyExc_OSError); + return 0; + } + + iterator = PyObject_GetIter(obj); + if (iterator == NULL) { + return 0; + } + + while ((item = PyIter_Next(iterator)) != NULL) { + signum = PyLong_AsLongAndOverflow(item, &overflow); + Py_DECREF(item); + if (signum <= 0 || signum >= NSIG) { + if (overflow || signum != -1 || !PyErr_Occurred()) { + PyErr_Format(PyExc_ValueError, + "signal number %ld out of range", signum); + } + goto error; + } + if (sigaddset(mask, (int)signum)) { + if (errno != EINVAL) { + /* Probably impossible */ + PyErr_SetFromErrno(PyExc_OSError); + goto error; + } + /* For backwards compatibility, allow idioms such as + * `range(1, NSIG)` but warn about invalid signal numbers + */ + const char msg[] = + "invalid signal number %ld, please use valid_signals()"; + if (PyErr_WarnFormat(PyExc_RuntimeWarning, 1, msg, signum)) { + goto error; + } + } + } + if (!PyErr_Occurred()) { + Py_DECREF(iterator); + return 1; + } + +error: + Py_DECREF(iterator); + return 0; +} +#endif /* HAVE_SIGSET_T */ + #ifdef MS_WINDOWS static int @@ -5112,6 +5175,237 @@ os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env) #endif /* HAVE_EXECV */ +#ifdef HAVE_POSIX_SPAWN + +enum posix_spawn_file_actions_identifier { + POSIX_SPAWN_OPEN, + POSIX_SPAWN_CLOSE, + POSIX_SPAWN_DUP2 +}; + +static int +parse_file_actions(PyObject *file_actions, + posix_spawn_file_actions_t *file_actionsp, + PyObject *temp_buffer) +{ + PyObject *seq; + PyObject *file_action = NULL; + PyObject *tag_obj; + + seq = PySequence_Fast(file_actions, + "file_actions must be a sequence or None"); + if (seq == NULL) { + return -1; + } + + errno = posix_spawn_file_actions_init(file_actionsp); + if (errno) { + posix_error(); + Py_DECREF(seq); + return -1; + } + + for (int i = 0; i < PySequence_Fast_GET_SIZE(seq); ++i) { + file_action = PySequence_Fast_GET_ITEM(seq, i); + Py_INCREF(file_action); + if (!PyTuple_Check(file_action) || !PyTuple_GET_SIZE(file_action)) { + PyErr_SetString(PyExc_TypeError, + "Each file_actions element must be a non-empty tuple"); + goto fail; + } + long tag = PyLong_AsLong(PyTuple_GET_ITEM(file_action, 0)); + if (tag == -1 && PyErr_Occurred()) { + goto fail; + } + + /* Populate the file_actions object */ + switch (tag) { + case POSIX_SPAWN_OPEN: { + int fd, oflag; + PyObject *path; + unsigned long mode; + if (!PyArg_ParseTuple(file_action, "OiO&ik" + ";A open file_action tuple must have 5 elements", + &tag_obj, &fd, PyUnicode_FSConverter, &path, + &oflag, &mode)) + { + goto fail; + } + if (PyList_Append(temp_buffer, path)) { + Py_DECREF(path); + goto fail; + } + errno = posix_spawn_file_actions_addopen(file_actionsp, + fd, PyBytes_AS_STRING(path), oflag, (mode_t)mode); + Py_DECREF(path); + if (errno) { + posix_error(); + goto fail; + } + break; + } + case POSIX_SPAWN_CLOSE: { + int fd; + if (!PyArg_ParseTuple(file_action, "Oi" + ";A close file_action tuple must have 2 elements", + &tag_obj, &fd)) + { + goto fail; + } + errno = posix_spawn_file_actions_addclose(file_actionsp, fd); + if (errno) { + posix_error(); + goto fail; + } + break; + } + case POSIX_SPAWN_DUP2: { + int fd1, fd2; + if (!PyArg_ParseTuple(file_action, "Oii" + ";A dup2 file_action tuple must have 3 elements", + &tag_obj, &fd1, &fd2)) + { + goto fail; + } + errno = posix_spawn_file_actions_adddup2(file_actionsp, + fd1, fd2); + if (errno) { + posix_error(); + goto fail; + } + break; + } + default: { + PyErr_SetString(PyExc_TypeError, + "Unknown file_actions identifier"); + goto fail; + } + } + Py_DECREF(file_action); + } + Py_DECREF(seq); + return 0; + +fail: + Py_DECREF(seq); + Py_DECREF(file_action); + (void)posix_spawn_file_actions_destroy(file_actionsp); + return -1; +} + +/*[clinic input] + +os.posix_spawn + path: path_t + Path of executable file. + argv: object + Tuple or list of strings. + env: object + Dictionary of strings mapping to strings. + file_actions: object = None + A sequence of file action tuples. + / + +Execute the program specified by path in a new process. +[clinic start generated code]*/ + +static PyObject * +os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv, + PyObject *env, PyObject *file_actions) +/*[clinic end generated code: output=d023521f541c709c input=a3db1021d33230dc]*/ +{ + EXECV_CHAR **argvlist = NULL; + EXECV_CHAR **envlist = NULL; + posix_spawn_file_actions_t file_actions_buf; + posix_spawn_file_actions_t *file_actionsp = NULL; + Py_ssize_t argc, envc; + PyObject *result = NULL; + PyObject *temp_buffer = NULL; + pid_t pid; + int err_code; + + /* posix_spawn has three arguments: (path, argv, env), where + argv is a list or tuple of strings and env is a dictionary + like posix.environ. */ + + if (!PyList_Check(argv) && !PyTuple_Check(argv)) { + PyErr_SetString(PyExc_TypeError, + "posix_spawn: argv must be a tuple or list"); + goto exit; + } + argc = PySequence_Size(argv); + if (argc < 1) { + PyErr_SetString(PyExc_ValueError, "posix_spawn: argv must not be empty"); + return NULL; + } + + if (!PyMapping_Check(env)) { + PyErr_SetString(PyExc_TypeError, + "posix_spawn: environment must be a mapping object"); + goto exit; + } + + argvlist = parse_arglist(argv, &argc); + if (argvlist == NULL) { + goto exit; + } + if (!argvlist[0][0]) { + PyErr_SetString(PyExc_ValueError, + "posix_spawn: argv first element cannot be empty"); + goto exit; + } + + envlist = parse_envlist(env, &envc); + if (envlist == NULL) { + goto exit; + } + + if (file_actions != Py_None) { + /* There is a bug in old versions of glibc that makes some of the + * helper functions for manipulating file actions not copy the provided + * buffers. The problem is that posix_spawn_file_actions_addopen does not + * copy the value of path for some old versions of glibc (<2.20). + * The use of temp_buffer here is a workaround that keeps the + * python objects that own the buffers alive until posix_spawn gets called. + * Check https://bugs.python.org/issue33630 and + * https://sourceware.org/bugzilla/show_bug.cgi?id=17048 for more info.*/ + temp_buffer = PyList_New(0); + if (!temp_buffer) { + goto exit; + } + if (parse_file_actions(file_actions, &file_actions_buf, temp_buffer)) { + goto exit; + } + file_actionsp = &file_actions_buf; + } + + _Py_BEGIN_SUPPRESS_IPH + err_code = posix_spawn(&pid, path->narrow, + file_actionsp, NULL, argvlist, envlist); + _Py_END_SUPPRESS_IPH + if (err_code) { + errno = err_code; + PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object); + goto exit; + } + result = PyLong_FromPid(pid); + +exit: + if (file_actionsp) { + (void)posix_spawn_file_actions_destroy(file_actionsp); + } + if (envlist) { + free_string_array(envlist, envc); + } + if (argvlist) { + free_string_array(argvlist, argc); + } + Py_XDECREF(temp_buffer); + return result; +} +#endif /* HAVE_POSIX_SPAWN */ + + #if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) /*[clinic input] os.spawnv @@ -7973,9 +8267,6 @@ os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how) } #endif /* SEEK_END */ - if (PyErr_Occurred()) - return -1; - Py_BEGIN_ALLOW_THREADS _Py_BEGIN_SUPPRESS_IPH #ifdef MS_WINDOWS @@ -8480,6 +8771,34 @@ posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict) #endif /* HAVE_SENDFILE */ +#if defined(__APPLE__) +/*[clinic input] +os._fcopyfile + + infd: int + outfd: int + flags: int + / + +Efficiently copy content or metadata of 2 regular file descriptors (macOS). +[clinic start generated code]*/ + +static PyObject * +os__fcopyfile_impl(PyObject *module, int infd, int outfd, int flags) +/*[clinic end generated code: output=8e8885c721ec38e3 input=69e0770e600cb44f]*/ +{ + int ret; + + Py_BEGIN_ALLOW_THREADS + ret = fcopyfile(infd, outfd, NULL, flags); + Py_END_ALLOW_THREADS + if (ret < 0) + return posix_error(); + Py_RETURN_NONE; +} +#endif + + /*[clinic input] os.fstat @@ -11282,7 +11601,7 @@ PyDoc_STRVAR(termsize__doc__, "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" \ + "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* @@ -12655,6 +12974,7 @@ static PyMethodDef posix_methods[] = { OS_UTIME_METHODDEF OS_TIMES_METHODDEF OS__EXIT_METHODDEF + OS__FCOPYFILE_METHODDEF OS_EXECV_METHODDEF OS_EXECVE_METHODDEF OS_SPAWNV_METHODDEF @@ -13267,6 +13587,10 @@ all_ins(PyObject *m) if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1; #endif +#if defined(__APPLE__) + if (PyModule_AddIntConstant(m, "_COPYFILE_DATA", COPYFILE_DATA)) return -1; +#endif + return 0; } diff --git a/Modules/posixmodule.h b/Modules/posixmodule.h index 1ec1833825f55a..1e00562abc3370 100644 --- a/Modules/posixmodule.h +++ b/Modules/posixmodule.h @@ -17,8 +17,17 @@ PyAPI_FUNC(PyObject *) _PyLong_FromGid(gid_t); PyAPI_FUNC(int) _Py_Uid_Converter(PyObject *, void *); PyAPI_FUNC(int) _Py_Gid_Converter(PyObject *, void *); #endif /* MS_WINDOWS */ + +#if defined(PYPTHREAD_SIGMASK) || defined(HAVE_SIGWAIT) || \ + defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT) +# define HAVE_SIGSET_T #endif +#ifdef HAVE_SIGSET_T +PyAPI_FUNC(int) _Py_Sigset_Converter(PyObject *, void *); +#endif /* HAVE_SIGSET_T */ +#endif /* Py_LIMITED_API */ + #ifdef __cplusplus } #endif diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index 3b7713abab3693..9ad6f8bdb7aee4 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -58,6 +58,34 @@ extern void bzero(void *, int); # define SOCKET int #endif +/*[clinic input] +module select +class select.poll "pollObject *" "&poll_Type" +class select.devpoll "devpollObject *" "&devpoll_Type" +class select.epoll "pyEpoll_Object *" "&pyEpoll_Type" +class select.kqueue "kqueue_queue_Object *" "&kqueue_queue_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ded80abdad2b7552]*/ + +static int +fildes_converter(PyObject *o, void *p) +{ + int fd; + int *pointer = (int *)p; + fd = PyObject_AsFileDescriptor(o); + if (fd == -1) + return 0; + *pointer = fd; + return 1; +} + +/*[python input] +class fildes_converter(CConverter): + type = 'int' + converter = 'fildes_converter' +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=ca54eb5aa476e20a]*/ + /* list of Python objects and their file descriptor */ typedef struct { PyObject *obj; /* owned reference */ @@ -179,8 +207,43 @@ set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1]) #define SELECT_USES_HEAP #endif /* FD_SETSIZE > 1024 */ +/*[clinic input] +select.select + + rlist: object + wlist: object + xlist: object + timeout as timeout_obj: object = None + / + +Wait until one or more file descriptors are ready for some kind of I/O. + +The first three arguments are sequences of file descriptors to be waited for: +rlist -- wait until ready for reading +wlist -- wait until ready for writing +xlist -- wait for an "exceptional condition" +If only one kind of condition is required, pass [] for the other lists. + +A file descriptor is either a socket or file object, or a small integer +gotten from a fileno() method call on one of those. + +The optional 4th argument specifies a timeout in seconds; it may be +a floating point number to specify fractions of seconds. If it is absent +or None, the call will never time out. + +The return value is a tuple of three lists corresponding to the first three +arguments; each contains the subset of the corresponding file descriptors +that are ready. + +*** IMPORTANT NOTICE *** +On Windows, only sockets are supported; on Unix, all file +descriptors can be used. +[clinic start generated code]*/ + static PyObject * -select_select(PyObject *self, PyObject *args) +select_select_impl(PyObject *module, PyObject *rlist, PyObject *wlist, + PyObject *xlist, PyObject *timeout_obj) +/*[clinic end generated code: output=2b3cfa824f7ae4cf input=177e72184352df25]*/ { #ifdef SELECT_USES_HEAP pylist *rfd2obj, *wfd2obj, *efd2obj; @@ -195,20 +258,13 @@ select_select(PyObject *self, PyObject *args) pylist wfd2obj[FD_SETSIZE + 1]; pylist efd2obj[FD_SETSIZE + 1]; #endif /* SELECT_USES_HEAP */ - PyObject *ifdlist, *ofdlist, *efdlist; PyObject *ret = NULL; - PyObject *timeout_obj = Py_None; fd_set ifdset, ofdset, efdset; struct timeval tv, *tvp; int imax, omax, emax, max; int n; _PyTime_t timeout, deadline = 0; - /* convert arguments */ - if (!PyArg_UnpackTuple(args, "select", 3, 4, - &ifdlist, &ofdlist, &efdlist, &timeout_obj)) - return NULL; - if (timeout_obj == Py_None) tvp = (struct timeval *)NULL; else { @@ -249,11 +305,11 @@ select_select(PyObject *self, PyObject *args) rfd2obj[0].sentinel = -1; wfd2obj[0].sentinel = -1; efd2obj[0].sentinel = -1; - if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0) + if ((imax = seq2set(rlist, &ifdset, rfd2obj)) < 0) goto finally; - if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0) + if ((omax = seq2set(wlist, &ofdset, wfd2obj)) < 0) goto finally; - if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0) + if ((emax = seq2set(xlist, &efdset, efd2obj)) < 0) goto finally; max = imax; @@ -301,17 +357,17 @@ select_select(PyObject *self, PyObject *args) convenient to test for this after all three calls... but is that acceptable? */ - ifdlist = set2list(&ifdset, rfd2obj); - ofdlist = set2list(&ofdset, wfd2obj); - efdlist = set2list(&efdset, efd2obj); + rlist = set2list(&ifdset, rfd2obj); + wlist = set2list(&ofdset, wfd2obj); + xlist = set2list(&efdset, efd2obj); if (PyErr_Occurred()) ret = NULL; else - ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist); + ret = PyTuple_Pack(3, rlist, wlist, xlist); - Py_XDECREF(ifdlist); - Py_XDECREF(ofdlist); - Py_XDECREF(efdlist); + Py_XDECREF(rlist); + Py_XDECREF(wlist); + Py_XDECREF(xlist); } finally: @@ -392,33 +448,31 @@ ushort_converter(PyObject *obj, void *ptr) return 1; } -PyDoc_STRVAR(poll_register_doc, -"register(fd [, eventmask] ) -> None\n\n\ -Register a file descriptor with the polling object.\n\ -fd -- either an integer, or an object with a fileno() method returning an\n\ - int.\n\ -events -- an optional bitmask describing the type of events to check for"); +/*[clinic input] +select.poll.register + + fd: fildes + either an integer, or an object with a fileno() method returning an int + eventmask: object(converter="ushort_converter", type="unsigned short", c_default="POLLIN | POLLPRI | POLLOUT") = POLLIN | POLLPRI | POLLOUT + an optional bitmask describing the type of events to check for + / + +Register a file descriptor with the polling object. +[clinic start generated code]*/ static PyObject * -poll_register(pollObject *self, PyObject *args) +select_poll_register_impl(pollObject *self, int fd, unsigned short eventmask) +/*[clinic end generated code: output=0dc7173c800a4a65 input=499d96a2836217f5]*/ { - PyObject *o, *key, *value; - int fd; - unsigned short events = POLLIN | POLLPRI | POLLOUT; + PyObject *key, *value; int err; - if (!PyArg_ParseTuple(args, "O|O&:register", &o, ushort_converter, &events)) - return NULL; - - fd = PyObject_AsFileDescriptor(o); - if (fd == -1) return NULL; - /* Add entry to the internal dictionary: the key is the file descriptor, and the value is the event mask. */ key = PyLong_FromLong(fd); if (key == NULL) return NULL; - value = PyLong_FromLong(events); + value = PyLong_FromLong(eventmask); if (value == NULL) { Py_DECREF(key); return NULL; @@ -434,27 +488,27 @@ poll_register(pollObject *self, PyObject *args) Py_RETURN_NONE; } -PyDoc_STRVAR(poll_modify_doc, -"modify(fd, eventmask) -> None\n\n\ -Modify an already registered file descriptor.\n\ -fd -- either an integer, or an object with a fileno() method returning an\n\ - int.\n\ -events -- an optional bitmask describing the type of events to check for"); + +/*[clinic input] +select.poll.modify + + fd: fildes + either an integer, or an object with a fileno() method returning + an int + eventmask: object(converter="ushort_converter", type="unsigned short") + a bitmask describing the type of events to check for + / + +Modify an already registered file descriptor. +[clinic start generated code]*/ static PyObject * -poll_modify(pollObject *self, PyObject *args) +select_poll_modify_impl(pollObject *self, int fd, unsigned short eventmask) +/*[clinic end generated code: output=1a7b88bf079eff17 input=b8e0e04a1264b78f]*/ { - PyObject *o, *key, *value; - int fd; - unsigned short events; + PyObject *key, *value; int err; - if (!PyArg_ParseTuple(args, "OO&:modify", &o, ushort_converter, &events)) - return NULL; - - fd = PyObject_AsFileDescriptor(o); - if (fd == -1) return NULL; - /* Modify registered fd */ key = PyLong_FromLong(fd); if (key == NULL) @@ -465,7 +519,7 @@ poll_modify(pollObject *self, PyObject *args) Py_DECREF(key); return NULL; } - value = PyLong_FromLong(events); + value = PyLong_FromLong(eventmask); if (value == NULL) { Py_DECREF(key); return NULL; @@ -482,19 +536,20 @@ poll_modify(pollObject *self, PyObject *args) } -PyDoc_STRVAR(poll_unregister_doc, -"unregister(fd) -> None\n\n\ -Remove a file descriptor being tracked by the polling object."); +/*[clinic input] +select.poll.unregister + + fd: fildes + / + +Remove a file descriptor being tracked by the polling object. +[clinic start generated code]*/ static PyObject * -poll_unregister(pollObject *self, PyObject *o) +select_poll_unregister_impl(pollObject *self, int fd) +/*[clinic end generated code: output=8c9f42e75e7d291b input=4b4fccc1040e79cb]*/ { PyObject *key; - int fd; - - fd = PyObject_AsFileDescriptor( o ); - if (fd == -1) - return NULL; /* Check whether the fd is already in the array */ key = PyLong_FromLong(fd); @@ -514,25 +569,29 @@ poll_unregister(pollObject *self, PyObject *o) Py_RETURN_NONE; } -PyDoc_STRVAR(poll_poll_doc, -"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\ -Polls the set of registered file descriptors, returning a list containing \n\ -any descriptors that have events or errors to report."); +/*[clinic input] +select.poll.poll + + timeout as timeout_obj: object = None + / + +Polls the set of registered file descriptors. + +Returns a list containing any descriptors that have events or errors to +report, as a list of (fd, event) 2-tuples. +[clinic start generated code]*/ static PyObject * -poll_poll(pollObject *self, PyObject *args) +select_poll_poll_impl(pollObject *self, PyObject *timeout_obj) +/*[clinic end generated code: output=876e837d193ed7e4 input=7a446ed45189e894]*/ { - PyObject *result_list = NULL, *timeout_obj = NULL; + PyObject *result_list = NULL; int poll_result, i, j; PyObject *value = NULL, *num = NULL; _PyTime_t timeout = -1, ms = -1, deadline = 0; int async_err = 0; - if (!PyArg_ParseTuple(args, "|O:poll", &timeout_obj)) { - return NULL; - } - - if (timeout_obj != NULL && timeout_obj != Py_None) { + if (timeout_obj != Py_None) { if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj, _PyTime_ROUND_TIMEOUT) < 0) { if (PyErr_ExceptionMatches(PyExc_TypeError)) { @@ -661,18 +720,6 @@ poll_poll(pollObject *self, PyObject *args) return NULL; } -static PyMethodDef poll_methods[] = { - {"register", (PyCFunction)poll_register, - METH_VARARGS, poll_register_doc}, - {"modify", (PyCFunction)poll_modify, - METH_VARARGS, poll_modify_doc}, - {"unregister", (PyCFunction)poll_unregister, - METH_O, poll_unregister_doc}, - {"poll", (PyCFunction)poll_poll, - METH_VARARGS, poll_poll_doc}, - {NULL, NULL} /* sentinel */ -}; - static pollObject * newPollObject(void) { @@ -702,39 +749,6 @@ poll_dealloc(pollObject *self) PyObject_Del(self); } -static PyTypeObject poll_Type = { - /* The ob_type field must be initialized in the module init function - * to be portable to Windows without using C++. */ - PyVarObject_HEAD_INIT(NULL, 0) - "select.poll", /*tp_name*/ - sizeof(pollObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)poll_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*/ - poll_methods, /*tp_methods*/ -}; #ifdef HAVE_SYS_DEVPOLL_H typedef struct { @@ -785,21 +799,12 @@ static int devpoll_flush(devpollObject *self) } static PyObject * -internal_devpoll_register(devpollObject *self, PyObject *args, int remove) +internal_devpoll_register(devpollObject *self, int fd, + unsigned short events, int remove) { - PyObject *o; - int fd; - unsigned short events = POLLIN | POLLPRI | POLLOUT; - if (self->fd_devpoll < 0) return devpoll_err_closed(); - if (!PyArg_ParseTuple(args, "O|O&:register", &o, ushort_converter, &events)) - return NULL; - - fd = PyObject_AsFileDescriptor(o); - if (fd == -1) return NULL; - if (remove) { self->fds[self->n_fds].fd = fd; self->fds[self->n_fds].events = POLLREMOVE; @@ -821,49 +826,66 @@ internal_devpoll_register(devpollObject *self, PyObject *args, int remove) Py_RETURN_NONE; } -PyDoc_STRVAR(devpoll_register_doc, -"register(fd [, eventmask] ) -> None\n\n\ -Register a file descriptor with the polling object.\n\ -fd -- either an integer, or an object with a fileno() method returning an\n\ - int.\n\ -events -- an optional bitmask describing the type of events to check for"); +/*[clinic input] +select.devpoll.register + + fd: fildes + either an integer, or an object with a fileno() method returning + an int + eventmask: object(converter="ushort_converter", type="unsigned short", c_default="POLLIN | POLLPRI | POLLOUT") = POLLIN | POLLPRI | POLLOUT + an optional bitmask describing the type of events to check for + / + +Register a file descriptor with the polling object. +[clinic start generated code]*/ static PyObject * -devpoll_register(devpollObject *self, PyObject *args) +select_devpoll_register_impl(devpollObject *self, int fd, + unsigned short eventmask) +/*[clinic end generated code: output=6e07fe8b74abba0c input=389a0785bb8feb57]*/ { - return internal_devpoll_register(self, args, 0); + return internal_devpoll_register(self, fd, eventmask, 0); } -PyDoc_STRVAR(devpoll_modify_doc, -"modify(fd[, eventmask]) -> None\n\n\ -Modify a possible already registered file descriptor.\n\ -fd -- either an integer, or an object with a fileno() method returning an\n\ - int.\n\ -events -- an optional bitmask describing the type of events to check for"); +/*[clinic input] +select.devpoll.modify + + fd: fildes + either an integer, or an object with a fileno() method returning + an int + eventmask: object(converter="ushort_converter", type="unsigned short", c_default="POLLIN | POLLPRI | POLLOUT") = POLLIN | POLLPRI | POLLOUT + an optional bitmask describing the type of events to check for + / + +Modify a possible already registered file descriptor. +[clinic start generated code]*/ +static PyObject * +select_devpoll_modify_impl(devpollObject *self, int fd, + unsigned short eventmask) +/*[clinic end generated code: output=bc2e6d23aaff98b4 input=f0d7de3889cc55fb]*/ static PyObject * devpoll_modify(devpollObject *self, PyObject *args) { - return internal_devpoll_register(self, args, 1); + return internal_devpoll_register(self, fd, eventmask, 1); } +/*[clinic input] +select.devpoll.unregister + + fd: fildes + / -PyDoc_STRVAR(devpoll_unregister_doc, -"unregister(fd) -> None\n\n\ -Remove a file descriptor being tracked by the polling object."); +Remove a file descriptor being tracked by the polling object. +[clinic start generated code]*/ static PyObject * -devpoll_unregister(devpollObject *self, PyObject *o) +select_devpoll_unregister_impl(devpollObject *self, int fd) +/*[clinic end generated code: output=95519ffa0c7d43fe input=b4ea42a4442fd467]*/ { - int fd; - if (self->fd_devpoll < 0) return devpoll_err_closed(); - fd = PyObject_AsFileDescriptor( o ); - if (fd == -1) - return NULL; - self->fds[self->n_fds].fd = fd; self->fds[self->n_fds].events = POLLREMOVE; @@ -875,13 +897,20 @@ devpoll_unregister(devpollObject *self, PyObject *o) Py_RETURN_NONE; } -PyDoc_STRVAR(devpoll_poll_doc, -"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\ -Polls the set of registered file descriptors, returning a list containing \n\ -any descriptors that have events or errors to report."); +/*[clinic input] +select.devpoll.poll + timeout as timeout_obj: object = None + / + +Polls the set of registered file descriptors. + +Returns a list containing any descriptors that have events or errors to +report, as a list of (fd, event) 2-tuples. +[clinic start generated code]*/ static PyObject * -devpoll_poll(devpollObject *self, PyObject *args) +select_devpoll_poll_impl(devpollObject *self, PyObject *timeout_obj) +/*[clinic end generated code: output=2654e5457cca0b3c input=fd0db698d84f0333]*/ { struct dvpoll dvp; PyObject *result_list = NULL, *timeout_obj = NULL; @@ -892,12 +921,8 @@ devpoll_poll(devpollObject *self, PyObject *args) if (self->fd_devpoll < 0) return devpoll_err_closed(); - if (!PyArg_ParseTuple(args, "|O:poll", &timeout_obj)) { - return NULL; - } - /* Check values for timeout */ - if (timeout_obj == NULL || timeout_obj == Py_None) { + if (timeout_obj == Py_None) { timeout = -1; ms = -1; } @@ -1005,8 +1030,17 @@ devpoll_internal_close(devpollObject *self) return save_errno; } -static PyObject* -devpoll_close(devpollObject *self) +/*[clinic input] +select.devpoll.close + +Close the devpoll file descriptor. + +Further operations on the devpoll object will raise an exception. +[clinic start generated code]*/ + +static PyObject * +select_devpoll_close_impl(devpollObject *self) +/*[clinic end generated code: output=26b355bd6429f21b input=6273c30f5560a99b]*/ { errno = devpoll_internal_close(self); if (errno < 0) { @@ -1016,12 +1050,6 @@ devpoll_close(devpollObject *self) Py_RETURN_NONE; } -PyDoc_STRVAR(devpoll_close_doc, -"close() -> None\n\ -\n\ -Close the devpoll file descriptor. Further operations on the devpoll\n\ -object will raise an exception."); - static PyObject* devpoll_get_closed(devpollObject *self) { @@ -1031,35 +1059,21 @@ devpoll_get_closed(devpollObject *self) Py_RETURN_FALSE; } -static PyObject* -devpoll_fileno(devpollObject *self) +/*[clinic input] +select.devpoll.fileno + +Return the file descriptor. +[clinic start generated code]*/ + +static PyObject * +select_devpoll_fileno_impl(devpollObject *self) +/*[clinic end generated code: output=26920929f8d292f4 input=ef15331ebde6c368]*/ { if (self->fd_devpoll < 0) return devpoll_err_closed(); return PyLong_FromLong(self->fd_devpoll); } -PyDoc_STRVAR(devpoll_fileno_doc, -"fileno() -> int\n\ -\n\ -Return the file descriptor."); - -static PyMethodDef devpoll_methods[] = { - {"register", (PyCFunction)devpoll_register, - METH_VARARGS, devpoll_register_doc}, - {"modify", (PyCFunction)devpoll_modify, - METH_VARARGS, devpoll_modify_doc}, - {"unregister", (PyCFunction)devpoll_unregister, - METH_O, devpoll_unregister_doc}, - {"poll", (PyCFunction)devpoll_poll, - METH_VARARGS, devpoll_poll_doc}, - {"close", (PyCFunction)devpoll_close, METH_NOARGS, - devpoll_close_doc}, - {"fileno", (PyCFunction)devpoll_fileno, METH_NOARGS, - devpoll_fileno_doc}, - {NULL, NULL} /* sentinel */ -}; - static PyGetSetDef devpoll_getsetlist[] = { {"closed", (getter)devpoll_get_closed, NULL, "True if the devpoll object is closed"}, @@ -1119,62 +1133,39 @@ devpoll_dealloc(devpollObject *self) PyObject_Del(self); } -static PyTypeObject devpoll_Type = { - /* The ob_type field must be initialized in the module init function - * to be portable to Windows without using C++. */ - PyVarObject_HEAD_INIT(NULL, 0) - "select.devpoll", /*tp_name*/ - sizeof(devpollObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)devpoll_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*/ - devpoll_methods, /*tp_methods*/ - 0, /* tp_members */ - devpoll_getsetlist, /* tp_getset */ -}; #endif /* HAVE_SYS_DEVPOLL_H */ +/*[clinic input] +select.poll -PyDoc_STRVAR(poll_doc, -"Returns a polling object, which supports registering and\n\ -unregistering file descriptors, and then polling them for I/O events."); +Returns a polling object. + +This object supports registering and unregistering file descriptors, and then +polling them for I/O events. +[clinic start generated code]*/ static PyObject * -select_poll(PyObject *self, PyObject *unused) +select_poll_impl(PyObject *module) +/*[clinic end generated code: output=16a665a4e1d228c5 input=3f877909d5696bbf]*/ { return (PyObject *)newPollObject(); } #ifdef HAVE_SYS_DEVPOLL_H -PyDoc_STRVAR(devpoll_doc, -"Returns a polling object, which supports registering and\n\ -unregistering file descriptors, and then polling them for I/O events."); + +/*[clinic input] +select.devpoll + +Returns a polling object. + +This object supports registering and unregistering file descriptors, and then +polling them for I/O events. +[clinic start generated code]*/ static PyObject * -select_devpoll(PyObject *self, PyObject *unused) +select_devpoll_impl(PyObject *module) +/*[clinic end generated code: output=ea9213cc87fd9581 input=53a1af94564f00a3]*/ { return (PyObject *)newDevPollObject(); } @@ -1294,16 +1285,30 @@ newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd) } +/*[clinic input] +@classmethod +select.epoll.__new__ + + sizehint: int = -1 + The expected number of events to be registered. It must be positive, + or -1 to use the default. It is only used on older systems where + epoll_create1() is not available; otherwise it has no effect (though its + value is still checked). + flags: int = 0 + Deprecated and completely ignored. However, when supplied, its value + must be 0 or select.EPOLL_CLOEXEC, otherwise OSError is raised. + +Returns an epolling object. +[clinic start generated code]*/ + static PyObject * -pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +select_epoll_impl(PyTypeObject *type, int sizehint, int flags) +/*[clinic end generated code: output=c87404e705013bb5 input=303e3295e7975e43]*/ { - int flags = 0, sizehint = FD_SETSIZE - 1; - static char *kwlist[] = {"sizehint", "flags", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii:epoll", kwlist, - &sizehint, &flags)) - return NULL; - if (sizehint < 0) { + if (sizehint == -1) { + sizehint = FD_SETSIZE - 1; + } + else if (sizehint <= 0) { PyErr_SetString(PyExc_ValueError, "negative sizehint"); return NULL; } @@ -1326,8 +1331,17 @@ pyepoll_dealloc(pyEpoll_Object *self) Py_TYPE(self)->tp_free(self); } -static PyObject* -pyepoll_close(pyEpoll_Object *self) +/*[clinic input] +select.epoll.close + +Close the epoll control file descriptor. + +Further operations on the epoll object will raise an exception. +[clinic start generated code]*/ + +static PyObject * +select_epoll_close_impl(pyEpoll_Object *self) +/*[clinic end generated code: output=ee2144c446a1a435 input=ca6c66ba5a736bfd]*/ { errno = pyepoll_internal_close(self); if (errno < 0) { @@ -1337,11 +1351,6 @@ pyepoll_close(pyEpoll_Object *self) Py_RETURN_NONE; } -PyDoc_STRVAR(pyepoll_close_doc, -"close() -> None\n\ -\n\ -Close the epoll control file descriptor. Further operations on the epoll\n\ -object will raise an exception."); static PyObject* pyepoll_get_closed(pyEpoll_Object *self) @@ -1352,50 +1361,50 @@ pyepoll_get_closed(pyEpoll_Object *self) Py_RETURN_FALSE; } -static PyObject* -pyepoll_fileno(pyEpoll_Object *self) +/*[clinic input] +select.epoll.fileno + +Return the epoll control file descriptor. +[clinic start generated code]*/ + +static PyObject * +select_epoll_fileno_impl(pyEpoll_Object *self) +/*[clinic end generated code: output=e171375fdc619ba3 input=c11091a6aee60b5c]*/ { if (self->epfd < 0) return pyepoll_err_closed(); return PyLong_FromLong(self->epfd); } -PyDoc_STRVAR(pyepoll_fileno_doc, -"fileno() -> int\n\ -\n\ -Return the epoll control file descriptor."); -static PyObject* -pyepoll_fromfd(PyObject *cls, PyObject *args) -{ - SOCKET fd; +/*[clinic input] +@classmethod +select.epoll.fromfd - if (!PyArg_ParseTuple(args, "i:fromfd", &fd)) - return NULL; + fd: int + / + +Create an epoll object from a given control fd. +[clinic start generated code]*/ - return newPyEpoll_Object((PyTypeObject*)cls, FD_SETSIZE - 1, fd); +static PyObject * +select_epoll_fromfd_impl(PyTypeObject *type, int fd) +/*[clinic end generated code: output=c15de2a083524e8e input=faecefdb55e3046e]*/ +{ + SOCKET s_fd = (SOCKET)fd; + return newPyEpoll_Object(type, FD_SETSIZE - 1, s_fd); } -PyDoc_STRVAR(pyepoll_fromfd_doc, -"fromfd(fd) -> epoll\n\ -\n\ -Create an epoll object from a given control fd."); static PyObject * -pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events) +pyepoll_internal_ctl(int epfd, int op, int fd, unsigned int events) { struct epoll_event ev; int result; - int fd; if (epfd < 0) return pyepoll_err_closed(); - fd = PyObject_AsFileDescriptor(pfd); - if (fd == -1) { - return NULL; - } - switch (op) { case EPOLL_CTL_ADD: case EPOLL_CTL_MOD: @@ -1430,77 +1439,82 @@ pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events) Py_RETURN_NONE; } +/*[clinic input] +select.epoll.register + + fd: fildes + the target file descriptor of the operation + eventmask: unsigned_int(c_default="EPOLLIN | EPOLLPRI | EPOLLOUT", bitwise=True) = EPOLLIN | EPOLLPRI | EPOLLOUT + a bit set composed of the various EPOLL constants + +Registers a new fd or raises an OSError if the fd is already registered. + +The epoll interface supports all file descriptors that support poll. +[clinic start generated code]*/ + static PyObject * -pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds) +select_epoll_register_impl(pyEpoll_Object *self, int fd, + unsigned int eventmask) +/*[clinic end generated code: output=318e5e6386520599 input=6cf699c152dd8ca9]*/ { - PyObject *pfd; - unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI; - static char *kwlist[] = {"fd", "eventmask", NULL}; + return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, fd, eventmask); +} - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist, - &pfd, &events)) { - return NULL; - } +/*[clinic input] +select.epoll.modify - return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events); -} + fd: fildes + the target file descriptor of the operation + eventmask: unsigned_int(bitwise=True) + a bit set composed of the various EPOLL constants -PyDoc_STRVAR(pyepoll_register_doc, -"register(fd[, eventmask]) -> None\n\ -\n\ -Registers a new fd or raises an OSError if the fd is already registered.\n\ -fd is the target file descriptor of the operation.\n\ -events is a bit set composed of the various EPOLL constants; the default\n\ -is EPOLLIN | EPOLLOUT | EPOLLPRI.\n\ -\n\ -The epoll interface supports all file descriptors that support poll."); +Modify event mask for a registered file descriptor. +[clinic start generated code]*/ static PyObject * -pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds) +select_epoll_modify_impl(pyEpoll_Object *self, int fd, + unsigned int eventmask) +/*[clinic end generated code: output=7e3447307cff6f65 input=88a83dac53a8c3da]*/ { - PyObject *pfd; - unsigned int events; - static char *kwlist[] = {"fd", "eventmask", NULL}; + return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, fd, eventmask); +} - if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist, - &pfd, &events)) { - return NULL; - } +/*[clinic input] +select.epoll.unregister - return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events); -} + fd: fildes + the target file descriptor of the operation -PyDoc_STRVAR(pyepoll_modify_doc, -"modify(fd, eventmask) -> None\n\ -\n\ -fd is the target file descriptor of the operation\n\ -events is a bit set composed of the various EPOLL constants"); +Remove a registered file descriptor from the epoll object. +[clinic start generated code]*/ static PyObject * -pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds) +select_epoll_unregister_impl(pyEpoll_Object *self, int fd) +/*[clinic end generated code: output=07c5dbd612a512d4 input=3093f68d3644743d]*/ { - PyObject *pfd; - static char *kwlist[] = {"fd", NULL}; + return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, fd, 0); +} - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist, - &pfd)) { - return NULL; - } +/*[clinic input] +select.epoll.poll - return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0); -} + timeout as timeout_obj: object = None + the maximum time to wait in seconds (as float); + a timeout of None or -1 makes poll wait indefinitely + maxevents: int = -1 + the maximum number of events returned; -1 means no limit -PyDoc_STRVAR(pyepoll_unregister_doc, -"unregister(fd) -> None\n\ -\n\ -fd is the target file descriptor of the operation."); +Wait for events on the epoll file descriptor. + +Returns a list containing any descriptors that have events to report, +as a list of (fd, events) 2-tuples. +[clinic start generated code]*/ static PyObject * -pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds) +select_epoll_poll_impl(pyEpoll_Object *self, PyObject *timeout_obj, + int maxevents) +/*[clinic end generated code: output=e02d121a20246c6c input=33d34a5ea430fd5b]*/ { - static char *kwlist[] = {"timeout", "maxevents", NULL}; - PyObject *timeout_obj = NULL; - int maxevents = -1; int nfds, i; PyObject *elist = NULL, *etuple = NULL; struct epoll_event *evs = NULL; @@ -1509,12 +1523,7 @@ pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds) if (self->epfd < 0) return pyepoll_err_closed(); - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:poll", kwlist, - &timeout_obj, &maxevents)) { - return NULL; - } - - if (timeout_obj == NULL || timeout_obj == Py_None) { + if (timeout_obj == Py_None) { timeout = -1; ms = -1; deadline = 0; /* initialize to prevent gcc warning */ @@ -1604,15 +1613,15 @@ pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds) return elist; } -PyDoc_STRVAR(pyepoll_poll_doc, -"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\ -\n\ -Wait for events on the epoll file descriptor for a maximum time of timeout\n\ -in seconds (as float). -1 makes poll wait indefinitely.\n\ -Up to maxevents are returned to the caller."); + +/*[clinic input] +select.epoll.__enter__ + +[clinic start generated code]*/ static PyObject * -pyepoll_enter(pyEpoll_Object *self, PyObject *args) +select_epoll___enter___impl(pyEpoll_Object *self) +/*[clinic end generated code: output=ab45d433504db2a0 input=3c22568587efeadb]*/ { if (self->epfd < 0) return pyepoll_err_closed(); @@ -1621,94 +1630,33 @@ pyepoll_enter(pyEpoll_Object *self, PyObject *args) return (PyObject *)self; } +/*[clinic input] +select.epoll.__exit__ + + exc_type: object = None + exc_value: object = None + exc_tb: object = None + / + +[clinic start generated code]*/ + static PyObject * -pyepoll_exit(PyObject *self, PyObject *args) +select_epoll___exit___impl(pyEpoll_Object *self, PyObject *exc_type, + PyObject *exc_value, PyObject *exc_tb) +/*[clinic end generated code: output=c480f38ce361748e input=7ae81a5a4c1a98d8]*/ { _Py_IDENTIFIER(close); - return _PyObject_CallMethodId(self, &PyId_close, NULL); + return _PyObject_CallMethodId((PyObject *)self, &PyId_close, NULL); } -static PyMethodDef pyepoll_methods[] = { - {"fromfd", (PyCFunction)pyepoll_fromfd, - METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc}, - {"close", (PyCFunction)pyepoll_close, METH_NOARGS, - pyepoll_close_doc}, - {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS, - pyepoll_fileno_doc}, - {"modify", (PyCFunction)pyepoll_modify, - METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc}, - {"register", (PyCFunction)pyepoll_register, - METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc}, - {"unregister", (PyCFunction)pyepoll_unregister, - METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc}, - {"poll", (PyCFunction)pyepoll_poll, - METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc}, - {"__enter__", (PyCFunction)pyepoll_enter, METH_NOARGS, - NULL}, - {"__exit__", (PyCFunction)pyepoll_exit, METH_VARARGS, - NULL}, - {NULL, NULL}, -}; - static PyGetSetDef pyepoll_getsetlist[] = { {"closed", (getter)pyepoll_get_closed, NULL, "True if the epoll handler is closed"}, {0}, }; -PyDoc_STRVAR(pyepoll_doc, -"select.epoll(sizehint=-1, flags=0)\n\ -\n\ -Returns an epolling object\n\ -\n\ -sizehint must be a positive integer or -1 for the default size. The\n\ -sizehint is used to optimize internal data structures. It doesn't limit\n\ -the maximum number of monitored events."); - -static PyTypeObject pyEpoll_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "select.epoll", /* tp_name */ - sizeof(pyEpoll_Object), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pyepoll_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 */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - pyepoll_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - pyepoll_methods, /* tp_methods */ - 0, /* tp_members */ - pyepoll_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 */ - pyepoll_new, /* tp_new */ - 0, /* tp_free */ -}; - -#endif /* HAVE_EPOLL */ +#endif /* HAVE_EPOLL */ #ifdef HAVE_KQUEUE /* ************************************************************************** @@ -1935,48 +1883,6 @@ kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o, Py_RETURN_RICHCOMPARE(result, 0, op); } -static PyTypeObject kqueue_event_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "select.kevent", /* tp_name */ - sizeof(kqueue_event_Object), /* tp_basicsize */ - 0, /* tp_itemsize */ - 0, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - (reprfunc)kqueue_event_repr, /* 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 */ - kqueue_event_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - kqueue_event_members, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)kqueue_event_init, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0, /* tp_free */ -}; - static PyObject * kqueue_queue_err_closed(void) { @@ -2032,16 +1938,29 @@ newKqueue_Object(PyTypeObject *type, SOCKET fd) return (PyObject *)self; } +/*[clinic input] +@classmethod +select.kqueue.__new__ + +Kqueue syscall wrapper. + +For example, to start watching a socket for input: +>>> kq = kqueue() +>>> sock = socket() +>>> sock.connect((host, port)) +>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0) + +To wait one second for it to become writeable: +>>> kq.control(None, 1, 1000) + +To stop listening: +>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0) +[clinic start generated code]*/ + static PyObject * -kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +select_kqueue_impl(PyTypeObject *type) +/*[clinic end generated code: output=e0ff89f154d56236 input=cf625e49218366e8]*/ { - if (PyTuple_GET_SIZE(args) || - (kwds != NULL && PyDict_GET_SIZE(kwds))) { - PyErr_SetString(PyExc_ValueError, - "select.kqueue doesn't accept arguments"); - return NULL; - } - return newKqueue_Object(type, -1); } @@ -2052,8 +1971,17 @@ kqueue_queue_dealloc(kqueue_queue_Object *self) Py_TYPE(self)->tp_free(self); } -static PyObject* -kqueue_queue_close(kqueue_queue_Object *self) +/*[clinic input] +select.kqueue.close + +Close the kqueue control file descriptor. + +Further operations on the kqueue object will raise an exception. +[clinic start generated code]*/ + +static PyObject * +select_kqueue_close_impl(kqueue_queue_Object *self) +/*[clinic end generated code: output=d1c7df0b407a4bc1 input=0b12d95430e0634c]*/ { errno = kqueue_queue_internal_close(self); if (errno < 0) { @@ -2063,12 +1991,6 @@ kqueue_queue_close(kqueue_queue_Object *self) Py_RETURN_NONE; } -PyDoc_STRVAR(kqueue_queue_close_doc, -"close() -> None\n\ -\n\ -Close the kqueue control file descriptor. Further operations on the kqueue\n\ -object will raise an exception."); - static PyObject* kqueue_queue_get_closed(kqueue_queue_Object *self) { @@ -2078,44 +2000,64 @@ kqueue_queue_get_closed(kqueue_queue_Object *self) Py_RETURN_FALSE; } -static PyObject* -kqueue_queue_fileno(kqueue_queue_Object *self) +/*[clinic input] +select.kqueue.fileno + +Return the kqueue control file descriptor. +[clinic start generated code]*/ + +static PyObject * +select_kqueue_fileno_impl(kqueue_queue_Object *self) +/*[clinic end generated code: output=716f46112a4f6e5c input=41911c539ca2b0ca]*/ { if (self->kqfd < 0) return kqueue_queue_err_closed(); return PyLong_FromLong(self->kqfd); } -PyDoc_STRVAR(kqueue_queue_fileno_doc, -"fileno() -> int\n\ -\n\ -Return the kqueue control file descriptor."); +/*[clinic input] +@classmethod +select.kqueue.fromfd -static PyObject* -kqueue_queue_fromfd(PyObject *cls, PyObject *args) -{ - SOCKET fd; + fd: int + / - if (!PyArg_ParseTuple(args, "i:fromfd", &fd)) - return NULL; +Create a kqueue object from a given control fd. +[clinic start generated code]*/ - return newKqueue_Object((PyTypeObject*)cls, fd); +static PyObject * +select_kqueue_fromfd_impl(PyTypeObject *type, int fd) +/*[clinic end generated code: output=d02c3c7dc538a653 input=f6172a48ca4ecdd0]*/ +{ + SOCKET s_fd = (SOCKET)fd; + + return newKqueue_Object(type, s_fd); } -PyDoc_STRVAR(kqueue_queue_fromfd_doc, -"fromfd(fd) -> kqueue\n\ -\n\ -Create a kqueue object from a given control fd."); +/*[clinic input] +select.kqueue.control + + changelist: object + Must be an iterable of kevent objects describing the changes to be made + to the kernel's watch list or None. + maxevents: int + The maximum number of events that the kernel will return. + timeout as otimeout: object = None + The maximum time to wait in seconds, or else None to wait forever. + This accepts floats for smaller timeouts, too. + / + +Calls the kernel kevent function. +[clinic start generated code]*/ static PyObject * -kqueue_queue_control(kqueue_queue_Object *self, PyObject *args) +select_kqueue_control_impl(kqueue_queue_Object *self, PyObject *changelist, + int maxevents, PyObject *otimeout) +/*[clinic end generated code: output=81324ff5130db7ae input=59c4e30811209c47]*/ { - int nevents = 0; int gotevents = 0; int nchanges = 0; int i = 0; - PyObject *otimeout = NULL; - PyObject *ch = NULL; PyObject *seq = NULL, *ei = NULL; PyObject *result = NULL; struct kevent *evl = NULL; @@ -2127,17 +2069,14 @@ kqueue_queue_control(kqueue_queue_Object *self, PyObject *args) if (self->kqfd < 0) return kqueue_queue_err_closed(); - if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout)) - return NULL; - - if (nevents < 0) { + if (maxevents < 0) { PyErr_Format(PyExc_ValueError, "Length of eventlist must be 0 or positive, got %d", - nevents); + maxevents); return NULL; } - if (otimeout == Py_None || otimeout == NULL) { + if (otimeout == Py_None) { ptimeoutspec = NULL; } else { @@ -2161,8 +2100,8 @@ kqueue_queue_control(kqueue_queue_Object *self, PyObject *args) ptimeoutspec = &timeoutspec; } - if (ch != NULL && ch != Py_None) { - seq = PySequence_Fast(ch, "changelist is not iterable"); + if (changelist != Py_None) { + seq = PySequence_Fast(changelist, "changelist is not iterable"); if (seq == NULL) { return NULL; } @@ -2192,8 +2131,8 @@ kqueue_queue_control(kqueue_queue_Object *self, PyObject *args) } /* event list */ - if (nevents) { - evl = PyMem_New(struct kevent, nevents); + if (maxevents) { + evl = PyMem_New(struct kevent, maxevents); if (evl == NULL) { PyErr_NoMemory(); goto error; @@ -2207,7 +2146,7 @@ kqueue_queue_control(kqueue_queue_Object *self, PyObject *args) Py_BEGIN_ALLOW_THREADS errno = 0; gotevents = kevent(self->kqfd, chl, nchanges, - evl, nevents, ptimeoutspec); + evl, maxevents, ptimeoutspec); Py_END_ALLOW_THREADS if (errno != EINTR) @@ -2261,50 +2200,225 @@ kqueue_queue_control(kqueue_queue_Object *self, PyObject *args) return NULL; } -PyDoc_STRVAR(kqueue_queue_control_doc, -"control(changelist, max_events[, timeout=None]) -> eventlist\n\ -\n\ -Calls the kernel kevent function.\n\ -- changelist must be an iterable of kevent objects describing the changes\n\ - to be made to the kernel's watch list or None.\n\ -- max_events lets you specify the maximum number of events that the\n\ - kernel will return.\n\ -- timeout is the maximum time to wait in seconds, or else None,\n\ - to wait forever. timeout accepts floats for smaller timeouts, too."); +static PyGetSetDef kqueue_queue_getsetlist[] = { + {"closed", (getter)kqueue_queue_get_closed, NULL, + "True if the kqueue handler is closed"}, + {0}, +}; +#endif /* HAVE_KQUEUE */ -static PyMethodDef kqueue_queue_methods[] = { - {"fromfd", (PyCFunction)kqueue_queue_fromfd, - METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc}, - {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS, - kqueue_queue_close_doc}, - {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS, - kqueue_queue_fileno_doc}, - {"control", (PyCFunction)kqueue_queue_control, - METH_VARARGS , kqueue_queue_control_doc}, + +/* ************************************************************************ */ + +#include "clinic/selectmodule.c.h" + +#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL) + +static PyMethodDef poll_methods[] = { + SELECT_POLL_REGISTER_METHODDEF + SELECT_POLL_MODIFY_METHODDEF + SELECT_POLL_UNREGISTER_METHODDEF + SELECT_POLL_POLL_METHODDEF + {NULL, NULL} /* sentinel */ +}; + +static PyTypeObject poll_Type = { + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyVarObject_HEAD_INIT(NULL, 0) + "select.poll", /*tp_name*/ + sizeof(pollObject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)poll_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*/ + poll_methods, /*tp_methods*/ +}; + +#ifdef HAVE_SYS_DEVPOLL_H + +static PyMethodDef devpoll_methods[] = { + SELECT_DEVPOLL_REGISTER_METHODDEF + SELECT_DEVPOLL_MODIFY_METHODDEF + SELECT_DEVPOLL_UNREGISTER_METHODDEF + SELECT_DEVPOLL_POLL_METHODDEF + SELECT_DEVPOLL_CLOSE_METHODDEF + SELECT_DEVPOLL_FILENO_METHODDEF + {NULL, NULL} /* sentinel */ +}; + +static PyTypeObject devpoll_Type = { + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyVarObject_HEAD_INIT(NULL, 0) + "select.devpoll", /*tp_name*/ + sizeof(devpollObject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)devpoll_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*/ + devpoll_methods, /*tp_methods*/ + 0, /* tp_members */ + devpoll_getsetlist, /* tp_getset */ +}; + +#endif /* HAVE_SYS_DEVPOLL_H */ + +#endif /* HAVE_POLL */ + +#ifdef HAVE_EPOLL + +static PyMethodDef pyepoll_methods[] = { + SELECT_EPOLL_FROMFD_METHODDEF + SELECT_EPOLL_CLOSE_METHODDEF + SELECT_EPOLL_FILENO_METHODDEF + SELECT_EPOLL_MODIFY_METHODDEF + SELECT_EPOLL_REGISTER_METHODDEF + SELECT_EPOLL_UNREGISTER_METHODDEF + SELECT_EPOLL_POLL_METHODDEF + SELECT_EPOLL___ENTER___METHODDEF + SELECT_EPOLL___EXIT___METHODDEF {NULL, NULL}, }; -static PyGetSetDef kqueue_queue_getsetlist[] = { - {"closed", (getter)kqueue_queue_get_closed, NULL, - "True if the kqueue handler is closed"}, - {0}, +static PyTypeObject pyEpoll_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "select.epoll", /* tp_name */ + sizeof(pyEpoll_Object), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)pyepoll_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 */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + select_epoll__doc__, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + pyepoll_methods, /* tp_methods */ + 0, /* tp_members */ + pyepoll_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 */ + select_epoll, /* tp_new */ + 0, /* tp_free */ }; -PyDoc_STRVAR(kqueue_queue_doc, -"Kqueue syscall wrapper.\n\ -\n\ -For example, to start watching a socket for input:\n\ ->>> kq = kqueue()\n\ ->>> sock = socket()\n\ ->>> sock.connect((host, port))\n\ ->>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\ -\n\ -To wait one second for it to become writeable:\n\ ->>> kq.control(None, 1, 1000)\n\ -\n\ -To stop listening:\n\ ->>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)"); +#endif /* HAVE_EPOLL */ + +#ifdef HAVE_KQUEUE + +static PyTypeObject kqueue_event_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "select.kevent", /* tp_name */ + sizeof(kqueue_event_Object), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)kqueue_event_repr, /* 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 */ + kqueue_event_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + kqueue_event_members, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)kqueue_event_init, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0, /* tp_free */ +}; + +static PyMethodDef kqueue_queue_methods[] = { + SELECT_KQUEUE_FROMFD_METHODDEF + SELECT_KQUEUE_CLOSE_METHODDEF + SELECT_KQUEUE_FILENO_METHODDEF + SELECT_KQUEUE_CONTROL_METHODDEF + {NULL, NULL}, +}; static PyTypeObject kqueue_queue_Type = { PyVarObject_HEAD_INIT(NULL, 0) @@ -2327,7 +2441,7 @@ static PyTypeObject kqueue_queue_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ - kqueue_queue_doc, /* tp_doc */ + select_kqueue__doc__, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ @@ -2344,7 +2458,7 @@ static PyTypeObject kqueue_queue_Type = { 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ - kqueue_queue_new, /* tp_new */ + select_kqueue, /* tp_new */ 0, /* tp_free */ }; @@ -2356,38 +2470,11 @@ static PyTypeObject kqueue_queue_Type = { /* ************************************************************************ */ -PyDoc_STRVAR(select_doc, -"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\ -\n\ -Wait until one or more file descriptors are ready for some kind of I/O.\n\ -The first three arguments are sequences of file descriptors to be waited for:\n\ -rlist -- wait until ready for reading\n\ -wlist -- wait until ready for writing\n\ -xlist -- wait for an ``exceptional condition''\n\ -If only one kind of condition is required, pass [] for the other lists.\n\ -A file descriptor is either a socket or file object, or a small integer\n\ -gotten from a fileno() method call on one of those.\n\ -\n\ -The optional 4th argument specifies a timeout in seconds; it may be\n\ -a floating point number to specify fractions of seconds. If it is absent\n\ -or None, the call will never time out.\n\ -\n\ -The return value is a tuple of three lists corresponding to the first three\n\ -arguments; each contains the subset of the corresponding file descriptors\n\ -that are ready.\n\ -\n\ -*** IMPORTANT NOTICE ***\n\ -On Windows, only sockets are supported; on Unix, all file\n\ -descriptors can be used."); static PyMethodDef select_methods[] = { - {"select", select_select, METH_VARARGS, select_doc}, -#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL) - {"poll", select_poll, METH_NOARGS, poll_doc}, -#endif /* HAVE_POLL */ -#ifdef HAVE_SYS_DEVPOLL_H - {"devpoll", select_devpoll, METH_NOARGS, devpoll_doc}, -#endif + SELECT_SELECT_METHODDEF + SELECT_POLL_METHODDEF + SELECT_DEVPOLL_METHODDEF {0, 0}, /* sentinel */ }; diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index e70c6fc3969adc..9de5c2ed181712 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -59,6 +59,14 @@ module signal [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=b0301a3bde5fe9d3]*/ +/*[python input] + +class sigset_t_converter(CConverter): + type = 'sigset_t' + converter = '_Py_Sigset_Converter' + +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=b5689d14466b6823]*/ /* NOTES ON THE INTERACTION BETWEEN SIGNALS AND THREADS @@ -497,6 +505,66 @@ signal_getsignal_impl(PyObject *module, int signalnum) } } + +/*[clinic input] +signal.strsignal + + signalnum: int + / + +Return the system description of the given signal. + +The return values can be such as "Interrupt", "Segmentation fault", etc. +Returns None if the signal is not recognized. +[clinic start generated code]*/ + +static PyObject * +signal_strsignal_impl(PyObject *module, int signalnum) +/*[clinic end generated code: output=44e12e1e3b666261 input=b77914b03f856c74]*/ +{ + char *res; + + if (signalnum < 1 || signalnum >= NSIG) { + PyErr_SetString(PyExc_ValueError, + "signal number out of range"); + return NULL; + } + +#ifdef MS_WINDOWS + /* Custom redefinition of POSIX signals allowed on Windows */ + switch (signalnum) { + case SIGINT: + res = "Interrupt"; + break; + case SIGILL: + res = "Illegal instruction"; + break; + case SIGABRT: + res = "Aborted"; + break; + case SIGFPE: + res = "Floating point exception"; + break; + case SIGSEGV: + res = "Segmentation fault"; + break; + case SIGTERM: + res = "Terminated"; + break; + default: + Py_RETURN_NONE; + } +#else + errno = 0; + res = strsignal(signalnum); + + if (errno || res == NULL || strstr(res, "Unknown signal") != NULL) + Py_RETURN_NONE; +#endif + + return Py_BuildValue("s", res); +} + #ifdef HAVE_SIGINTERRUPT /*[clinic input] @@ -741,59 +809,6 @@ signal_getitimer_impl(PyObject *module, int which) #endif -#if defined(PYPTHREAD_SIGMASK) || defined(HAVE_SIGWAIT) || \ - defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT) -/* Convert an iterable to a sigset. - Return 0 on success, return -1 and raise an exception on error. */ - -static int -iterable_to_sigset(PyObject *iterable, sigset_t *mask) -{ - int result = -1; - PyObject *iterator, *item; - long signum; - - sigemptyset(mask); - - iterator = PyObject_GetIter(iterable); - if (iterator == NULL) - goto error; - - while (1) - { - item = PyIter_Next(iterator); - if (item == NULL) { - if (PyErr_Occurred()) - goto error; - else - break; - } - - signum = PyLong_AsLong(item); - Py_DECREF(item); - if (signum == -1 && PyErr_Occurred()) - goto error; - if (0 < signum && signum < NSIG) { - /* bpo-33329: ignore sigaddset() return value as it can fail - * for some reserved signals, but we want the `range(1, NSIG)` - * idiom to allow selecting all valid signals. - */ - (void) sigaddset(mask, (int)signum); - } - else { - PyErr_Format(PyExc_ValueError, - "signal number %ld out of range", signum); - goto error; - } - } - result = 0; - -error: - Py_XDECREF(iterator); - return result; -} -#endif - #if defined(PYPTHREAD_SIGMASK) || defined(HAVE_SIGPENDING) static PyObject* sigset_to_set(sigset_t mask) @@ -836,23 +851,20 @@ sigset_to_set(sigset_t mask) signal.pthread_sigmask how: int - mask: object + mask: sigset_t / Fetch and/or change the signal mask of the calling thread. [clinic start generated code]*/ static PyObject * -signal_pthread_sigmask_impl(PyObject *module, int how, PyObject *mask) -/*[clinic end generated code: output=ff640fe092bc9181 input=f3b7d7a61b7b8283]*/ +signal_pthread_sigmask_impl(PyObject *module, int how, sigset_t mask) +/*[clinic end generated code: output=0562c0fb192981a8 input=85bcebda442fa77f]*/ { - sigset_t newmask, previous; + sigset_t previous; int err; - if (iterable_to_sigset(mask, &newmask)) - return NULL; - - err = pthread_sigmask(how, &newmask, &previous); + err = pthread_sigmask(how, &mask, &previous); if (err != 0) { errno = err; PyErr_SetFromErrno(PyExc_OSError); @@ -900,7 +912,7 @@ signal_sigpending_impl(PyObject *module) /*[clinic input] signal.sigwait - sigset: object + sigset: sigset_t / Wait for a signal. @@ -911,17 +923,13 @@ and returns the signal number. [clinic start generated code]*/ static PyObject * -signal_sigwait(PyObject *module, PyObject *sigset) -/*[clinic end generated code: output=557173647424f6e4 input=11af2d82d83c2e94]*/ +signal_sigwait_impl(PyObject *module, sigset_t sigset) +/*[clinic end generated code: output=f43770699d682f96 input=a6fbd47b1086d119]*/ { - sigset_t set; int err, signum; - if (iterable_to_sigset(sigset, &set)) - return NULL; - Py_BEGIN_ALLOW_THREADS - err = sigwait(&set, &signum); + err = sigwait(&sigset, &signum); Py_END_ALLOW_THREADS if (err) { errno = err; @@ -934,6 +942,47 @@ signal_sigwait(PyObject *module, PyObject *sigset) #endif /* #ifdef HAVE_SIGWAIT */ +#if defined(HAVE_SIGFILLSET) || defined(MS_WINDOWS) + +/*[clinic input] +signal.valid_signals + +Return a set of valid signal numbers on this platform. + +The signal numbers returned by this function can be safely passed to +functions like `pthread_sigmask`. +[clinic start generated code]*/ + +static PyObject * +signal_valid_signals_impl(PyObject *module) +/*[clinic end generated code: output=1609cffbcfcf1314 input=86a3717ff25288f2]*/ +{ +#ifdef MS_WINDOWS +#ifdef SIGBREAK + PyObject *tup = Py_BuildValue("(iiiiiii)", SIGABRT, SIGBREAK, SIGFPE, + SIGILL, SIGINT, SIGSEGV, SIGTERM); +#else + PyObject *tup = Py_BuildValue("(iiiiii)", SIGABRT, SIGFPE, SIGILL, + SIGINT, SIGSEGV, SIGTERM); +#endif + if (tup == NULL) { + return NULL; + } + PyObject *set = PySet_New(tup); + Py_DECREF(tup); + return set; +#else + sigset_t mask; + if (sigemptyset(&mask) || sigfillset(&mask)) { + return PyErr_SetFromErrno(PyExc_OSError); + } + return sigset_to_set(mask); +#endif +} + +#endif /* #if defined(HAVE_SIGFILLSET) || defined(MS_WINDOWS) */ + + #if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT) static int initialized; static PyStructSequence_Field struct_siginfo_fields[] = { @@ -995,7 +1044,7 @@ fill_siginfo(siginfo_t *si) /*[clinic input] signal.sigwaitinfo - sigset: object + sigset: sigset_t / Wait synchronously until one of the signals in *sigset* is delivered. @@ -1004,20 +1053,16 @@ Returns a struct_siginfo containing information about the signal. [clinic start generated code]*/ static PyObject * -signal_sigwaitinfo(PyObject *module, PyObject *sigset) -/*[clinic end generated code: output=c40f27b269cd2309 input=f3779a74a991e171]*/ +signal_sigwaitinfo_impl(PyObject *module, sigset_t sigset) +/*[clinic end generated code: output=1eb2f1fa236fdbca input=3d1a7e1f27fc664c]*/ { - sigset_t set; siginfo_t si; int err; int async_err = 0; - if (iterable_to_sigset(sigset, &set)) - return NULL; - do { Py_BEGIN_ALLOW_THREADS - err = sigwaitinfo(&set, &si); + err = sigwaitinfo(&sigset, &si); Py_END_ALLOW_THREADS } while (err == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals())); @@ -1034,7 +1079,7 @@ signal_sigwaitinfo(PyObject *module, PyObject *sigset) /*[clinic input] signal.sigtimedwait - sigset: object + sigset: sigset_t timeout as timeout_obj: object / @@ -1044,12 +1089,11 @@ The timeout is specified in seconds, with floating point numbers allowed. [clinic start generated code]*/ static PyObject * -signal_sigtimedwait_impl(PyObject *module, PyObject *sigset, +signal_sigtimedwait_impl(PyObject *module, sigset_t sigset, PyObject *timeout_obj) -/*[clinic end generated code: output=f7eff31e679f4312 input=53fd4ea3e3724eb8]*/ +/*[clinic end generated code: output=59c8971e8ae18a64 input=87fd39237cf0b7ba]*/ { struct timespec ts; - sigset_t set; siginfo_t si; int res; _PyTime_t timeout, deadline, monotonic; @@ -1063,9 +1107,6 @@ signal_sigtimedwait_impl(PyObject *module, PyObject *sigset, return NULL; } - if (iterable_to_sigset(sigset, &set)) - return NULL; - deadline = _PyTime_GetMonotonicClock() + timeout; do { @@ -1073,7 +1114,7 @@ signal_sigtimedwait_impl(PyObject *module, PyObject *sigset, return NULL; Py_BEGIN_ALLOW_THREADS - res = sigtimedwait(&set, &si, &ts); + res = sigtimedwait(&sigset, &si, &ts); Py_END_ALLOW_THREADS if (res != -1) @@ -1147,6 +1188,7 @@ static PyMethodDef signal_methods[] = { SIGNAL_SETITIMER_METHODDEF SIGNAL_GETITIMER_METHODDEF SIGNAL_SIGNAL_METHODDEF + SIGNAL_STRSIGNAL_METHODDEF SIGNAL_GETSIGNAL_METHODDEF {"set_wakeup_fd", (PyCFunction)signal_set_wakeup_fd, METH_VARARGS | METH_KEYWORDS, set_wakeup_fd_doc}, SIGNAL_SIGINTERRUPT_METHODDEF @@ -1157,6 +1199,9 @@ static PyMethodDef signal_methods[] = { SIGNAL_SIGWAIT_METHODDEF SIGNAL_SIGWAITINFO_METHODDEF SIGNAL_SIGTIMEDWAIT_METHODDEF +#if defined(HAVE_SIGFILLSET) || defined(MS_WINDOWS) + SIGNAL_VALID_SIGNALS_METHODDEF +#endif {NULL, NULL} /* sentinel */ }; diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 10ce770ebad201..35e33e160fb995 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -2504,7 +2504,7 @@ sock_accept_impl(PySocketSockObject *s, void *data) /* s._accept() -> (fd, address) */ static PyObject * -sock_accept(PySocketSockObject *s) +sock_accept(PySocketSockObject *s, PyObject *Py_UNUSED(ignored)) { sock_addr_t addrbuf; SOCKET_T newfd; @@ -2605,7 +2605,7 @@ setblocking(False) is equivalent to settimeout(0.0)."); False if it is in non-blocking mode. */ static PyObject * -sock_getblocking(PySocketSockObject *s) +sock_getblocking(PySocketSockObject *s, PyObject *Py_UNUSED(ignored)) { if (s->sock_timeout) { Py_RETURN_TRUE; @@ -2717,7 +2717,7 @@ Setting a timeout of zero is the same as setblocking(0)."); /* s.gettimeout() method. Returns the timeout associated with a socket. */ static PyObject * -sock_gettimeout(PySocketSockObject *s) +sock_gettimeout(PySocketSockObject *s, PyObject *Py_UNUSED(ignored)) { if (s->sock_timeout < 0) { Py_RETURN_NONE; @@ -2731,8 +2731,8 @@ sock_gettimeout(PySocketSockObject *s) PyDoc_STRVAR(gettimeout_doc, "gettimeout() -> timeout\n\ \n\ -Returns the timeout in seconds (float) associated with socket \n\ -operations. A timeout of None indicates that timeouts on socket \n\ +Returns the timeout in seconds (float) associated with socket\n\ +operations. A timeout of None indicates that timeouts on socket\n\ operations are disabled."); /* s.setsockopt() method. @@ -2822,7 +2822,7 @@ setsockopt(level, option, value: buffer)\n\ setsockopt(level, option, None, optlen: int)\n\ \n\ Set a socket option. See the Unix manual for level and option.\n\ -The value argument can either be an integer, a string buffer, or \n\ +The value argument can either be an integer, a string buffer, or\n\ None, optlen."); @@ -2935,7 +2935,7 @@ sockets the address is a tuple (ifname, proto [,pkttype [,hatype]])"); will surely fail. */ static PyObject * -sock_close(PySocketSockObject *s) +sock_close(PySocketSockObject *s, PyObject *Py_UNUSED(ignored)) { SOCKET_T fd; int res; @@ -2966,7 +2966,7 @@ PyDoc_STRVAR(sock_close_doc, Close the socket. It cannot be used after this call."); static PyObject * -sock_detach(PySocketSockObject *s) +sock_detach(PySocketSockObject *s, PyObject *Py_UNUSED(ignored)) { SOCKET_T fd = s->sock_fd; s->sock_fd = INVALID_SOCKET; @@ -3130,7 +3130,7 @@ instead of raising an exception when an error occurs."); /* s.fileno() method */ static PyObject * -sock_fileno(PySocketSockObject *s) +sock_fileno(PySocketSockObject *s, PyObject *Py_UNUSED(ignored)) { return PyLong_FromSocket_t(s->sock_fd); } @@ -3144,7 +3144,7 @@ Return the integer file descriptor of the socket."); /* s.getsockname() method */ static PyObject * -sock_getsockname(PySocketSockObject *s) +sock_getsockname(PySocketSockObject *s, PyObject *Py_UNUSED(ignored)) { sock_addr_t addrbuf; int res; @@ -3173,7 +3173,7 @@ info is a pair (hostaddr, port)."); /* s.getpeername() method */ static PyObject * -sock_getpeername(PySocketSockObject *s) +sock_getpeername(PySocketSockObject *s, PyObject *Py_UNUSED(ignored)) { sock_addr_t addrbuf; int res; @@ -3393,8 +3393,8 @@ sock_recv_into(PySocketSockObject *s, PyObject *args, PyObject *kwds) PyDoc_STRVAR(recv_into_doc, "recv_into(buffer, [nbytes[, flags]]) -> nbytes_read\n\ \n\ -A version of recv() that stores its data into a buffer rather than creating \n\ -a new string. Receive up to buffersize bytes from the socket. If buffersize \n\ +A version of recv() that stores its data into a buffer rather than creating\n\ +a new string. Receive up to buffersize bytes from the socket. If buffersize\n\ is not specified (or 0), receive up to the size available in the given buffer.\n\ \n\ See recv() for documentation about the flags."); @@ -5277,9 +5277,6 @@ socket_gethostbyname(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "et:gethostbyname", "idna", &name)) return NULL; - if (PySys_Audit("socket.gethostbyname", "O", args) < 0) { - goto finally; - } if (setipaddr(name, (struct sockaddr *)&addrbuf, sizeof(addrbuf), AF_INET) < 0) goto finally; ret = make_ipv4_addr(&addrbuf); @@ -5912,7 +5909,7 @@ Convert a 16-bit unsigned integer from network to host byte order.\n\ Note that in case the received integer does not fit in 16-bit unsigned\n\ integer, but does fit in a positive C int, it is silently truncated to\n\ 16-bit unsigned integer.\n\ -However, this silent truncation feature is deprecated, and will raise an \n\ +However, this silent truncation feature is deprecated, and will raise an\n\ exception in future versions of Python."); @@ -5983,7 +5980,7 @@ Convert a 16-bit unsigned integer from host to network byte order.\n\ Note that in case the received integer does not fit in 16-bit unsigned\n\ integer, but does fit in a positive C int, it is silently truncated to\n\ 16-bit unsigned integer.\n\ -However, this silent truncation feature is deprecated, and will raise an \n\ +However, this silent truncation feature is deprecated, and will raise an\n\ exception in future versions of Python."); @@ -6468,7 +6465,7 @@ Get host and port for a sockaddr."); /* Python API to getting and setting the default timeout value. */ static PyObject * -socket_getdefaulttimeout(PyObject *self) +socket_getdefaulttimeout(PyObject *self, PyObject *Py_UNUSED(ignored)) { if (defaulttimeout < 0) { Py_RETURN_NONE; @@ -6717,7 +6714,7 @@ static PyMethodDef socket_methods[] = { METH_VARARGS | METH_KEYWORDS, getaddrinfo_doc}, {"getnameinfo", socket_getnameinfo, METH_VARARGS, getnameinfo_doc}, - {"getdefaulttimeout", (PyCFunction)socket_getdefaulttimeout, + {"getdefaulttimeout", socket_getdefaulttimeout, METH_NOARGS, getdefaulttimeout_doc}, {"setdefaulttimeout", socket_setdefaulttimeout, METH_O, setdefaulttimeout_doc}, diff --git a/Modules/unicodedata.c b/Modules/unicodedata.c index 7a9a964a0f6cf0..e8788f5036ddef 100644 --- a/Modules/unicodedata.c +++ b/Modules/unicodedata.c @@ -681,15 +681,19 @@ nfc_nfkc(PyObject *self, PyObject *input, int k) if (LBase <= code && code < (LBase+LCount) && i + 1 < len && VBase <= PyUnicode_READ(kind, data, i+1) && - PyUnicode_READ(kind, data, i+1) <= (VBase+VCount)) { + PyUnicode_READ(kind, data, i+1) < (VBase+VCount)) { + /* check L character is a modern leading consonant (0x1100 ~ 0x1112) + and V character is a modern vowel (0x1161 ~ 0x1175). */ int LIndex, VIndex; LIndex = code - LBase; VIndex = PyUnicode_READ(kind, data, i+1) - VBase; code = SBase + (LIndex*VCount+VIndex)*TCount; i+=2; if (i < len && - TBase <= PyUnicode_READ(kind, data, i) && - PyUnicode_READ(kind, data, i) <= (TBase+TCount)) { + TBase < PyUnicode_READ(kind, data, i) && + PyUnicode_READ(kind, data, i) < (TBase+TCount)) { + /* check T character is a modern trailing consonant + (0x11A8 ~ 0x11C2). */ code += PyUnicode_READ(kind, data, i)-TBase; i++; } diff --git a/Modules/zlibmodule.c b/Modules/zlibmodule.c index cd587b4ac9c77d..36a3835e421fbb 100644 --- a/Modules/zlibmodule.c +++ b/Modules/zlibmodule.c @@ -984,6 +984,32 @@ zlib_Compress_copy_impl(compobject *self) return NULL; } +/*[clinic input] +zlib.Compress.__copy__ +[clinic start generated code]*/ + +static PyObject * +zlib_Compress___copy___impl(compobject *self) +/*[clinic end generated code: output=1875e6791975442e input=be97a05a788dfd83]*/ +{ + return zlib_Compress_copy_impl(self); +} + +/*[clinic input] +zlib.Compress.__deepcopy__ + + memo: object + / + +[clinic start generated code]*/ + +static PyObject * +zlib_Compress___deepcopy__(compobject *self, PyObject *memo) +/*[clinic end generated code: output=f47a2213282c9eb0 input=a9a8b0b40d83388e]*/ +{ + return zlib_Compress_copy_impl(self); +} + /*[clinic input] zlib.Decompress.copy @@ -1039,6 +1065,33 @@ zlib_Decompress_copy_impl(compobject *self) Py_XDECREF(retval); return NULL; } + +/*[clinic input] +zlib.Decompress.__copy__ +[clinic start generated code]*/ + +static PyObject * +zlib_Decompress___copy___impl(compobject *self) +/*[clinic end generated code: output=80bae8bc43498ad4 input=efcb98b5472c13d2]*/ +{ + return zlib_Decompress_copy_impl(self); +} + +/*[clinic input] +zlib.Decompress.__deepcopy__ + + memo: object + / + +[clinic start generated code]*/ + +static PyObject * +zlib_Decompress___deepcopy__(compobject *self, PyObject *memo) +/*[clinic end generated code: output=1f77286ab490124b input=6e99bd0ac4b9cd8b]*/ +{ + return zlib_Decompress_copy_impl(self); +} + #endif /*[clinic input] @@ -1139,6 +1192,8 @@ static PyMethodDef comp_methods[] = ZLIB_COMPRESS_COMPRESS_METHODDEF ZLIB_COMPRESS_FLUSH_METHODDEF ZLIB_COMPRESS_COPY_METHODDEF + ZLIB_COMPRESS___COPY___METHODDEF + ZLIB_COMPRESS___DEEPCOPY___METHODDEF {NULL, NULL} }; @@ -1147,6 +1202,8 @@ static PyMethodDef Decomp_methods[] = ZLIB_DECOMPRESS_DECOMPRESS_METHODDEF ZLIB_DECOMPRESS_FLUSH_METHODDEF ZLIB_DECOMPRESS_COPY_METHODDEF + ZLIB_DECOMPRESS___COPY___METHODDEF + ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF {NULL, NULL} }; diff --git a/Objects/abstract.c b/Objects/abstract.c index 93eda62a2745bf..192ade115789b5 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -1244,6 +1244,15 @@ PyNumber_Absolute(PyObject *o) return type_error("bad operand type for abs(): '%.200s'", o); } +#undef PyIndex_Check + +int +PyIndex_Check(PyObject *obj) +{ + return obj->ob_type->tp_as_number != NULL && + obj->ob_type->tp_as_number->nb_index != NULL; +} + /* 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. @@ -2535,6 +2544,14 @@ PyObject_GetIter(PyObject *o) } } +#undef PyIter_Check + +int PyIter_Check(PyObject *obj) +{ + return obj->ob_type->tp_iternext != NULL && + obj->ob_type->tp_iternext != &_PyObject_NextNotImplemented; +} + /* Return next item. * If an error occurs, return NULL. PyErr_Occurred() will be true. * If the iteration terminates normally, return NULL and clear the diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 692b7be7392455..9d32965ca23842 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -1940,7 +1940,7 @@ PyDoc_STRVAR(alloc_doc, Return the number of bytes actually allocated."); static PyObject * -bytearray_alloc(PyByteArrayObject *self) +bytearray_alloc(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored)) { return PyLong_FromSsize_t(self->ob_alloc); } @@ -2018,7 +2018,7 @@ Create a string of hexadecimal numbers from a bytearray object.\n\ Example: bytearray([0xb9, 0x01, 0xef]).hex() -> 'b901ef'."); static PyObject * -bytearray_hex(PyBytesObject *self) +bytearray_hex(PyBytesObject *self, PyObject *Py_UNUSED(ignored)) { char* argbuf = PyByteArray_AS_STRING(self); Py_ssize_t arglen = PyByteArray_GET_SIZE(self); @@ -2136,9 +2136,9 @@ bytearray_methods[] = { BYTEARRAY_REDUCE_EX_METHODDEF BYTEARRAY_SIZEOF_METHODDEF BYTEARRAY_APPEND_METHODDEF - {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS, + {"capitalize", stringlib_capitalize, METH_NOARGS, _Py_capitalize__doc__}, - {"center", (PyCFunction)stringlib_center, METH_VARARGS, _Py_center__doc__}, + STRINGLIB_CENTER_METHODDEF BYTEARRAY_CLEAR_METHODDEF BYTEARRAY_COPY_METHODDEF {"count", (PyCFunction)bytearray_count, METH_VARARGS, @@ -2146,8 +2146,7 @@ bytearray_methods[] = { BYTEARRAY_DECODE_METHODDEF {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, _Py_endswith__doc__}, - {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS | METH_KEYWORDS, - _Py_expandtabs__doc__}, + STRINGLIB_EXPANDTABS_METHODDEF BYTEARRAY_EXTEND_METHODDEF {"find", (PyCFunction)bytearray_find, METH_VARARGS, _Py_find__doc__}, @@ -2155,25 +2154,25 @@ bytearray_methods[] = { {"hex", (PyCFunction)bytearray_hex, METH_NOARGS, hex__doc__}, {"index", (PyCFunction)bytearray_index, METH_VARARGS, _Py_index__doc__}, BYTEARRAY_INSERT_METHODDEF - {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS, + {"isalnum", stringlib_isalnum, METH_NOARGS, _Py_isalnum__doc__}, - {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS, + {"isalpha", stringlib_isalpha, METH_NOARGS, _Py_isalpha__doc__}, - {"isascii", (PyCFunction)stringlib_isascii, METH_NOARGS, + {"isascii", stringlib_isascii, METH_NOARGS, _Py_isascii__doc__}, - {"isdigit", (PyCFunction)stringlib_isdigit, METH_NOARGS, + {"isdigit", stringlib_isdigit, METH_NOARGS, _Py_isdigit__doc__}, - {"islower", (PyCFunction)stringlib_islower, METH_NOARGS, + {"islower", stringlib_islower, METH_NOARGS, _Py_islower__doc__}, - {"isspace", (PyCFunction)stringlib_isspace, METH_NOARGS, + {"isspace", stringlib_isspace, METH_NOARGS, _Py_isspace__doc__}, - {"istitle", (PyCFunction)stringlib_istitle, METH_NOARGS, + {"istitle", stringlib_istitle, METH_NOARGS, _Py_istitle__doc__}, - {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS, + {"isupper", stringlib_isupper, METH_NOARGS, _Py_isupper__doc__}, BYTEARRAY_JOIN_METHODDEF - {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, _Py_ljust__doc__}, - {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__}, + STRINGLIB_LJUST_METHODDEF + {"lower", stringlib_lower, METH_NOARGS, _Py_lower__doc__}, BYTEARRAY_LSTRIP_METHODDEF BYTEARRAY_MAKETRANS_METHODDEF BYTEARRAY_PARTITION_METHODDEF @@ -2183,7 +2182,7 @@ bytearray_methods[] = { BYTEARRAY_REVERSE_METHODDEF {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, _Py_rfind__doc__}, {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, _Py_rindex__doc__}, - {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, _Py_rjust__doc__}, + STRINGLIB_RJUST_METHODDEF BYTEARRAY_RPARTITION_METHODDEF BYTEARRAY_RSPLIT_METHODDEF BYTEARRAY_RSTRIP_METHODDEF @@ -2192,12 +2191,12 @@ bytearray_methods[] = { {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS , _Py_startswith__doc__}, BYTEARRAY_STRIP_METHODDEF - {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS, + {"swapcase", stringlib_swapcase, METH_NOARGS, _Py_swapcase__doc__}, - {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__}, + {"title", stringlib_title, METH_NOARGS, _Py_title__doc__}, BYTEARRAY_TRANSLATE_METHODDEF - {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__}, - {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, _Py_zfill__doc__}, + {"upper", stringlib_upper, METH_NOARGS, _Py_upper__doc__}, + STRINGLIB_ZFILL_METHODDEF {NULL} }; @@ -2324,7 +2323,7 @@ bytearrayiter_next(bytesiterobject *it) } static PyObject * -bytearrayiter_length_hint(bytesiterobject *it) +bytearrayiter_length_hint(bytesiterobject *it, PyObject *Py_UNUSED(ignored)) { Py_ssize_t len = 0; if (it->it_seq) { @@ -2340,7 +2339,7 @@ PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); static PyObject * -bytearrayiter_reduce(bytesiterobject *it) +bytearrayiter_reduce(bytesiterobject *it, PyObject *Py_UNUSED(ignored)) { if (it->it_seq != NULL) { return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"), diff --git a/Objects/bytes_methods.c b/Objects/bytes_methods.c index 07842f74691013..05679e31c9d68c 100644 --- a/Objects/bytes_methods.c +++ b/Objects/bytes_methods.c @@ -845,33 +845,3 @@ _Py_bytes_endswith(const char *str, Py_ssize_t len, PyObject *args) { return _Py_bytes_tailmatch(str, len, "endswith", args, +1); } - -PyDoc_STRVAR_shared(_Py_expandtabs__doc__, -"B.expandtabs(tabsize=8) -> copy of B\n\ -\n\ -Return a copy of B where all tab characters are expanded using spaces.\n\ -If tabsize is not given, a tab size of 8 characters is assumed."); - -PyDoc_STRVAR_shared(_Py_ljust__doc__, -"B.ljust(width[, fillchar]) -> copy of B\n" -"\n" -"Return B left justified in a string of length width. Padding is\n" -"done using the specified fill character (default is a space)."); - -PyDoc_STRVAR_shared(_Py_rjust__doc__, -"B.rjust(width[, fillchar]) -> copy of B\n" -"\n" -"Return B right justified in a string of length width. Padding is\n" -"done using the specified fill character (default is a space)"); - -PyDoc_STRVAR_shared(_Py_center__doc__, -"B.center(width[, fillchar]) -> copy of B\n" -"\n" -"Return B centered in a string of length width. Padding is\n" -"done using the specified fill character (default is a space)."); - -PyDoc_STRVAR_shared(_Py_zfill__doc__, -"B.zfill(width) -> copy of B\n" -"\n" -"Pad a numeric string B with zeros on the left, to fill a field\n" -"of the specified width. B is never truncated."); diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index c358756bfea8e6..943c329ebc2190 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -2422,7 +2422,7 @@ Create a string of hexadecimal numbers from a bytes object.\n\ Example: b'\\xb9\\x01\\xef'.hex() -> 'b901ef'."); static PyObject * -bytes_hex(PyBytesObject *self) +bytes_hex(PyBytesObject *self, PyObject *Py_UNUSED(ignored)) { char* argbuf = PyBytes_AS_STRING(self); Py_ssize_t arglen = PyBytes_GET_SIZE(self); @@ -2430,7 +2430,7 @@ bytes_hex(PyBytesObject *self) } static PyObject * -bytes_getnewargs(PyBytesObject *v) +bytes_getnewargs(PyBytesObject *v, PyObject *Py_UNUSED(ignored)) { return Py_BuildValue("(y#)", v->ob_sval, Py_SIZE(v)); } @@ -2439,48 +2439,46 @@ bytes_getnewargs(PyBytesObject *v) static PyMethodDef bytes_methods[] = { {"__getnewargs__", (PyCFunction)bytes_getnewargs, METH_NOARGS}, - {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS, + {"capitalize", stringlib_capitalize, METH_NOARGS, _Py_capitalize__doc__}, - {"center", (PyCFunction)stringlib_center, METH_VARARGS, - _Py_center__doc__}, + STRINGLIB_CENTER_METHODDEF {"count", (PyCFunction)bytes_count, METH_VARARGS, _Py_count__doc__}, BYTES_DECODE_METHODDEF {"endswith", (PyCFunction)bytes_endswith, METH_VARARGS, _Py_endswith__doc__}, - {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS | METH_KEYWORDS, - _Py_expandtabs__doc__}, + STRINGLIB_EXPANDTABS_METHODDEF {"find", (PyCFunction)bytes_find, METH_VARARGS, _Py_find__doc__}, BYTES_FROMHEX_METHODDEF {"hex", (PyCFunction)bytes_hex, METH_NOARGS, hex__doc__}, {"index", (PyCFunction)bytes_index, METH_VARARGS, _Py_index__doc__}, - {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS, + {"isalnum", stringlib_isalnum, METH_NOARGS, _Py_isalnum__doc__}, - {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS, + {"isalpha", stringlib_isalpha, METH_NOARGS, _Py_isalpha__doc__}, - {"isascii", (PyCFunction)stringlib_isascii, METH_NOARGS, + {"isascii", stringlib_isascii, METH_NOARGS, _Py_isascii__doc__}, - {"isdigit", (PyCFunction)stringlib_isdigit, METH_NOARGS, + {"isdigit", stringlib_isdigit, METH_NOARGS, _Py_isdigit__doc__}, - {"islower", (PyCFunction)stringlib_islower, METH_NOARGS, + {"islower", stringlib_islower, METH_NOARGS, _Py_islower__doc__}, - {"isspace", (PyCFunction)stringlib_isspace, METH_NOARGS, + {"isspace", stringlib_isspace, METH_NOARGS, _Py_isspace__doc__}, - {"istitle", (PyCFunction)stringlib_istitle, METH_NOARGS, + {"istitle", stringlib_istitle, METH_NOARGS, _Py_istitle__doc__}, - {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS, + {"isupper", stringlib_isupper, METH_NOARGS, _Py_isupper__doc__}, BYTES_JOIN_METHODDEF - {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, _Py_ljust__doc__}, - {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__}, + STRINGLIB_LJUST_METHODDEF + {"lower", stringlib_lower, METH_NOARGS, _Py_lower__doc__}, BYTES_LSTRIP_METHODDEF BYTES_MAKETRANS_METHODDEF BYTES_PARTITION_METHODDEF BYTES_REPLACE_METHODDEF {"rfind", (PyCFunction)bytes_rfind, METH_VARARGS, _Py_rfind__doc__}, {"rindex", (PyCFunction)bytes_rindex, METH_VARARGS, _Py_rindex__doc__}, - {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, _Py_rjust__doc__}, + STRINGLIB_RJUST_METHODDEF BYTES_RPARTITION_METHODDEF BYTES_RSPLIT_METHODDEF BYTES_RSTRIP_METHODDEF @@ -2489,12 +2487,12 @@ bytes_methods[] = { {"startswith", (PyCFunction)bytes_startswith, METH_VARARGS, _Py_startswith__doc__}, BYTES_STRIP_METHODDEF - {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS, + {"swapcase", stringlib_swapcase, METH_NOARGS, _Py_swapcase__doc__}, - {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__}, + {"title", stringlib_title, METH_NOARGS, _Py_title__doc__}, BYTES_TRANSLATE_METHODDEF - {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__}, - {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, _Py_zfill__doc__}, + {"upper", stringlib_upper, METH_NOARGS, _Py_upper__doc__}, + STRINGLIB_ZFILL_METHODDEF {NULL, NULL} /* sentinel */ }; @@ -3037,7 +3035,7 @@ striter_next(striterobject *it) } static PyObject * -striter_len(striterobject *it) +striter_len(striterobject *it, PyObject *Py_UNUSED(ignored)) { Py_ssize_t len = 0; if (it->it_seq) @@ -3049,7 +3047,7 @@ PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); static PyObject * -striter_reduce(striterobject *it) +striter_reduce(striterobject *it, PyObject *Py_UNUSED(ignored)) { if (it->it_seq != NULL) { return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"), diff --git a/Objects/classobject.c b/Objects/classobject.c index 3dc23b796c2c16..095b0cad2b5c57 100644 --- a/Objects/classobject.c +++ b/Objects/classobject.c @@ -73,7 +73,7 @@ PyMethod_New(PyObject *func, PyObject *self) } static PyObject * -method_reduce(PyMethodObject *im) +method_reduce(PyMethodObject *im, PyObject *Py_UNUSED(ignored)) { PyObject *self = PyMethod_GET_SELF(im); PyObject *func = PyMethod_GET_FUNCTION(im); diff --git a/Objects/codeobject.c b/Objects/codeobject.c index f5f4b7c26d5738..048129e6148127 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -492,14 +492,21 @@ _PyCode_ConstantKey(PyObject *op) { PyObject *key; - /* Py_None and Py_Ellipsis are singleton */ + /* Py_None and Py_Ellipsis are singletons. */ if (op == Py_None || op == Py_Ellipsis || PyLong_CheckExact(op) - || PyBool_Check(op) - || PyBytes_CheckExact(op) || PyUnicode_CheckExact(op) /* code_richcompare() uses _PyCode_ConstantKey() internally */ - || PyCode_Check(op)) { + || PyCode_Check(op)) + { + /* Objects of these types are always different from object of other + * type and from tuples. */ + Py_INCREF(op); + key = op; + } + else if (PyBool_Check(op) || PyBytes_CheckExact(op)) { + /* Make booleans different from integers 0 and 1. + * Avoid BytesWarning from comparing bytes with strings. */ key = PyTuple_Pack(2, Py_TYPE(op), op); } else if (PyFloat_CheckExact(op)) { diff --git a/Objects/complexobject.c b/Objects/complexobject.c index 2c886c7a7685db..6e3d47b62d1937 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -695,7 +695,7 @@ complex_float(PyObject *v) } static PyObject * -complex_conjugate(PyObject *self) +complex_conjugate(PyObject *self, PyObject *Py_UNUSED(ignored)) { Py_complex c; c = ((PyComplexObject *)self)->cval; @@ -709,7 +709,7 @@ PyDoc_STRVAR(complex_conjugate_doc, "Return the complex conjugate of its argument. (3-4j).conjugate() == 3+4j."); static PyObject * -complex_getnewargs(PyComplexObject *v) +complex_getnewargs(PyComplexObject *v, PyObject *Py_UNUSED(ignored)) { Py_complex c = v->cval; return Py_BuildValue("(dd)", c.real, c.imag); diff --git a/Objects/descrobject.c b/Objects/descrobject.c index c2ee157c817765..7e0179bcbe3e09 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -455,7 +455,7 @@ descr_get_qualname(PyDescrObject *descr) } static PyObject * -descr_reduce(PyDescrObject *descr) +descr_reduce(PyDescrObject *descr, PyObject *Py_UNUSED(ignored)) { PyObject *builtins; PyObject *getattr; @@ -875,28 +875,28 @@ mappingproxy_get(mappingproxyobject *pp, PyObject *args) } static PyObject * -mappingproxy_keys(mappingproxyobject *pp) +mappingproxy_keys(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored)) { _Py_IDENTIFIER(keys); return _PyObject_CallMethodId(pp->mapping, &PyId_keys, NULL); } static PyObject * -mappingproxy_values(mappingproxyobject *pp) +mappingproxy_values(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored)) { _Py_IDENTIFIER(values); return _PyObject_CallMethodId(pp->mapping, &PyId_values, NULL); } static PyObject * -mappingproxy_items(mappingproxyobject *pp) +mappingproxy_items(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored)) { _Py_IDENTIFIER(items); return _PyObject_CallMethodId(pp->mapping, &PyId_items, NULL); } static PyObject * -mappingproxy_copy(mappingproxyobject *pp) +mappingproxy_copy(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored)) { _Py_IDENTIFIER(copy); return _PyObject_CallMethodId(pp->mapping, &PyId_copy, NULL); @@ -1093,7 +1093,7 @@ wrapper_repr(wrapperobject *wp) } static PyObject * -wrapper_reduce(wrapperobject *wp) +wrapper_reduce(wrapperobject *wp, PyObject *Py_UNUSED(ignored)) { PyObject *builtins; PyObject *getattr; diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 7a1bcebec6fdfd..413557d6674127 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -656,6 +656,13 @@ clone_combined_dict(PyDictObject *orig) /* Maintain tracking. */ _PyObject_GC_TRACK(new); } + + /* Since we copied the keys table we now have an extra reference + in the system. Manually call _Py_INC_REFTOTAL to signal that + we have it now; calling DK_INCREF would be an error as + keys->dk_refcnt is already set to 1 (after memcpy). */ + _Py_INC_REFTOTAL; + return (PyObject *)new; } @@ -2511,7 +2518,7 @@ _PyDict_MergeEx(PyObject *a, PyObject *b, int override) } static PyObject * -dict_copy(PyDictObject *mp) +dict_copy(PyDictObject *mp, PyObject *Py_UNUSED(ignored)) { return PyDict_Copy((PyObject*)mp); } @@ -2874,7 +2881,7 @@ dict_setdefault_impl(PyDictObject *self, PyObject *key, } static PyObject * -dict_clear(PyDictObject *mp) +dict_clear(PyDictObject *mp, PyObject *Py_UNUSED(ignored)) { PyDict_Clear((PyObject *)mp); Py_RETURN_NONE; @@ -2892,7 +2899,7 @@ dict_pop(PyDictObject *mp, PyObject *args) } static PyObject * -dict_popitem(PyDictObject *mp) +dict_popitem(PyDictObject *mp, PyObject *Py_UNUSED(ignored)) { Py_ssize_t i, j; PyDictKeyEntry *ep0, *ep; @@ -3020,7 +3027,7 @@ _PyDict_KeysSize(PyDictKeysObject *keys) } static PyObject * -dict_sizeof(PyDictObject *mp) +dict_sizeof(PyDictObject *mp, PyObject *Py_UNUSED(ignored)) { return PyLong_FromSsize_t(_PyDict_SizeOf(mp)); } @@ -3051,9 +3058,9 @@ PyDoc_STRVAR(copy__doc__, "D.copy() -> a shallow copy of D"); /* Forward */ -static PyObject *dictkeys_new(PyObject *); -static PyObject *dictitems_new(PyObject *); -static PyObject *dictvalues_new(PyObject *); +static PyObject *dictkeys_new(PyObject *, PyObject *); +static PyObject *dictitems_new(PyObject *, PyObject *); +static PyObject *dictvalues_new(PyObject *, PyObject *); PyDoc_STRVAR(keys__doc__, "D.keys() -> a set-like object providing a view on D's keys"); @@ -3074,11 +3081,11 @@ static PyMethodDef mapp_methods[] = { pop__doc__}, {"popitem", (PyCFunction)dict_popitem, METH_NOARGS, popitem__doc__}, - {"keys", (PyCFunction)dictkeys_new, METH_NOARGS, + {"keys", dictkeys_new, METH_NOARGS, keys__doc__}, - {"items", (PyCFunction)dictitems_new, METH_NOARGS, + {"items", dictitems_new, METH_NOARGS, items__doc__}, - {"values", (PyCFunction)dictvalues_new, METH_NOARGS, + {"values", dictvalues_new, METH_NOARGS, values__doc__}, {"update", (PyCFunction)dict_update, METH_VARARGS | METH_KEYWORDS, update__doc__}, @@ -3361,7 +3368,7 @@ dictiter_traverse(dictiterobject *di, visitproc visit, void *arg) } static PyObject * -dictiter_len(dictiterobject *di) +dictiter_len(dictiterobject *di, PyObject *Py_UNUSED(ignored)) { Py_ssize_t len = 0; if (di->di_dict != NULL && di->di_used == di->di_dict->ma_used) @@ -3373,7 +3380,7 @@ PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); static PyObject * -dictiter_reduce(dictiterobject *di); +dictiter_reduce(dictiterobject *di, PyObject *Py_UNUSED(ignored)); PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); @@ -3652,7 +3659,7 @@ PyTypeObject PyDictIterItem_Type = { static PyObject * -dictiter_reduce(dictiterobject *di) +dictiter_reduce(dictiterobject *di, PyObject *Py_UNUSED(ignored)) { PyObject *list; dictiterobject tmp; @@ -4092,7 +4099,7 @@ PyTypeObject PyDictKeys_Type = { }; static PyObject * -dictkeys_new(PyObject *dict) +dictkeys_new(PyObject *dict, PyObject *Py_UNUSED(ignored)) { return _PyDictView_New(dict, &PyDictKeys_Type); } @@ -4182,7 +4189,7 @@ PyTypeObject PyDictItems_Type = { }; static PyObject * -dictitems_new(PyObject *dict) +dictitems_new(PyObject *dict, PyObject *Py_UNUSED(ignored)) { return _PyDictView_New(dict, &PyDictItems_Type); } @@ -4247,7 +4254,7 @@ PyTypeObject PyDictValues_Type = { }; static PyObject * -dictvalues_new(PyObject *dict) +dictvalues_new(PyObject *dict, PyObject *Py_UNUSED(ignored)) { return _PyDictView_New(dict, &PyDictValues_Type); } diff --git a/Objects/enumobject.c b/Objects/enumobject.c index 4d0af14008b939..d993a5063fdf60 100644 --- a/Objects/enumobject.c +++ b/Objects/enumobject.c @@ -189,7 +189,7 @@ enum_next(enumobject *en) } static PyObject * -enum_reduce(enumobject *en) +enum_reduce(enumobject *en, PyObject *Py_UNUSED(ignored)) { if (en->en_longindex != NULL) return Py_BuildValue("O(OO)", Py_TYPE(en), en->en_sit, en->en_longindex); @@ -349,7 +349,7 @@ reversed_next(reversedobject *ro) } static PyObject * -reversed_len(reversedobject *ro) +reversed_len(reversedobject *ro, PyObject *Py_UNUSED(ignored)) { Py_ssize_t position, seqsize; @@ -365,7 +365,7 @@ reversed_len(reversedobject *ro) PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); static PyObject * -reversed_reduce(reversedobject *ro) +reversed_reduce(reversedobject *ro, PyObject *Py_UNUSED(ignored)) { if (ro->seq) return Py_BuildValue("O(O)n", Py_TYPE(ro), ro->seq, ro->index); diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 2cce40f884442a..bb50c1c36964d9 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -126,7 +126,7 @@ BaseException_repr(PyBaseExceptionObject *self) /* Pickling support */ static PyObject * -BaseException_reduce(PyBaseExceptionObject *self) +BaseException_reduce(PyBaseExceptionObject *self, PyObject *Py_UNUSED(ignored)) { if (self->args && self->dict) return PyTuple_Pack(3, Py_TYPE(self), self->args, self->dict); @@ -342,6 +342,13 @@ PyException_SetContext(PyObject *self, PyObject *context) Py_XSETREF(((PyBaseExceptionObject *)self)->context, context); } +#undef PyExceptionClass_Name + +const char * +PyExceptionClass_Name(PyObject *ob) +{ + return ((PyTypeObject*)ob)->tp_name; +} static struct PyMemberDef BaseException_members[] = { {"__suppress_context__", T_BOOL, @@ -713,7 +720,7 @@ ImportError_getstate(PyImportErrorObject *self) /* Pickling support */ static PyObject * -ImportError_reduce(PyImportErrorObject *self) +ImportError_reduce(PyImportErrorObject *self, PyObject *Py_UNUSED(ignored)) { PyObject *res; PyObject *args; @@ -1123,7 +1130,7 @@ OSError_str(PyOSErrorObject *self) } static PyObject * -OSError_reduce(PyOSErrorObject *self) +OSError_reduce(PyOSErrorObject *self, PyObject *Py_UNUSED(ignored)) { PyObject *args = self->args; PyObject *res = NULL, *tmp; diff --git a/Objects/fileobject.c b/Objects/fileobject.c index dd4f06d3631531..e6c7612710b7eb 100644 --- a/Objects/fileobject.c +++ b/Objects/fileobject.c @@ -398,7 +398,7 @@ stdprinter_write(PyStdPrinter_Object *self, PyObject *args) } static PyObject * -stdprinter_fileno(PyStdPrinter_Object *self) +stdprinter_fileno(PyStdPrinter_Object *self, PyObject *Py_UNUSED(ignored)) { return PyLong_FromLong((long) self->fd); } @@ -411,13 +411,13 @@ stdprinter_repr(PyStdPrinter_Object *self) } static PyObject * -stdprinter_noop(PyStdPrinter_Object *self) +stdprinter_noop(PyStdPrinter_Object *self, PyObject *Py_UNUSED(ignored)) { Py_RETURN_NONE; } static PyObject * -stdprinter_isatty(PyStdPrinter_Object *self) +stdprinter_isatty(PyStdPrinter_Object *self, PyObject *Py_UNUSED(ignored)) { long res; if (self->fd < 0) { diff --git a/Objects/frameobject.c b/Objects/frameobject.c index f518dc4856162e..9f224fdc9728f4 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -45,6 +45,27 @@ frame_getlineno(PyFrameObject *f, void *closure) return PyLong_FromLong(PyFrame_GetLineNumber(f)); } + +/* Given the index of the effective opcode, + scan back to construct the oparg with EXTENDED_ARG */ +static unsigned int +get_arg(const _Py_CODEUNIT *codestr, Py_ssize_t i) +{ + _Py_CODEUNIT word; + unsigned int oparg = _Py_OPARG(codestr[i]); + if (i >= 1 && _Py_OPCODE(word = codestr[i-1]) == EXTENDED_ARG) { + oparg |= _Py_OPARG(word) << 8; + if (i >= 2 && _Py_OPCODE(word = codestr[i-2]) == EXTENDED_ARG) { + oparg |= _Py_OPARG(word) << 16; + if (i >= 3 && _Py_OPCODE(word = codestr[i-3]) == EXTENDED_ARG) { + oparg |= _Py_OPARG(word) << 24; + } + } + } + return oparg; +} + + /* Setter for f_lineno - you can set f_lineno from within a trace function in * order to jump to a given line of code, subject to some restrictions. Most * lines are OK to jump to because they don't make any assumptions about the @@ -56,8 +77,9 @@ frame_getlineno(PyFrameObject *f, void *closure) * they expect an exception to be on the top of the stack. * o Lines that live in a 'finally' block can't be jumped from or to, since * the END_FINALLY expects to clean up the stack after the 'try' block. - * o 'try'/'for'/'while' blocks can't be jumped into because the blockstack - * needs to be set up before their code runs, and for 'for' loops the + * o 'try', 'with' and 'async with' blocks can't be jumped into because + * the blockstack needs to be set up before their code runs. + * o 'for' and 'async for' loops can't be jumped into because the * iterator needs to be on the stack. * o Jumps cannot be made from within a trace function invoked with a * 'return' or 'exception' event since the eval loop has been exited at @@ -70,7 +92,6 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno) long l_new_lineno; int overflow; int new_lasti = 0; /* The new value of f_lasti */ - int new_iblock = 0; /* The new value of f_iblock */ unsigned char *code = NULL; /* The bytecode for the frame... */ Py_ssize_t code_len = 0; /* ...and its length */ unsigned char *lnotab = NULL; /* Iterating over co_lnotab */ @@ -78,17 +99,10 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno) int offset = 0; /* (ditto) */ int line = 0; /* (ditto) */ int addr = 0; /* (ditto) */ - int min_addr = 0; /* Scanning the SETUPs and POPs */ - int max_addr = 0; /* (ditto) */ - int delta_iblock = 0; /* (ditto) */ - int min_delta_iblock = 0; /* (ditto) */ - int min_iblock = 0; /* (ditto) */ - int f_lasti_setup_addr = 0; /* Policing no-jump-into-finally */ - int new_lasti_setup_addr = 0; /* (ditto) */ + int delta_iblock = 0; /* Scanning the SETUPs and POPs */ + int delta = 0; int blockstack[CO_MAXBLOCKS]; /* Walking the 'finally' blocks */ - int in_finally[CO_MAXBLOCKS]; /* (ditto) */ int blockstack_top = 0; /* (ditto) */ - unsigned char setup_op = 0; /* (ditto) */ /* f_lineno must be an integer. */ if (!PyLong_CheckExact(p_new_lineno)) { @@ -191,9 +205,6 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno) return -1; } - min_addr = Py_MIN(new_lasti, f->f_lasti); - max_addr = Py_MAX(new_lasti, f->f_lasti); - /* You can't jump onto a line with an 'except' statement on it - * they expect to have an exception on the top of the stack, which * won't be true if you jump to them. They always start with code @@ -211,146 +222,87 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno) } /* You can't jump into or out of a 'finally' block because the 'try' - * block leaves something on the stack for the END_FINALLY to clean - * up. So we walk the bytecode, maintaining a simulated blockstack. - * When we reach the old or new address and it's in a 'finally' block - * we note the address of the corresponding SETUP_FINALLY. The jump - * is only legal if neither address is in a 'finally' block or - * they're both in the same one. 'blockstack' is a stack of the - * bytecode addresses of the SETUP_X opcodes, and 'in_finally' tracks - * whether we're in a 'finally' block at each blockstack level. */ - f_lasti_setup_addr = -1; - new_lasti_setup_addr = -1; + * block leaves something on the stack for the END_FINALLY to clean up. + * So we walk the bytecode, maintaining a simulated blockstack. + * 'blockstack' is a stack of the bytecode addresses of the starts of + * the 'finally' blocks. */ memset(blockstack, '\0', sizeof(blockstack)); - memset(in_finally, '\0', sizeof(in_finally)); blockstack_top = 0; for (addr = 0; addr < code_len; addr += sizeof(_Py_CODEUNIT)) { unsigned char op = code[addr]; switch (op) { - case SETUP_LOOP: - case SETUP_EXCEPT: case SETUP_FINALLY: case SETUP_WITH: case SETUP_ASYNC_WITH: - blockstack[blockstack_top++] = addr; - in_finally[blockstack_top-1] = 0; - break; - - case POP_BLOCK: - assert(blockstack_top > 0); - setup_op = code[blockstack[blockstack_top-1]]; - if (setup_op == SETUP_FINALLY || setup_op == SETUP_WITH - || setup_op == SETUP_ASYNC_WITH) { - in_finally[blockstack_top-1] = 1; - } - else { - blockstack_top--; + case FOR_ITER: { + unsigned int oparg = get_arg((const _Py_CODEUNIT *)code, + addr / sizeof(_Py_CODEUNIT)); + int target_addr = addr + oparg + sizeof(_Py_CODEUNIT); + assert(target_addr < code_len); + /* Police block-jumping (you can't jump into the middle of a block) + * and ensure that the blockstack finishes up in a sensible state (by + * popping any blocks we're jumping out of). We look at all the + * blockstack operations between the current position and the new + * one, and keep track of how many blocks we drop out of on the way. + * By also keeping track of the lowest blockstack position we see, we + * can tell whether the jump goes into any blocks without coming out + * again - in that case we raise an exception below. */ + int first_in = addr < f->f_lasti && f->f_lasti < target_addr; + int second_in = addr < new_lasti && new_lasti < target_addr; + if (!first_in && second_in) { + PyErr_SetString(PyExc_ValueError, + "can't jump into the middle of a block"); + return -1; } - break; - - case END_FINALLY: - /* Ignore END_FINALLYs for SETUP_EXCEPTs - they exist - * in the bytecode but don't correspond to an actual - * 'finally' block. (If blockstack_top is 0, we must - * be seeing such an END_FINALLY.) */ - if (blockstack_top > 0) { - setup_op = code[blockstack[blockstack_top-1]]; - if (setup_op == SETUP_FINALLY || setup_op == SETUP_WITH - || setup_op == SETUP_ASYNC_WITH) { - blockstack_top--; + if (first_in && !second_in) { + if (op != FOR_ITER && code[target_addr] != END_ASYNC_FOR) { + delta_iblock++; } + else if (!delta_iblock) { + /* Pop the iterators of any 'for' and 'async for' loop + * we're jumping out of. */ + delta++; + } + } + if (op != FOR_ITER && code[target_addr] != END_ASYNC_FOR) { + blockstack[blockstack_top++] = target_addr; } break; } - /* For the addresses we're interested in, see whether they're - * within a 'finally' block and if so, remember the address - * of the SETUP_FINALLY. */ - if (addr == new_lasti || addr == f->f_lasti) { - int i = 0; - int setup_addr = -1; - for (i = blockstack_top-1; i >= 0; i--) { - if (in_finally[i]) { - setup_addr = blockstack[i]; - break; - } - } - - if (setup_addr != -1) { - if (addr == new_lasti) { - new_lasti_setup_addr = setup_addr; - } - - if (addr == f->f_lasti) { - f_lasti_setup_addr = setup_addr; - } + case END_FINALLY: { + assert(blockstack_top > 0); + int target_addr = blockstack[--blockstack_top]; + assert(target_addr <= addr); + int first_in = target_addr <= f->f_lasti && f->f_lasti <= addr; + int second_in = target_addr <= new_lasti && new_lasti <= addr; + if (first_in != second_in) { + op = code[target_addr]; + PyErr_Format(PyExc_ValueError, + "can't jump %s %s block", + second_in ? "into" : "out of", + (op == DUP_TOP || op == POP_TOP) ? + "an 'except'" : "a 'finally'"); + return -1; } + break; + } } } /* Verify that the blockstack tracking code didn't get lost. */ assert(blockstack_top == 0); - /* After all that, are we jumping into / out of a 'finally' block? */ - if (new_lasti_setup_addr != f_lasti_setup_addr) { - PyErr_SetString(PyExc_ValueError, - "can't jump into or out of a 'finally' block"); - return -1; - } - - - /* Police block-jumping (you can't jump into the middle of a block) - * and ensure that the blockstack finishes up in a sensible state (by - * popping any blocks we're jumping out of). We look at all the - * blockstack operations between the current position and the new - * one, and keep track of how many blocks we drop out of on the way. - * By also keeping track of the lowest blockstack position we see, we - * can tell whether the jump goes into any blocks without coming out - * again - in that case we raise an exception below. */ - delta_iblock = 0; - for (addr = min_addr; addr < max_addr; addr += sizeof(_Py_CODEUNIT)) { - unsigned char op = code[addr]; - switch (op) { - case SETUP_LOOP: - case SETUP_EXCEPT: - case SETUP_FINALLY: - case SETUP_WITH: - case SETUP_ASYNC_WITH: - delta_iblock++; - break; - - case POP_BLOCK: - delta_iblock--; - break; - } - - min_delta_iblock = Py_MIN(min_delta_iblock, delta_iblock); - } - - /* Derive the absolute iblock values from the deltas. */ - min_iblock = f->f_iblock + min_delta_iblock; - if (new_lasti > f->f_lasti) { - /* Forwards jump. */ - new_iblock = f->f_iblock + delta_iblock; - } - else { - /* Backwards jump. */ - new_iblock = f->f_iblock - delta_iblock; - } - - /* Are we jumping into a block? */ - if (new_iblock > min_iblock) { - PyErr_SetString(PyExc_ValueError, - "can't jump into the middle of a block"); - return -1; - } - /* Pop any blocks that we're jumping out of. */ - while (f->f_iblock > new_iblock) { - PyTryBlock *b = &f->f_blockstack[--f->f_iblock]; - while ((f->f_stacktop - f->f_valuestack) > b->b_level) { - PyObject *v = (*--f->f_stacktop); - Py_DECREF(v); + if (delta_iblock > 0) { + f->f_iblock -= delta_iblock; + PyTryBlock *b = &f->f_blockstack[f->f_iblock]; + delta += (int)(f->f_stacktop - f->f_valuestack) - b->b_level; + if (b->b_type == SETUP_FINALLY && + code[b->b_handler] == WITH_CLEANUP_START) + { + /* Pop the exit function. */ + delta++; } if (b->b_type == SETUP_FINALLY && code[b->b_handler] == WITH_CLEANUP_START) @@ -360,6 +312,11 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno) Py_DECREF(v); } } + while (delta > 0) { + PyObject *v = (*--f->f_stacktop); + Py_DECREF(v); + delta--; + } /* Finally set the new f_lineno and f_lasti and return OK. */ f->f_lineno = new_lineno; @@ -550,7 +507,7 @@ frame_tp_clear(PyFrameObject *f) } static PyObject * -frame_clear(PyFrameObject *f) +frame_clear(PyFrameObject *f, PyObject *Py_UNUSED(ignored)) { if (f->f_executing) { PyErr_SetString(PyExc_RuntimeError, @@ -569,7 +526,7 @@ PyDoc_STRVAR(clear__doc__, "F.clear(): clear most references held by the frame"); static PyObject * -frame_sizeof(PyFrameObject *f) +frame_sizeof(PyFrameObject *f, PyObject *Py_UNUSED(ignored)) { Py_ssize_t res, extras, ncells, nfrees; @@ -640,14 +597,6 @@ PyTypeObject PyFrame_Type = { _Py_IDENTIFIER(__builtins__); -int _PyFrame_Init() -{ - /* Before, PyId___builtins__ was a string created explicitly in - this function. Now there is nothing to initialize anymore, but - the function is kept for backward compatibility. */ - return 1; -} - PyFrameObject* _Py_HOT_FUNCTION _PyFrame_New_NoTrack(PyThreadState *tstate, PyCodeObject *code, PyObject *globals, PyObject *locals) diff --git a/Objects/funcobject.c b/Objects/funcobject.c index c6a4b80ef455e9..da5c539db8391c 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -545,23 +545,31 @@ func_new_impl(PyTypeObject *type, PyCodeObject *code, PyObject *globals, return (PyObject *)newfunc; } +static int +func_clear(PyFunctionObject *op) +{ + Py_CLEAR(op->func_code); + Py_CLEAR(op->func_globals); + Py_CLEAR(op->func_module); + Py_CLEAR(op->func_name); + Py_CLEAR(op->func_defaults); + Py_CLEAR(op->func_kwdefaults); + Py_CLEAR(op->func_doc); + Py_CLEAR(op->func_dict); + Py_CLEAR(op->func_closure); + Py_CLEAR(op->func_annotations); + Py_CLEAR(op->func_qualname); + return 0; +} + static void func_dealloc(PyFunctionObject *op) { _PyObject_GC_UNTRACK(op); - if (op->func_weakreflist != NULL) + if (op->func_weakreflist != NULL) { PyObject_ClearWeakRefs((PyObject *) op); - Py_DECREF(op->func_code); - Py_DECREF(op->func_globals); - Py_XDECREF(op->func_module); - Py_DECREF(op->func_name); - Py_XDECREF(op->func_defaults); - Py_XDECREF(op->func_kwdefaults); - Py_XDECREF(op->func_doc); - Py_XDECREF(op->func_dict); - Py_XDECREF(op->func_closure); - Py_XDECREF(op->func_annotations); - Py_XDECREF(op->func_qualname); + } + (void)func_clear(op); PyObject_GC_Del(op); } @@ -634,7 +642,7 @@ PyTypeObject PyFunction_Type = { Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ func_new__doc__, /* tp_doc */ (traverseproc)func_traverse, /* tp_traverse */ - 0, /* tp_clear */ + (inquiry)func_clear, /* tp_clear */ 0, /* tp_richcompare */ offsetof(PyFunctionObject, func_weakreflist), /* tp_weaklistoffset */ 0, /* tp_iter */ diff --git a/Objects/genobject.c b/Objects/genobject.c index 88b03c5ef313ca..e55cfd21c69c2c 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -822,18 +822,16 @@ PyGen_New(PyFrameObject *f) int PyGen_NeedsFinalizing(PyGenObject *gen) { - int i; PyFrameObject *f = gen->gi_frame; if (f == NULL || f->f_stacktop == NULL) return 0; /* no frame or empty blockstack == no finalization */ - /* Any block type besides a loop requires cleanup. */ - for (i = 0; i < f->f_iblock; i++) - if (f->f_blockstack[i].b_type != SETUP_LOOP) - return 1; + /* Any (exception-handling) block type requires cleanup. */ + if (f->f_iblock > 0) + return 1; - /* No blocks except loops, it's safe to skip finalization. */ + /* No blocks, it's safe to skip finalization. */ return 0; } @@ -1878,21 +1876,20 @@ async_gen_athrow_send(PyAsyncGenAThrow *o, PyObject *arg) return NULL; check_error: - if (PyErr_ExceptionMatches(PyExc_StopAsyncIteration)) { + if (PyErr_ExceptionMatches(PyExc_StopAsyncIteration) || + PyErr_ExceptionMatches(PyExc_GeneratorExit)) + { o->agt_state = AWAITABLE_STATE_CLOSED; if (o->agt_args == NULL) { /* when aclose() is called we don't want to propagate - StopAsyncIteration; just raise StopIteration, signalling - that 'aclose()' is done. */ + StopAsyncIteration or GeneratorExit; just raise + StopIteration, signalling that this 'aclose()' await + is done. + */ PyErr_Clear(); PyErr_SetNone(PyExc_StopIteration); } } - else if (PyErr_ExceptionMatches(PyExc_GeneratorExit)) { - o->agt_state = AWAITABLE_STATE_CLOSED; - PyErr_Clear(); /* ignore these errors */ - PyErr_SetNone(PyExc_StopIteration); - } return NULL; } diff --git a/Objects/iterobject.c b/Objects/iterobject.c index 252169acbfdb8f..5f5ebfc8c0e5cd 100644 --- a/Objects/iterobject.c +++ b/Objects/iterobject.c @@ -78,7 +78,7 @@ iter_iternext(PyObject *iterator) } static PyObject * -iter_len(seqiterobject *it) +iter_len(seqiterobject *it, PyObject *Py_UNUSED(ignored)) { Py_ssize_t seqsize, len; @@ -101,7 +101,7 @@ iter_len(seqiterobject *it) PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); static PyObject * -iter_reduce(seqiterobject *it) +iter_reduce(seqiterobject *it, PyObject *Py_UNUSED(ignored)) { if (it->it_seq != NULL) return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"), @@ -240,7 +240,7 @@ calliter_iternext(calliterobject *it) } static PyObject * -calliter_reduce(calliterobject *it) +calliter_reduce(calliterobject *it, PyObject *Py_UNUSED(ignored)) { if (it->it_callable != NULL && it->it_sentinel != NULL) return Py_BuildValue("N(OO)", _PyObject_GetBuiltin("iter"), diff --git a/Objects/listobject.c b/Objects/listobject.c index c8ffeff09368de..4108f502023ad0 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -2983,9 +2983,9 @@ typedef struct { static void listiter_dealloc(listiterobject *); static int listiter_traverse(listiterobject *, visitproc, void *); static PyObject *listiter_next(listiterobject *); -static PyObject *listiter_len(listiterobject *); +static PyObject *listiter_len(listiterobject *, PyObject *); static PyObject *listiter_reduce_general(void *_it, int forward); -static PyObject *listiter_reduce(listiterobject *); +static PyObject *listiter_reduce(listiterobject *, PyObject *); static PyObject *listiter_setstate(listiterobject *, PyObject *state); PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); @@ -3092,7 +3092,7 @@ listiter_next(listiterobject *it) } static PyObject * -listiter_len(listiterobject *it) +listiter_len(listiterobject *it, PyObject *Py_UNUSED(ignored)) { Py_ssize_t len; if (it->it_seq) { @@ -3104,7 +3104,7 @@ listiter_len(listiterobject *it) } static PyObject * -listiter_reduce(listiterobject *it) +listiter_reduce(listiterobject *it, PyObject *Py_UNUSED(ignored)) { return listiter_reduce_general(it, 1); } @@ -3136,8 +3136,8 @@ typedef struct { static void listreviter_dealloc(listreviterobject *); static int listreviter_traverse(listreviterobject *, visitproc, void *); static PyObject *listreviter_next(listreviterobject *); -static PyObject *listreviter_len(listreviterobject *); -static PyObject *listreviter_reduce(listreviterobject *); +static PyObject *listreviter_len(listreviterobject *, PyObject *); +static PyObject *listreviter_reduce(listreviterobject *, PyObject *); static PyObject *listreviter_setstate(listreviterobject *, PyObject *); static PyMethodDef listreviter_methods[] = { @@ -3246,7 +3246,7 @@ listreviter_next(listreviterobject *it) } static PyObject * -listreviter_len(listreviterobject *it) +listreviter_len(listreviterobject *it, PyObject *Py_UNUSED(ignored)) { Py_ssize_t len = it->it_index + 1; if (it->it_seq == NULL || PyList_GET_SIZE(it->it_seq) < len) @@ -3255,7 +3255,7 @@ listreviter_len(listreviterobject *it) } static PyObject * -listreviter_reduce(listreviterobject *it) +listreviter_reduce(listreviterobject *it, PyObject *Py_UNUSED(ignored)) { return listiter_reduce_general(it, 0); } diff --git a/Objects/longobject.c b/Objects/longobject.c index 269d6cdea590ff..ebf87a55b54bcd 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -4880,12 +4880,14 @@ int___getnewargs___impl(PyObject *self) } static PyObject * -long_get0(PyLongObject *v, void *context) { +long_get0(PyObject *Py_UNUSED(self), void *Py_UNUSED(context)) +{ return PyLong_FromLong(0L); } static PyObject * -long_get1(PyLongObject *v, void *context) { +long_get1(PyObject *Py_UNUSED(self), void *Py_UNUSED(ignored)) +{ return PyLong_FromLong(1L); } @@ -5278,8 +5280,14 @@ int_from_bytes_impl(PyTypeObject *type, PyObject *bytes_obj, return long_obj; } +static PyObject * +long_long_meth(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return long_long(self); +} + static PyMethodDef long_methods[] = { - {"conjugate", (PyCFunction)long_long, METH_NOARGS, + {"conjugate", long_long_meth, METH_NOARGS, "Returns self, the complex conjugate of any int."}, INT_BIT_LENGTH_METHODDEF #if 0 @@ -5288,11 +5296,11 @@ static PyMethodDef long_methods[] = { #endif INT_TO_BYTES_METHODDEF INT_FROM_BYTES_METHODDEF - {"__trunc__", (PyCFunction)long_long, METH_NOARGS, + {"__trunc__", long_long_meth, METH_NOARGS, "Truncating an Integral returns itself."}, - {"__floor__", (PyCFunction)long_long, METH_NOARGS, + {"__floor__", long_long_meth, METH_NOARGS, "Flooring an Integral returns itself."}, - {"__ceil__", (PyCFunction)long_long, METH_NOARGS, + {"__ceil__", long_long_meth, METH_NOARGS, "Ceiling of an Integral returns itself."}, {"__round__", (PyCFunction)long_round, METH_VARARGS, "Rounding an Integral returns itself.\n" @@ -5305,19 +5313,19 @@ static PyMethodDef long_methods[] = { static PyGetSetDef long_getset[] = { {"real", - (getter)long_long, (setter)NULL, + (getter)long_long_meth, (setter)NULL, "the real part of a complex number", NULL}, {"imag", - (getter)long_get0, (setter)NULL, + long_get0, (setter)NULL, "the imaginary part of a complex number", NULL}, {"numerator", - (getter)long_long, (setter)NULL, + (getter)long_long_meth, (setter)NULL, "the numerator of a rational number in lowest terms", NULL}, {"denominator", - (getter)long_get1, (setter)NULL, + long_get1, (setter)NULL, "the denominator of a rational number in lowest terms", NULL}, {NULL} /* Sentinel */ @@ -5347,7 +5355,7 @@ static PyNumberMethods long_as_number = { long_divmod, /*nb_divmod*/ long_pow, /*nb_power*/ (unaryfunc)long_neg, /*nb_negative*/ - (unaryfunc)long_long, /*tp_positive*/ + long_long, /*tp_positive*/ (unaryfunc)long_abs, /*tp_absolute*/ (inquiry)long_bool, /*tp_bool*/ (unaryfunc)long_invert, /*nb_invert*/ diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c index ccf45ffc582608..adaa67c064466b 100644 --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -1398,6 +1398,20 @@ memory_cast(PyMemoryViewObject *self, PyObject *args, PyObject *kwds) return NULL; } +static PyObject * +memory_toreadonly(PyMemoryViewObject *self, PyObject *noargs) +{ + CHECK_RELEASED(self); + /* Even if self is already readonly, we still need to create a new + * object for .release() to work correctly. + */ + self = (PyMemoryViewObject *) mbuf_add_view(self->mbuf, &self->view); + if (self != NULL) { + self->view.readonly = 1; + }; + return (PyObject *) self; +} + /**************************************************************************/ /* getbuffer */ @@ -3061,6 +3075,10 @@ PyDoc_STRVAR(memory_cast_doc, "cast($self, /, format, *, shape)\n--\n\ \n\ Cast a memoryview to a new format or shape."); +PyDoc_STRVAR(memory_toreadonly_doc, +"toreadonly($self, /)\n--\n\ +\n\ +Return a readonly version of the memoryview."); static PyMethodDef memory_methods[] = { {"release", (PyCFunction)memory_release, METH_NOARGS, memory_release_doc}, @@ -3068,6 +3086,7 @@ static PyMethodDef memory_methods[] = { {"hex", (PyCFunction)memory_hex, METH_NOARGS, memory_hex_doc}, {"tolist", (PyCFunction)memory_tolist, METH_NOARGS, memory_tolist_doc}, {"cast", (PyCFunction)memory_cast, METH_VARARGS|METH_KEYWORDS, memory_cast_doc}, + {"toreadonly", (PyCFunction)memory_toreadonly, METH_NOARGS, memory_toreadonly_doc}, {"__enter__", memory_enter, METH_NOARGS, NULL}, {"__exit__", memory_exit, METH_VARARGS, NULL}, {NULL, NULL} diff --git a/Objects/methodobject.c b/Objects/methodobject.c index 2cf314660d00c2..9606768a48c5e0 100644 --- a/Objects/methodobject.c +++ b/Objects/methodobject.c @@ -101,7 +101,7 @@ meth_dealloc(PyCFunctionObject *m) } static PyObject * -meth_reduce(PyCFunctionObject *m) +meth_reduce(PyCFunctionObject *m, PyObject *Py_UNUSED(ignored)) { PyObject *builtins; PyObject *getattr; diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index 8fb368e41474a8..5fad4474be0f7c 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -603,8 +603,9 @@ _PyModule_ClearDict(PyObject *d) else PyErr_Clear(); } - if (PyDict_SetItem(d, key, Py_None) != 0) - PyErr_Clear(); + if (PyDict_SetItem(d, key, Py_None) != 0) { + PyErr_WriteUnraisable(NULL); + } } } } @@ -623,8 +624,9 @@ _PyModule_ClearDict(PyObject *d) else PyErr_Clear(); } - if (PyDict_SetItem(d, key, Py_None) != 0) - PyErr_Clear(); + if (PyDict_SetItem(d, key, Py_None) != 0) { + PyErr_WriteUnraisable(NULL); + } } } } diff --git a/Objects/namespaceobject.c b/Objects/namespaceobject.c index e5698e6378de60..a6c941afc0ade3 100644 --- a/Objects/namespaceobject.c +++ b/Objects/namespaceobject.c @@ -173,7 +173,7 @@ namespace_richcompare(PyObject *self, PyObject *other, int op) PyDoc_STRVAR(namespace_reduce__doc__, "Return state information for pickling"); static PyObject * -namespace_reduce(_PyNamespaceObject *ns) +namespace_reduce(_PyNamespaceObject *ns, PyObject *Py_UNUSED(ignored)) { PyObject *result, *args = PyTuple_New(0); diff --git a/Objects/object.c b/Objects/object.c index d205b552be42bb..51490746e5d1d2 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -316,9 +316,7 @@ PyObject_CallFinalizerFromDealloc(PyObject *self) _Py_NewReference(self); self->ob_refcnt = refcnt; - if (PyType_IS_GC(Py_TYPE(self))) { - assert(_PyGC_REFS(self) != _PyGC_REFS_UNTRACKED); - } + assert(!PyType_IS_GC(Py_TYPE(self)) || _PyObject_GC_IS_TRACKED(self)); /* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so * we need to undo that. */ _Py_DEC_REFTOTAL; @@ -1626,13 +1624,13 @@ NotImplemented_repr(PyObject *op) } static PyObject * -NotImplemented_reduce(PyObject *op) +NotImplemented_reduce(PyObject *op, PyObject *Py_UNUSED(ignored)) { return PyUnicode_FromString("NotImplemented"); } static PyMethodDef notimplemented_methods[] = { - {"__reduce__", (PyCFunction)NotImplemented_reduce, METH_NOARGS, NULL}, + {"__reduce__", NotImplemented_reduce, METH_NOARGS, NULL}, {NULL, NULL} }; @@ -2102,7 +2100,7 @@ void _PyTrash_deposit_object(PyObject *op) { assert(PyObject_IS_GC(op)); - assert(_PyGC_REFS(op) == _PyGC_REFS_UNTRACKED); + assert(!_PyObject_GC_IS_TRACKED(op)); assert(op->ob_refcnt == 0); _Py_AS_GC(op)->gc.gc_prev = (PyGC_Head *)_PyRuntime.gc.trash_delete_later; _PyRuntime.gc.trash_delete_later = op; @@ -2114,7 +2112,7 @@ _PyTrash_thread_deposit_object(PyObject *op) { PyThreadState *tstate = PyThreadState_GET(); assert(PyObject_IS_GC(op)); - assert(_PyGC_REFS(op) == _PyGC_REFS_UNTRACKED); + assert(!_PyObject_GC_IS_TRACKED(op)); assert(op->ob_refcnt == 0); _Py_AS_GC(op)->gc.gc_prev = (PyGC_Head *) tstate->trash_delete_later; tstate->trash_delete_later = op; diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c index 0e485d62114daf..eb7cbfca157c6c 100644 --- a/Objects/obmalloc.c +++ b/Objects/obmalloc.c @@ -849,30 +849,6 @@ static int running_on_valgrind = -1; /*==========================================================================*/ -/* - * Locking - * - * To reduce lock contention, it would probably be better to refine the - * crude function locking with per size class locking. I'm not positive - * however, whether it's worth switching to such locking policy because - * of the performance penalty it might introduce. - * - * The following macros describe the simplest (should also be the fastest) - * lock object on a particular platform and the init/fini/lock/unlock - * operations on it. The locks defined here are not expected to be recursive - * because it is assumed that they will always be called in the order: - * INIT, [LOCK, UNLOCK]*, FINI. - */ - -/* - * Python's threads are serialized, so object malloc locking is disabled. - */ -#define SIMPLELOCK_DECL(lock) /* simple lock declaration */ -#define SIMPLELOCK_INIT(lock) /* allocate (if needed) and initialize */ -#define SIMPLELOCK_FINI(lock) /* free/destroy an existing lock */ -#define SIMPLELOCK_LOCK(lock) /* acquire released lock */ -#define SIMPLELOCK_UNLOCK(lock) /* release acquired lock */ - /* When you say memory, my mind reasons in terms of (pointers to) blocks */ typedef uint8_t block; @@ -944,15 +920,6 @@ struct arena_object { /*==========================================================================*/ -/* - * This malloc lock - */ -SIMPLELOCK_DECL(_malloc_lock) -#define LOCK() SIMPLELOCK_LOCK(_malloc_lock) -#define UNLOCK() SIMPLELOCK_UNLOCK(_malloc_lock) -#define LOCK_INIT() SIMPLELOCK_INIT(_malloc_lock) -#define LOCK_FINI() SIMPLELOCK_FINI(_malloc_lock) - /* * Pool table -- headed, circular, doubly-linked lists of partially used pools. @@ -1381,7 +1348,6 @@ pymalloc_alloc(void *ctx, void **ptr_p, size_t nbytes) return 0; } - LOCK(); /* * Most frequent paths first */ @@ -1537,13 +1503,11 @@ pymalloc_alloc(void *ctx, void **ptr_p, size_t nbytes) goto init_pool; success: - UNLOCK(); assert(bp != NULL); *ptr_p = (void *)bp; return 1; failed: - UNLOCK(); return 0; } @@ -1612,8 +1576,6 @@ pymalloc_free(void *ctx, void *p) } /* We allocated this address. */ - LOCK(); - /* Link p to the start of the pool's freeblock list. Since * the pool had at least the p block outstanding, the pool * wasn't empty (so it's already in a usedpools[] list, or @@ -1798,7 +1760,6 @@ pymalloc_free(void *ctx, void *p) goto success; success: - UNLOCK(); return 1; } diff --git a/Objects/odictobject.c b/Objects/odictobject.c index ac97f52179e35c..353afd23d6b5e8 100644 --- a/Objects/odictobject.c +++ b/Objects/odictobject.c @@ -67,7 +67,7 @@ Linked-List API As noted, the linked-list implemented here does not have all the bells and whistles. However, we recognize that the implementation may need to change to accommodate performance improvements or extra functionality. To -that end, We use a simple API to interact with the linked-list. Here's a +that end, we use a simple API to interact with the linked-list. Here's a summary of the methods/macros: Node info: @@ -444,7 +444,7 @@ Potential Optimizations - Set node->key to NULL to indicate the node is not-in-use. - Add _odict_EXISTS()? - How to maintain consistency across resizes? Existing node pointers - would be invalidate after a resize, which is particularly problematic + would be invalidated after a resize, which is particularly problematic for the iterators. * Use a more stream-lined implementation of update() and, likely indirectly, __init__(). @@ -884,7 +884,7 @@ OrderedDict_fromkeys_impl(PyTypeObject *type, PyObject *seq, PyObject *value) PyDoc_STRVAR(odict_sizeof__doc__, ""); static PyObject * -odict_sizeof(PyODictObject *od) +odict_sizeof(PyODictObject *od, PyObject *Py_UNUSED(ignored)) { Py_ssize_t res = _PyDict_SizeOf((PyDictObject *)od); res += sizeof(_ODictNode *) * _odict_FAST_SIZE(od); /* od_fast_nodes */ @@ -899,7 +899,7 @@ odict_sizeof(PyODictObject *od) PyDoc_STRVAR(odict_reduce__doc__, "Return state information for pickling"); static PyObject * -odict_reduce(register PyODictObject *od) +odict_reduce(register PyODictObject *od, PyObject *Py_UNUSED(ignored)) { _Py_IDENTIFIER(__dict__); _Py_IDENTIFIER(items); @@ -1143,21 +1143,21 @@ OrderedDict_popitem_impl(PyODictObject *self, int last) /* MutableMapping.keys() does not have a docstring. */ PyDoc_STRVAR(odict_keys__doc__, ""); -static PyObject * odictkeys_new(PyObject *od); /* forward */ +static PyObject * odictkeys_new(PyObject *od, PyObject *Py_UNUSED(ignored)); /* forward */ /* values() */ /* MutableMapping.values() does not have a docstring. */ PyDoc_STRVAR(odict_values__doc__, ""); -static PyObject * odictvalues_new(PyObject *od); /* forward */ +static PyObject * odictvalues_new(PyObject *od, PyObject *Py_UNUSED(ignored)); /* forward */ /* items() */ /* MutableMapping.items() does not have a docstring. */ PyDoc_STRVAR(odict_items__doc__, ""); -static PyObject * odictitems_new(PyObject *od); /* forward */ +static PyObject * odictitems_new(PyObject *od, PyObject *Py_UNUSED(ignored)); /* forward */ /* update() */ @@ -1175,7 +1175,7 @@ PyDoc_STRVAR(odict_clear__doc__, "od.clear() -> None. Remove all items from od."); static PyObject * -odict_clear(register PyODictObject *od) +odict_clear(register PyODictObject *od, PyObject *Py_UNUSED(ignored)) { PyDict_Clear((PyObject *)od); _odict_clear_nodes(od); @@ -1193,7 +1193,7 @@ static int _PyODict_SetItem_KnownHash(PyObject *, PyObject *, PyObject *, PyDoc_STRVAR(odict_copy__doc__, "od.copy() -> a shallow copy of od"); static PyObject * -odict_copy(register PyODictObject *od) +odict_copy(register PyODictObject *od, PyObject *Py_UNUSED(ignored)) { _ODictNode *node; PyObject *od_copy; @@ -1252,7 +1252,7 @@ PyDoc_STRVAR(odict_reversed__doc__, "od.__reversed__() <==> reversed(od)"); static PyObject * odictiter_new(PyODictObject *, int); static PyObject * -odict_reversed(PyODictObject *od) +odict_reversed(PyODictObject *od, PyObject *Py_UNUSED(ignored)) { return odictiter_new(od, _odict_ITER_KEYS|_odict_ITER_REVERSED); } @@ -1322,11 +1322,11 @@ static PyMethodDef odict_methods[] = { {"pop", (PyCFunction)odict_pop, METH_VARARGS | METH_KEYWORDS, odict_pop__doc__}, ORDEREDDICT_POPITEM_METHODDEF - {"keys", (PyCFunction)odictkeys_new, METH_NOARGS, + {"keys", odictkeys_new, METH_NOARGS, odict_keys__doc__}, - {"values", (PyCFunction)odictvalues_new, METH_NOARGS, + {"values", odictvalues_new, METH_NOARGS, odict_values__doc__}, - {"items", (PyCFunction)odictitems_new, METH_NOARGS, + {"items", odictitems_new, METH_NOARGS, odict_items__doc__}, {"update", (PyCFunction)odict_update, METH_VARARGS | METH_KEYWORDS, odict_update__doc__}, @@ -1487,7 +1487,7 @@ odict_tp_clear(PyODictObject *od) PyObject *res; Py_CLEAR(od->od_inst_dict); Py_CLEAR(od->od_weakreflist); - res = odict_clear(od); + res = odict_clear(od, NULL); if (res == NULL) return -1; Py_DECREF(res); @@ -1956,7 +1956,7 @@ odictkeys_iter(_PyDictViewObject *dv) } static PyObject * -odictkeys_reversed(_PyDictViewObject *dv) +odictkeys_reversed(_PyDictViewObject *dv, PyObject *Py_UNUSED(ignored)) { if (dv->dv_dict == NULL) { Py_RETURN_NONE; @@ -2005,7 +2005,7 @@ PyTypeObject PyODictKeys_Type = { }; static PyObject * -odictkeys_new(PyObject *od) +odictkeys_new(PyObject *od, PyObject *Py_UNUSED(ignored)) { return _PyDictView_New(od, &PyODictKeys_Type); } @@ -2023,7 +2023,7 @@ odictitems_iter(_PyDictViewObject *dv) } static PyObject * -odictitems_reversed(_PyDictViewObject *dv) +odictitems_reversed(_PyDictViewObject *dv, PyObject *Py_UNUSED(ignored)) { if (dv->dv_dict == NULL) { Py_RETURN_NONE; @@ -2072,7 +2072,7 @@ PyTypeObject PyODictItems_Type = { }; static PyObject * -odictitems_new(PyObject *od) +odictitems_new(PyObject *od, PyObject *Py_UNUSED(ignored)) { return _PyDictView_New(od, &PyODictItems_Type); } @@ -2090,7 +2090,7 @@ odictvalues_iter(_PyDictViewObject *dv) } static PyObject * -odictvalues_reversed(_PyDictViewObject *dv) +odictvalues_reversed(_PyDictViewObject *dv, PyObject *Py_UNUSED(ignored)) { if (dv->dv_dict == NULL) { Py_RETURN_NONE; @@ -2139,7 +2139,7 @@ PyTypeObject PyODictValues_Type = { }; static PyObject * -odictvalues_new(PyObject *od) +odictvalues_new(PyObject *od, PyObject *Py_UNUSED(ignored)) { return _PyDictView_New(od, &PyODictValues_Type); } diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c index dd0e4bed537002..28a244e5371007 100644 --- a/Objects/rangeobject.c +++ b/Objects/rangeobject.c @@ -636,7 +636,7 @@ static PyNumberMethods range_as_number = { }; static PyObject * range_iter(PyObject *seq); -static PyObject * range_reverse(PyObject *seq); +static PyObject * range_reverse(PyObject *seq, PyObject *Py_UNUSED(ignored)); PyDoc_STRVAR(reverse_doc, "Return a reverse iterator."); @@ -649,7 +649,7 @@ PyDoc_STRVAR(index_doc, "Raise ValueError if the value is not present."); static PyMethodDef range_methods[] = { - {"__reversed__", (PyCFunction)range_reverse, METH_NOARGS, reverse_doc}, + {"__reversed__", range_reverse, METH_NOARGS, reverse_doc}, {"__reduce__", (PyCFunction)range_reduce, METH_VARARGS}, {"count", (PyCFunction)range_count, METH_O, count_doc}, {"index", (PyCFunction)range_index, METH_O, index_doc}, @@ -731,7 +731,7 @@ rangeiter_next(rangeiterobject *r) } static PyObject * -rangeiter_len(rangeiterobject *r) +rangeiter_len(rangeiterobject *r, PyObject *Py_UNUSED(ignored)) { return PyLong_FromLong(r->len - r->index); } @@ -740,7 +740,7 @@ PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); static PyObject * -rangeiter_reduce(rangeiterobject *r) +rangeiter_reduce(rangeiterobject *r, PyObject *Py_UNUSED(ignored)) { PyObject *start=NULL, *stop=NULL, *step=NULL; PyObject *range; @@ -896,7 +896,7 @@ longrangeiter_len(longrangeiterobject *r, PyObject *no_args) } static PyObject * -longrangeiter_reduce(longrangeiterobject *r) +longrangeiter_reduce(longrangeiterobject *r, PyObject *Py_UNUSED(ignored)) { PyObject *product, *stop=NULL; PyObject *range; @@ -1081,7 +1081,7 @@ range_iter(PyObject *seq) } static PyObject * -range_reverse(PyObject *seq) +range_reverse(PyObject *seq, PyObject *Py_UNUSED(ignored)) { rangeobject *range = (rangeobject*) seq; longrangeiterobject *it; diff --git a/Objects/setobject.c b/Objects/setobject.c index ce35aa2a0cdb9e..82b58382081625 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -703,7 +703,7 @@ set_merge(PySetObject *so, PyObject *otherset) } static PyObject * -set_pop(PySetObject *so) +set_pop(PySetObject *so, PyObject *Py_UNUSED(ignored)) { /* Make sure the search finger is in bounds */ Py_ssize_t i = so->finger & so->mask; @@ -833,7 +833,7 @@ setiter_traverse(setiterobject *si, visitproc visit, void *arg) } static PyObject * -setiter_len(setiterobject *si) +setiter_len(setiterobject *si, PyObject *Py_UNUSED(ignored)) { Py_ssize_t len = 0; if (si->si_set != NULL && si->si_used == si->si_set->used) @@ -846,7 +846,7 @@ PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list( static PyObject *setiter_iternext(setiterobject *si); static PyObject * -setiter_reduce(setiterobject *si) +setiter_reduce(setiterobject *si, PyObject *Py_UNUSED(ignored)) { PyObject *list; setiterobject tmp; @@ -1175,25 +1175,25 @@ set_swap_bodies(PySetObject *a, PySetObject *b) } static PyObject * -set_copy(PySetObject *so) +set_copy(PySetObject *so, PyObject *Py_UNUSED(ignored)) { return make_new_set_basetype(Py_TYPE(so), (PyObject *)so); } static PyObject * -frozenset_copy(PySetObject *so) +frozenset_copy(PySetObject *so, PyObject *Py_UNUSED(ignored)) { if (PyFrozenSet_CheckExact(so)) { Py_INCREF(so); return (PyObject *)so; } - return set_copy(so); + return set_copy(so, NULL); } PyDoc_STRVAR(copy_doc, "Return a shallow copy of a set."); static PyObject * -set_clear(PySetObject *so) +set_clear(PySetObject *so, PyObject *Py_UNUSED(ignored)) { set_clear_internal(so); Py_RETURN_NONE; @@ -1208,7 +1208,7 @@ set_union(PySetObject *so, PyObject *args) PyObject *other; Py_ssize_t i; - result = (PySetObject *)set_copy(so); + result = (PySetObject *)set_copy(so, NULL); if (result == NULL) return NULL; @@ -1237,7 +1237,7 @@ set_or(PySetObject *so, PyObject *other) if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) Py_RETURN_NOTIMPLEMENTED; - result = (PySetObject *)set_copy(so); + result = (PySetObject *)set_copy(so, NULL); if (result == NULL) return NULL; if ((PyObject *)so == other) @@ -1270,7 +1270,7 @@ set_intersection(PySetObject *so, PyObject *other) int rv; if ((PyObject *)so == other) - return set_copy(so); + return set_copy(so, NULL); result = (PySetObject *)make_new_set_basetype(Py_TYPE(so), NULL); if (result == NULL) @@ -1343,7 +1343,7 @@ set_intersection_multi(PySetObject *so, PyObject *args) PyObject *result = (PyObject *)so; if (PyTuple_GET_SIZE(args) == 0) - return set_copy(so); + return set_copy(so, NULL); Py_INCREF(so); for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) { @@ -1542,7 +1542,7 @@ set_copy_and_difference(PySetObject *so, PyObject *other) { PyObject *result; - result = set_copy(so); + result = set_copy(so, NULL); if (result == NULL) return NULL; if (set_difference_update_internal((PySetObject *) result, other) == 0) @@ -1562,7 +1562,7 @@ set_difference(PySetObject *so, PyObject *other) int rv; if (PySet_GET_SIZE(so) == 0) { - return set_copy(so); + return set_copy(so, NULL); } if (PyAnySet_Check(other)) { @@ -1630,7 +1630,7 @@ set_difference_multi(PySetObject *so, PyObject *args) PyObject *result, *other; if (PyTuple_GET_SIZE(args) == 0) - return set_copy(so); + return set_copy(so, NULL); other = PyTuple_GET_ITEM(args, 0); result = set_difference(so, other); @@ -1681,7 +1681,7 @@ set_symmetric_difference_update(PySetObject *so, PyObject *other) int rv; if ((PyObject *)so == other) - return set_clear(so); + return set_clear(so, NULL); if (PyDict_CheckExact(other)) { PyObject *value; @@ -1978,7 +1978,7 @@ PyDoc_STRVAR(discard_doc, If the element is not a member, do nothing."); static PyObject * -set_reduce(PySetObject *so) +set_reduce(PySetObject *so, PyObject *Py_UNUSED(ignored)) { PyObject *keys=NULL, *args=NULL, *result=NULL, *dict=NULL; _Py_IDENTIFIER(__dict__); @@ -2004,7 +2004,7 @@ set_reduce(PySetObject *so) } static PyObject * -set_sizeof(PySetObject *so) +set_sizeof(PySetObject *so, PyObject *Py_UNUSED(ignored)) { Py_ssize_t res; @@ -2046,7 +2046,7 @@ static PySequenceMethods set_as_sequence = { /* set object ********************************************************/ #ifdef Py_DEBUG -static PyObject *test_c_api(PySetObject *so); +static PyObject *test_c_api(PySetObject *so, PyObject *Py_UNUSED(ignored)); PyDoc_STRVAR(test_c_api_doc, "Exercises C API. Returns True.\n\ All is well if assertions don't fail."); @@ -2381,7 +2381,7 @@ PySet_Pop(PyObject *set) PyErr_BadInternalCall(); return NULL; } - return set_pop((PySetObject *)set); + return set_pop((PySetObject *)set, NULL); } int @@ -2410,7 +2410,7 @@ PyObject *_PySet_Dummy = dummy; } while(0) static PyObject * -test_c_api(PySetObject *so) +test_c_api(PySetObject *so, PyObject *Py_UNUSED(ignored)) { Py_ssize_t count; const char *s; diff --git a/Objects/sliceobject.c b/Objects/sliceobject.c index 59f084d1a612cc..2288df5149541b 100644 --- a/Objects/sliceobject.c +++ b/Objects/sliceobject.c @@ -36,13 +36,13 @@ ellipsis_repr(PyObject *op) } static PyObject * -ellipsis_reduce(PyObject *op) +ellipsis_reduce(PyObject *op, PyObject *Py_UNUSED(ignored)) { return PyUnicode_FromString("Ellipsis"); } static PyMethodDef ellipsis_methods[] = { - {"__reduce__", (PyCFunction)ellipsis_reduce, METH_NOARGS, NULL}, + {"__reduce__", ellipsis_reduce, METH_NOARGS, NULL}, {NULL, NULL} }; @@ -546,7 +546,7 @@ S. Out of bounds indices are clipped in a manner consistent with the\n\ handling of normal slices."); static PyObject * -slice_reduce(PySliceObject* self) +slice_reduce(PySliceObject* self, PyObject *Py_UNUSED(ignored)) { return Py_BuildValue("O(OOO)", Py_TYPE(self), self->start, self->stop, self->step); } diff --git a/Objects/stringlib/clinic/transmogrify.h.h b/Objects/stringlib/clinic/transmogrify.h.h new file mode 100644 index 00000000000000..6d266225c02054 --- /dev/null +++ b/Objects/stringlib/clinic/transmogrify.h.h @@ -0,0 +1,158 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(stringlib_expandtabs__doc__, +"expandtabs($self, /, tabsize=8)\n" +"--\n" +"\n" +"Return a copy where all tab characters are expanded using spaces.\n" +"\n" +"If tabsize is not given, a tab size of 8 characters is assumed."); + +#define STRINGLIB_EXPANDTABS_METHODDEF \ + {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_FASTCALL|METH_KEYWORDS, stringlib_expandtabs__doc__}, + +static PyObject * +stringlib_expandtabs_impl(PyObject *self, int tabsize); + +static PyObject * +stringlib_expandtabs(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"tabsize", NULL}; + static _PyArg_Parser _parser = {"|i:expandtabs", _keywords, 0}; + int tabsize = 8; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &tabsize)) { + goto exit; + } + return_value = stringlib_expandtabs_impl(self, tabsize); + +exit: + return return_value; +} + +PyDoc_STRVAR(stringlib_ljust__doc__, +"ljust($self, width, fillchar=b\' \', /)\n" +"--\n" +"\n" +"Return a left-justified string of length width.\n" +"\n" +"Padding is done using the specified fill character."); + +#define STRINGLIB_LJUST_METHODDEF \ + {"ljust", (PyCFunction)stringlib_ljust, METH_FASTCALL, stringlib_ljust__doc__}, + +static PyObject * +stringlib_ljust_impl(PyObject *self, Py_ssize_t width, char fillchar); + +static PyObject * +stringlib_ljust(PyObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t width; + char fillchar = ' '; + + if (!_PyArg_ParseStack(args, nargs, "n|c:ljust", + &width, &fillchar)) { + goto exit; + } + return_value = stringlib_ljust_impl(self, width, fillchar); + +exit: + return return_value; +} + +PyDoc_STRVAR(stringlib_rjust__doc__, +"rjust($self, width, fillchar=b\' \', /)\n" +"--\n" +"\n" +"Return a right-justified string of length width.\n" +"\n" +"Padding is done using the specified fill character."); + +#define STRINGLIB_RJUST_METHODDEF \ + {"rjust", (PyCFunction)stringlib_rjust, METH_FASTCALL, stringlib_rjust__doc__}, + +static PyObject * +stringlib_rjust_impl(PyObject *self, Py_ssize_t width, char fillchar); + +static PyObject * +stringlib_rjust(PyObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t width; + char fillchar = ' '; + + if (!_PyArg_ParseStack(args, nargs, "n|c:rjust", + &width, &fillchar)) { + goto exit; + } + return_value = stringlib_rjust_impl(self, width, fillchar); + +exit: + return return_value; +} + +PyDoc_STRVAR(stringlib_center__doc__, +"center($self, width, fillchar=b\' \', /)\n" +"--\n" +"\n" +"Return a centered string of length width.\n" +"\n" +"Padding is done using the specified fill character."); + +#define STRINGLIB_CENTER_METHODDEF \ + {"center", (PyCFunction)stringlib_center, METH_FASTCALL, stringlib_center__doc__}, + +static PyObject * +stringlib_center_impl(PyObject *self, Py_ssize_t width, char fillchar); + +static PyObject * +stringlib_center(PyObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t width; + char fillchar = ' '; + + if (!_PyArg_ParseStack(args, nargs, "n|c:center", + &width, &fillchar)) { + goto exit; + } + return_value = stringlib_center_impl(self, width, fillchar); + +exit: + return return_value; +} + +PyDoc_STRVAR(stringlib_zfill__doc__, +"zfill($self, width, /)\n" +"--\n" +"\n" +"Pad a numeric string with zeros on the left, to fill a field of the given width.\n" +"\n" +"The original string is never truncated."); + +#define STRINGLIB_ZFILL_METHODDEF \ + {"zfill", (PyCFunction)stringlib_zfill, METH_O, stringlib_zfill__doc__}, + +static PyObject * +stringlib_zfill_impl(PyObject *self, Py_ssize_t width); + +static PyObject * +stringlib_zfill(PyObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_ssize_t width; + + if (!PyArg_Parse(arg, "n:zfill", &width)) { + goto exit; + } + return_value = stringlib_zfill_impl(self, width); + +exit: + return return_value; +} +/*[clinic end generated code: output=336620159a1fc70d input=a9049054013a1b77]*/ diff --git a/Objects/stringlib/ctype.h b/Objects/stringlib/ctype.h index fd7b1bd49e54f7..843cfa22a84546 100644 --- a/Objects/stringlib/ctype.h +++ b/Objects/stringlib/ctype.h @@ -5,49 +5,49 @@ #include "bytes_methods.h" static PyObject* -stringlib_isspace(PyObject *self) +stringlib_isspace(PyObject *self, PyObject *Py_UNUSED(ignored)) { return _Py_bytes_isspace(STRINGLIB_STR(self), STRINGLIB_LEN(self)); } static PyObject* -stringlib_isalpha(PyObject *self) +stringlib_isalpha(PyObject *self, PyObject *Py_UNUSED(ignored)) { return _Py_bytes_isalpha(STRINGLIB_STR(self), STRINGLIB_LEN(self)); } static PyObject* -stringlib_isalnum(PyObject *self) +stringlib_isalnum(PyObject *self, PyObject *Py_UNUSED(ignored)) { return _Py_bytes_isalnum(STRINGLIB_STR(self), STRINGLIB_LEN(self)); } static PyObject* -stringlib_isascii(PyObject *self) +stringlib_isascii(PyObject *self, PyObject *Py_UNUSED(ignored)) { return _Py_bytes_isascii(STRINGLIB_STR(self), STRINGLIB_LEN(self)); } static PyObject* -stringlib_isdigit(PyObject *self) +stringlib_isdigit(PyObject *self, PyObject *Py_UNUSED(ignored)) { return _Py_bytes_isdigit(STRINGLIB_STR(self), STRINGLIB_LEN(self)); } static PyObject* -stringlib_islower(PyObject *self) +stringlib_islower(PyObject *self, PyObject *Py_UNUSED(ignored)) { return _Py_bytes_islower(STRINGLIB_STR(self), STRINGLIB_LEN(self)); } static PyObject* -stringlib_isupper(PyObject *self) +stringlib_isupper(PyObject *self, PyObject *Py_UNUSED(ignored)) { return _Py_bytes_isupper(STRINGLIB_STR(self), STRINGLIB_LEN(self)); } static PyObject* -stringlib_istitle(PyObject *self) +stringlib_istitle(PyObject *self, PyObject *Py_UNUSED(ignored)) { return _Py_bytes_istitle(STRINGLIB_STR(self), STRINGLIB_LEN(self)); } @@ -56,7 +56,7 @@ stringlib_istitle(PyObject *self) /* functions that return a new object partially translated by ctype funcs: */ static PyObject* -stringlib_lower(PyObject *self) +stringlib_lower(PyObject *self, PyObject *Py_UNUSED(ignored)) { PyObject* newobj; newobj = STRINGLIB_NEW(NULL, STRINGLIB_LEN(self)); @@ -68,7 +68,7 @@ stringlib_lower(PyObject *self) } static PyObject* -stringlib_upper(PyObject *self) +stringlib_upper(PyObject *self, PyObject *Py_UNUSED(ignored)) { PyObject* newobj; newobj = STRINGLIB_NEW(NULL, STRINGLIB_LEN(self)); @@ -80,7 +80,7 @@ stringlib_upper(PyObject *self) } static PyObject* -stringlib_title(PyObject *self) +stringlib_title(PyObject *self, PyObject *Py_UNUSED(ignored)) { PyObject* newobj; newobj = STRINGLIB_NEW(NULL, STRINGLIB_LEN(self)); @@ -92,7 +92,7 @@ stringlib_title(PyObject *self) } static PyObject* -stringlib_capitalize(PyObject *self) +stringlib_capitalize(PyObject *self, PyObject *Py_UNUSED(ignored)) { PyObject* newobj; newobj = STRINGLIB_NEW(NULL, STRINGLIB_LEN(self)); @@ -104,7 +104,7 @@ stringlib_capitalize(PyObject *self) } static PyObject* -stringlib_swapcase(PyObject *self) +stringlib_swapcase(PyObject *self, PyObject *Py_UNUSED(ignored)) { PyObject* newobj; newobj = STRINGLIB_NEW(NULL, STRINGLIB_LEN(self)); diff --git a/Objects/stringlib/transmogrify.h b/Objects/stringlib/transmogrify.h index 326ce14849c982..9506019d5af2b8 100644 --- a/Objects/stringlib/transmogrify.h +++ b/Objects/stringlib/transmogrify.h @@ -5,6 +5,13 @@ /* the more complicated methods. parts of these should be pulled out into the shared code in bytes_methods.c to cut down on duplicate code bloat. */ +/*[clinic input] +class B "PyObject *" "&PyType_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=2935558188d97c76]*/ + +#include "clinic/transmogrify.h.h" + static inline PyObject * return_self(PyObject *self) { @@ -17,19 +24,24 @@ return_self(PyObject *self) return STRINGLIB_NEW(STRINGLIB_STR(self), STRINGLIB_LEN(self)); } -static PyObject* -stringlib_expandtabs(PyObject *self, PyObject *args, PyObject *kwds) +/*[clinic input] +B.expandtabs as stringlib_expandtabs + + tabsize: int = 8 + +Return a copy where all tab characters are expanded using spaces. + +If tabsize is not given, a tab size of 8 characters is assumed. +[clinic start generated code]*/ + +static PyObject * +stringlib_expandtabs_impl(PyObject *self, int tabsize) +/*[clinic end generated code: output=069cb7fae72e4c2b input=3c6d3b12aa3ccbea]*/ { const char *e, *p; char *q; Py_ssize_t i, j; PyObject *u; - static char *kwlist[] = {"tabsize", 0}; - int tabsize = 8; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:expandtabs", - kwlist, &tabsize)) - return NULL; /* First pass: determine size of output string */ i = j = 0; @@ -119,15 +131,22 @@ pad(PyObject *self, Py_ssize_t left, Py_ssize_t right, char fill) return u; } -static PyObject * -stringlib_ljust(PyObject *self, PyObject *args) -{ - Py_ssize_t width; - char fillchar = ' '; +/*[clinic input] +B.ljust as stringlib_ljust - if (!PyArg_ParseTuple(args, "n|c:ljust", &width, &fillchar)) - return NULL; + width: Py_ssize_t + fillchar: char = b' ' + / + +Return a left-justified string of length width. + +Padding is done using the specified fill character. +[clinic start generated code]*/ +static PyObject * +stringlib_ljust_impl(PyObject *self, Py_ssize_t width, char fillchar) +/*[clinic end generated code: output=c79ca173c5ff8337 input=eff2d014bc7d80df]*/ +{ if (STRINGLIB_LEN(self) >= width) { return return_self(self); } @@ -136,15 +155,22 @@ stringlib_ljust(PyObject *self, PyObject *args) } -static PyObject * -stringlib_rjust(PyObject *self, PyObject *args) -{ - Py_ssize_t width; - char fillchar = ' '; +/*[clinic input] +B.rjust as stringlib_rjust - if (!PyArg_ParseTuple(args, "n|c:rjust", &width, &fillchar)) - return NULL; + width: Py_ssize_t + fillchar: char = b' ' + / + +Return a right-justified string of length width. + +Padding is done using the specified fill character. +[clinic start generated code]*/ +static PyObject * +stringlib_rjust_impl(PyObject *self, Py_ssize_t width, char fillchar) +/*[clinic end generated code: output=7df5d728a5439570 input=218b0bd31308955d]*/ +{ if (STRINGLIB_LEN(self) >= width) { return return_self(self); } @@ -153,15 +179,23 @@ stringlib_rjust(PyObject *self, PyObject *args) } +/*[clinic input] +B.center as stringlib_center + + width: Py_ssize_t + fillchar: char = b' ' + / + +Return a centered string of length width. + +Padding is done using the specified fill character. +[clinic start generated code]*/ + static PyObject * -stringlib_center(PyObject *self, PyObject *args) +stringlib_center_impl(PyObject *self, Py_ssize_t width, char fillchar) +/*[clinic end generated code: output=d8da2e055288b4c2 input=3776fd278765d89b]*/ { Py_ssize_t marg, left; - Py_ssize_t width; - char fillchar = ' '; - - if (!PyArg_ParseTuple(args, "n|c:center", &width, &fillchar)) - return NULL; if (STRINGLIB_LEN(self) >= width) { return return_self(self); @@ -173,16 +207,24 @@ stringlib_center(PyObject *self, PyObject *args) return pad(self, left, marg - left, fillchar); } +/*[clinic input] +B.zfill as stringlib_zfill + + width: Py_ssize_t + / + +Pad a numeric string with zeros on the left, to fill a field of the given width. + +The original string is never truncated. +[clinic start generated code]*/ + static PyObject * -stringlib_zfill(PyObject *self, PyObject *args) +stringlib_zfill_impl(PyObject *self, Py_ssize_t width) +/*[clinic end generated code: output=0b3c684a7f1b2319 input=2da6d7b8e9bcb19a]*/ { Py_ssize_t fill; PyObject *s; char *p; - Py_ssize_t width; - - if (!PyArg_ParseTuple(args, "n:zfill", &width)) - return NULL; if (STRINGLIB_LEN(self) >= width) { return return_self(self); diff --git a/Objects/structseq.c b/Objects/structseq.c index 1b71f724a66b09..1705837f71fa57 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -240,7 +240,7 @@ structseq_repr(PyStructSequence *obj) } static PyObject * -structseq_reduce(PyStructSequence* self) +structseq_reduce(PyStructSequence* self, PyObject *Py_UNUSED(ignored)) { PyObject* tup = NULL; PyObject* dict = NULL; diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index 9bb91a5e65a0a0..e268f75be7172f 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -989,7 +989,7 @@ tupleiter_next(tupleiterobject *it) } static PyObject * -tupleiter_len(tupleiterobject *it) +tupleiter_len(tupleiterobject *it, PyObject *Py_UNUSED(ignored)) { Py_ssize_t len = 0; if (it->it_seq) @@ -1000,7 +1000,7 @@ tupleiter_len(tupleiterobject *it) PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); static PyObject * -tupleiter_reduce(tupleiterobject *it) +tupleiter_reduce(tupleiterobject *it, PyObject *Py_UNUSED(ignored)) { if (it->it_seq) return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"), diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index d5e7d10b1759ed..80d1bba1e9b407 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -3727,10 +3727,6 @@ PyUnicode_FSDecoder(PyObject* arg, void* addr) } if (PyUnicode_Check(path)) { - if (PyUnicode_READY(path) == -1) { - Py_DECREF(path); - return 0; - } output = path; } else if (PyBytes_Check(path) || is_buffer) { @@ -6426,7 +6422,7 @@ PyUnicode_AsRawUnicodeEscapeString(PyObject *unicode) if (ch < 0x100) { *p++ = (char) ch; } - /* U+0000-U+00ff range: Map 16-bit characters to '\uHHHH' */ + /* U+0100-U+ffff range: Map 16-bit characters to '\uHHHH' */ else if (ch < 0x10000) { *p++ = '\\'; *p++ = 'u'; @@ -11591,7 +11587,7 @@ unicode_hash(PyObject *self) PyDoc_STRVAR(index__doc__, "S.index(sub[, start[, end]]) -> int\n\ \n\ -Return the lowest index in S where substring sub is found, \n\ +Return the lowest index in S where substring sub is found,\n\ such that sub is contained within S[start:end]. Optional\n\ arguments start and end are interpreted as in slice notation.\n\ \n\ @@ -13796,7 +13792,7 @@ unicode_sizeof_impl(PyObject *self) } static PyObject * -unicode_getnewargs(PyObject *v) +unicode_getnewargs(PyObject *v, PyObject *Py_UNUSED(ignored)) { PyObject *copy = _PyUnicode_Copy(v); if (!copy) @@ -13857,7 +13853,7 @@ static PyMethodDef unicode_methods[] = { {"_decimal2ascii", (PyCFunction) unicode__decimal2ascii, METH_NOARGS}, #endif - {"__getnewargs__", (PyCFunction)unicode_getnewargs, METH_NOARGS}, + {"__getnewargs__", unicode_getnewargs, METH_NOARGS}, {NULL, NULL} }; @@ -15065,46 +15061,46 @@ static PyObject *unicode_iter(PyObject *seq); PyTypeObject PyUnicode_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) - "str", /* tp_name */ - sizeof(PyUnicodeObject), /* tp_size */ - 0, /* tp_itemsize */ + "str", /* tp_name */ + sizeof(PyUnicodeObject), /* tp_basicsize */ + 0, /* tp_itemsize */ /* Slots */ - (destructor)unicode_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - unicode_repr, /* tp_repr */ - &unicode_as_number, /* tp_as_number */ - &unicode_as_sequence, /* tp_as_sequence */ - &unicode_as_mapping, /* tp_as_mapping */ - (hashfunc) unicode_hash, /* tp_hash*/ - 0, /* tp_call*/ - (reprfunc) unicode_str, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ + (destructor)unicode_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + unicode_repr, /* tp_repr */ + &unicode_as_number, /* tp_as_number */ + &unicode_as_sequence, /* tp_as_sequence */ + &unicode_as_mapping, /* tp_as_mapping */ + (hashfunc) unicode_hash, /* tp_hash*/ + 0, /* tp_call*/ + (reprfunc) unicode_str, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | - Py_TPFLAGS_UNICODE_SUBCLASS, /* tp_flags */ - unicode_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - PyUnicode_RichCompare, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - unicode_iter, /* tp_iter */ - 0, /* tp_iternext */ - unicode_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - &PyBaseObject_Type, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - unicode_new, /* tp_new */ - PyObject_Del, /* tp_free */ + Py_TPFLAGS_UNICODE_SUBCLASS, /* tp_flags */ + unicode_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + PyUnicode_RichCompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + unicode_iter, /* tp_iter */ + 0, /* tp_iternext */ + unicode_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &PyBaseObject_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + unicode_new, /* tp_new */ + PyObject_Del, /* tp_free */ }; /* Initialize the Unicode implementation */ @@ -15338,7 +15334,7 @@ unicodeiter_next(unicodeiterobject *it) } static PyObject * -unicodeiter_len(unicodeiterobject *it) +unicodeiter_len(unicodeiterobject *it, PyObject *Py_UNUSED(ignored)) { Py_ssize_t len = 0; if (it->it_seq) @@ -15349,7 +15345,7 @@ unicodeiter_len(unicodeiterobject *it) PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); static PyObject * -unicodeiter_reduce(unicodeiterobject *it) +unicodeiter_reduce(unicodeiterobject *it, PyObject *Py_UNUSED(ignored)) { if (it->it_seq != NULL) { return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"), diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c index f600179d0e9bac..9f492e4b25e49f 100644 --- a/Objects/weakrefobject.c +++ b/Objects/weakrefobject.c @@ -452,7 +452,7 @@ proxy_checkref(PyWeakReference *proxy) #define WRAP_METHOD(method, special) \ static PyObject * \ - method(PyObject *proxy) { \ + method(PyObject *proxy, PyObject *Py_UNUSED(ignored)) { \ _Py_IDENTIFIER(special); \ UNWRAP(proxy); \ return _PyObject_CallMethodId(proxy, &PyId_##special, NULL); \ @@ -602,7 +602,7 @@ WRAP_METHOD(proxy_bytes, __bytes__) static PyMethodDef proxy_methods[] = { - {"__bytes__", (PyCFunction)proxy_bytes, METH_NOARGS}, + {"__bytes__", proxy_bytes, METH_NOARGS}, {NULL, NULL} }; diff --git a/PC/bdist_wininst/install.c b/PC/bdist_wininst/install.c index 04323ebd170681..6d01ad5c2d50e7 100644 --- a/PC/bdist_wininst/install.c +++ b/PC/bdist_wininst/install.c @@ -631,19 +631,18 @@ static PyObject *PyMessageBox(PyObject *self, PyObject *args) return g_Py_BuildValue("i", rc); } -static PyObject *GetRootHKey(PyObject *self) +static PyObject *GetRootHKey(PyObject *self, PyObject *Py_UNUSED(ignored)) { return g_PyLong_FromVoidPtr(hkey_root); } #define METH_VARARGS 0x0001 #define METH_NOARGS 0x0004 -typedef PyObject *(*PyCFunction)(PyObject *, PyObject *); PyMethodDef meth[] = { {"create_shortcut", CreateShortcut, METH_VARARGS, NULL}, {"get_special_folder_path", GetSpecialFolderPath, METH_VARARGS, NULL}, - {"get_root_hkey", (PyCFunction)GetRootHKey, METH_NOARGS, NULL}, + {"get_root_hkey", GetRootHKey, METH_NOARGS, NULL}, {"file_created", FileCreated, METH_VARARGS, NULL}, {"directory_created", DirectoryCreated, METH_VARARGS, NULL}, {"message_box", PyMessageBox, METH_VARARGS, NULL}, diff --git a/PC/config.c b/PC/config.c index 2037b3db64ba4b..568a0fa9a467c4 100644 --- a/PC/config.c +++ b/PC/config.c @@ -32,8 +32,9 @@ extern PyObject* PyInit__locale(void); #endif extern PyObject* PyInit__codecs(void); extern PyObject* PyInit__weakref(void); -/* XXX: This one should really be extracted to standalone extension. */ +/* XXX: These two should really be extracted to standalone extensions. */ extern PyObject* PyInit_xxsubtype(void); +extern PyObject* PyInit__xxsubinterpreters(void); extern PyObject* PyInit_zipimport(void); extern PyObject* PyInit__random(void); extern PyObject* PyInit_itertools(void); @@ -129,6 +130,7 @@ struct _inittab _PyImport_Inittab[] = { {"_json", PyInit__json}, {"xxsubtype", PyInit_xxsubtype}, + {"_xxsubinterpreters", PyInit__xxsubinterpreters}, {"zipimport", PyInit_zipimport}, #ifdef _Py_HAVE_ZLIB {"zlib", PyInit_zlib}, diff --git a/PC/launcher.c b/PC/launcher.c index d717a7e3419ab9..455f42b617c01c 100644 --- a/PC/launcher.c +++ b/PC/launcher.c @@ -61,6 +61,7 @@ debug(wchar_t * format, ...) if (log_fp != NULL) { va_start(va, format); vfwprintf_s(log_fp, format, va); + va_end(va); } } @@ -83,6 +84,7 @@ error(int rc, wchar_t * format, ... ) va_start(va, format); len = _vsnwprintf_s(message, MSGSIZE, _TRUNCATE, format, va); + va_end(va); if (rc == 0) { /* a Windows error */ winerror(GetLastError(), win_message, MSGSIZE); @@ -1116,6 +1118,7 @@ static PYC_MAGIC magic_values[] = { { 3320, 3351, L"3.5" }, { 3360, 3379, L"3.6" }, { 3390, 3399, L"3.7" }, + { 3400, 3409, L"3.8" }, { 0 } }; diff --git a/PC/pyconfig.h b/PC/pyconfig.h index d2a3f5dd39bb7f..388a3c64f18c1f 100644 --- a/PC/pyconfig.h +++ b/PC/pyconfig.h @@ -284,11 +284,11 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */ file in their Makefile (other compilers are generally taken care of by distutils.) */ # if defined(_DEBUG) -# pragma comment(lib,"python37_d.lib") +# pragma comment(lib,"python38_d.lib") # elif defined(Py_LIMITED_API) # pragma comment(lib,"python3.lib") # else -# pragma comment(lib,"python37.lib") +# pragma comment(lib,"python38.lib") # endif /* _DEBUG */ # endif /* _MSC_VER */ # endif /* Py_BUILD_CORE */ diff --git a/PC/python3.def b/PC/python3.def index 9e0348b6254462..5d93c18af87ec2 100644 --- a/PC/python3.def +++ b/PC/python3.def @@ -2,798 +2,801 @@ ; It is used when building python3dll.vcxproj LIBRARY "python3" EXPORTS - PyArg_Parse=python37.PyArg_Parse - PyArg_ParseTuple=python37.PyArg_ParseTuple - PyArg_ParseTupleAndKeywords=python37.PyArg_ParseTupleAndKeywords - PyArg_UnpackTuple=python37.PyArg_UnpackTuple - PyArg_VaParse=python37.PyArg_VaParse - PyArg_VaParseTupleAndKeywords=python37.PyArg_VaParseTupleAndKeywords - PyArg_ValidateKeywordArguments=python37.PyArg_ValidateKeywordArguments - PyBaseObject_Type=python37.PyBaseObject_Type DATA - PyBool_FromLong=python37.PyBool_FromLong - PyBool_Type=python37.PyBool_Type DATA - PyByteArrayIter_Type=python37.PyByteArrayIter_Type DATA - PyByteArray_AsString=python37.PyByteArray_AsString - PyByteArray_Concat=python37.PyByteArray_Concat - PyByteArray_FromObject=python37.PyByteArray_FromObject - PyByteArray_FromStringAndSize=python37.PyByteArray_FromStringAndSize - PyByteArray_Resize=python37.PyByteArray_Resize - PyByteArray_Size=python37.PyByteArray_Size - PyByteArray_Type=python37.PyByteArray_Type DATA - PyBytesIter_Type=python37.PyBytesIter_Type DATA - PyBytes_AsString=python37.PyBytes_AsString - PyBytes_AsStringAndSize=python37.PyBytes_AsStringAndSize - PyBytes_Concat=python37.PyBytes_Concat - PyBytes_ConcatAndDel=python37.PyBytes_ConcatAndDel - PyBytes_DecodeEscape=python37.PyBytes_DecodeEscape - PyBytes_FromFormat=python37.PyBytes_FromFormat - PyBytes_FromFormatV=python37.PyBytes_FromFormatV - PyBytes_FromObject=python37.PyBytes_FromObject - PyBytes_FromString=python37.PyBytes_FromString - PyBytes_FromStringAndSize=python37.PyBytes_FromStringAndSize - PyBytes_Repr=python37.PyBytes_Repr - PyBytes_Size=python37.PyBytes_Size - PyBytes_Type=python37.PyBytes_Type DATA - PyCFunction_Call=python37.PyCFunction_Call - PyCFunction_ClearFreeList=python37.PyCFunction_ClearFreeList - PyCFunction_GetFlags=python37.PyCFunction_GetFlags - PyCFunction_GetFunction=python37.PyCFunction_GetFunction - PyCFunction_GetSelf=python37.PyCFunction_GetSelf - PyCFunction_New=python37.PyCFunction_New - PyCFunction_NewEx=python37.PyCFunction_NewEx - PyCFunction_Type=python37.PyCFunction_Type DATA - PyCallIter_New=python37.PyCallIter_New - PyCallIter_Type=python37.PyCallIter_Type DATA - PyCallable_Check=python37.PyCallable_Check - PyCapsule_GetContext=python37.PyCapsule_GetContext - PyCapsule_GetDestructor=python37.PyCapsule_GetDestructor - PyCapsule_GetName=python37.PyCapsule_GetName - PyCapsule_GetPointer=python37.PyCapsule_GetPointer - PyCapsule_Import=python37.PyCapsule_Import - PyCapsule_IsValid=python37.PyCapsule_IsValid - PyCapsule_New=python37.PyCapsule_New - PyCapsule_SetContext=python37.PyCapsule_SetContext - PyCapsule_SetDestructor=python37.PyCapsule_SetDestructor - PyCapsule_SetName=python37.PyCapsule_SetName - PyCapsule_SetPointer=python37.PyCapsule_SetPointer - PyCapsule_Type=python37.PyCapsule_Type DATA - PyClassMethodDescr_Type=python37.PyClassMethodDescr_Type DATA - PyCodec_BackslashReplaceErrors=python37.PyCodec_BackslashReplaceErrors - PyCodec_Decode=python37.PyCodec_Decode - PyCodec_Decoder=python37.PyCodec_Decoder - PyCodec_Encode=python37.PyCodec_Encode - PyCodec_Encoder=python37.PyCodec_Encoder - PyCodec_IgnoreErrors=python37.PyCodec_IgnoreErrors - PyCodec_IncrementalDecoder=python37.PyCodec_IncrementalDecoder - PyCodec_IncrementalEncoder=python37.PyCodec_IncrementalEncoder - PyCodec_KnownEncoding=python37.PyCodec_KnownEncoding - PyCodec_LookupError=python37.PyCodec_LookupError - PyCodec_NameReplaceErrors=python37.PyCodec_NameReplaceErrors - PyCodec_Register=python37.PyCodec_Register - PyCodec_RegisterError=python37.PyCodec_RegisterError - PyCodec_ReplaceErrors=python37.PyCodec_ReplaceErrors - PyCodec_StreamReader=python37.PyCodec_StreamReader - PyCodec_StreamWriter=python37.PyCodec_StreamWriter - PyCodec_StrictErrors=python37.PyCodec_StrictErrors - PyCodec_XMLCharRefReplaceErrors=python37.PyCodec_XMLCharRefReplaceErrors - PyComplex_FromDoubles=python37.PyComplex_FromDoubles - PyComplex_ImagAsDouble=python37.PyComplex_ImagAsDouble - PyComplex_RealAsDouble=python37.PyComplex_RealAsDouble - PyComplex_Type=python37.PyComplex_Type DATA - PyDescr_NewClassMethod=python37.PyDescr_NewClassMethod - PyDescr_NewGetSet=python37.PyDescr_NewGetSet - PyDescr_NewMember=python37.PyDescr_NewMember - PyDescr_NewMethod=python37.PyDescr_NewMethod - PyDictItems_Type=python37.PyDictItems_Type DATA - PyDictIterItem_Type=python37.PyDictIterItem_Type DATA - PyDictIterKey_Type=python37.PyDictIterKey_Type DATA - PyDictIterValue_Type=python37.PyDictIterValue_Type DATA - PyDictKeys_Type=python37.PyDictKeys_Type DATA - PyDictProxy_New=python37.PyDictProxy_New - PyDictProxy_Type=python37.PyDictProxy_Type DATA - PyDictValues_Type=python37.PyDictValues_Type DATA - PyDict_Clear=python37.PyDict_Clear - PyDict_Contains=python37.PyDict_Contains - PyDict_Copy=python37.PyDict_Copy - PyDict_DelItem=python37.PyDict_DelItem - PyDict_DelItemString=python37.PyDict_DelItemString - PyDict_GetItem=python37.PyDict_GetItem - PyDict_GetItemString=python37.PyDict_GetItemString - PyDict_GetItemWithError=python37.PyDict_GetItemWithError - PyDict_Items=python37.PyDict_Items - PyDict_Keys=python37.PyDict_Keys - PyDict_Merge=python37.PyDict_Merge - PyDict_MergeFromSeq2=python37.PyDict_MergeFromSeq2 - PyDict_New=python37.PyDict_New - PyDict_Next=python37.PyDict_Next - PyDict_SetItem=python37.PyDict_SetItem - PyDict_SetItemString=python37.PyDict_SetItemString - PyDict_Size=python37.PyDict_Size - PyDict_Type=python37.PyDict_Type DATA - PyDict_Update=python37.PyDict_Update - PyDict_Values=python37.PyDict_Values - PyEllipsis_Type=python37.PyEllipsis_Type DATA - PyEnum_Type=python37.PyEnum_Type DATA - PyErr_BadArgument=python37.PyErr_BadArgument - PyErr_BadInternalCall=python37.PyErr_BadInternalCall - PyErr_CheckSignals=python37.PyErr_CheckSignals - PyErr_Clear=python37.PyErr_Clear - PyErr_Display=python37.PyErr_Display - PyErr_ExceptionMatches=python37.PyErr_ExceptionMatches - PyErr_Fetch=python37.PyErr_Fetch - PyErr_Format=python37.PyErr_Format - PyErr_FormatV=python37.PyErr_FormatV - PyErr_GetExcInfo=python37.PyErr_GetExcInfo - PyErr_GivenExceptionMatches=python37.PyErr_GivenExceptionMatches - PyErr_NewException=python37.PyErr_NewException - PyErr_NewExceptionWithDoc=python37.PyErr_NewExceptionWithDoc - PyErr_NoMemory=python37.PyErr_NoMemory - PyErr_NormalizeException=python37.PyErr_NormalizeException - PyErr_Occurred=python37.PyErr_Occurred - PyErr_Print=python37.PyErr_Print - PyErr_PrintEx=python37.PyErr_PrintEx - PyErr_ProgramText=python37.PyErr_ProgramText - PyErr_ResourceWarning=python37.PyErr_ResourceWarning - PyErr_Restore=python37.PyErr_Restore - PyErr_SetExcFromWindowsErr=python37.PyErr_SetExcFromWindowsErr - PyErr_SetExcFromWindowsErrWithFilename=python37.PyErr_SetExcFromWindowsErrWithFilename - PyErr_SetExcFromWindowsErrWithFilenameObject=python37.PyErr_SetExcFromWindowsErrWithFilenameObject - PyErr_SetExcFromWindowsErrWithFilenameObjects=python37.PyErr_SetExcFromWindowsErrWithFilenameObjects - PyErr_SetExcInfo=python37.PyErr_SetExcInfo - PyErr_SetFromErrno=python37.PyErr_SetFromErrno - PyErr_SetFromErrnoWithFilename=python37.PyErr_SetFromErrnoWithFilename - PyErr_SetFromErrnoWithFilenameObject=python37.PyErr_SetFromErrnoWithFilenameObject - PyErr_SetFromErrnoWithFilenameObjects=python37.PyErr_SetFromErrnoWithFilenameObjects - PyErr_SetFromWindowsErr=python37.PyErr_SetFromWindowsErr - PyErr_SetFromWindowsErrWithFilename=python37.PyErr_SetFromWindowsErrWithFilename - PyErr_SetImportError=python37.PyErr_SetImportError - PyErr_SetImportErrorSubclass=python37.PyErr_SetImportErrorSubclass - PyErr_SetInterrupt=python37.PyErr_SetInterrupt - PyErr_SetNone=python37.PyErr_SetNone - PyErr_SetObject=python37.PyErr_SetObject - PyErr_SetString=python37.PyErr_SetString - PyErr_SyntaxLocation=python37.PyErr_SyntaxLocation - PyErr_SyntaxLocationEx=python37.PyErr_SyntaxLocationEx - PyErr_WarnEx=python37.PyErr_WarnEx - PyErr_WarnExplicit=python37.PyErr_WarnExplicit - PyErr_WarnFormat=python37.PyErr_WarnFormat - PyErr_WriteUnraisable=python37.PyErr_WriteUnraisable - PyEval_AcquireLock=python37.PyEval_AcquireLock - PyEval_AcquireThread=python37.PyEval_AcquireThread - PyEval_CallFunction=python37.PyEval_CallFunction - PyEval_CallMethod=python37.PyEval_CallMethod - PyEval_CallObjectWithKeywords=python37.PyEval_CallObjectWithKeywords - PyEval_EvalCode=python37.PyEval_EvalCode - PyEval_EvalCodeEx=python37.PyEval_EvalCodeEx - PyEval_EvalFrame=python37.PyEval_EvalFrame - PyEval_EvalFrameEx=python37.PyEval_EvalFrameEx - PyEval_GetBuiltins=python37.PyEval_GetBuiltins - PyEval_GetCallStats=python37.PyEval_GetCallStats - PyEval_GetFrame=python37.PyEval_GetFrame - PyEval_GetFuncDesc=python37.PyEval_GetFuncDesc - PyEval_GetFuncName=python37.PyEval_GetFuncName - PyEval_GetGlobals=python37.PyEval_GetGlobals - PyEval_GetLocals=python37.PyEval_GetLocals - PyEval_InitThreads=python37.PyEval_InitThreads - PyEval_ReInitThreads=python37.PyEval_ReInitThreads - PyEval_ReleaseLock=python37.PyEval_ReleaseLock - PyEval_ReleaseThread=python37.PyEval_ReleaseThread - PyEval_RestoreThread=python37.PyEval_RestoreThread - PyEval_SaveThread=python37.PyEval_SaveThread - PyEval_ThreadsInitialized=python37.PyEval_ThreadsInitialized - PyExc_ArithmeticError=python37.PyExc_ArithmeticError DATA - PyExc_AssertionError=python37.PyExc_AssertionError DATA - PyExc_AttributeError=python37.PyExc_AttributeError DATA - PyExc_BaseException=python37.PyExc_BaseException DATA - PyExc_BlockingIOError=python37.PyExc_BlockingIOError DATA - PyExc_BrokenPipeError=python37.PyExc_BrokenPipeError DATA - PyExc_BufferError=python37.PyExc_BufferError DATA - PyExc_BytesWarning=python37.PyExc_BytesWarning DATA - PyExc_ChildProcessError=python37.PyExc_ChildProcessError DATA - PyExc_ConnectionAbortedError=python37.PyExc_ConnectionAbortedError DATA - PyExc_ConnectionError=python37.PyExc_ConnectionError DATA - PyExc_ConnectionRefusedError=python37.PyExc_ConnectionRefusedError DATA - PyExc_ConnectionResetError=python37.PyExc_ConnectionResetError DATA - PyExc_DeprecationWarning=python37.PyExc_DeprecationWarning DATA - PyExc_EOFError=python37.PyExc_EOFError DATA - PyExc_EnvironmentError=python37.PyExc_EnvironmentError DATA - PyExc_Exception=python37.PyExc_Exception DATA - PyExc_FileExistsError=python37.PyExc_FileExistsError DATA - PyExc_FileNotFoundError=python37.PyExc_FileNotFoundError DATA - PyExc_FloatingPointError=python37.PyExc_FloatingPointError DATA - PyExc_FutureWarning=python37.PyExc_FutureWarning DATA - PyExc_GeneratorExit=python37.PyExc_GeneratorExit DATA - PyExc_IOError=python37.PyExc_IOError DATA - PyExc_ImportError=python37.PyExc_ImportError DATA - PyExc_ImportWarning=python37.PyExc_ImportWarning DATA - PyExc_IndentationError=python37.PyExc_IndentationError DATA - PyExc_IndexError=python37.PyExc_IndexError DATA - PyExc_InterruptedError=python37.PyExc_InterruptedError DATA - PyExc_IsADirectoryError=python37.PyExc_IsADirectoryError DATA - PyExc_KeyError=python37.PyExc_KeyError DATA - PyExc_KeyboardInterrupt=python37.PyExc_KeyboardInterrupt DATA - PyExc_LookupError=python37.PyExc_LookupError DATA - PyExc_MemoryError=python37.PyExc_MemoryError DATA - PyExc_ModuleNotFoundError=python37.PyExc_ModuleNotFoundError DATA - PyExc_NameError=python37.PyExc_NameError DATA - PyExc_NotADirectoryError=python37.PyExc_NotADirectoryError DATA - PyExc_NotImplementedError=python37.PyExc_NotImplementedError DATA - PyExc_OSError=python37.PyExc_OSError DATA - PyExc_OverflowError=python37.PyExc_OverflowError DATA - PyExc_PendingDeprecationWarning=python37.PyExc_PendingDeprecationWarning DATA - PyExc_PermissionError=python37.PyExc_PermissionError DATA - PyExc_ProcessLookupError=python37.PyExc_ProcessLookupError DATA - PyExc_RecursionError=python37.PyExc_RecursionError DATA - PyExc_ReferenceError=python37.PyExc_ReferenceError DATA - PyExc_ResourceWarning=python37.PyExc_ResourceWarning DATA - PyExc_RuntimeError=python37.PyExc_RuntimeError DATA - PyExc_RuntimeWarning=python37.PyExc_RuntimeWarning DATA - PyExc_StopAsyncIteration=python37.PyExc_StopAsyncIteration DATA - PyExc_StopIteration=python37.PyExc_StopIteration DATA - PyExc_SyntaxError=python37.PyExc_SyntaxError DATA - PyExc_SyntaxWarning=python37.PyExc_SyntaxWarning DATA - PyExc_SystemError=python37.PyExc_SystemError DATA - PyExc_SystemExit=python37.PyExc_SystemExit DATA - PyExc_TabError=python37.PyExc_TabError DATA - PyExc_TimeoutError=python37.PyExc_TimeoutError DATA - PyExc_TypeError=python37.PyExc_TypeError DATA - PyExc_UnboundLocalError=python37.PyExc_UnboundLocalError DATA - PyExc_UnicodeDecodeError=python37.PyExc_UnicodeDecodeError DATA - PyExc_UnicodeEncodeError=python37.PyExc_UnicodeEncodeError DATA - PyExc_UnicodeError=python37.PyExc_UnicodeError DATA - PyExc_UnicodeTranslateError=python37.PyExc_UnicodeTranslateError DATA - PyExc_UnicodeWarning=python37.PyExc_UnicodeWarning DATA - PyExc_UserWarning=python37.PyExc_UserWarning DATA - PyExc_ValueError=python37.PyExc_ValueError DATA - PyExc_Warning=python37.PyExc_Warning DATA - PyExc_WindowsError=python37.PyExc_WindowsError DATA - PyExc_ZeroDivisionError=python37.PyExc_ZeroDivisionError DATA - PyException_GetCause=python37.PyException_GetCause - PyException_GetContext=python37.PyException_GetContext - PyException_GetTraceback=python37.PyException_GetTraceback - PyException_SetCause=python37.PyException_SetCause - PyException_SetContext=python37.PyException_SetContext - PyException_SetTraceback=python37.PyException_SetTraceback - PyFile_FromFd=python37.PyFile_FromFd - PyFile_GetLine=python37.PyFile_GetLine - PyFile_WriteObject=python37.PyFile_WriteObject - PyFile_WriteString=python37.PyFile_WriteString - PyFilter_Type=python37.PyFilter_Type DATA - PyFloat_AsDouble=python37.PyFloat_AsDouble - PyFloat_FromDouble=python37.PyFloat_FromDouble - PyFloat_FromString=python37.PyFloat_FromString - PyFloat_GetInfo=python37.PyFloat_GetInfo - PyFloat_GetMax=python37.PyFloat_GetMax - PyFloat_GetMin=python37.PyFloat_GetMin - PyFloat_Type=python37.PyFloat_Type DATA - PyFrozenSet_New=python37.PyFrozenSet_New - PyFrozenSet_Type=python37.PyFrozenSet_Type DATA - PyGC_Collect=python37.PyGC_Collect - PyGILState_Ensure=python37.PyGILState_Ensure - PyGILState_GetThisThreadState=python37.PyGILState_GetThisThreadState - PyGILState_Release=python37.PyGILState_Release - PyGetSetDescr_Type=python37.PyGetSetDescr_Type DATA - PyImport_AddModule=python37.PyImport_AddModule - PyImport_AddModuleObject=python37.PyImport_AddModuleObject - PyImport_AppendInittab=python37.PyImport_AppendInittab - PyImport_Cleanup=python37.PyImport_Cleanup - PyImport_ExecCodeModule=python37.PyImport_ExecCodeModule - PyImport_ExecCodeModuleEx=python37.PyImport_ExecCodeModuleEx - PyImport_ExecCodeModuleObject=python37.PyImport_ExecCodeModuleObject - PyImport_ExecCodeModuleWithPathnames=python37.PyImport_ExecCodeModuleWithPathnames - PyImport_GetImporter=python37.PyImport_GetImporter - PyImport_GetMagicNumber=python37.PyImport_GetMagicNumber - PyImport_GetMagicTag=python37.PyImport_GetMagicTag - PyImport_GetModule=python37.PyImport_GetModule - PyImport_GetModuleDict=python37.PyImport_GetModuleDict - PyImport_Import=python37.PyImport_Import - PyImport_ImportFrozenModule=python37.PyImport_ImportFrozenModule - PyImport_ImportFrozenModuleObject=python37.PyImport_ImportFrozenModuleObject - PyImport_ImportModule=python37.PyImport_ImportModule - PyImport_ImportModuleLevel=python37.PyImport_ImportModuleLevel - PyImport_ImportModuleLevelObject=python37.PyImport_ImportModuleLevelObject - PyImport_ImportModuleNoBlock=python37.PyImport_ImportModuleNoBlock - PyImport_ReloadModule=python37.PyImport_ReloadModule - PyInterpreterState_Clear=python37.PyInterpreterState_Clear - PyInterpreterState_Delete=python37.PyInterpreterState_Delete - PyInterpreterState_New=python37.PyInterpreterState_New - PyIter_Next=python37.PyIter_Next - PyListIter_Type=python37.PyListIter_Type DATA - PyListRevIter_Type=python37.PyListRevIter_Type DATA - PyList_Append=python37.PyList_Append - PyList_AsTuple=python37.PyList_AsTuple - PyList_GetItem=python37.PyList_GetItem - PyList_GetSlice=python37.PyList_GetSlice - PyList_Insert=python37.PyList_Insert - PyList_New=python37.PyList_New - PyList_Reverse=python37.PyList_Reverse - PyList_SetItem=python37.PyList_SetItem - PyList_SetSlice=python37.PyList_SetSlice - PyList_Size=python37.PyList_Size - PyList_Sort=python37.PyList_Sort - PyList_Type=python37.PyList_Type DATA - PyLongRangeIter_Type=python37.PyLongRangeIter_Type DATA - PyLong_AsDouble=python37.PyLong_AsDouble - PyLong_AsLong=python37.PyLong_AsLong - PyLong_AsLongAndOverflow=python37.PyLong_AsLongAndOverflow - PyLong_AsLongLong=python37.PyLong_AsLongLong - PyLong_AsLongLongAndOverflow=python37.PyLong_AsLongLongAndOverflow - PyLong_AsSize_t=python37.PyLong_AsSize_t - PyLong_AsSsize_t=python37.PyLong_AsSsize_t - PyLong_AsUnsignedLong=python37.PyLong_AsUnsignedLong - PyLong_AsUnsignedLongLong=python37.PyLong_AsUnsignedLongLong - PyLong_AsUnsignedLongLongMask=python37.PyLong_AsUnsignedLongLongMask - PyLong_AsUnsignedLongMask=python37.PyLong_AsUnsignedLongMask - PyLong_AsVoidPtr=python37.PyLong_AsVoidPtr - PyLong_FromDouble=python37.PyLong_FromDouble - PyLong_FromLong=python37.PyLong_FromLong - PyLong_FromLongLong=python37.PyLong_FromLongLong - PyLong_FromSize_t=python37.PyLong_FromSize_t - PyLong_FromSsize_t=python37.PyLong_FromSsize_t - PyLong_FromString=python37.PyLong_FromString - PyLong_FromUnsignedLong=python37.PyLong_FromUnsignedLong - PyLong_FromUnsignedLongLong=python37.PyLong_FromUnsignedLongLong - PyLong_FromVoidPtr=python37.PyLong_FromVoidPtr - PyLong_GetInfo=python37.PyLong_GetInfo - PyLong_Type=python37.PyLong_Type DATA - PyMap_Type=python37.PyMap_Type DATA - PyMapping_Check=python37.PyMapping_Check - PyMapping_GetItemString=python37.PyMapping_GetItemString - PyMapping_HasKey=python37.PyMapping_HasKey - PyMapping_HasKeyString=python37.PyMapping_HasKeyString - PyMapping_Items=python37.PyMapping_Items - PyMapping_Keys=python37.PyMapping_Keys - PyMapping_Length=python37.PyMapping_Length - PyMapping_SetItemString=python37.PyMapping_SetItemString - PyMapping_Size=python37.PyMapping_Size - PyMapping_Values=python37.PyMapping_Values - PyMem_Calloc=python37.PyMem_Calloc - PyMem_Free=python37.PyMem_Free - PyMem_Malloc=python37.PyMem_Malloc - PyMem_Realloc=python37.PyMem_Realloc - PyMemberDescr_Type=python37.PyMemberDescr_Type DATA - PyMemoryView_FromMemory=python37.PyMemoryView_FromMemory - PyMemoryView_FromObject=python37.PyMemoryView_FromObject - PyMemoryView_GetContiguous=python37.PyMemoryView_GetContiguous - PyMemoryView_Type=python37.PyMemoryView_Type DATA - PyMethodDescr_Type=python37.PyMethodDescr_Type DATA - PyModuleDef_Init=python37.PyModuleDef_Init - PyModuleDef_Type=python37.PyModuleDef_Type DATA - PyModule_AddFunctions=python37.PyModule_AddFunctions - PyModule_AddIntConstant=python37.PyModule_AddIntConstant - PyModule_AddObject=python37.PyModule_AddObject - PyModule_AddStringConstant=python37.PyModule_AddStringConstant - PyModule_Create2=python37.PyModule_Create2 - PyModule_ExecDef=python37.PyModule_ExecDef - PyModule_FromDefAndSpec2=python37.PyModule_FromDefAndSpec2 - PyModule_GetDef=python37.PyModule_GetDef - PyModule_GetDict=python37.PyModule_GetDict - PyModule_GetFilename=python37.PyModule_GetFilename - PyModule_GetFilenameObject=python37.PyModule_GetFilenameObject - PyModule_GetName=python37.PyModule_GetName - PyModule_GetNameObject=python37.PyModule_GetNameObject - PyModule_GetState=python37.PyModule_GetState - PyModule_New=python37.PyModule_New - PyModule_NewObject=python37.PyModule_NewObject - PyModule_SetDocString=python37.PyModule_SetDocString - PyModule_Type=python37.PyModule_Type DATA - PyNullImporter_Type=python37.PyNullImporter_Type DATA - PyNumber_Absolute=python37.PyNumber_Absolute - PyNumber_Add=python37.PyNumber_Add - PyNumber_And=python37.PyNumber_And - PyNumber_AsSsize_t=python37.PyNumber_AsSsize_t - PyNumber_Check=python37.PyNumber_Check - PyNumber_Divmod=python37.PyNumber_Divmod - PyNumber_Float=python37.PyNumber_Float - PyNumber_FloorDivide=python37.PyNumber_FloorDivide - PyNumber_InPlaceAdd=python37.PyNumber_InPlaceAdd - PyNumber_InPlaceAnd=python37.PyNumber_InPlaceAnd - PyNumber_InPlaceFloorDivide=python37.PyNumber_InPlaceFloorDivide - PyNumber_InPlaceLshift=python37.PyNumber_InPlaceLshift - PyNumber_InPlaceMatrixMultiply=python37.PyNumber_InPlaceMatrixMultiply - PyNumber_InPlaceMultiply=python37.PyNumber_InPlaceMultiply - PyNumber_InPlaceOr=python37.PyNumber_InPlaceOr - PyNumber_InPlacePower=python37.PyNumber_InPlacePower - PyNumber_InPlaceRemainder=python37.PyNumber_InPlaceRemainder - PyNumber_InPlaceRshift=python37.PyNumber_InPlaceRshift - PyNumber_InPlaceSubtract=python37.PyNumber_InPlaceSubtract - PyNumber_InPlaceTrueDivide=python37.PyNumber_InPlaceTrueDivide - PyNumber_InPlaceXor=python37.PyNumber_InPlaceXor - PyNumber_Index=python37.PyNumber_Index - PyNumber_Invert=python37.PyNumber_Invert - PyNumber_Long=python37.PyNumber_Long - PyNumber_Lshift=python37.PyNumber_Lshift - PyNumber_MatrixMultiply=python37.PyNumber_MatrixMultiply - PyNumber_Multiply=python37.PyNumber_Multiply - PyNumber_Negative=python37.PyNumber_Negative - PyNumber_Or=python37.PyNumber_Or - PyNumber_Positive=python37.PyNumber_Positive - PyNumber_Power=python37.PyNumber_Power - PyNumber_Remainder=python37.PyNumber_Remainder - PyNumber_Rshift=python37.PyNumber_Rshift - PyNumber_Subtract=python37.PyNumber_Subtract - PyNumber_ToBase=python37.PyNumber_ToBase - PyNumber_TrueDivide=python37.PyNumber_TrueDivide - PyNumber_Xor=python37.PyNumber_Xor - PyODictItems_Type=python37.PyODictItems_Type DATA - PyODictIter_Type=python37.PyODictIter_Type DATA - PyODictKeys_Type=python37.PyODictKeys_Type DATA - PyODictValues_Type=python37.PyODictValues_Type DATA - PyODict_DelItem=python37.PyODict_DelItem - PyODict_New=python37.PyODict_New - PyODict_SetItem=python37.PyODict_SetItem - PyODict_Type=python37.PyODict_Type DATA - PyOS_AfterFork=python37.PyOS_AfterFork - PyOS_CheckStack=python37.PyOS_CheckStack - PyOS_FSPath=python37.PyOS_FSPath - PyOS_InitInterrupts=python37.PyOS_InitInterrupts - PyOS_InputHook=python37.PyOS_InputHook DATA - PyOS_InterruptOccurred=python37.PyOS_InterruptOccurred - PyOS_ReadlineFunctionPointer=python37.PyOS_ReadlineFunctionPointer DATA - PyOS_double_to_string=python37.PyOS_double_to_string - PyOS_getsig=python37.PyOS_getsig - PyOS_mystricmp=python37.PyOS_mystricmp - PyOS_mystrnicmp=python37.PyOS_mystrnicmp - PyOS_setsig=python37.PyOS_setsig - PyOS_snprintf=python37.PyOS_snprintf - PyOS_string_to_double=python37.PyOS_string_to_double - PyOS_strtol=python37.PyOS_strtol - PyOS_strtoul=python37.PyOS_strtoul - PyOS_vsnprintf=python37.PyOS_vsnprintf - PyObject_ASCII=python37.PyObject_ASCII - PyObject_AsCharBuffer=python37.PyObject_AsCharBuffer - PyObject_AsFileDescriptor=python37.PyObject_AsFileDescriptor - PyObject_AsReadBuffer=python37.PyObject_AsReadBuffer - PyObject_AsWriteBuffer=python37.PyObject_AsWriteBuffer - PyObject_Bytes=python37.PyObject_Bytes - PyObject_Call=python37.PyObject_Call - PyObject_CallFunction=python37.PyObject_CallFunction - PyObject_CallFunctionObjArgs=python37.PyObject_CallFunctionObjArgs - PyObject_CallMethod=python37.PyObject_CallMethod - PyObject_CallMethodObjArgs=python37.PyObject_CallMethodObjArgs - PyObject_CallObject=python37.PyObject_CallObject - PyObject_Calloc=python37.PyObject_Calloc - PyObject_CheckReadBuffer=python37.PyObject_CheckReadBuffer - PyObject_ClearWeakRefs=python37.PyObject_ClearWeakRefs - PyObject_DelItem=python37.PyObject_DelItem - PyObject_DelItemString=python37.PyObject_DelItemString - PyObject_Dir=python37.PyObject_Dir - PyObject_Format=python37.PyObject_Format - PyObject_Free=python37.PyObject_Free - PyObject_GC_Del=python37.PyObject_GC_Del - PyObject_GC_Track=python37.PyObject_GC_Track - PyObject_GC_UnTrack=python37.PyObject_GC_UnTrack - PyObject_GenericGetAttr=python37.PyObject_GenericGetAttr - PyObject_GenericSetAttr=python37.PyObject_GenericSetAttr - PyObject_GenericSetDict=python37.PyObject_GenericSetDict - PyObject_GetAttr=python37.PyObject_GetAttr - PyObject_GetAttrString=python37.PyObject_GetAttrString - PyObject_GetItem=python37.PyObject_GetItem - PyObject_GetIter=python37.PyObject_GetIter - PyObject_HasAttr=python37.PyObject_HasAttr - PyObject_HasAttrString=python37.PyObject_HasAttrString - PyObject_Hash=python37.PyObject_Hash - PyObject_HashNotImplemented=python37.PyObject_HashNotImplemented - PyObject_Init=python37.PyObject_Init - PyObject_InitVar=python37.PyObject_InitVar - PyObject_IsInstance=python37.PyObject_IsInstance - PyObject_IsSubclass=python37.PyObject_IsSubclass - PyObject_IsTrue=python37.PyObject_IsTrue - PyObject_Length=python37.PyObject_Length - PyObject_Malloc=python37.PyObject_Malloc - PyObject_Not=python37.PyObject_Not - PyObject_Realloc=python37.PyObject_Realloc - PyObject_Repr=python37.PyObject_Repr - PyObject_RichCompare=python37.PyObject_RichCompare - PyObject_RichCompareBool=python37.PyObject_RichCompareBool - PyObject_SelfIter=python37.PyObject_SelfIter - PyObject_SetAttr=python37.PyObject_SetAttr - PyObject_SetAttrString=python37.PyObject_SetAttrString - PyObject_SetItem=python37.PyObject_SetItem - PyObject_Size=python37.PyObject_Size - PyObject_Str=python37.PyObject_Str - PyObject_Type=python37.PyObject_Type - PyParser_SimpleParseFileFlags=python37.PyParser_SimpleParseFileFlags - PyParser_SimpleParseStringFlags=python37.PyParser_SimpleParseStringFlags - PyParser_SimpleParseStringFlagsFilename=python37.PyParser_SimpleParseStringFlagsFilename - PyProperty_Type=python37.PyProperty_Type DATA - PyRangeIter_Type=python37.PyRangeIter_Type DATA - PyRange_Type=python37.PyRange_Type DATA - PyReversed_Type=python37.PyReversed_Type DATA - PySeqIter_New=python37.PySeqIter_New - PySeqIter_Type=python37.PySeqIter_Type DATA - PySequence_Check=python37.PySequence_Check - PySequence_Concat=python37.PySequence_Concat - PySequence_Contains=python37.PySequence_Contains - PySequence_Count=python37.PySequence_Count - PySequence_DelItem=python37.PySequence_DelItem - PySequence_DelSlice=python37.PySequence_DelSlice - PySequence_Fast=python37.PySequence_Fast - PySequence_GetItem=python37.PySequence_GetItem - PySequence_GetSlice=python37.PySequence_GetSlice - PySequence_In=python37.PySequence_In - PySequence_InPlaceConcat=python37.PySequence_InPlaceConcat - PySequence_InPlaceRepeat=python37.PySequence_InPlaceRepeat - PySequence_Index=python37.PySequence_Index - PySequence_Length=python37.PySequence_Length - PySequence_List=python37.PySequence_List - PySequence_Repeat=python37.PySequence_Repeat - PySequence_SetItem=python37.PySequence_SetItem - PySequence_SetSlice=python37.PySequence_SetSlice - PySequence_Size=python37.PySequence_Size - PySequence_Tuple=python37.PySequence_Tuple - PySetIter_Type=python37.PySetIter_Type DATA - PySet_Add=python37.PySet_Add - PySet_Clear=python37.PySet_Clear - PySet_Contains=python37.PySet_Contains - PySet_Discard=python37.PySet_Discard - PySet_New=python37.PySet_New - PySet_Pop=python37.PySet_Pop - PySet_Size=python37.PySet_Size - PySet_Type=python37.PySet_Type DATA - PySlice_AdjustIndices=python37.PySlice_AdjustIndices - PySlice_GetIndices=python37.PySlice_GetIndices - PySlice_GetIndicesEx=python37.PySlice_GetIndicesEx - PySlice_New=python37.PySlice_New - PySlice_Type=python37.PySlice_Type DATA - PySlice_Unpack=python37.PySlice_Unpack - PySortWrapper_Type=python37.PySortWrapper_Type DATA - PyInterpreterState_GetID=python37.PyInterpreterState_GetID - PyState_AddModule=python37.PyState_AddModule - PyState_FindModule=python37.PyState_FindModule - PyState_RemoveModule=python37.PyState_RemoveModule - PyStructSequence_GetItem=python37.PyStructSequence_GetItem - PyStructSequence_New=python37.PyStructSequence_New - PyStructSequence_NewType=python37.PyStructSequence_NewType - PyStructSequence_SetItem=python37.PyStructSequence_SetItem - PySuper_Type=python37.PySuper_Type DATA - PySys_AddWarnOption=python37.PySys_AddWarnOption - PySys_AddWarnOptionUnicode=python37.PySys_AddWarnOptionUnicode - PySys_AddXOption=python37.PySys_AddXOption - PySys_FormatStderr=python37.PySys_FormatStderr - PySys_FormatStdout=python37.PySys_FormatStdout - PySys_GetObject=python37.PySys_GetObject - PySys_GetXOptions=python37.PySys_GetXOptions - PySys_HasWarnOptions=python37.PySys_HasWarnOptions - PySys_ResetWarnOptions=python37.PySys_ResetWarnOptions - PySys_SetArgv=python37.PySys_SetArgv - PySys_SetArgvEx=python37.PySys_SetArgvEx - PySys_SetObject=python37.PySys_SetObject - PySys_SetPath=python37.PySys_SetPath - PySys_WriteStderr=python37.PySys_WriteStderr - PySys_WriteStdout=python37.PySys_WriteStdout - PyThreadState_Clear=python37.PyThreadState_Clear - PyThreadState_Delete=python37.PyThreadState_Delete - PyThreadState_DeleteCurrent=python37.PyThreadState_DeleteCurrent - PyThreadState_Get=python37.PyThreadState_Get - PyThreadState_GetDict=python37.PyThreadState_GetDict - PyThreadState_New=python37.PyThreadState_New - PyThreadState_SetAsyncExc=python37.PyThreadState_SetAsyncExc - PyThreadState_Swap=python37.PyThreadState_Swap - PyThread_tss_alloc=python37.PyThread_tss_alloc - PyThread_tss_create=python37.PyThread_tss_create - PyThread_tss_delete=python37.PyThread_tss_delete - PyThread_tss_free=python37.PyThread_tss_free - PyThread_tss_get=python37.PyThread_tss_get - PyThread_tss_is_created=python37.PyThread_tss_is_created - PyThread_tss_set=python37.PyThread_tss_set - PyTraceBack_Here=python37.PyTraceBack_Here - PyTraceBack_Print=python37.PyTraceBack_Print - PyTraceBack_Type=python37.PyTraceBack_Type DATA - PyTupleIter_Type=python37.PyTupleIter_Type DATA - PyTuple_ClearFreeList=python37.PyTuple_ClearFreeList - PyTuple_GetItem=python37.PyTuple_GetItem - PyTuple_GetSlice=python37.PyTuple_GetSlice - PyTuple_New=python37.PyTuple_New - PyTuple_Pack=python37.PyTuple_Pack - PyTuple_SetItem=python37.PyTuple_SetItem - PyTuple_Size=python37.PyTuple_Size - PyTuple_Type=python37.PyTuple_Type DATA - PyType_ClearCache=python37.PyType_ClearCache - PyType_FromSpec=python37.PyType_FromSpec - PyType_FromSpecWithBases=python37.PyType_FromSpecWithBases - PyType_GenericAlloc=python37.PyType_GenericAlloc - PyType_GenericNew=python37.PyType_GenericNew - PyType_GetFlags=python37.PyType_GetFlags - PyType_GetSlot=python37.PyType_GetSlot - PyType_IsSubtype=python37.PyType_IsSubtype - PyType_Modified=python37.PyType_Modified - PyType_Ready=python37.PyType_Ready - PyType_Type=python37.PyType_Type DATA - PyUnicodeDecodeError_Create=python37.PyUnicodeDecodeError_Create - PyUnicodeDecodeError_GetEncoding=python37.PyUnicodeDecodeError_GetEncoding - PyUnicodeDecodeError_GetEnd=python37.PyUnicodeDecodeError_GetEnd - PyUnicodeDecodeError_GetObject=python37.PyUnicodeDecodeError_GetObject - PyUnicodeDecodeError_GetReason=python37.PyUnicodeDecodeError_GetReason - PyUnicodeDecodeError_GetStart=python37.PyUnicodeDecodeError_GetStart - PyUnicodeDecodeError_SetEnd=python37.PyUnicodeDecodeError_SetEnd - PyUnicodeDecodeError_SetReason=python37.PyUnicodeDecodeError_SetReason - PyUnicodeDecodeError_SetStart=python37.PyUnicodeDecodeError_SetStart - PyUnicodeEncodeError_GetEncoding=python37.PyUnicodeEncodeError_GetEncoding - PyUnicodeEncodeError_GetEnd=python37.PyUnicodeEncodeError_GetEnd - PyUnicodeEncodeError_GetObject=python37.PyUnicodeEncodeError_GetObject - PyUnicodeEncodeError_GetReason=python37.PyUnicodeEncodeError_GetReason - PyUnicodeEncodeError_GetStart=python37.PyUnicodeEncodeError_GetStart - PyUnicodeEncodeError_SetEnd=python37.PyUnicodeEncodeError_SetEnd - PyUnicodeEncodeError_SetReason=python37.PyUnicodeEncodeError_SetReason - PyUnicodeEncodeError_SetStart=python37.PyUnicodeEncodeError_SetStart - PyUnicodeIter_Type=python37.PyUnicodeIter_Type DATA - PyUnicodeTranslateError_GetEnd=python37.PyUnicodeTranslateError_GetEnd - PyUnicodeTranslateError_GetObject=python37.PyUnicodeTranslateError_GetObject - PyUnicodeTranslateError_GetReason=python37.PyUnicodeTranslateError_GetReason - PyUnicodeTranslateError_GetStart=python37.PyUnicodeTranslateError_GetStart - PyUnicodeTranslateError_SetEnd=python37.PyUnicodeTranslateError_SetEnd - PyUnicodeTranslateError_SetReason=python37.PyUnicodeTranslateError_SetReason - PyUnicodeTranslateError_SetStart=python37.PyUnicodeTranslateError_SetStart - PyUnicode_Append=python37.PyUnicode_Append - PyUnicode_AppendAndDel=python37.PyUnicode_AppendAndDel - PyUnicode_AsASCIIString=python37.PyUnicode_AsASCIIString - PyUnicode_AsCharmapString=python37.PyUnicode_AsCharmapString - PyUnicode_AsDecodedObject=python37.PyUnicode_AsDecodedObject - PyUnicode_AsDecodedUnicode=python37.PyUnicode_AsDecodedUnicode - PyUnicode_AsEncodedObject=python37.PyUnicode_AsEncodedObject - PyUnicode_AsEncodedString=python37.PyUnicode_AsEncodedString - PyUnicode_AsEncodedUnicode=python37.PyUnicode_AsEncodedUnicode - PyUnicode_AsLatin1String=python37.PyUnicode_AsLatin1String - PyUnicode_AsMBCSString=python37.PyUnicode_AsMBCSString - PyUnicode_AsRawUnicodeEscapeString=python37.PyUnicode_AsRawUnicodeEscapeString - PyUnicode_AsUCS4=python37.PyUnicode_AsUCS4 - PyUnicode_AsUCS4Copy=python37.PyUnicode_AsUCS4Copy - PyUnicode_AsUTF16String=python37.PyUnicode_AsUTF16String - PyUnicode_AsUTF32String=python37.PyUnicode_AsUTF32String - PyUnicode_AsUTF8String=python37.PyUnicode_AsUTF8String - PyUnicode_AsUnicodeEscapeString=python37.PyUnicode_AsUnicodeEscapeString - PyUnicode_AsWideChar=python37.PyUnicode_AsWideChar - PyUnicode_AsWideCharString=python37.PyUnicode_AsWideCharString - PyUnicode_BuildEncodingMap=python37.PyUnicode_BuildEncodingMap - PyUnicode_ClearFreeList=python37.PyUnicode_ClearFreeList - PyUnicode_Compare=python37.PyUnicode_Compare - PyUnicode_CompareWithASCIIString=python37.PyUnicode_CompareWithASCIIString - PyUnicode_Concat=python37.PyUnicode_Concat - PyUnicode_Contains=python37.PyUnicode_Contains - PyUnicode_Count=python37.PyUnicode_Count - PyUnicode_Decode=python37.PyUnicode_Decode - PyUnicode_DecodeASCII=python37.PyUnicode_DecodeASCII - PyUnicode_DecodeCharmap=python37.PyUnicode_DecodeCharmap - PyUnicode_DecodeCodePageStateful=python37.PyUnicode_DecodeCodePageStateful - PyUnicode_DecodeFSDefault=python37.PyUnicode_DecodeFSDefault - PyUnicode_DecodeFSDefaultAndSize=python37.PyUnicode_DecodeFSDefaultAndSize - PyUnicode_DecodeLatin1=python37.PyUnicode_DecodeLatin1 - PyUnicode_DecodeLocale=python37.PyUnicode_DecodeLocale - PyUnicode_DecodeLocaleAndSize=python37.PyUnicode_DecodeLocaleAndSize - PyUnicode_DecodeMBCS=python37.PyUnicode_DecodeMBCS - PyUnicode_DecodeMBCSStateful=python37.PyUnicode_DecodeMBCSStateful - PyUnicode_DecodeRawUnicodeEscape=python37.PyUnicode_DecodeRawUnicodeEscape - PyUnicode_DecodeUTF16=python37.PyUnicode_DecodeUTF16 - PyUnicode_DecodeUTF16Stateful=python37.PyUnicode_DecodeUTF16Stateful - PyUnicode_DecodeUTF32=python37.PyUnicode_DecodeUTF32 - PyUnicode_DecodeUTF32Stateful=python37.PyUnicode_DecodeUTF32Stateful - PyUnicode_DecodeUTF7=python37.PyUnicode_DecodeUTF7 - PyUnicode_DecodeUTF7Stateful=python37.PyUnicode_DecodeUTF7Stateful - PyUnicode_DecodeUTF8=python37.PyUnicode_DecodeUTF8 - PyUnicode_DecodeUTF8Stateful=python37.PyUnicode_DecodeUTF8Stateful - PyUnicode_DecodeUnicodeEscape=python37.PyUnicode_DecodeUnicodeEscape - PyUnicode_EncodeCodePage=python37.PyUnicode_EncodeCodePage - PyUnicode_EncodeFSDefault=python37.PyUnicode_EncodeFSDefault - PyUnicode_EncodeLocale=python37.PyUnicode_EncodeLocale - PyUnicode_FSConverter=python37.PyUnicode_FSConverter - PyUnicode_FSDecoder=python37.PyUnicode_FSDecoder - PyUnicode_Find=python37.PyUnicode_Find - PyUnicode_FindChar=python37.PyUnicode_FindChar - PyUnicode_Format=python37.PyUnicode_Format - PyUnicode_FromEncodedObject=python37.PyUnicode_FromEncodedObject - PyUnicode_FromFormat=python37.PyUnicode_FromFormat - PyUnicode_FromFormatV=python37.PyUnicode_FromFormatV - PyUnicode_FromObject=python37.PyUnicode_FromObject - PyUnicode_FromOrdinal=python37.PyUnicode_FromOrdinal - PyUnicode_FromString=python37.PyUnicode_FromString - PyUnicode_FromStringAndSize=python37.PyUnicode_FromStringAndSize - PyUnicode_FromWideChar=python37.PyUnicode_FromWideChar - PyUnicode_GetDefaultEncoding=python37.PyUnicode_GetDefaultEncoding - PyUnicode_GetLength=python37.PyUnicode_GetLength - PyUnicode_GetSize=python37.PyUnicode_GetSize - PyUnicode_InternFromString=python37.PyUnicode_InternFromString - PyUnicode_InternImmortal=python37.PyUnicode_InternImmortal - PyUnicode_InternInPlace=python37.PyUnicode_InternInPlace - PyUnicode_IsIdentifier=python37.PyUnicode_IsIdentifier - PyUnicode_Join=python37.PyUnicode_Join - PyUnicode_Partition=python37.PyUnicode_Partition - PyUnicode_RPartition=python37.PyUnicode_RPartition - PyUnicode_RSplit=python37.PyUnicode_RSplit - PyUnicode_ReadChar=python37.PyUnicode_ReadChar - PyUnicode_Replace=python37.PyUnicode_Replace - PyUnicode_Resize=python37.PyUnicode_Resize - PyUnicode_RichCompare=python37.PyUnicode_RichCompare - PyUnicode_Split=python37.PyUnicode_Split - PyUnicode_Splitlines=python37.PyUnicode_Splitlines - PyUnicode_Substring=python37.PyUnicode_Substring - PyUnicode_Tailmatch=python37.PyUnicode_Tailmatch - PyUnicode_Translate=python37.PyUnicode_Translate - PyUnicode_Type=python37.PyUnicode_Type DATA - PyUnicode_WriteChar=python37.PyUnicode_WriteChar - PyWeakref_GetObject=python37.PyWeakref_GetObject - PyWeakref_NewProxy=python37.PyWeakref_NewProxy - PyWeakref_NewRef=python37.PyWeakref_NewRef - PyWrapperDescr_Type=python37.PyWrapperDescr_Type DATA - PyWrapper_New=python37.PyWrapper_New - PyZip_Type=python37.PyZip_Type DATA - Py_AddPendingCall=python37.Py_AddPendingCall - Py_AtExit=python37.Py_AtExit - Py_BuildValue=python37.Py_BuildValue - Py_CompileString=python37.Py_CompileString - Py_DecRef=python37.Py_DecRef - Py_DecodeLocale=python37.Py_DecodeLocale - Py_EncodeLocale=python37.Py_EncodeLocale - Py_EndInterpreter=python37.Py_EndInterpreter - Py_Exit=python37.Py_Exit - Py_FatalError=python37.Py_FatalError - Py_FileSystemDefaultEncodeErrors=python37.Py_FileSystemDefaultEncodeErrors DATA - Py_FileSystemDefaultEncoding=python37.Py_FileSystemDefaultEncoding DATA - Py_Finalize=python37.Py_Finalize - Py_FinalizeEx=python37.Py_FinalizeEx - Py_GetBuildInfo=python37.Py_GetBuildInfo - Py_GetCompiler=python37.Py_GetCompiler - Py_GetCopyright=python37.Py_GetCopyright - Py_GetExecPrefix=python37.Py_GetExecPrefix - Py_GetPath=python37.Py_GetPath - Py_GetPlatform=python37.Py_GetPlatform - Py_GetPrefix=python37.Py_GetPrefix - Py_GetProgramFullPath=python37.Py_GetProgramFullPath - Py_GetProgramName=python37.Py_GetProgramName - Py_GetPythonHome=python37.Py_GetPythonHome - Py_GetRecursionLimit=python37.Py_GetRecursionLimit - Py_GetVersion=python37.Py_GetVersion - Py_HasFileSystemDefaultEncoding=python37.Py_HasFileSystemDefaultEncoding DATA - Py_IncRef=python37.Py_IncRef - Py_Initialize=python37.Py_Initialize - Py_InitializeEx=python37.Py_InitializeEx - Py_IsInitialized=python37.Py_IsInitialized - Py_Main=python37.Py_Main - Py_MakePendingCalls=python37.Py_MakePendingCalls - Py_NewInterpreter=python37.Py_NewInterpreter - Py_ReprEnter=python37.Py_ReprEnter - Py_ReprLeave=python37.Py_ReprLeave - Py_SetPath=python37.Py_SetPath - Py_SetProgramName=python37.Py_SetProgramName - Py_SetPythonHome=python37.Py_SetPythonHome - Py_SetRecursionLimit=python37.Py_SetRecursionLimit - Py_SymtableString=python37.Py_SymtableString - Py_UTF8Mode=python37.Py_UTF8Mode DATA - Py_VaBuildValue=python37.Py_VaBuildValue - _PyArg_ParseTupleAndKeywords_SizeT=python37._PyArg_ParseTupleAndKeywords_SizeT - _PyArg_ParseTuple_SizeT=python37._PyArg_ParseTuple_SizeT - _PyArg_Parse_SizeT=python37._PyArg_Parse_SizeT - _PyArg_VaParseTupleAndKeywords_SizeT=python37._PyArg_VaParseTupleAndKeywords_SizeT - _PyArg_VaParse_SizeT=python37._PyArg_VaParse_SizeT - _PyErr_BadInternalCall=python37._PyErr_BadInternalCall - _PyObject_CallFunction_SizeT=python37._PyObject_CallFunction_SizeT - _PyObject_CallMethod_SizeT=python37._PyObject_CallMethod_SizeT - _PyObject_GC_Malloc=python37._PyObject_GC_Malloc - _PyObject_GC_New=python37._PyObject_GC_New - _PyObject_GC_NewVar=python37._PyObject_GC_NewVar - _PyObject_GC_Resize=python37._PyObject_GC_Resize - _PyObject_New=python37._PyObject_New - _PyObject_NewVar=python37._PyObject_NewVar - _PyState_AddModule=python37._PyState_AddModule - _PyThreadState_Init=python37._PyThreadState_Init - _PyThreadState_Prealloc=python37._PyThreadState_Prealloc - _PyTrash_delete_later=python37._PyTrash_delete_later DATA - _PyTrash_delete_nesting=python37._PyTrash_delete_nesting DATA - _PyTrash_deposit_object=python37._PyTrash_deposit_object - _PyTrash_destroy_chain=python37._PyTrash_destroy_chain - _PyTrash_thread_deposit_object=python37._PyTrash_thread_deposit_object - _PyTrash_thread_destroy_chain=python37._PyTrash_thread_destroy_chain - _PyWeakref_CallableProxyType=python37._PyWeakref_CallableProxyType DATA - _PyWeakref_ProxyType=python37._PyWeakref_ProxyType DATA - _PyWeakref_RefType=python37._PyWeakref_RefType DATA - _Py_BuildValue_SizeT=python37._Py_BuildValue_SizeT - _Py_CheckRecursionLimit=python37._Py_CheckRecursionLimit DATA - _Py_CheckRecursiveCall=python37._Py_CheckRecursiveCall - _Py_Dealloc=python37._Py_Dealloc - _Py_EllipsisObject=python37._Py_EllipsisObject DATA - _Py_FalseStruct=python37._Py_FalseStruct DATA - _Py_NoneStruct=python37._Py_NoneStruct DATA - _Py_NotImplementedStruct=python37._Py_NotImplementedStruct DATA - _Py_SwappedOp=python37._Py_SwappedOp DATA - _Py_TrueStruct=python37._Py_TrueStruct DATA - _Py_VaBuildValue_SizeT=python37._Py_VaBuildValue_SizeT + PyArg_Parse=python38.PyArg_Parse + PyArg_ParseTuple=python38.PyArg_ParseTuple + PyArg_ParseTupleAndKeywords=python38.PyArg_ParseTupleAndKeywords + PyArg_UnpackTuple=python38.PyArg_UnpackTuple + PyArg_VaParse=python38.PyArg_VaParse + PyArg_VaParseTupleAndKeywords=python38.PyArg_VaParseTupleAndKeywords + PyArg_ValidateKeywordArguments=python38.PyArg_ValidateKeywordArguments + PyBaseObject_Type=python38.PyBaseObject_Type DATA + PyBool_FromLong=python38.PyBool_FromLong + PyBool_Type=python38.PyBool_Type DATA + PyByteArrayIter_Type=python38.PyByteArrayIter_Type DATA + PyByteArray_AsString=python38.PyByteArray_AsString + PyByteArray_Concat=python38.PyByteArray_Concat + PyByteArray_FromObject=python38.PyByteArray_FromObject + PyByteArray_FromStringAndSize=python38.PyByteArray_FromStringAndSize + PyByteArray_Resize=python38.PyByteArray_Resize + PyByteArray_Size=python38.PyByteArray_Size + PyByteArray_Type=python38.PyByteArray_Type DATA + PyBytesIter_Type=python38.PyBytesIter_Type DATA + PyBytes_AsString=python38.PyBytes_AsString + PyBytes_AsStringAndSize=python38.PyBytes_AsStringAndSize + PyBytes_Concat=python38.PyBytes_Concat + PyBytes_ConcatAndDel=python38.PyBytes_ConcatAndDel + PyBytes_DecodeEscape=python38.PyBytes_DecodeEscape + PyBytes_FromFormat=python38.PyBytes_FromFormat + PyBytes_FromFormatV=python38.PyBytes_FromFormatV + PyBytes_FromObject=python38.PyBytes_FromObject + PyBytes_FromString=python38.PyBytes_FromString + PyBytes_FromStringAndSize=python38.PyBytes_FromStringAndSize + PyBytes_Repr=python38.PyBytes_Repr + PyBytes_Size=python38.PyBytes_Size + PyBytes_Type=python38.PyBytes_Type DATA + PyCFunction_Call=python38.PyCFunction_Call + PyCFunction_ClearFreeList=python38.PyCFunction_ClearFreeList + PyCFunction_GetFlags=python38.PyCFunction_GetFlags + PyCFunction_GetFunction=python38.PyCFunction_GetFunction + PyCFunction_GetSelf=python38.PyCFunction_GetSelf + PyCFunction_New=python38.PyCFunction_New + PyCFunction_NewEx=python38.PyCFunction_NewEx + PyCFunction_Type=python38.PyCFunction_Type DATA + PyCallIter_New=python38.PyCallIter_New + PyCallIter_Type=python38.PyCallIter_Type DATA + PyCallable_Check=python38.PyCallable_Check + PyCapsule_GetContext=python38.PyCapsule_GetContext + PyCapsule_GetDestructor=python38.PyCapsule_GetDestructor + PyCapsule_GetName=python38.PyCapsule_GetName + PyCapsule_GetPointer=python38.PyCapsule_GetPointer + PyCapsule_Import=python38.PyCapsule_Import + PyCapsule_IsValid=python38.PyCapsule_IsValid + PyCapsule_New=python38.PyCapsule_New + PyCapsule_SetContext=python38.PyCapsule_SetContext + PyCapsule_SetDestructor=python38.PyCapsule_SetDestructor + PyCapsule_SetName=python38.PyCapsule_SetName + PyCapsule_SetPointer=python38.PyCapsule_SetPointer + PyCapsule_Type=python38.PyCapsule_Type DATA + PyClassMethodDescr_Type=python38.PyClassMethodDescr_Type DATA + PyCodec_BackslashReplaceErrors=python38.PyCodec_BackslashReplaceErrors + PyCodec_Decode=python38.PyCodec_Decode + PyCodec_Decoder=python38.PyCodec_Decoder + PyCodec_Encode=python38.PyCodec_Encode + PyCodec_Encoder=python38.PyCodec_Encoder + PyCodec_IgnoreErrors=python38.PyCodec_IgnoreErrors + PyCodec_IncrementalDecoder=python38.PyCodec_IncrementalDecoder + PyCodec_IncrementalEncoder=python38.PyCodec_IncrementalEncoder + PyCodec_KnownEncoding=python38.PyCodec_KnownEncoding + PyCodec_LookupError=python38.PyCodec_LookupError + PyCodec_NameReplaceErrors=python38.PyCodec_NameReplaceErrors + PyCodec_Register=python38.PyCodec_Register + PyCodec_RegisterError=python38.PyCodec_RegisterError + PyCodec_ReplaceErrors=python38.PyCodec_ReplaceErrors + PyCodec_StreamReader=python38.PyCodec_StreamReader + PyCodec_StreamWriter=python38.PyCodec_StreamWriter + PyCodec_StrictErrors=python38.PyCodec_StrictErrors + PyCodec_XMLCharRefReplaceErrors=python38.PyCodec_XMLCharRefReplaceErrors + PyComplex_FromDoubles=python38.PyComplex_FromDoubles + PyComplex_ImagAsDouble=python38.PyComplex_ImagAsDouble + PyComplex_RealAsDouble=python38.PyComplex_RealAsDouble + PyComplex_Type=python38.PyComplex_Type DATA + PyDescr_NewClassMethod=python38.PyDescr_NewClassMethod + PyDescr_NewGetSet=python38.PyDescr_NewGetSet + PyDescr_NewMember=python38.PyDescr_NewMember + PyDescr_NewMethod=python38.PyDescr_NewMethod + PyDictItems_Type=python38.PyDictItems_Type DATA + PyDictIterItem_Type=python38.PyDictIterItem_Type DATA + PyDictIterKey_Type=python38.PyDictIterKey_Type DATA + PyDictIterValue_Type=python38.PyDictIterValue_Type DATA + PyDictKeys_Type=python38.PyDictKeys_Type DATA + PyDictProxy_New=python38.PyDictProxy_New + PyDictProxy_Type=python38.PyDictProxy_Type DATA + PyDictValues_Type=python38.PyDictValues_Type DATA + PyDict_Clear=python38.PyDict_Clear + PyDict_Contains=python38.PyDict_Contains + PyDict_Copy=python38.PyDict_Copy + PyDict_DelItem=python38.PyDict_DelItem + PyDict_DelItemString=python38.PyDict_DelItemString + PyDict_GetItem=python38.PyDict_GetItem + PyDict_GetItemString=python38.PyDict_GetItemString + PyDict_GetItemWithError=python38.PyDict_GetItemWithError + PyDict_Items=python38.PyDict_Items + PyDict_Keys=python38.PyDict_Keys + PyDict_Merge=python38.PyDict_Merge + PyDict_MergeFromSeq2=python38.PyDict_MergeFromSeq2 + PyDict_New=python38.PyDict_New + PyDict_Next=python38.PyDict_Next + PyDict_SetItem=python38.PyDict_SetItem + PyDict_SetItemString=python38.PyDict_SetItemString + PyDict_Size=python38.PyDict_Size + PyDict_Type=python38.PyDict_Type DATA + PyDict_Update=python38.PyDict_Update + PyDict_Values=python38.PyDict_Values + PyEllipsis_Type=python38.PyEllipsis_Type DATA + PyEnum_Type=python38.PyEnum_Type DATA + PyErr_BadArgument=python38.PyErr_BadArgument + PyErr_BadInternalCall=python38.PyErr_BadInternalCall + PyErr_CheckSignals=python38.PyErr_CheckSignals + PyErr_Clear=python38.PyErr_Clear + PyErr_Display=python38.PyErr_Display + PyErr_ExceptionMatches=python38.PyErr_ExceptionMatches + PyErr_Fetch=python38.PyErr_Fetch + PyErr_Format=python38.PyErr_Format + PyErr_FormatV=python38.PyErr_FormatV + PyErr_GetExcInfo=python38.PyErr_GetExcInfo + PyErr_GivenExceptionMatches=python38.PyErr_GivenExceptionMatches + PyErr_NewException=python38.PyErr_NewException + PyErr_NewExceptionWithDoc=python38.PyErr_NewExceptionWithDoc + PyErr_NoMemory=python38.PyErr_NoMemory + PyErr_NormalizeException=python38.PyErr_NormalizeException + PyErr_Occurred=python38.PyErr_Occurred + PyErr_Print=python38.PyErr_Print + PyErr_PrintEx=python38.PyErr_PrintEx + PyErr_ProgramText=python38.PyErr_ProgramText + PyErr_ResourceWarning=python38.PyErr_ResourceWarning + PyErr_Restore=python38.PyErr_Restore + PyErr_SetExcFromWindowsErr=python38.PyErr_SetExcFromWindowsErr + PyErr_SetExcFromWindowsErrWithFilename=python38.PyErr_SetExcFromWindowsErrWithFilename + PyErr_SetExcFromWindowsErrWithFilenameObject=python38.PyErr_SetExcFromWindowsErrWithFilenameObject + PyErr_SetExcFromWindowsErrWithFilenameObjects=python38.PyErr_SetExcFromWindowsErrWithFilenameObjects + PyErr_SetExcInfo=python38.PyErr_SetExcInfo + PyErr_SetFromErrno=python38.PyErr_SetFromErrno + PyErr_SetFromErrnoWithFilename=python38.PyErr_SetFromErrnoWithFilename + PyErr_SetFromErrnoWithFilenameObject=python38.PyErr_SetFromErrnoWithFilenameObject + PyErr_SetFromErrnoWithFilenameObjects=python38.PyErr_SetFromErrnoWithFilenameObjects + PyErr_SetFromWindowsErr=python38.PyErr_SetFromWindowsErr + PyErr_SetFromWindowsErrWithFilename=python38.PyErr_SetFromWindowsErrWithFilename + PyErr_SetImportError=python38.PyErr_SetImportError + PyErr_SetImportErrorSubclass=python38.PyErr_SetImportErrorSubclass + PyErr_SetInterrupt=python38.PyErr_SetInterrupt + PyErr_SetNone=python38.PyErr_SetNone + PyErr_SetObject=python38.PyErr_SetObject + PyErr_SetString=python38.PyErr_SetString + PyErr_SyntaxLocation=python38.PyErr_SyntaxLocation + PyErr_SyntaxLocationEx=python38.PyErr_SyntaxLocationEx + PyErr_WarnEx=python38.PyErr_WarnEx + PyErr_WarnExplicit=python38.PyErr_WarnExplicit + PyErr_WarnFormat=python38.PyErr_WarnFormat + PyErr_WriteUnraisable=python38.PyErr_WriteUnraisable + PyEval_AcquireLock=python38.PyEval_AcquireLock + PyEval_AcquireThread=python38.PyEval_AcquireThread + PyEval_CallFunction=python38.PyEval_CallFunction + PyEval_CallMethod=python38.PyEval_CallMethod + PyEval_CallObjectWithKeywords=python38.PyEval_CallObjectWithKeywords + PyEval_EvalCode=python38.PyEval_EvalCode + PyEval_EvalCodeEx=python38.PyEval_EvalCodeEx + PyEval_EvalFrame=python38.PyEval_EvalFrame + PyEval_EvalFrameEx=python38.PyEval_EvalFrameEx + PyEval_GetBuiltins=python38.PyEval_GetBuiltins + PyEval_GetCallStats=python38.PyEval_GetCallStats + PyEval_GetFrame=python38.PyEval_GetFrame + PyEval_GetFuncDesc=python38.PyEval_GetFuncDesc + PyEval_GetFuncName=python38.PyEval_GetFuncName + PyEval_GetGlobals=python38.PyEval_GetGlobals + PyEval_GetLocals=python38.PyEval_GetLocals + PyEval_InitThreads=python38.PyEval_InitThreads + PyEval_ReInitThreads=python38.PyEval_ReInitThreads + PyEval_ReleaseLock=python38.PyEval_ReleaseLock + PyEval_ReleaseThread=python38.PyEval_ReleaseThread + PyEval_RestoreThread=python38.PyEval_RestoreThread + PyEval_SaveThread=python38.PyEval_SaveThread + PyEval_ThreadsInitialized=python38.PyEval_ThreadsInitialized + PyExc_ArithmeticError=python38.PyExc_ArithmeticError DATA + PyExc_AssertionError=python38.PyExc_AssertionError DATA + PyExc_AttributeError=python38.PyExc_AttributeError DATA + PyExc_BaseException=python38.PyExc_BaseException DATA + PyExc_BlockingIOError=python38.PyExc_BlockingIOError DATA + PyExc_BrokenPipeError=python38.PyExc_BrokenPipeError DATA + PyExc_BufferError=python38.PyExc_BufferError DATA + PyExc_BytesWarning=python38.PyExc_BytesWarning DATA + PyExc_ChildProcessError=python38.PyExc_ChildProcessError DATA + PyExc_ConnectionAbortedError=python38.PyExc_ConnectionAbortedError DATA + PyExc_ConnectionError=python38.PyExc_ConnectionError DATA + PyExc_ConnectionRefusedError=python38.PyExc_ConnectionRefusedError DATA + PyExc_ConnectionResetError=python38.PyExc_ConnectionResetError DATA + PyExc_DeprecationWarning=python38.PyExc_DeprecationWarning DATA + PyExc_EOFError=python38.PyExc_EOFError DATA + PyExc_EnvironmentError=python38.PyExc_EnvironmentError DATA + PyExc_Exception=python38.PyExc_Exception DATA + PyExc_FileExistsError=python38.PyExc_FileExistsError DATA + PyExc_FileNotFoundError=python38.PyExc_FileNotFoundError DATA + PyExc_FloatingPointError=python38.PyExc_FloatingPointError DATA + PyExc_FutureWarning=python38.PyExc_FutureWarning DATA + PyExc_GeneratorExit=python38.PyExc_GeneratorExit DATA + PyExc_IOError=python38.PyExc_IOError DATA + PyExc_ImportError=python38.PyExc_ImportError DATA + PyExc_ImportWarning=python38.PyExc_ImportWarning DATA + PyExc_IndentationError=python38.PyExc_IndentationError DATA + PyExc_IndexError=python38.PyExc_IndexError DATA + PyExc_InterruptedError=python38.PyExc_InterruptedError DATA + PyExc_IsADirectoryError=python38.PyExc_IsADirectoryError DATA + PyExc_KeyError=python38.PyExc_KeyError DATA + PyExc_KeyboardInterrupt=python38.PyExc_KeyboardInterrupt DATA + PyExc_LookupError=python38.PyExc_LookupError DATA + PyExc_MemoryError=python38.PyExc_MemoryError DATA + PyExc_ModuleNotFoundError=python38.PyExc_ModuleNotFoundError DATA + PyExc_NameError=python38.PyExc_NameError DATA + PyExc_NotADirectoryError=python38.PyExc_NotADirectoryError DATA + PyExc_NotImplementedError=python38.PyExc_NotImplementedError DATA + PyExc_OSError=python38.PyExc_OSError DATA + PyExc_OverflowError=python38.PyExc_OverflowError DATA + PyExc_PendingDeprecationWarning=python38.PyExc_PendingDeprecationWarning DATA + PyExc_PermissionError=python38.PyExc_PermissionError DATA + PyExc_ProcessLookupError=python38.PyExc_ProcessLookupError DATA + PyExc_RecursionError=python38.PyExc_RecursionError DATA + PyExc_ReferenceError=python38.PyExc_ReferenceError DATA + PyExc_ResourceWarning=python38.PyExc_ResourceWarning DATA + PyExc_RuntimeError=python38.PyExc_RuntimeError DATA + PyExc_RuntimeWarning=python38.PyExc_RuntimeWarning DATA + PyExc_StopAsyncIteration=python38.PyExc_StopAsyncIteration DATA + PyExc_StopIteration=python38.PyExc_StopIteration DATA + PyExc_SyntaxError=python38.PyExc_SyntaxError DATA + PyExc_SyntaxWarning=python38.PyExc_SyntaxWarning DATA + PyExc_SystemError=python38.PyExc_SystemError DATA + PyExc_SystemExit=python38.PyExc_SystemExit DATA + PyExc_TabError=python38.PyExc_TabError DATA + PyExc_TimeoutError=python38.PyExc_TimeoutError DATA + PyExc_TypeError=python38.PyExc_TypeError DATA + PyExc_UnboundLocalError=python38.PyExc_UnboundLocalError DATA + PyExc_UnicodeDecodeError=python38.PyExc_UnicodeDecodeError DATA + PyExc_UnicodeEncodeError=python38.PyExc_UnicodeEncodeError DATA + PyExc_UnicodeError=python38.PyExc_UnicodeError DATA + PyExc_UnicodeTranslateError=python38.PyExc_UnicodeTranslateError DATA + PyExc_UnicodeWarning=python38.PyExc_UnicodeWarning DATA + PyExc_UserWarning=python38.PyExc_UserWarning DATA + PyExc_ValueError=python38.PyExc_ValueError DATA + PyExc_Warning=python38.PyExc_Warning DATA + PyExc_WindowsError=python38.PyExc_WindowsError DATA + PyExc_ZeroDivisionError=python38.PyExc_ZeroDivisionError DATA + PyExceptionClass_Name=python38.PyExceptionClass_Name + PyException_GetCause=python38.PyException_GetCause + PyException_GetContext=python38.PyException_GetContext + PyException_GetTraceback=python38.PyException_GetTraceback + PyException_SetCause=python38.PyException_SetCause + PyException_SetContext=python38.PyException_SetContext + PyException_SetTraceback=python38.PyException_SetTraceback + PyFile_FromFd=python38.PyFile_FromFd + PyFile_GetLine=python38.PyFile_GetLine + PyFile_WriteObject=python38.PyFile_WriteObject + PyFile_WriteString=python38.PyFile_WriteString + PyFilter_Type=python38.PyFilter_Type DATA + PyFloat_AsDouble=python38.PyFloat_AsDouble + PyFloat_FromDouble=python38.PyFloat_FromDouble + PyFloat_FromString=python38.PyFloat_FromString + PyFloat_GetInfo=python38.PyFloat_GetInfo + PyFloat_GetMax=python38.PyFloat_GetMax + PyFloat_GetMin=python38.PyFloat_GetMin + PyFloat_Type=python38.PyFloat_Type DATA + PyFrozenSet_New=python38.PyFrozenSet_New + PyFrozenSet_Type=python38.PyFrozenSet_Type DATA + PyGC_Collect=python38.PyGC_Collect + PyGILState_Ensure=python38.PyGILState_Ensure + PyGILState_GetThisThreadState=python38.PyGILState_GetThisThreadState + PyGILState_Release=python38.PyGILState_Release + PyGetSetDescr_Type=python38.PyGetSetDescr_Type DATA + PyImport_AddModule=python38.PyImport_AddModule + PyImport_AddModuleObject=python38.PyImport_AddModuleObject + PyImport_AppendInittab=python38.PyImport_AppendInittab + PyImport_Cleanup=python38.PyImport_Cleanup + PyImport_ExecCodeModule=python38.PyImport_ExecCodeModule + PyImport_ExecCodeModuleEx=python38.PyImport_ExecCodeModuleEx + PyImport_ExecCodeModuleObject=python38.PyImport_ExecCodeModuleObject + PyImport_ExecCodeModuleWithPathnames=python38.PyImport_ExecCodeModuleWithPathnames + PyImport_GetImporter=python38.PyImport_GetImporter + PyImport_GetMagicNumber=python38.PyImport_GetMagicNumber + PyImport_GetMagicTag=python38.PyImport_GetMagicTag + PyImport_GetModule=python38.PyImport_GetModule + PyImport_GetModuleDict=python38.PyImport_GetModuleDict + PyImport_Import=python38.PyImport_Import + PyImport_ImportFrozenModule=python38.PyImport_ImportFrozenModule + PyImport_ImportFrozenModuleObject=python38.PyImport_ImportFrozenModuleObject + PyImport_ImportModule=python38.PyImport_ImportModule + PyImport_ImportModuleLevel=python38.PyImport_ImportModuleLevel + PyImport_ImportModuleLevelObject=python38.PyImport_ImportModuleLevelObject + PyImport_ImportModuleNoBlock=python38.PyImport_ImportModuleNoBlock + PyImport_ReloadModule=python38.PyImport_ReloadModule + PyIndex_Check=python38.PyIndex_Check + PyInterpreterState_Clear=python38.PyInterpreterState_Clear + PyInterpreterState_Delete=python38.PyInterpreterState_Delete + PyInterpreterState_New=python38.PyInterpreterState_New + PyIter_Check=python38.PyIter_Check + PyIter_Next=python38.PyIter_Next + PyListIter_Type=python38.PyListIter_Type DATA + PyListRevIter_Type=python38.PyListRevIter_Type DATA + PyList_Append=python38.PyList_Append + PyList_AsTuple=python38.PyList_AsTuple + PyList_GetItem=python38.PyList_GetItem + PyList_GetSlice=python38.PyList_GetSlice + PyList_Insert=python38.PyList_Insert + PyList_New=python38.PyList_New + PyList_Reverse=python38.PyList_Reverse + PyList_SetItem=python38.PyList_SetItem + PyList_SetSlice=python38.PyList_SetSlice + PyList_Size=python38.PyList_Size + PyList_Sort=python38.PyList_Sort + PyList_Type=python38.PyList_Type DATA + PyLongRangeIter_Type=python38.PyLongRangeIter_Type DATA + PyLong_AsDouble=python38.PyLong_AsDouble + PyLong_AsLong=python38.PyLong_AsLong + PyLong_AsLongAndOverflow=python38.PyLong_AsLongAndOverflow + PyLong_AsLongLong=python38.PyLong_AsLongLong + PyLong_AsLongLongAndOverflow=python38.PyLong_AsLongLongAndOverflow + PyLong_AsSize_t=python38.PyLong_AsSize_t + PyLong_AsSsize_t=python38.PyLong_AsSsize_t + PyLong_AsUnsignedLong=python38.PyLong_AsUnsignedLong + PyLong_AsUnsignedLongLong=python38.PyLong_AsUnsignedLongLong + PyLong_AsUnsignedLongLongMask=python38.PyLong_AsUnsignedLongLongMask + PyLong_AsUnsignedLongMask=python38.PyLong_AsUnsignedLongMask + PyLong_AsVoidPtr=python38.PyLong_AsVoidPtr + PyLong_FromDouble=python38.PyLong_FromDouble + PyLong_FromLong=python38.PyLong_FromLong + PyLong_FromLongLong=python38.PyLong_FromLongLong + PyLong_FromSize_t=python38.PyLong_FromSize_t + PyLong_FromSsize_t=python38.PyLong_FromSsize_t + PyLong_FromString=python38.PyLong_FromString + PyLong_FromUnsignedLong=python38.PyLong_FromUnsignedLong + PyLong_FromUnsignedLongLong=python38.PyLong_FromUnsignedLongLong + PyLong_FromVoidPtr=python38.PyLong_FromVoidPtr + PyLong_GetInfo=python38.PyLong_GetInfo + PyLong_Type=python38.PyLong_Type DATA + PyMap_Type=python38.PyMap_Type DATA + PyMapping_Check=python38.PyMapping_Check + PyMapping_GetItemString=python38.PyMapping_GetItemString + PyMapping_HasKey=python38.PyMapping_HasKey + PyMapping_HasKeyString=python38.PyMapping_HasKeyString + PyMapping_Items=python38.PyMapping_Items + PyMapping_Keys=python38.PyMapping_Keys + PyMapping_Length=python38.PyMapping_Length + PyMapping_SetItemString=python38.PyMapping_SetItemString + PyMapping_Size=python38.PyMapping_Size + PyMapping_Values=python38.PyMapping_Values + PyMem_Calloc=python38.PyMem_Calloc + PyMem_Free=python38.PyMem_Free + PyMem_Malloc=python38.PyMem_Malloc + PyMem_Realloc=python38.PyMem_Realloc + PyMemberDescr_Type=python38.PyMemberDescr_Type DATA + PyMemoryView_FromMemory=python38.PyMemoryView_FromMemory + PyMemoryView_FromObject=python38.PyMemoryView_FromObject + PyMemoryView_GetContiguous=python38.PyMemoryView_GetContiguous + PyMemoryView_Type=python38.PyMemoryView_Type DATA + PyMethodDescr_Type=python38.PyMethodDescr_Type DATA + PyModuleDef_Init=python38.PyModuleDef_Init + PyModuleDef_Type=python38.PyModuleDef_Type DATA + PyModule_AddFunctions=python38.PyModule_AddFunctions + PyModule_AddIntConstant=python38.PyModule_AddIntConstant + PyModule_AddObject=python38.PyModule_AddObject + PyModule_AddStringConstant=python38.PyModule_AddStringConstant + PyModule_Create2=python38.PyModule_Create2 + PyModule_ExecDef=python38.PyModule_ExecDef + PyModule_FromDefAndSpec2=python38.PyModule_FromDefAndSpec2 + PyModule_GetDef=python38.PyModule_GetDef + PyModule_GetDict=python38.PyModule_GetDict + PyModule_GetFilename=python38.PyModule_GetFilename + PyModule_GetFilenameObject=python38.PyModule_GetFilenameObject + PyModule_GetName=python38.PyModule_GetName + PyModule_GetNameObject=python38.PyModule_GetNameObject + PyModule_GetState=python38.PyModule_GetState + PyModule_New=python38.PyModule_New + PyModule_NewObject=python38.PyModule_NewObject + PyModule_SetDocString=python38.PyModule_SetDocString + PyModule_Type=python38.PyModule_Type DATA + PyNullImporter_Type=python38.PyNullImporter_Type DATA + PyNumber_Absolute=python38.PyNumber_Absolute + PyNumber_Add=python38.PyNumber_Add + PyNumber_And=python38.PyNumber_And + PyNumber_AsSsize_t=python38.PyNumber_AsSsize_t + PyNumber_Check=python38.PyNumber_Check + PyNumber_Divmod=python38.PyNumber_Divmod + PyNumber_Float=python38.PyNumber_Float + PyNumber_FloorDivide=python38.PyNumber_FloorDivide + PyNumber_InPlaceAdd=python38.PyNumber_InPlaceAdd + PyNumber_InPlaceAnd=python38.PyNumber_InPlaceAnd + PyNumber_InPlaceFloorDivide=python38.PyNumber_InPlaceFloorDivide + PyNumber_InPlaceLshift=python38.PyNumber_InPlaceLshift + PyNumber_InPlaceMatrixMultiply=python38.PyNumber_InPlaceMatrixMultiply + PyNumber_InPlaceMultiply=python38.PyNumber_InPlaceMultiply + PyNumber_InPlaceOr=python38.PyNumber_InPlaceOr + PyNumber_InPlacePower=python38.PyNumber_InPlacePower + PyNumber_InPlaceRemainder=python38.PyNumber_InPlaceRemainder + PyNumber_InPlaceRshift=python38.PyNumber_InPlaceRshift + PyNumber_InPlaceSubtract=python38.PyNumber_InPlaceSubtract + PyNumber_InPlaceTrueDivide=python38.PyNumber_InPlaceTrueDivide + PyNumber_InPlaceXor=python38.PyNumber_InPlaceXor + PyNumber_Index=python38.PyNumber_Index + PyNumber_Invert=python38.PyNumber_Invert + PyNumber_Long=python38.PyNumber_Long + PyNumber_Lshift=python38.PyNumber_Lshift + PyNumber_MatrixMultiply=python38.PyNumber_MatrixMultiply + PyNumber_Multiply=python38.PyNumber_Multiply + PyNumber_Negative=python38.PyNumber_Negative + PyNumber_Or=python38.PyNumber_Or + PyNumber_Positive=python38.PyNumber_Positive + PyNumber_Power=python38.PyNumber_Power + PyNumber_Remainder=python38.PyNumber_Remainder + PyNumber_Rshift=python38.PyNumber_Rshift + PyNumber_Subtract=python38.PyNumber_Subtract + PyNumber_ToBase=python38.PyNumber_ToBase + PyNumber_TrueDivide=python38.PyNumber_TrueDivide + PyNumber_Xor=python38.PyNumber_Xor + PyODictItems_Type=python38.PyODictItems_Type DATA + PyODictIter_Type=python38.PyODictIter_Type DATA + PyODictKeys_Type=python38.PyODictKeys_Type DATA + PyODictValues_Type=python38.PyODictValues_Type DATA + PyODict_DelItem=python38.PyODict_DelItem + PyODict_New=python38.PyODict_New + PyODict_SetItem=python38.PyODict_SetItem + PyODict_Type=python38.PyODict_Type DATA + PyOS_AfterFork=python38.PyOS_AfterFork + PyOS_CheckStack=python38.PyOS_CheckStack + PyOS_FSPath=python38.PyOS_FSPath + PyOS_InitInterrupts=python38.PyOS_InitInterrupts + PyOS_InputHook=python38.PyOS_InputHook DATA + PyOS_InterruptOccurred=python38.PyOS_InterruptOccurred + PyOS_ReadlineFunctionPointer=python38.PyOS_ReadlineFunctionPointer DATA + PyOS_double_to_string=python38.PyOS_double_to_string + PyOS_getsig=python38.PyOS_getsig + PyOS_mystricmp=python38.PyOS_mystricmp + PyOS_mystrnicmp=python38.PyOS_mystrnicmp + PyOS_setsig=python38.PyOS_setsig + PyOS_snprintf=python38.PyOS_snprintf + PyOS_string_to_double=python38.PyOS_string_to_double + PyOS_strtol=python38.PyOS_strtol + PyOS_strtoul=python38.PyOS_strtoul + PyOS_vsnprintf=python38.PyOS_vsnprintf + PyObject_ASCII=python38.PyObject_ASCII + PyObject_AsCharBuffer=python38.PyObject_AsCharBuffer + PyObject_AsFileDescriptor=python38.PyObject_AsFileDescriptor + PyObject_AsReadBuffer=python38.PyObject_AsReadBuffer + PyObject_AsWriteBuffer=python38.PyObject_AsWriteBuffer + PyObject_Bytes=python38.PyObject_Bytes + PyObject_Call=python38.PyObject_Call + PyObject_CallFunction=python38.PyObject_CallFunction + PyObject_CallFunctionObjArgs=python38.PyObject_CallFunctionObjArgs + PyObject_CallMethod=python38.PyObject_CallMethod + PyObject_CallMethodObjArgs=python38.PyObject_CallMethodObjArgs + PyObject_CallObject=python38.PyObject_CallObject + PyObject_Calloc=python38.PyObject_Calloc + PyObject_CheckReadBuffer=python38.PyObject_CheckReadBuffer + PyObject_ClearWeakRefs=python38.PyObject_ClearWeakRefs + PyObject_DelItem=python38.PyObject_DelItem + PyObject_DelItemString=python38.PyObject_DelItemString + PyObject_Dir=python38.PyObject_Dir + PyObject_Format=python38.PyObject_Format + PyObject_Free=python38.PyObject_Free + PyObject_GC_Del=python38.PyObject_GC_Del + PyObject_GC_Track=python38.PyObject_GC_Track + PyObject_GC_UnTrack=python38.PyObject_GC_UnTrack + PyObject_GenericGetAttr=python38.PyObject_GenericGetAttr + PyObject_GenericSetAttr=python38.PyObject_GenericSetAttr + PyObject_GenericSetDict=python38.PyObject_GenericSetDict + PyObject_GetAttr=python38.PyObject_GetAttr + PyObject_GetAttrString=python38.PyObject_GetAttrString + PyObject_GetItem=python38.PyObject_GetItem + PyObject_GetIter=python38.PyObject_GetIter + PyObject_HasAttr=python38.PyObject_HasAttr + PyObject_HasAttrString=python38.PyObject_HasAttrString + PyObject_Hash=python38.PyObject_Hash + PyObject_HashNotImplemented=python38.PyObject_HashNotImplemented + PyObject_Init=python38.PyObject_Init + PyObject_InitVar=python38.PyObject_InitVar + PyObject_IsInstance=python38.PyObject_IsInstance + PyObject_IsSubclass=python38.PyObject_IsSubclass + PyObject_IsTrue=python38.PyObject_IsTrue + PyObject_Length=python38.PyObject_Length + PyObject_Malloc=python38.PyObject_Malloc + PyObject_Not=python38.PyObject_Not + PyObject_Realloc=python38.PyObject_Realloc + PyObject_Repr=python38.PyObject_Repr + PyObject_RichCompare=python38.PyObject_RichCompare + PyObject_RichCompareBool=python38.PyObject_RichCompareBool + PyObject_SelfIter=python38.PyObject_SelfIter + PyObject_SetAttr=python38.PyObject_SetAttr + PyObject_SetAttrString=python38.PyObject_SetAttrString + PyObject_SetItem=python38.PyObject_SetItem + PyObject_Size=python38.PyObject_Size + PyObject_Str=python38.PyObject_Str + PyObject_Type=python38.PyObject_Type + PyParser_SimpleParseFileFlags=python38.PyParser_SimpleParseFileFlags + PyParser_SimpleParseStringFlags=python38.PyParser_SimpleParseStringFlags + PyParser_SimpleParseStringFlagsFilename=python38.PyParser_SimpleParseStringFlagsFilename + PyProperty_Type=python38.PyProperty_Type DATA + PyRangeIter_Type=python38.PyRangeIter_Type DATA + PyRange_Type=python38.PyRange_Type DATA + PyReversed_Type=python38.PyReversed_Type DATA + PySeqIter_New=python38.PySeqIter_New + PySeqIter_Type=python38.PySeqIter_Type DATA + PySequence_Check=python38.PySequence_Check + PySequence_Concat=python38.PySequence_Concat + PySequence_Contains=python38.PySequence_Contains + PySequence_Count=python38.PySequence_Count + PySequence_DelItem=python38.PySequence_DelItem + PySequence_DelSlice=python38.PySequence_DelSlice + PySequence_Fast=python38.PySequence_Fast + PySequence_GetItem=python38.PySequence_GetItem + PySequence_GetSlice=python38.PySequence_GetSlice + PySequence_In=python38.PySequence_In + PySequence_InPlaceConcat=python38.PySequence_InPlaceConcat + PySequence_InPlaceRepeat=python38.PySequence_InPlaceRepeat + PySequence_Index=python38.PySequence_Index + PySequence_Length=python38.PySequence_Length + PySequence_List=python38.PySequence_List + PySequence_Repeat=python38.PySequence_Repeat + PySequence_SetItem=python38.PySequence_SetItem + PySequence_SetSlice=python38.PySequence_SetSlice + PySequence_Size=python38.PySequence_Size + PySequence_Tuple=python38.PySequence_Tuple + PySetIter_Type=python38.PySetIter_Type DATA + PySet_Add=python38.PySet_Add + PySet_Clear=python38.PySet_Clear + PySet_Contains=python38.PySet_Contains + PySet_Discard=python38.PySet_Discard + PySet_New=python38.PySet_New + PySet_Pop=python38.PySet_Pop + PySet_Size=python38.PySet_Size + PySet_Type=python38.PySet_Type DATA + PySlice_AdjustIndices=python38.PySlice_AdjustIndices + PySlice_GetIndices=python38.PySlice_GetIndices + PySlice_GetIndicesEx=python38.PySlice_GetIndicesEx + PySlice_New=python38.PySlice_New + PySlice_Type=python38.PySlice_Type DATA + PySlice_Unpack=python38.PySlice_Unpack + PySortWrapper_Type=python38.PySortWrapper_Type DATA + PyInterpreterState_GetID=python38.PyInterpreterState_GetID + PyState_AddModule=python38.PyState_AddModule + PyState_FindModule=python38.PyState_FindModule + PyState_RemoveModule=python38.PyState_RemoveModule + PyStructSequence_GetItem=python38.PyStructSequence_GetItem + PyStructSequence_New=python38.PyStructSequence_New + PyStructSequence_NewType=python38.PyStructSequence_NewType + PyStructSequence_SetItem=python38.PyStructSequence_SetItem + PySuper_Type=python38.PySuper_Type DATA + PySys_AddWarnOption=python38.PySys_AddWarnOption + PySys_AddWarnOptionUnicode=python38.PySys_AddWarnOptionUnicode + PySys_AddXOption=python38.PySys_AddXOption + PySys_FormatStderr=python38.PySys_FormatStderr + PySys_FormatStdout=python38.PySys_FormatStdout + PySys_GetObject=python38.PySys_GetObject + PySys_GetXOptions=python38.PySys_GetXOptions + PySys_HasWarnOptions=python38.PySys_HasWarnOptions + PySys_ResetWarnOptions=python38.PySys_ResetWarnOptions + PySys_SetArgv=python38.PySys_SetArgv + PySys_SetArgvEx=python38.PySys_SetArgvEx + PySys_SetObject=python38.PySys_SetObject + PySys_SetPath=python38.PySys_SetPath + PySys_WriteStderr=python38.PySys_WriteStderr + PySys_WriteStdout=python38.PySys_WriteStdout + PyThreadState_Clear=python38.PyThreadState_Clear + PyThreadState_Delete=python38.PyThreadState_Delete + PyThreadState_DeleteCurrent=python38.PyThreadState_DeleteCurrent + PyThreadState_Get=python38.PyThreadState_Get + PyThreadState_GetDict=python38.PyThreadState_GetDict + PyThreadState_New=python38.PyThreadState_New + PyThreadState_SetAsyncExc=python38.PyThreadState_SetAsyncExc + PyThreadState_Swap=python38.PyThreadState_Swap + PyThread_tss_alloc=python38.PyThread_tss_alloc + PyThread_tss_create=python38.PyThread_tss_create + PyThread_tss_delete=python38.PyThread_tss_delete + PyThread_tss_free=python38.PyThread_tss_free + PyThread_tss_get=python38.PyThread_tss_get + PyThread_tss_is_created=python38.PyThread_tss_is_created + PyThread_tss_set=python38.PyThread_tss_set + PyTraceBack_Here=python38.PyTraceBack_Here + PyTraceBack_Print=python38.PyTraceBack_Print + PyTraceBack_Type=python38.PyTraceBack_Type DATA + PyTupleIter_Type=python38.PyTupleIter_Type DATA + PyTuple_ClearFreeList=python38.PyTuple_ClearFreeList + PyTuple_GetItem=python38.PyTuple_GetItem + PyTuple_GetSlice=python38.PyTuple_GetSlice + PyTuple_New=python38.PyTuple_New + PyTuple_Pack=python38.PyTuple_Pack + PyTuple_SetItem=python38.PyTuple_SetItem + PyTuple_Size=python38.PyTuple_Size + PyTuple_Type=python38.PyTuple_Type DATA + PyType_ClearCache=python38.PyType_ClearCache + PyType_FromSpec=python38.PyType_FromSpec + PyType_FromSpecWithBases=python38.PyType_FromSpecWithBases + PyType_GenericAlloc=python38.PyType_GenericAlloc + PyType_GenericNew=python38.PyType_GenericNew + PyType_GetFlags=python38.PyType_GetFlags + PyType_GetSlot=python38.PyType_GetSlot + PyType_IsSubtype=python38.PyType_IsSubtype + PyType_Modified=python38.PyType_Modified + PyType_Ready=python38.PyType_Ready + PyType_Type=python38.PyType_Type DATA + PyUnicodeDecodeError_Create=python38.PyUnicodeDecodeError_Create + PyUnicodeDecodeError_GetEncoding=python38.PyUnicodeDecodeError_GetEncoding + PyUnicodeDecodeError_GetEnd=python38.PyUnicodeDecodeError_GetEnd + PyUnicodeDecodeError_GetObject=python38.PyUnicodeDecodeError_GetObject + PyUnicodeDecodeError_GetReason=python38.PyUnicodeDecodeError_GetReason + PyUnicodeDecodeError_GetStart=python38.PyUnicodeDecodeError_GetStart + PyUnicodeDecodeError_SetEnd=python38.PyUnicodeDecodeError_SetEnd + PyUnicodeDecodeError_SetReason=python38.PyUnicodeDecodeError_SetReason + PyUnicodeDecodeError_SetStart=python38.PyUnicodeDecodeError_SetStart + PyUnicodeEncodeError_GetEncoding=python38.PyUnicodeEncodeError_GetEncoding + PyUnicodeEncodeError_GetEnd=python38.PyUnicodeEncodeError_GetEnd + PyUnicodeEncodeError_GetObject=python38.PyUnicodeEncodeError_GetObject + PyUnicodeEncodeError_GetReason=python38.PyUnicodeEncodeError_GetReason + PyUnicodeEncodeError_GetStart=python38.PyUnicodeEncodeError_GetStart + PyUnicodeEncodeError_SetEnd=python38.PyUnicodeEncodeError_SetEnd + PyUnicodeEncodeError_SetReason=python38.PyUnicodeEncodeError_SetReason + PyUnicodeEncodeError_SetStart=python38.PyUnicodeEncodeError_SetStart + PyUnicodeIter_Type=python38.PyUnicodeIter_Type DATA + PyUnicodeTranslateError_GetEnd=python38.PyUnicodeTranslateError_GetEnd + PyUnicodeTranslateError_GetObject=python38.PyUnicodeTranslateError_GetObject + PyUnicodeTranslateError_GetReason=python38.PyUnicodeTranslateError_GetReason + PyUnicodeTranslateError_GetStart=python38.PyUnicodeTranslateError_GetStart + PyUnicodeTranslateError_SetEnd=python38.PyUnicodeTranslateError_SetEnd + PyUnicodeTranslateError_SetReason=python38.PyUnicodeTranslateError_SetReason + PyUnicodeTranslateError_SetStart=python38.PyUnicodeTranslateError_SetStart + PyUnicode_Append=python38.PyUnicode_Append + PyUnicode_AppendAndDel=python38.PyUnicode_AppendAndDel + PyUnicode_AsASCIIString=python38.PyUnicode_AsASCIIString + PyUnicode_AsCharmapString=python38.PyUnicode_AsCharmapString + PyUnicode_AsDecodedObject=python38.PyUnicode_AsDecodedObject + PyUnicode_AsDecodedUnicode=python38.PyUnicode_AsDecodedUnicode + PyUnicode_AsEncodedObject=python38.PyUnicode_AsEncodedObject + PyUnicode_AsEncodedString=python38.PyUnicode_AsEncodedString + PyUnicode_AsEncodedUnicode=python38.PyUnicode_AsEncodedUnicode + PyUnicode_AsLatin1String=python38.PyUnicode_AsLatin1String + PyUnicode_AsMBCSString=python38.PyUnicode_AsMBCSString + PyUnicode_AsRawUnicodeEscapeString=python38.PyUnicode_AsRawUnicodeEscapeString + PyUnicode_AsUCS4=python38.PyUnicode_AsUCS4 + PyUnicode_AsUCS4Copy=python38.PyUnicode_AsUCS4Copy + PyUnicode_AsUTF16String=python38.PyUnicode_AsUTF16String + PyUnicode_AsUTF32String=python38.PyUnicode_AsUTF32String + PyUnicode_AsUTF8String=python38.PyUnicode_AsUTF8String + PyUnicode_AsUnicodeEscapeString=python38.PyUnicode_AsUnicodeEscapeString + PyUnicode_AsWideChar=python38.PyUnicode_AsWideChar + PyUnicode_AsWideCharString=python38.PyUnicode_AsWideCharString + PyUnicode_BuildEncodingMap=python38.PyUnicode_BuildEncodingMap + PyUnicode_ClearFreeList=python38.PyUnicode_ClearFreeList + PyUnicode_Compare=python38.PyUnicode_Compare + PyUnicode_CompareWithASCIIString=python38.PyUnicode_CompareWithASCIIString + PyUnicode_Concat=python38.PyUnicode_Concat + PyUnicode_Contains=python38.PyUnicode_Contains + PyUnicode_Count=python38.PyUnicode_Count + PyUnicode_Decode=python38.PyUnicode_Decode + PyUnicode_DecodeASCII=python38.PyUnicode_DecodeASCII + PyUnicode_DecodeCharmap=python38.PyUnicode_DecodeCharmap + PyUnicode_DecodeCodePageStateful=python38.PyUnicode_DecodeCodePageStateful + PyUnicode_DecodeFSDefault=python38.PyUnicode_DecodeFSDefault + PyUnicode_DecodeFSDefaultAndSize=python38.PyUnicode_DecodeFSDefaultAndSize + PyUnicode_DecodeLatin1=python38.PyUnicode_DecodeLatin1 + PyUnicode_DecodeLocale=python38.PyUnicode_DecodeLocale + PyUnicode_DecodeLocaleAndSize=python38.PyUnicode_DecodeLocaleAndSize + PyUnicode_DecodeMBCS=python38.PyUnicode_DecodeMBCS + PyUnicode_DecodeMBCSStateful=python38.PyUnicode_DecodeMBCSStateful + PyUnicode_DecodeRawUnicodeEscape=python38.PyUnicode_DecodeRawUnicodeEscape + PyUnicode_DecodeUTF16=python38.PyUnicode_DecodeUTF16 + PyUnicode_DecodeUTF16Stateful=python38.PyUnicode_DecodeUTF16Stateful + PyUnicode_DecodeUTF32=python38.PyUnicode_DecodeUTF32 + PyUnicode_DecodeUTF32Stateful=python38.PyUnicode_DecodeUTF32Stateful + PyUnicode_DecodeUTF7=python38.PyUnicode_DecodeUTF7 + PyUnicode_DecodeUTF7Stateful=python38.PyUnicode_DecodeUTF7Stateful + PyUnicode_DecodeUTF8=python38.PyUnicode_DecodeUTF8 + PyUnicode_DecodeUTF8Stateful=python38.PyUnicode_DecodeUTF8Stateful + PyUnicode_DecodeUnicodeEscape=python38.PyUnicode_DecodeUnicodeEscape + PyUnicode_EncodeCodePage=python38.PyUnicode_EncodeCodePage + PyUnicode_EncodeFSDefault=python38.PyUnicode_EncodeFSDefault + PyUnicode_EncodeLocale=python38.PyUnicode_EncodeLocale + PyUnicode_FSConverter=python38.PyUnicode_FSConverter + PyUnicode_FSDecoder=python38.PyUnicode_FSDecoder + PyUnicode_Find=python38.PyUnicode_Find + PyUnicode_FindChar=python38.PyUnicode_FindChar + PyUnicode_Format=python38.PyUnicode_Format + PyUnicode_FromEncodedObject=python38.PyUnicode_FromEncodedObject + PyUnicode_FromFormat=python38.PyUnicode_FromFormat + PyUnicode_FromFormatV=python38.PyUnicode_FromFormatV + PyUnicode_FromObject=python38.PyUnicode_FromObject + PyUnicode_FromOrdinal=python38.PyUnicode_FromOrdinal + PyUnicode_FromString=python38.PyUnicode_FromString + PyUnicode_FromStringAndSize=python38.PyUnicode_FromStringAndSize + PyUnicode_FromWideChar=python38.PyUnicode_FromWideChar + PyUnicode_GetDefaultEncoding=python38.PyUnicode_GetDefaultEncoding + PyUnicode_GetLength=python38.PyUnicode_GetLength + PyUnicode_GetSize=python38.PyUnicode_GetSize + PyUnicode_InternFromString=python38.PyUnicode_InternFromString + PyUnicode_InternImmortal=python38.PyUnicode_InternImmortal + PyUnicode_InternInPlace=python38.PyUnicode_InternInPlace + PyUnicode_IsIdentifier=python38.PyUnicode_IsIdentifier + PyUnicode_Join=python38.PyUnicode_Join + PyUnicode_Partition=python38.PyUnicode_Partition + PyUnicode_RPartition=python38.PyUnicode_RPartition + PyUnicode_RSplit=python38.PyUnicode_RSplit + PyUnicode_ReadChar=python38.PyUnicode_ReadChar + PyUnicode_Replace=python38.PyUnicode_Replace + PyUnicode_Resize=python38.PyUnicode_Resize + PyUnicode_RichCompare=python38.PyUnicode_RichCompare + PyUnicode_Split=python38.PyUnicode_Split + PyUnicode_Splitlines=python38.PyUnicode_Splitlines + PyUnicode_Substring=python38.PyUnicode_Substring + PyUnicode_Tailmatch=python38.PyUnicode_Tailmatch + PyUnicode_Translate=python38.PyUnicode_Translate + PyUnicode_Type=python38.PyUnicode_Type DATA + PyUnicode_WriteChar=python38.PyUnicode_WriteChar + PyWeakref_GetObject=python38.PyWeakref_GetObject + PyWeakref_NewProxy=python38.PyWeakref_NewProxy + PyWeakref_NewRef=python38.PyWeakref_NewRef + PyWrapperDescr_Type=python38.PyWrapperDescr_Type DATA + PyWrapper_New=python38.PyWrapper_New + PyZip_Type=python38.PyZip_Type DATA + Py_AddPendingCall=python38.Py_AddPendingCall + Py_AtExit=python38.Py_AtExit + Py_BuildValue=python38.Py_BuildValue + Py_CompileString=python38.Py_CompileString + Py_DecRef=python38.Py_DecRef + Py_DecodeLocale=python38.Py_DecodeLocale + Py_EncodeLocale=python38.Py_EncodeLocale + Py_EndInterpreter=python38.Py_EndInterpreter + Py_Exit=python38.Py_Exit + Py_FatalError=python38.Py_FatalError + Py_FileSystemDefaultEncodeErrors=python38.Py_FileSystemDefaultEncodeErrors DATA + Py_FileSystemDefaultEncoding=python38.Py_FileSystemDefaultEncoding DATA + Py_Finalize=python38.Py_Finalize + Py_FinalizeEx=python38.Py_FinalizeEx + Py_GetBuildInfo=python38.Py_GetBuildInfo + Py_GetCompiler=python38.Py_GetCompiler + Py_GetCopyright=python38.Py_GetCopyright + Py_GetExecPrefix=python38.Py_GetExecPrefix + Py_GetPath=python38.Py_GetPath + Py_GetPlatform=python38.Py_GetPlatform + Py_GetPrefix=python38.Py_GetPrefix + Py_GetProgramFullPath=python38.Py_GetProgramFullPath + Py_GetProgramName=python38.Py_GetProgramName + Py_GetPythonHome=python38.Py_GetPythonHome + Py_GetRecursionLimit=python38.Py_GetRecursionLimit + Py_GetVersion=python38.Py_GetVersion + Py_HasFileSystemDefaultEncoding=python38.Py_HasFileSystemDefaultEncoding DATA + Py_IncRef=python38.Py_IncRef + Py_Initialize=python38.Py_Initialize + Py_InitializeEx=python38.Py_InitializeEx + Py_IsInitialized=python38.Py_IsInitialized + Py_Main=python38.Py_Main + Py_MakePendingCalls=python38.Py_MakePendingCalls + Py_NewInterpreter=python38.Py_NewInterpreter + Py_ReprEnter=python38.Py_ReprEnter + Py_ReprLeave=python38.Py_ReprLeave + Py_SetPath=python38.Py_SetPath + Py_SetProgramName=python38.Py_SetProgramName + Py_SetPythonHome=python38.Py_SetPythonHome + Py_SetRecursionLimit=python38.Py_SetRecursionLimit + Py_SymtableString=python38.Py_SymtableString + Py_UTF8Mode=python38.Py_UTF8Mode DATA + Py_VaBuildValue=python38.Py_VaBuildValue + _PyArg_ParseTupleAndKeywords_SizeT=python38._PyArg_ParseTupleAndKeywords_SizeT + _PyArg_ParseTuple_SizeT=python38._PyArg_ParseTuple_SizeT + _PyArg_Parse_SizeT=python38._PyArg_Parse_SizeT + _PyArg_VaParseTupleAndKeywords_SizeT=python38._PyArg_VaParseTupleAndKeywords_SizeT + _PyArg_VaParse_SizeT=python38._PyArg_VaParse_SizeT + _PyErr_BadInternalCall=python38._PyErr_BadInternalCall + _PyObject_CallFunction_SizeT=python38._PyObject_CallFunction_SizeT + _PyObject_CallMethod_SizeT=python38._PyObject_CallMethod_SizeT + _PyObject_GC_Malloc=python38._PyObject_GC_Malloc + _PyObject_GC_New=python38._PyObject_GC_New + _PyObject_GC_NewVar=python38._PyObject_GC_NewVar + _PyObject_GC_Resize=python38._PyObject_GC_Resize + _PyObject_New=python38._PyObject_New + _PyObject_NewVar=python38._PyObject_NewVar + _PyState_AddModule=python38._PyState_AddModule + _PyThreadState_Init=python38._PyThreadState_Init + _PyThreadState_Prealloc=python38._PyThreadState_Prealloc + _PyTrash_delete_later=python38._PyTrash_delete_later DATA + _PyTrash_delete_nesting=python38._PyTrash_delete_nesting DATA + _PyTrash_deposit_object=python38._PyTrash_deposit_object + _PyTrash_destroy_chain=python38._PyTrash_destroy_chain + _PyTrash_thread_deposit_object=python38._PyTrash_thread_deposit_object + _PyTrash_thread_destroy_chain=python38._PyTrash_thread_destroy_chain + _PyWeakref_CallableProxyType=python38._PyWeakref_CallableProxyType DATA + _PyWeakref_ProxyType=python38._PyWeakref_ProxyType DATA + _PyWeakref_RefType=python38._PyWeakref_RefType DATA + _Py_BuildValue_SizeT=python38._Py_BuildValue_SizeT + _Py_CheckRecursionLimit=python38._Py_CheckRecursionLimit DATA + _Py_CheckRecursiveCall=python38._Py_CheckRecursiveCall + _Py_Dealloc=python38._Py_Dealloc + _Py_EllipsisObject=python38._Py_EllipsisObject DATA + _Py_FalseStruct=python38._Py_FalseStruct DATA + _Py_NoneStruct=python38._Py_NoneStruct DATA + _Py_NotImplementedStruct=python38._Py_NotImplementedStruct DATA + _Py_SwappedOp=python38._Py_SwappedOp DATA + _Py_TrueStruct=python38._Py_TrueStruct DATA + _Py_VaBuildValue_SizeT=python38._Py_VaBuildValue_SizeT diff --git a/PC/winreg.c b/PC/winreg.c index ddaf3b1abc9206..78864b1a69cfe9 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -83,7 +83,7 @@ PyDoc_STRVAR(PyHKEY_doc, "the object is destroyed. To guarantee cleanup, you can call either\n" "the Close() method on the PyHKEY, or the CloseKey() method.\n" "\n" -"All functions which accept a handle object also accept an integer - \n" +"All functions which accept a handle object also accept an integer --\n" "however, use of the handle object is encouraged.\n" "\n" "Functions:\n" diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index d19b5f5acf8923..90330faa0cf26f 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -280,6 +280,7 @@ <ClCompile Include="..\Modules\_tracemalloc.c" /> <ClCompile Include="..\Modules\timemodule.c" /> <ClCompile Include="..\Modules\xxsubtype.c" /> + <ClCompile Include="..\Modules\_xxsubinterpretersmodule.c" /> <ClCompile Include="..\Modules\zipimport.c" /> <ClCompile Include="..\Modules\_io\fileio.c" /> <ClCompile Include="..\Modules\_io\bytesio.c" /> diff --git a/PCbuild/readme.txt b/PCbuild/readme.txt index 1f2fb929efd9d9..c84732861191a8 100644 --- a/PCbuild/readme.txt +++ b/PCbuild/readme.txt @@ -38,7 +38,7 @@ 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: - python37_d.dll, python_d.exe, parser_d.pyd, and so on. Both the + python38_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. diff --git a/Parser/myreadline.c b/Parser/myreadline.c index ab6bd4e83000ae..2aa3bef2b0bbf6 100644 --- a/Parser/myreadline.c +++ b/Parser/myreadline.c @@ -114,6 +114,9 @@ _PyOS_WindowsConsoleReadline(HANDLE hStdIn) wbuf = wbuf_local; wbuflen = sizeof(wbuf_local) / sizeof(wbuf_local[0]) - 1; while (1) { + if (PyOS_InputHook != NULL) { + (void)(PyOS_InputHook)(); + } if (!ReadConsoleW(hStdIn, &wbuf[total_read], wbuflen - total_read, &n_read, NULL)) { err = GetLastError(); goto exit; diff --git a/Python/_warnings.c b/Python/_warnings.c index 29e475d67d1f61..d6614b2cf6d46b 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -9,7 +9,6 @@ PyDoc_STRVAR(warnings__doc__, MODULE_NAME " provides basic warning filtering support.\n" "It is a helper module to speed up interpreter start-up."); -_Py_IDENTIFIER(argv); _Py_IDENTIFIER(stderr); #ifndef Py_DEBUG _Py_IDENTIFIER(default); @@ -671,7 +670,7 @@ setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno, { PyObject *globals; - /* Setup globals and lineno. */ + /* Setup globals, filename and lineno. */ PyFrameObject *f = PyThreadState_GET()->frame; // Stack level comparisons to Python code is off by one as there is no // warnings-related stack level to avoid. @@ -688,10 +687,13 @@ setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno, if (f == NULL) { globals = PyThreadState_Get()->interp->sysdict; + *filename = PyUnicode_FromString("sys"); *lineno = 1; } else { globals = f->f_globals; + *filename = f->f_code->co_filename; + Py_INCREF(*filename); *lineno = PyFrame_GetLineNumber(f); } @@ -726,71 +728,6 @@ setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno, goto handle_error; } - /* Setup filename. */ - *filename = PyDict_GetItemString(globals, "__file__"); - if (*filename != NULL && PyUnicode_Check(*filename)) { - Py_ssize_t len; - int kind; - void *data; - - if (PyUnicode_READY(*filename)) - goto handle_error; - - len = PyUnicode_GetLength(*filename); - kind = PyUnicode_KIND(*filename); - data = PyUnicode_DATA(*filename); - -#define ascii_lower(c) ((c <= 127) ? Py_TOLOWER(c) : 0) - /* if filename.lower().endswith(".pyc"): */ - if (len >= 4 && - PyUnicode_READ(kind, data, len-4) == '.' && - ascii_lower(PyUnicode_READ(kind, data, len-3)) == 'p' && - ascii_lower(PyUnicode_READ(kind, data, len-2)) == 'y' && - ascii_lower(PyUnicode_READ(kind, data, len-1)) == 'c') - { - *filename = PyUnicode_Substring(*filename, 0, - PyUnicode_GET_LENGTH(*filename)-1); - if (*filename == NULL) - goto handle_error; - } - else - Py_INCREF(*filename); - } - else { - *filename = NULL; - if (*module != Py_None && _PyUnicode_EqualToASCIIString(*module, "__main__")) { - PyObject *argv = _PySys_GetObjectId(&PyId_argv); - /* PyList_Check() is needed because sys.argv is set to None during - Python finalization */ - if (argv != NULL && PyList_Check(argv) && PyList_Size(argv) > 0) { - int is_true; - *filename = PyList_GetItem(argv, 0); - Py_INCREF(*filename); - /* If sys.argv[0] is false, then use '__main__'. */ - is_true = PyObject_IsTrue(*filename); - if (is_true < 0) { - Py_DECREF(*filename); - goto handle_error; - } - else if (!is_true) { - Py_SETREF(*filename, PyUnicode_FromString("__main__")); - if (*filename == NULL) - goto handle_error; - } - } - else { - /* embedded interpreters don't have sys.argv, see bug #839151 */ - *filename = PyUnicode_FromString("__main__"); - if (*filename == NULL) - goto handle_error; - } - } - if (*filename == NULL) { - *filename = *module; - Py_INCREF(*filename); - } - } - return 1; handle_error: diff --git a/Python/ast.c b/Python/ast.c index 6e1793dc337505..3b4cd162fcce2f 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -4024,7 +4024,7 @@ ast_for_stmt(struct compiling *c, const node *n) return ast_for_async_stmt(c, ch); default: PyErr_Format(PyExc_SystemError, - "unhandled small_stmt: TYPE=%d NCH=%d\n", + "unhandled compound_stmt: TYPE=%d NCH=%d\n", TYPE(n), NCH(n)); return NULL; } @@ -4274,7 +4274,7 @@ fstring_fix_node_location(const node *parent, node *n, char *expr_str) break; start--; } - cols += substr - start; + cols += (int)(substr - start); /* Fix lineno in mulitline strings. */ while ((substr = strchr(substr + 1, '\n'))) lines--; @@ -5260,3 +5260,23 @@ parsestrplus(struct compiling *c, const node *n) FstringParser_Dealloc(&state); return NULL; } + +PyObject * +_PyAST_GetDocString(asdl_seq *body) +{ + if (!asdl_seq_LEN(body)) { + return NULL; + } + stmt_ty st = (stmt_ty)asdl_seq_GET(body, 0); + if (st->kind != Expr_kind) { + return NULL; + } + expr_ty e = st->v.Expr.value; + if (e->kind == Str_kind) { + return e->v.Str.s; + } + if (e->kind == Constant_kind && PyUnicode_CheckExact(e->v.Constant.value)) { + return e->v.Constant.value; + } + return NULL; +} diff --git a/Python/ast_opt.c b/Python/ast_opt.c index 7bc681a421d645..5e57638e3d0172 100644 --- a/Python/ast_opt.c +++ b/Python/ast_opt.c @@ -1,6 +1,8 @@ /* AST Optimizer */ #include "Python.h" #include "Python-ast.h" +#include "node.h" +#include "ast.h" /* TODO: is_const and get_const_value are copied from Python/compile.c. @@ -369,7 +371,8 @@ fold_subscr(expr_ty node, PyArena *arena, int optimize) } /* Change literal list or set of constants into constant - tuple or frozenset respectively. + tuple or frozenset respectively. Change literal list of + non-constants into tuple. Used for right operand of "in" and "not in" tests and for iterable in "for" loop and comprehensions. */ @@ -378,7 +381,21 @@ fold_iter(expr_ty arg, PyArena *arena, int optimize) { PyObject *newval; if (arg->kind == List_kind) { - newval = make_const_tuple(arg->v.List.elts); + /* First change a list into tuple. */ + asdl_seq *elts = arg->v.List.elts; + Py_ssize_t n = asdl_seq_LEN(elts); + for (Py_ssize_t i = 0; i < n; i++) { + expr_ty e = (expr_ty)asdl_seq_GET(elts, i); + if (e->kind == Starred_kind) { + return 1; + } + } + expr_context_ty ctx = arg->v.List.ctx; + arg->kind = Tuple_kind; + arg->v.Tuple.elts = elts; + arg->v.Tuple.ctx = ctx; + /* Try to create a constant tuple. */ + newval = make_const_tuple(elts); } else if (arg->kind == Set_kind) { newval = make_const_tuple(arg->v.Set.elts); @@ -452,37 +469,19 @@ static int astfold_excepthandler(excepthandler_ty node_, PyArena *ctx_, int opti } \ } -static int -isdocstring(stmt_ty s) -{ - if (s->kind != Expr_kind) - return 0; - if (s->v.Expr.value->kind == Str_kind) - return 1; - if (s->v.Expr.value->kind == Constant_kind) - return PyUnicode_CheckExact(s->v.Expr.value->v.Constant.value); - return 0; -} - static int astfold_body(asdl_seq *stmts, PyArena *ctx_, int optimize_) { - if (!asdl_seq_LEN(stmts)) { - return 1; - } - int docstring = isdocstring((stmt_ty)asdl_seq_GET(stmts, 0)); + int docstring = _PyAST_GetDocString(stmts) != NULL; CALL_SEQ(astfold_stmt, stmt_ty, stmts); - if (docstring) { - return 1; - } - stmt_ty st = (stmt_ty)asdl_seq_GET(stmts, 0); - if (isdocstring(st)) { + if (!docstring && _PyAST_GetDocString(stmts) != NULL) { + stmt_ty st = (stmt_ty)asdl_seq_GET(stmts, 0); asdl_seq *values = _Py_asdl_seq_new(1, ctx_); if (!values) { return 0; } asdl_seq_SET(values, 0, st->v.Expr.value); - expr_ty expr = _Py_JoinedStr(values, st->lineno, st->col_offset, ctx_); + expr_ty expr = JoinedStr(values, st->lineno, st->col_offset, ctx_); if (!expr) { return 0; } diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 713731aed368fd..eeab35ae119946 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -254,30 +254,19 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs, if (cls != NULL && PyType_Check(cls) && PyCell_Check(cell)) { PyObject *cell_cls = PyCell_GET(cell); if (cell_cls != cls) { - /* TODO: In 3.7, DeprecationWarning will become RuntimeError. - * At that point, cell_error won't be needed. - */ - int cell_error; if (cell_cls == NULL) { const char *msg = "__class__ not set defining %.200R as %.200R. " "Was __classcell__ propagated to type.__new__?"; - cell_error = PyErr_WarnFormat( - PyExc_DeprecationWarning, 1, msg, name, cls); + PyErr_Format(PyExc_RuntimeError, msg, name, cls); } else { const char *msg = "__class__ set to %.200R defining %.200R as %.200R"; PyErr_Format(PyExc_TypeError, msg, cell_cls, name, cls); - cell_error = 1; - } - if (cell_error) { - Py_DECREF(cls); - cls = NULL; - goto error; - } else { - /* Fill in the cell, since type.__new__ didn't do it */ - PyCell_Set(cell, cls); } + Py_DECREF(cls); + cls = NULL; + goto error; } } } @@ -619,7 +608,7 @@ filter_next(filterobject *lz) } static PyObject * -filter_reduce(filterobject *lz) +filter_reduce(filterobject *lz, PyObject *Py_UNUSED(ignored)) { return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->func, lz->it); } @@ -1346,7 +1335,7 @@ map_next(mapobject *lz) } static PyObject * -map_reduce(mapobject *lz) +map_reduce(mapobject *lz, PyObject *Py_UNUSED(ignored)) { Py_ssize_t numargs = PyTuple_GET_SIZE(lz->iters); PyObject *args = PyTuple_New(numargs+1); @@ -2671,7 +2660,7 @@ zip_next(zipobject *lz) } static PyObject * -zip_reduce(zipobject *lz) +zip_reduce(zipobject *lz, PyObject *Py_UNUSED(ignored)) { /* Just recreate the zip with the internal iterator tuple */ return Py_BuildValue("OO", Py_TYPE(lz), lz->ittuple); diff --git a/Python/ceval.c b/Python/ceval.c index 482ad28cf95032..f2dfffd394a27b 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -501,17 +501,6 @@ _Py_CheckRecursiveCall(const char *where) return 0; } -/* Status code for main loop (reason for stack unwind) */ -enum why_code { - WHY_NOT = 0x0001, /* No error */ - WHY_EXCEPTION = 0x0002, /* Exception occurred */ - WHY_RETURN = 0x0008, /* 'return' statement */ - WHY_BREAK = 0x0010, /* 'break' statement */ - WHY_CONTINUE = 0x0020, /* 'continue' statement */ - WHY_YIELD = 0x0040, /* 'yield' operator */ - WHY_SILENCED = 0x0080 /* Exception silenced by 'with' */ -}; - static int do_raise(PyObject *, PyObject *); static int unpack_iterable(PyObject *, int, int, PyObject **); @@ -557,7 +546,6 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) const _Py_CODEUNIT *next_instr; int opcode; /* Current opcode */ int oparg; /* Current opcode argument, if any */ - enum why_code why; /* Reason for block stack unwind */ PyObject **fastlocals, **freevars; PyObject *retval = NULL; /* Return value */ PyThreadState *tstate = PyThreadState_GET(); @@ -915,8 +903,6 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) lltrace = _PyDict_GetItemId(f->f_globals, &PyId___ltrace__) != NULL; #endif - why = WHY_NOT; - if (throwflag) /* support for generator.throw() */ goto error; @@ -927,6 +913,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) assert(!PyErr_Occurred()); #endif +main_loop: for (;;) { assert(stack_pointer >= f->f_valuestack); /* else underflow */ assert(STACK_LEVEL() <= co->co_stacksize); /* else overflow */ @@ -1057,9 +1044,8 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) switch (opcode) { /* BEWARE! - It is essential that any operation that fails sets either - x to NULL, err to nonzero, or why to anything but WHY_NOT, - and that no operation that succeeds does this! */ + It is essential that any operation that fails must goto error + and that all operation that succeed call [FAST_]DISPATCH() ! */ TARGET(NOP) FAST_DISPATCH(); @@ -1116,6 +1102,18 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) FAST_DISPATCH(); } + TARGET(ROT_FOUR) { + PyObject *top = TOP(); + PyObject *second = SECOND(); + PyObject *third = THIRD(); + PyObject *fourth = FOURTH(); + SET_TOP(second); + SET_SECOND(third); + SET_THIRD(fourth); + SET_FOURTH(top); + FAST_DISPATCH(); + } + TARGET(DUP_TOP) { PyObject *top = TOP(); Py_INCREF(top); @@ -1619,8 +1617,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) /* fall through */ case 0: if (do_raise(exc, cause)) { - why = WHY_EXCEPTION; - goto fast_block_end; + goto exception_unwind; } break; default: @@ -1633,8 +1630,8 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) TARGET(RETURN_VALUE) { retval = POP(); - why = WHY_RETURN; - goto fast_block_end; + assert(f->f_iblock == 0); + goto return_or_yield; } TARGET(GET_AITER) { @@ -1800,11 +1797,10 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) } /* receiver remains on stack, retval is value to be yielded */ f->f_stacktop = stack_pointer; - why = WHY_YIELD; /* and repeat... */ assert(f->f_lasti >= (int)sizeof(_Py_CODEUNIT)); f->f_lasti -= sizeof(_Py_CODEUNIT); - goto fast_yield; + goto return_or_yield; } TARGET(YIELD_VALUE) { @@ -1821,67 +1817,157 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) } f->f_stacktop = stack_pointer; - why = WHY_YIELD; - goto fast_yield; + goto return_or_yield; } TARGET(POP_EXCEPT) { + PyObject *type, *value, *traceback; + _PyErr_StackItem *exc_info; PyTryBlock *b = PyFrame_BlockPop(f); if (b->b_type != EXCEPT_HANDLER) { PyErr_SetString(PyExc_SystemError, "popped block is not an except handler"); goto error; } - UNWIND_EXCEPT_HANDLER(b); + assert(STACK_LEVEL() >= (b)->b_level + 3 && + STACK_LEVEL() <= (b)->b_level + 4); + exc_info = tstate->exc_info; + type = exc_info->exc_type; + value = exc_info->exc_value; + traceback = exc_info->exc_traceback; + exc_info->exc_type = POP(); + exc_info->exc_value = POP(); + exc_info->exc_traceback = POP(); + Py_XDECREF(type); + Py_XDECREF(value); + Py_XDECREF(traceback); DISPATCH(); } PREDICTED(POP_BLOCK); TARGET(POP_BLOCK) { - PyTryBlock *b = PyFrame_BlockPop(f); - UNWIND_BLOCK(b); + PyFrame_BlockPop(f); DISPATCH(); } + TARGET(POP_FINALLY) { + /* If oparg is 0 at the top of the stack are 1 or 6 values: + Either: + - TOP = NULL or an integer + or: + - (TOP, SECOND, THIRD) = exc_info() + - (FOURTH, FITH, SIXTH) = previous exception for EXCEPT_HANDLER + + If oparg is 1 the value for 'return' was additionally pushed + at the top of the stack. + */ + PyObject *res = NULL; + if (oparg) { + res = POP(); + } + PyObject *exc = POP(); + if (exc == NULL || PyLong_CheckExact(exc)) { + Py_XDECREF(exc); + } + else { + Py_DECREF(exc); + Py_DECREF(POP()); + Py_DECREF(POP()); + + PyObject *type, *value, *traceback; + _PyErr_StackItem *exc_info; + PyTryBlock *b = PyFrame_BlockPop(f); + if (b->b_type != EXCEPT_HANDLER) { + PyErr_SetString(PyExc_SystemError, + "popped block is not an except handler"); + Py_XDECREF(res); + goto error; + } + assert(STACK_LEVEL() == (b)->b_level + 3); + exc_info = tstate->exc_info; + type = exc_info->exc_type; + value = exc_info->exc_value; + traceback = exc_info->exc_traceback; + exc_info->exc_type = POP(); + exc_info->exc_value = POP(); + exc_info->exc_traceback = POP(); + Py_XDECREF(type); + Py_XDECREF(value); + Py_XDECREF(traceback); + } + if (oparg) { + PUSH(res); + } + DISPATCH(); + } + + TARGET(CALL_FINALLY) { + PyObject *ret = PyLong_FromLong(INSTR_OFFSET()); + if (ret == NULL) { + goto error; + } + PUSH(ret); + JUMPBY(oparg); + FAST_DISPATCH(); + } + + TARGET(BEGIN_FINALLY) { + /* Push NULL onto the stack for using it in END_FINALLY, + POP_FINALLY, WITH_CLEANUP_START and WITH_CLEANUP_FINISH. + */ + PUSH(NULL); + FAST_DISPATCH(); + } + PREDICTED(END_FINALLY); TARGET(END_FINALLY) { - PyObject *status = POP(); - if (PyLong_Check(status)) { - why = (enum why_code) PyLong_AS_LONG(status); - assert(why != WHY_YIELD && why != WHY_EXCEPTION); - if (why == WHY_RETURN || - why == WHY_CONTINUE) - retval = POP(); - if (why == WHY_SILENCED) { - /* An exception was silenced by 'with', we must - manually unwind the EXCEPT_HANDLER block which was - created when the exception was caught, otherwise - the stack will be in an inconsistent state. */ - PyTryBlock *b = PyFrame_BlockPop(f); - assert(b->b_type == EXCEPT_HANDLER); - UNWIND_EXCEPT_HANDLER(b); - why = WHY_NOT; - Py_DECREF(status); - DISPATCH(); + /* At the top of the stack are 1 or 6 values: + Either: + - TOP = NULL or an integer + or: + - (TOP, SECOND, THIRD) = exc_info() + - (FOURTH, FITH, SIXTH) = previous exception for EXCEPT_HANDLER + */ + PyObject *exc = POP(); + if (exc == NULL) { + FAST_DISPATCH(); + } + else if (PyLong_CheckExact(exc)) { + int ret = _PyLong_AsInt(exc); + Py_DECREF(exc); + if (ret == -1 && PyErr_Occurred()) { + goto error; } - Py_DECREF(status); - goto fast_block_end; + JUMPTO(ret); + FAST_DISPATCH(); } - else if (PyExceptionClass_Check(status)) { - PyObject *exc = POP(); + else { + assert(PyExceptionClass_Check(exc)); + PyObject *val = POP(); PyObject *tb = POP(); - PyErr_Restore(status, exc, tb); - why = WHY_EXCEPTION; - goto fast_block_end; + PyErr_Restore(exc, val, tb); + goto exception_unwind; } - else if (status != Py_None) { - PyErr_SetString(PyExc_SystemError, - "'finally' pops bad exception"); - Py_DECREF(status); - goto error; + } + + TARGET(END_ASYNC_FOR) { + PyObject *exc = POP(); + assert(PyExceptionClass_Check(exc)); + if (PyErr_GivenExceptionMatches(exc, PyExc_StopAsyncIteration)) { + PyTryBlock *b = PyFrame_BlockPop(f); + assert(b->b_type == EXCEPT_HANDLER); + Py_DECREF(exc); + UNWIND_EXCEPT_HANDLER(b); + Py_DECREF(POP()); + JUMPBY(oparg); + FAST_DISPATCH(); + } + else { + PyObject *val = POP(); + PyObject *tb = POP(); + PyErr_Restore(exc, val, tb); + goto exception_unwind; } - Py_DECREF(status); - DISPATCH(); } TARGET(LOAD_BUILD_CLASS) { @@ -2821,28 +2907,13 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) DISPATCH(); } - TARGET(BREAK_LOOP) { - why = WHY_BREAK; - goto fast_block_end; - } - - TARGET(CONTINUE_LOOP) { - retval = PyLong_FromLong(oparg); - if (retval == NULL) - goto error; - why = WHY_CONTINUE; - goto fast_block_end; - } - - TARGET(SETUP_LOOP) - TARGET(SETUP_EXCEPT) TARGET(SETUP_FINALLY) { /* NOTE: If you add any new block-setup opcodes that are not try/except/finally handlers, you may need to update the PyGen_NeedsFinalizing() function. */ - PyFrame_BlockSetup(f, opcode, INSTR_OFFSET() + oparg, + PyFrame_BlockSetup(f, SETUP_FINALLY, INSTR_OFFSET() + oparg, STACK_LEVEL()); DISPATCH(); } @@ -2910,60 +2981,40 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) } TARGET(WITH_CLEANUP_START) { - /* At the top of the stack are 1-6 values indicating + /* At the top of the stack are 1 or 6 values indicating how/why we entered the finally clause: - - TOP = None - - (TOP, SECOND) = (WHY_{RETURN,CONTINUE}), retval - - TOP = WHY_*; no retval below it + - TOP = NULL - (TOP, SECOND, THIRD) = exc_info() (FOURTH, FITH, SIXTH) = previous exception for EXCEPT_HANDLER - Below them is EXIT, the context.__exit__ bound method. - In the last case, we must call - EXIT(TOP, SECOND, THIRD) - otherwise we must call + Below them is EXIT, the context.__exit__ or context.__aexit__ + bound method. + In the first case, we must call EXIT(None, None, None) + otherwise we must call + EXIT(TOP, SECOND, THIRD) - In the first three cases, we remove EXIT from the - stack, leaving the rest in the same order. In the - fourth case, we shift the bottom 3 values of the - stack down, and replace the empty spot with NULL. + In the first case, we remove EXIT from the + stack, leaving TOP, and push TOP on the stack. + Otherwise we shift the bottom 3 values of the + stack down, replace the empty spot with NULL, and push + None on the stack. - In addition, if the stack represents an exception, - *and* the function call returns a 'true' value, we - push WHY_SILENCED onto the stack. END_FINALLY will - then not re-raise the exception. (But non-local - gotos should still be resumed.) + Finally we push the result of the call. */ - - PyObject* stack[3]; + PyObject *stack[3]; PyObject *exit_func; PyObject *exc, *val, *tb, *res; val = tb = Py_None; exc = TOP(); - if (exc == Py_None) { - (void)POP(); + if (exc == NULL) { + STACKADJ(-1); exit_func = TOP(); SET_TOP(exc); - } - else if (PyLong_Check(exc)) { - STACKADJ(-1); - switch (PyLong_AsLong(exc)) { - case WHY_RETURN: - case WHY_CONTINUE: - /* Retval in TOP. */ - exit_func = SECOND(); - SET_SECOND(TOP()); - SET_TOP(exc); - break; - default: - exit_func = TOP(); - SET_TOP(exc); - break; - } exc = Py_None; } else { + assert(PyExceptionClass_Check(exc)); PyObject *tp2, *exc2, *tb2; PyTryBlock *block; val = SECOND(); @@ -2980,8 +3031,10 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) /* We just shifted the stack down, so we have to tell the except handler block that the values are lower than it expects. */ + assert(f->f_iblock > 0); block = &f->f_blockstack[f->f_iblock - 1]; assert(block->b_type == EXCEPT_HANDLER); + assert(block->b_level > 0); block->b_level--; } @@ -3002,6 +3055,12 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) PREDICTED(WITH_CLEANUP_FINISH); TARGET(WITH_CLEANUP_FINISH) { + /* TOP = the result of calling the context.__exit__ bound method + SECOND = either None or exception type + + If SECOND is None below is NULL or the return address, + otherwise below are 7 values representing an exception. + */ PyObject *res = POP(); PyObject *exc = POP(); int err; @@ -3017,8 +3076,15 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) if (err < 0) goto error; else if (err > 0) { - /* There was an exception and a True return */ - PUSH(PyLong_FromLong((long) WHY_SILENCED)); + /* There was an exception and a True return. + * We must manually unwind the EXCEPT_HANDLER block + * which was created when the exception was caught, + * otherwise the stack will be in an inconsisten state. + */ + PyTryBlock *b = PyFrame_BlockPop(f); + assert(b->b_type == EXCEPT_HANDLER); + UNWIND_EXCEPT_HANDLER(b); + PUSH(NULL); } PREDICT(END_FINALLY); DISPATCH(); @@ -3328,10 +3394,6 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) Py_UNREACHABLE(); error: - - assert(why == WHY_NOT); - why = WHY_EXCEPTION; - /* Double-check exception status. */ #ifdef NDEBUG if (!PyErr_Occurred()) @@ -3348,36 +3410,18 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, tstate, f); -fast_block_end: - assert(why != WHY_NOT); - - /* Unwind stacks if a (pseudo) exception occurred */ - while (why != WHY_NOT && f->f_iblock > 0) { - /* Peek at the current block. */ - PyTryBlock *b = &f->f_blockstack[f->f_iblock - 1]; - - assert(why != WHY_YIELD); - if (b->b_type == SETUP_LOOP && why == WHY_CONTINUE) { - why = WHY_NOT; - JUMPTO(PyLong_AS_LONG(retval)); - Py_DECREF(retval); - break; - } - /* Now we have to pop the block. */ - f->f_iblock--; +exception_unwind: + /* Unwind stacks if an exception occurred */ + while (f->f_iblock > 0) { + /* Pop the current block. */ + PyTryBlock *b = &f->f_blockstack[--f->f_iblock]; if (b->b_type == EXCEPT_HANDLER) { UNWIND_EXCEPT_HANDLER(b); continue; } UNWIND_BLOCK(b); - if (b->b_type == SETUP_LOOP && why == WHY_BREAK) { - why = WHY_NOT; - JUMPTO(b->b_handler); - break; - } - if (why == WHY_EXCEPTION && (b->b_type == SETUP_EXCEPT - || b->b_type == SETUP_FINALLY)) { + if (b->b_type == SETUP_FINALLY) { PyObject *exc, *val, *tb; int handler = b->b_handler; _PyErr_StackItem *exc_info = tstate->exc_info; @@ -3414,70 +3458,37 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) PUSH(tb); PUSH(val); PUSH(exc); - why = WHY_NOT; JUMPTO(handler); - break; - } - if (b->b_type == SETUP_FINALLY) { - if (why & (WHY_RETURN | WHY_CONTINUE)) - PUSH(retval); - PUSH(PyLong_FromLong((long)why)); - why = WHY_NOT; - JUMPTO(b->b_handler); - break; + /* Resume normal execution */ + goto main_loop; } } /* unwind stack */ - /* End the loop if we still have an error (or return) */ - - if (why != WHY_NOT) - break; - - assert(!PyErr_Occurred()); - + /* End the loop as we still have an error */ + break; } /* main loop */ - assert(why != WHY_YIELD); /* Pop remaining stack entries. */ while (!EMPTY()) { PyObject *o = POP(); Py_XDECREF(o); } - if (why != WHY_RETURN) - retval = NULL; - - assert((retval != NULL) ^ (PyErr_Occurred() != NULL)); - -fast_yield: + assert(retval == NULL); + assert(PyErr_Occurred()); +return_or_yield: if (tstate->use_tracing) { if (tstate->c_tracefunc) { - if (why == WHY_RETURN || why == WHY_YIELD) { - if (call_trace(tstate->c_tracefunc, tstate->c_traceobj, - tstate, f, - PyTrace_RETURN, retval)) { - Py_CLEAR(retval); - why = WHY_EXCEPTION; - } - } - else if (why == WHY_EXCEPTION) { - call_trace_protected(tstate->c_tracefunc, tstate->c_traceobj, - tstate, f, - PyTrace_RETURN, NULL); + if (call_trace_protected(tstate->c_tracefunc, tstate->c_traceobj, + tstate, f, PyTrace_RETURN, retval)) { + Py_CLEAR(retval); } } if (tstate->c_profilefunc) { - if (why == WHY_EXCEPTION) - call_trace_protected(tstate->c_profilefunc, - tstate->c_profileobj, - tstate, f, - PyTrace_RETURN, NULL); - else if (call_trace(tstate->c_profilefunc, tstate->c_profileobj, - tstate, f, - PyTrace_RETURN, retval)) { + if (call_trace_protected(tstate->c_profilefunc, tstate->c_profileobj, + tstate, f, PyTrace_RETURN, retval)) { Py_CLEAR(retval); - /* why = WHY_EXCEPTION; useless yet but cause compiler warnings */ } } } @@ -4852,6 +4863,7 @@ import_all_from(PyObject *locals, PyObject *v) { _Py_IDENTIFIER(__all__); _Py_IDENTIFIER(__dict__); + _Py_IDENTIFIER(__name__); PyObject *all, *dict, *name, *value; int skip_leading_underscores = 0; int pos, err; @@ -4884,7 +4896,32 @@ import_all_from(PyObject *locals, PyObject *v) PyErr_Clear(); break; } - if (skip_leading_underscores && PyUnicode_Check(name)) { + if (!PyUnicode_Check(name)) { + PyObject *modname = _PyObject_GetAttrId(v, &PyId___name__); + if (modname == NULL) { + Py_DECREF(name); + err = -1; + break; + } + if (!PyUnicode_Check(modname)) { + PyErr_Format(PyExc_TypeError, + "module __name__ must be a string, not %.100s", + Py_TYPE(modname)->tp_name); + } + else { + PyErr_Format(PyExc_TypeError, + "%s in %U.%s must be str, not %.100s", + skip_leading_underscores ? "Key" : "Item", + modname, + skip_leading_underscores ? "__dict__" : "__all__", + Py_TYPE(name)->tp_name); + } + Py_DECREF(modname); + Py_DECREF(name); + err = -1; + break; + } + if (skip_leading_underscores) { if (PyUnicode_READY(name) == -1) { Py_DECREF(name); err = -1; diff --git a/Python/compile.c b/Python/compile.c index b459096c6f00c6..26e50f3b6852a4 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -81,11 +81,14 @@ It's called a frame block to distinguish it from a basic block in the compiler IR. */ -enum fblocktype { LOOP, EXCEPT, FINALLY_TRY, FINALLY_END }; +enum fblocktype { WHILE_LOOP, FOR_LOOP, EXCEPT, FINALLY_TRY, FINALLY_END, + WITH, ASYNC_WITH, HANDLER_CLEANUP }; struct fblockinfo { enum fblocktype fb_type; basicblock *fb_block; + /* (optional) type-specific exit or cleanup block */ + basicblock *fb_exit; }; enum { @@ -168,7 +171,6 @@ static void compiler_free(struct compiler *); static basicblock *compiler_new_block(struct compiler *); static int compiler_next_instr(struct compiler *, basicblock *); static int compiler_addop(struct compiler *, int); -static int compiler_addop_o(struct compiler *, int, PyObject *, PyObject *); static int compiler_addop_i(struct compiler *, int, Py_ssize_t); static int compiler_addop_j(struct compiler *, int, basicblock *, int); static int compiler_error(struct compiler *, const char *); @@ -183,13 +185,6 @@ static int compiler_annassign(struct compiler *, stmt_ty); static int compiler_visit_slice(struct compiler *, slice_ty, expr_context_ty); -static int compiler_push_fblock(struct compiler *, enum fblocktype, - basicblock *); -static void compiler_pop_fblock(struct compiler *, enum fblocktype, - basicblock *); -/* Returns true if there is a loop on the fblock stack. */ -static int compiler_in_loop(struct compiler *); - static int inplace_binop(struct compiler *, operator_ty); static int expr_constant(expr_ty); @@ -411,14 +406,11 @@ list2dict(PyObject *list) return NULL; } k = PyList_GET_ITEM(list, i); - k = _PyCode_ConstantKey(k); - if (k == NULL || PyDict_SetItem(dict, k, v) < 0) { - Py_XDECREF(k); + if (PyDict_SetItem(dict, k, v) < 0) { Py_DECREF(v); Py_DECREF(dict); return NULL; } - Py_DECREF(k); Py_DECREF(v); } return dict; @@ -467,23 +459,20 @@ dictbytype(PyObject *src, int scope_type, int flag, Py_ssize_t offset) scope = (vi >> SCOPE_OFFSET) & SCOPE_MASK; if (scope == scope_type || vi & flag) { - PyObject *tuple, *item = PyLong_FromSsize_t(i); + PyObject *item = PyLong_FromSsize_t(i); if (item == NULL) { Py_DECREF(sorted_keys); Py_DECREF(dest); return NULL; } i++; - tuple = _PyCode_ConstantKey(k); - if (!tuple || PyDict_SetItem(dest, tuple, item) < 0) { + if (PyDict_SetItem(dest, k, item) < 0) { Py_DECREF(sorted_keys); Py_DECREF(item); Py_DECREF(dest); - Py_XDECREF(tuple); return NULL; } Py_DECREF(item); - Py_DECREF(tuple); } } Py_DECREF(sorted_keys); @@ -569,7 +558,7 @@ compiler_enter_scope(struct compiler *c, identifier name, if (u->u_ste->ste_needs_class_closure) { /* Cook up an implicit __class__ cell. */ _Py_IDENTIFIER(__class__); - PyObject *tuple, *name; + PyObject *name; int res; assert(u->u_scope_type == COMPILER_SCOPE_CLASS); assert(PyDict_GET_SIZE(u->u_cellvars) == 0); @@ -578,13 +567,7 @@ compiler_enter_scope(struct compiler *c, identifier name, compiler_unit_free(u); return 0; } - tuple = _PyCode_ConstantKey(name); - if (!tuple) { - compiler_unit_free(u); - return 0; - } - res = PyDict_SetItem(u->u_cellvars, tuple, _PyLong_Zero); - Py_DECREF(tuple); + res = PyDict_SetItem(u->u_cellvars, name, _PyLong_Zero); if (res < 0) { compiler_unit_free(u); return 0; @@ -846,7 +829,7 @@ compiler_next_instr(struct compiler *c, basicblock *b) - when entering a new scope - on each statement - on each expression that start a new line - - before the "except" clause + - before the "except" and "finally" clauses - before the "for" and "while" expressions */ @@ -876,11 +859,16 @@ static int stack_effect(int opcode, int oparg, int jump) { switch (opcode) { + case NOP: + case EXTENDED_ARG: + return 0; + /* Stack manipulation */ case POP_TOP: return -1; case ROT_TWO: case ROT_THREE: + case ROT_FOUR: return 0; case DUP_TOP: return 1; @@ -947,8 +935,7 @@ stack_effect(int opcode, int oparg, int jump) case INPLACE_XOR: case INPLACE_OR: return -1; - case BREAK_LOOP: - return 0; + case SETUP_WITH: /* 1 in the normal flow. * Restore the stack position and push 6 values before jumping to @@ -975,6 +962,7 @@ stack_effect(int opcode, int oparg, int jump) case POP_EXCEPT: return -3; case END_FINALLY: + case POP_FINALLY: /* Pop 6 values when an exception was raised. */ return -6; @@ -1043,16 +1031,20 @@ stack_effect(int opcode, int oparg, int jump) case LOAD_GLOBAL: return 1; - case CONTINUE_LOOP: - return 0; - case SETUP_LOOP: - return 0; - case SETUP_EXCEPT: + /* Exception handling */ case SETUP_FINALLY: /* 0 in the normal flow. * Restore the stack position and push 6 values before jumping to * the handler if an exception be raised. */ return jump ? 6 : 0; + case BEGIN_FINALLY: + /* Actually pushes 1 value, but count 6 for balancing with + * END_FINALLY and POP_FINALLY. + * This is the main reason of using this opcode instead of + * "LOAD_CONST None". */ + return 6; + case CALL_FINALLY: + return jump ? 1 : 0; case LOAD_FAST: return 1; @@ -1110,6 +1102,8 @@ stack_effect(int opcode, int oparg, int jump) return 1; case GET_YIELD_FROM_ITER: return 0; + case END_ASYNC_FOR: + return -7; case FORMAT_VALUE: /* If there's a fmt_spec on the stack, we go from 2->1, else 1->1. */ @@ -1155,27 +1149,20 @@ compiler_addop(struct compiler *c, int opcode) static Py_ssize_t compiler_add_o(struct compiler *c, PyObject *dict, PyObject *o) { - PyObject *t, *v; + PyObject *v; Py_ssize_t arg; - t = _PyCode_ConstantKey(o); - if (t == NULL) - return -1; - - v = PyDict_GetItem(dict, t); + v = PyDict_GetItemWithError(dict, o); if (!v) { if (PyErr_Occurred()) { - Py_DECREF(t); return -1; } arg = PyDict_GET_SIZE(dict); v = PyLong_FromSsize_t(arg); if (!v) { - Py_DECREF(t); return -1; } - if (PyDict_SetItem(dict, t, v) < 0) { - Py_DECREF(t); + if (PyDict_SetItem(dict, o, v) < 0) { Py_DECREF(v); return -1; } @@ -1183,10 +1170,33 @@ compiler_add_o(struct compiler *c, PyObject *dict, PyObject *o) } else arg = PyLong_AsLong(v); + return arg; +} + +static Py_ssize_t +compiler_add_const(struct compiler *c, PyObject *o) +{ + PyObject *t; + Py_ssize_t arg; + + t = _PyCode_ConstantKey(o); + if (t == NULL) + return -1; + + arg = compiler_add_o(c, c->u->u_consts, t); Py_DECREF(t); return arg; } +static int +compiler_addop_load_const(struct compiler *c, PyObject *o) +{ + Py_ssize_t arg = compiler_add_const(c, o); + if (arg < 0) + return 0; + return compiler_addop_i(c, LOAD_CONST, arg); +} + static int compiler_addop_o(struct compiler *c, int opcode, PyObject *dict, PyObject *o) @@ -1287,6 +1297,24 @@ compiler_addop_j(struct compiler *c, int opcode, basicblock *b, int absolute) } \ } +#define ADDOP_LOAD_CONST(C, O) { \ + if (!compiler_addop_load_const((C), (O))) \ + return 0; \ +} + +/* Same as ADDOP_LOAD_CONST, but steals a reference. */ +#define ADDOP_LOAD_CONST_NEW(C, O) { \ + PyObject *__new_const = (O); \ + if (__new_const == NULL) { \ + return 0; \ + } \ + if (!compiler_addop_load_const((C), __new_const)) { \ + Py_DECREF(__new_const); \ + return 0; \ + } \ + Py_DECREF(__new_const); \ +} + #define ADDOP_O(C, OP, O, TYPE) { \ if (!compiler_addop_o((C), (OP), (C)->u->u_ ## TYPE, (O))) \ return 0; \ @@ -1470,6 +1498,103 @@ find_ann(asdl_seq *stmts) return res; } +/* + * Frame block handling functions + */ + +static int +compiler_push_fblock(struct compiler *c, enum fblocktype t, basicblock *b, + basicblock *exit) +{ + struct fblockinfo *f; + if (c->u->u_nfblocks >= CO_MAXBLOCKS) { + PyErr_SetString(PyExc_SyntaxError, + "too many statically nested blocks"); + return 0; + } + f = &c->u->u_fblock[c->u->u_nfblocks++]; + f->fb_type = t; + f->fb_block = b; + f->fb_exit = exit; + return 1; +} + +static void +compiler_pop_fblock(struct compiler *c, enum fblocktype t, basicblock *b) +{ + struct compiler_unit *u = c->u; + assert(u->u_nfblocks > 0); + u->u_nfblocks--; + assert(u->u_fblock[u->u_nfblocks].fb_type == t); + assert(u->u_fblock[u->u_nfblocks].fb_block == b); +} + +/* Unwind a frame block. If preserve_tos is true, the TOS before + * popping the blocks will be restored afterwards. + */ +static int +compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info, + int preserve_tos) +{ + switch (info->fb_type) { + case WHILE_LOOP: + return 1; + + case FINALLY_END: + ADDOP_I(c, POP_FINALLY, preserve_tos); + return 1; + + case FOR_LOOP: + /* Pop the iterator */ + if (preserve_tos) { + ADDOP(c, ROT_TWO); + } + ADDOP(c, POP_TOP); + return 1; + + case EXCEPT: + ADDOP(c, POP_BLOCK); + return 1; + + case FINALLY_TRY: + ADDOP(c, POP_BLOCK); + ADDOP_JREL(c, CALL_FINALLY, info->fb_exit); + return 1; + + case WITH: + case ASYNC_WITH: + ADDOP(c, POP_BLOCK); + if (preserve_tos) { + ADDOP(c, ROT_TWO); + } + ADDOP(c, BEGIN_FINALLY); + ADDOP(c, WITH_CLEANUP_START); + if (info->fb_type == ASYNC_WITH) { + ADDOP(c, GET_AWAITABLE); + ADDOP_LOAD_CONST(c, Py_None); + ADDOP(c, YIELD_FROM); + } + ADDOP(c, WITH_CLEANUP_FINISH); + ADDOP_I(c, POP_FINALLY, 0); + return 1; + + case HANDLER_CLEANUP: + if (preserve_tos) { + ADDOP(c, ROT_FOUR); + } + if (info->fb_exit) { + ADDOP(c, POP_BLOCK); + ADDOP(c, POP_EXCEPT); + ADDOP_JREL(c, CALL_FINALLY, info->fb_exit); + } + else { + ADDOP(c, POP_EXCEPT); + } + return 1; + } + Py_UNREACHABLE(); +} + /* Compile a sequence of statements, checking for a docstring and for annotations. */ @@ -1478,6 +1603,7 @@ compiler_body(struct compiler *c, asdl_seq *stmts) { int i = 0; stmt_ty st; + PyObject *docstring; /* Set current line number to the line number of first statement. This way line number for SETUP_ANNOTATIONS will always @@ -1494,14 +1620,17 @@ compiler_body(struct compiler *c, asdl_seq *stmts) } if (!asdl_seq_LEN(stmts)) return 1; - st = (stmt_ty)asdl_seq_GET(stmts, 0); /* if not -OO mode, set docstring */ - if (compiler_isdocstring(st) && c->c_optimize < 2) { - /* don't generate docstrings if -OO */ - i = 1; - VISIT(c, expr, st->v.Expr.value); - if (!compiler_nameop(c, __doc__, Store)) - return 0; + if (c->c_optimize < 2) { + docstring = _PyAST_GetDocString(stmts); + if (docstring) { + i = 1; + st = (stmt_ty)asdl_seq_GET(stmts, 0); + assert(st->kind == Expr_kind); + VISIT(c, expr, st->v.Expr.value); + if (!compiler_nameop(c, __doc__, Store)) + return 0; + } } for (; i < asdl_seq_LEN(stmts); i++) VISIT(c, stmt, (stmt_ty)asdl_seq_GET(stmts, i)); @@ -1590,12 +1719,8 @@ get_ref_type(struct compiler *c, PyObject *name) static int compiler_lookup_arg(PyObject *dict, PyObject *name) { - PyObject *k, *v; - k = _PyCode_ConstantKey(name); - if (k == NULL) - return -1; - v = PyDict_GetItem(dict, k); - Py_DECREF(k); + PyObject *v; + v = PyDict_GetItem(dict, name); if (v == NULL) return -1; return PyLong_AS_LONG(v); @@ -1643,8 +1768,8 @@ compiler_make_closure(struct compiler *c, PyCodeObject *co, Py_ssize_t flags, Py flags |= 0x08; ADDOP_I(c, BUILD_TUPLE, free); } - ADDOP_O(c, LOAD_CONST, (PyObject*)co, consts); - ADDOP_O(c, LOAD_CONST, qualname, consts); + ADDOP_LOAD_CONST(c, (PyObject*)co); + ADDOP_LOAD_CONST(c, qualname); ADDOP_I(c, MAKE_FUNCTION, flags); return 1; } @@ -1706,10 +1831,7 @@ compiler_visit_kwonlydefaults(struct compiler *c, asdl_seq *kwonlyargs, Py_ssize_t default_count = PyList_GET_SIZE(keys); PyObject *keys_tuple = PyList_AsTuple(keys); Py_DECREF(keys); - if (keys_tuple == NULL) { - return 0; - } - ADDOP_N(c, LOAD_CONST, keys_tuple, consts); + ADDOP_LOAD_CONST_NEW(c, keys_tuple); ADDOP_I(c, BUILD_CONST_KEY_MAP, default_count); assert(default_count > 0); return 1; @@ -1726,12 +1848,7 @@ compiler_visit_kwonlydefaults(struct compiler *c, asdl_seq *kwonlyargs, static int compiler_visit_annexpr(struct compiler *c, expr_ty annotation) { - PyObject *ann_as_str; - ann_as_str = _PyAST_ExprAsUnicode(annotation); - if (!ann_as_str) { - return 0; - } - ADDOP_N(c, LOAD_CONST, ann_as_str, consts); + ADDOP_LOAD_CONST_NEW(c, _PyAST_ExprAsUnicode(annotation)); return 1; } @@ -1818,10 +1935,7 @@ compiler_visit_annotations(struct compiler *c, arguments_ty args, if (len) { PyObject *keytuple = PyList_AsTuple(names); Py_DECREF(names); - if (keytuple == NULL) { - return 0; - } - ADDOP_N(c, LOAD_CONST, keytuple, consts); + ADDOP_LOAD_CONST_NEW(c, keytuple); ADDOP_I(c, BUILD_CONST_KEY_MAP, len); return 1; } @@ -1869,7 +1983,7 @@ static int compiler_function(struct compiler *c, stmt_ty s, int is_async) { PyCodeObject *co; - PyObject *qualname, *first_const = Py_None; + PyObject *qualname, *docstring = NULL; arguments_ty args; expr_ty returns; identifier name; @@ -1923,15 +2037,11 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async) return 0; } - st = (stmt_ty)asdl_seq_GET(body, 0); - docstring = compiler_isdocstring(st); - if (docstring && c->c_optimize < 2) { - if (st->v.Expr.value->kind == Constant_kind) - first_const = st->v.Expr.value->v.Constant.value; - else - first_const = st->v.Expr.value->v.Str.s; + /* if not -OO mode, add docstring */ + if (c->c_optimize < 2) { + docstring = _PyAST_GetDocString(body); } - if (compiler_add_o(c, c->u->u_consts, first_const) < 0) { + if (compiler_add_const(c, docstring ? docstring : Py_None) < 0) { compiler_exit_scope(c); return 0; } @@ -2010,7 +2120,7 @@ compiler_class(struct compiler *c, stmt_ty s) } Py_DECREF(str); assert(c->u->u_qualname); - ADDOP_O(c, LOAD_CONST, c->u->u_qualname, consts); + ADDOP_LOAD_CONST(c, c->u->u_qualname); str = PyUnicode_InternFromString("__qualname__"); if (!str || !compiler_nameop(c, str, Store)) { Py_XDECREF(str); @@ -2052,7 +2162,7 @@ compiler_class(struct compiler *c, stmt_ty s) else { /* No methods referenced __class__, so just return None */ assert(PyDict_GET_SIZE(c->u->u_cellvars) == 0); - ADDOP_O(c, LOAD_CONST, Py_None, consts); + ADDOP_LOAD_CONST(c, Py_None); } ADDOP_IN_SCOPE(c, RETURN_VALUE); /* create the code object */ @@ -2071,7 +2181,7 @@ compiler_class(struct compiler *c, stmt_ty s) Py_DECREF(co); /* 4. load class name */ - ADDOP_O(c, LOAD_CONST, s->v.ClassDef.name, consts); + ADDOP_LOAD_CONST(c, s->v.ClassDef.name); /* 5. generate the rest of the code for the call */ if (!compiler_call_helper(c, 2, @@ -2264,7 +2374,7 @@ compiler_lambda(struct compiler *c, expr_ty e) /* Make None the first constant, so the lambda can't have a docstring. */ - if (compiler_add_o(c, c->u->u_consts, Py_None) < 0) + if (compiler_add_const(c, Py_None) < 0) return 0; c->u->u_argcount = asdl_seq_LEN(args->args); @@ -2340,9 +2450,10 @@ compiler_for(struct compiler *c, stmt_ty s) end = compiler_new_block(c); if (start == NULL || end == NULL || cleanup == NULL) return 0; - ADDOP_JREL(c, SETUP_LOOP, end); - if (!compiler_push_fblock(c, LOOP, start)) + + if (!compiler_push_fblock(c, FOR_LOOP, start, end)) return 0; + VISIT(c, expr, s->v.For.iter); ADDOP(c, GET_ITER); compiler_use_next_block(c, start); @@ -2351,8 +2462,9 @@ compiler_for(struct compiler *c, stmt_ty s) VISIT_SEQ(c, stmt, s->v.For.body); ADDOP_JABS(c, JUMP_ABSOLUTE, start); compiler_use_next_block(c, cleanup); - ADDOP(c, POP_BLOCK); - compiler_pop_fblock(c, LOOP, start); + + compiler_pop_fblock(c, FOR_LOOP, start); + VISIT_SEQ(c, stmt, s->v.For.orelse); compiler_use_next_block(c, end); return 1; @@ -2362,76 +2474,44 @@ compiler_for(struct compiler *c, stmt_ty s) static int compiler_async_for(struct compiler *c, stmt_ty s) { - _Py_IDENTIFIER(StopAsyncIteration); - - basicblock *try, *except, *end, *after_try, *try_cleanup, - *after_loop_else; - + basicblock *start, *except, *end; if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION) { return compiler_error(c, "'async for' outside async function"); } - PyObject *stop_aiter_error = _PyUnicode_FromId(&PyId_StopAsyncIteration); - if (stop_aiter_error == NULL) { - return 0; - } - - try = compiler_new_block(c); + start = compiler_new_block(c); except = compiler_new_block(c); end = compiler_new_block(c); - after_try = compiler_new_block(c); - try_cleanup = compiler_new_block(c); - after_loop_else = compiler_new_block(c); - if (try == NULL || except == NULL || end == NULL - || after_try == NULL || try_cleanup == NULL - || after_loop_else == NULL) - return 0; - - ADDOP_JREL(c, SETUP_LOOP, end); - if (!compiler_push_fblock(c, LOOP, try)) + if (start == NULL || except == NULL || end == NULL) return 0; VISIT(c, expr, s->v.AsyncFor.iter); ADDOP(c, GET_AITER); - compiler_use_next_block(c, try); - - - ADDOP_JREL(c, SETUP_EXCEPT, except); - if (!compiler_push_fblock(c, EXCEPT, try)) + compiler_use_next_block(c, start); + if (!compiler_push_fblock(c, FOR_LOOP, start, end)) return 0; + /* SETUP_FINALLY to guard the __anext__ call */ + ADDOP_JREL(c, SETUP_FINALLY, except); ADDOP(c, GET_ANEXT); - ADDOP_O(c, LOAD_CONST, Py_None, consts); + ADDOP_LOAD_CONST(c, Py_None); ADDOP(c, YIELD_FROM); + ADDOP(c, POP_BLOCK); /* for SETUP_FINALLY */ + + /* Success block for __anext__ */ VISIT(c, expr, s->v.AsyncFor.target); - ADDOP(c, POP_BLOCK); - compiler_pop_fblock(c, EXCEPT, try); - ADDOP_JREL(c, JUMP_FORWARD, after_try); + VISIT_SEQ(c, stmt, s->v.AsyncFor.body); + ADDOP_JABS(c, JUMP_ABSOLUTE, start); + compiler_pop_fblock(c, FOR_LOOP, start); + /* Except block for __anext__ */ compiler_use_next_block(c, except); - ADDOP(c, DUP_TOP); - ADDOP_O(c, LOAD_GLOBAL, stop_aiter_error, names); - ADDOP_I(c, COMPARE_OP, PyCmp_EXC_MATCH); - ADDOP_JABS(c, POP_JUMP_IF_TRUE, try_cleanup); - ADDOP(c, END_FINALLY); - - compiler_use_next_block(c, after_try); - VISIT_SEQ(c, stmt, s->v.AsyncFor.body); - ADDOP_JABS(c, JUMP_ABSOLUTE, try); - - compiler_use_next_block(c, try_cleanup); - ADDOP(c, POP_TOP); - ADDOP(c, POP_TOP); - ADDOP(c, POP_TOP); - ADDOP(c, POP_EXCEPT); /* for SETUP_EXCEPT */ - ADDOP(c, POP_TOP); /* for correct calculation of stack effect */ - ADDOP(c, POP_BLOCK); /* for SETUP_LOOP */ - compiler_pop_fblock(c, LOOP, try); + ADDOP(c, END_ASYNC_FOR); - compiler_use_next_block(c, after_loop_else); + /* `else` block */ VISIT_SEQ(c, stmt, s->v.For.orelse); compiler_use_next_block(c, end); @@ -2467,9 +2547,8 @@ compiler_while(struct compiler *c, stmt_ty s) else orelse = NULL; - ADDOP_JREL(c, SETUP_LOOP, end); compiler_use_next_block(c, loop); - if (!compiler_push_fblock(c, LOOP, loop)) + if (!compiler_push_fblock(c, WHILE_LOOP, loop, end)) return 0; if (constant == -1) { if (!compiler_jump_if(c, s->v.While.test, anchor, 0)) @@ -2484,8 +2563,8 @@ compiler_while(struct compiler *c, stmt_ty s) if (constant == -1) compiler_use_next_block(c, anchor); - ADDOP(c, POP_BLOCK); - compiler_pop_fblock(c, LOOP, loop); + compiler_pop_fblock(c, WHILE_LOOP, loop); + if (orelse != NULL) /* what if orelse is just pass? */ VISIT_SEQ(c, stmt, s->v.While.orelse); compiler_use_next_block(c, end); @@ -2494,46 +2573,79 @@ compiler_while(struct compiler *c, stmt_ty s) } static int -compiler_continue(struct compiler *c) +compiler_return(struct compiler *c, stmt_ty s) { - static const char LOOP_ERROR_MSG[] = "'continue' not properly in loop"; - static const char IN_FINALLY_ERROR_MSG[] = - "'continue' not supported inside 'finally' clause"; - int i; + int preserve_tos = ((s->v.Return.value != NULL) && + !is_const(s->v.Return.value)); + if (c->u->u_ste->ste_type != FunctionBlock) + return compiler_error(c, "'return' outside function"); + if (s->v.Return.value != NULL && + c->u->u_ste->ste_coroutine && c->u->u_ste->ste_generator) + { + return compiler_error( + c, "'return' with value in async generator"); + } + if (preserve_tos) { + VISIT(c, expr, s->v.Return.value); + } + for (int depth = c->u->u_nfblocks; depth--;) { + struct fblockinfo *info = &c->u->u_fblock[depth]; - if (!c->u->u_nfblocks) - return compiler_error(c, LOOP_ERROR_MSG); - i = c->u->u_nfblocks - 1; - switch (c->u->u_fblock[i].fb_type) { - case LOOP: - ADDOP_JABS(c, JUMP_ABSOLUTE, c->u->u_fblock[i].fb_block); - break; - case EXCEPT: - case FINALLY_TRY: - while (--i >= 0 && c->u->u_fblock[i].fb_type != LOOP) { - /* Prevent continue anywhere under a finally - even if hidden in a sub-try or except. */ - if (c->u->u_fblock[i].fb_type == FINALLY_END) - return compiler_error(c, IN_FINALLY_ERROR_MSG); - } - if (i == -1) - return compiler_error(c, LOOP_ERROR_MSG); - ADDOP_JABS(c, CONTINUE_LOOP, c->u->u_fblock[i].fb_block); - break; - case FINALLY_END: - return compiler_error(c, IN_FINALLY_ERROR_MSG); + if (!compiler_unwind_fblock(c, info, preserve_tos)) + return 0; } + if (s->v.Return.value == NULL) { + ADDOP_LOAD_CONST(c, Py_None); + } + else if (!preserve_tos) { + VISIT(c, expr, s->v.Return.value); + } + ADDOP(c, RETURN_VALUE); return 1; } +static int +compiler_break(struct compiler *c) +{ + for (int depth = c->u->u_nfblocks; depth--;) { + struct fblockinfo *info = &c->u->u_fblock[depth]; + + if (!compiler_unwind_fblock(c, info, 0)) + return 0; + if (info->fb_type == WHILE_LOOP || info->fb_type == FOR_LOOP) { + ADDOP_JABS(c, JUMP_ABSOLUTE, info->fb_exit); + return 1; + } + } + return compiler_error(c, "'break' outside loop"); +} + +static int +compiler_continue(struct compiler *c) +{ + for (int depth = c->u->u_nfblocks; depth--;) { + struct fblockinfo *info = &c->u->u_fblock[depth]; + + if (info->fb_type == WHILE_LOOP || info->fb_type == FOR_LOOP) { + ADDOP_JABS(c, JUMP_ABSOLUTE, info->fb_block); + return 1; + } + if (!compiler_unwind_fblock(c, info, 0)) + return 0; + } + return compiler_error(c, "'continue' not properly in loop"); +} + + /* Code generated for "try: <body> finally: <finalbody>" is as follows: SETUP_FINALLY L <code for body> POP_BLOCK - LOAD_CONST <None> - L: <code for finalbody> + BEGIN_FINALLY + L: + <code for finalbody> END_FINALLY The special instructions use the block stack. Each block @@ -2545,33 +2657,34 @@ compiler_continue(struct compiler *c) Pushes the current value stack level and the label onto the block stack. POP_BLOCK: - Pops en entry from the block stack, and pops the value - stack until its level is the same as indicated on the - block stack. (The label is ignored.) + Pops en entry from the block stack. + BEGIN_FINALLY + Pushes NULL onto the value stack. END_FINALLY: - Pops a variable number of entries from the *value* stack - and re-raises the exception they specify. The number of - entries popped depends on the (pseudo) exception type. + Pops 1 (NULL or int) or 6 entries from the *value* stack and restore + the raised and the caught exceptions they specify. The block stack is unwound when an exception is raised: - when a SETUP_FINALLY entry is found, the exception is pushed - onto the value stack (and the exception condition is cleared), - and the interpreter jumps to the label gotten from the block - stack. + when a SETUP_FINALLY entry is found, the raised and the caught + exceptions are pushed onto the value stack (and the exception + condition is cleared), and the interpreter jumps to the label + gotten from the block stack. */ static int compiler_try_finally(struct compiler *c, stmt_ty s) { basicblock *body, *end; + body = compiler_new_block(c); end = compiler_new_block(c); if (body == NULL || end == NULL) return 0; + /* `try` block */ ADDOP_JREL(c, SETUP_FINALLY, end); compiler_use_next_block(c, body); - if (!compiler_push_fblock(c, FINALLY_TRY, body)) + if (!compiler_push_fblock(c, FINALLY_TRY, body, end)) return 0; if (s->v.Try.handlers && asdl_seq_LEN(s->v.Try.handlers)) { if (!compiler_try_except(c, s)) @@ -2581,16 +2694,16 @@ compiler_try_finally(struct compiler *c, stmt_ty s) VISIT_SEQ(c, stmt, s->v.Try.body); } ADDOP(c, POP_BLOCK); + ADDOP(c, BEGIN_FINALLY); compiler_pop_fblock(c, FINALLY_TRY, body); - ADDOP_O(c, LOAD_CONST, Py_None, consts); + /* `finally` block */ compiler_use_next_block(c, end); - if (!compiler_push_fblock(c, FINALLY_END, end)) + if (!compiler_push_fblock(c, FINALLY_END, end, NULL)) return 0; VISIT_SEQ(c, stmt, s->v.Try.finalbody); ADDOP(c, END_FINALLY); compiler_pop_fblock(c, FINALLY_END, end); - return 1; } @@ -2601,7 +2714,7 @@ compiler_try_finally(struct compiler *c, stmt_ty s) associated value, and 'exc' the exception.) Value stack Label Instruction Argument - [] SETUP_EXCEPT L1 + [] SETUP_FINALLY L1 [] <code for S> [] POP_BLOCK [] JUMP_FORWARD L0 @@ -2637,9 +2750,9 @@ compiler_try_except(struct compiler *c, stmt_ty s) end = compiler_new_block(c); if (body == NULL || except == NULL || orelse == NULL || end == NULL) return 0; - ADDOP_JREL(c, SETUP_EXCEPT, except); + ADDOP_JREL(c, SETUP_FINALLY, except); compiler_use_next_block(c, body); - if (!compiler_push_fblock(c, EXCEPT, body)) + if (!compiler_push_fblock(c, EXCEPT, body, NULL)) return 0; VISIT_SEQ(c, stmt, s->v.Try.body); ADDOP(c, POP_BLOCK); @@ -2690,25 +2803,23 @@ compiler_try_except(struct compiler *c, stmt_ty s) /* second try: */ ADDOP_JREL(c, SETUP_FINALLY, cleanup_end); compiler_use_next_block(c, cleanup_body); - if (!compiler_push_fblock(c, FINALLY_TRY, cleanup_body)) + if (!compiler_push_fblock(c, HANDLER_CLEANUP, cleanup_body, cleanup_end)) return 0; /* second # body */ VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body); ADDOP(c, POP_BLOCK); - compiler_pop_fblock(c, FINALLY_TRY, cleanup_body); + ADDOP(c, BEGIN_FINALLY); + compiler_pop_fblock(c, HANDLER_CLEANUP, cleanup_body); /* finally: */ - ADDOP_O(c, LOAD_CONST, Py_None, consts); compiler_use_next_block(c, cleanup_end); - if (!compiler_push_fblock(c, FINALLY_END, cleanup_end)) + if (!compiler_push_fblock(c, FINALLY_END, cleanup_end, NULL)) return 0; - /* name = None */ - ADDOP_O(c, LOAD_CONST, Py_None, consts); + /* name = None; del name */ + ADDOP_LOAD_CONST(c, Py_None); compiler_nameop(c, handler->v.ExceptHandler.name, Store); - - /* del name */ compiler_nameop(c, handler->v.ExceptHandler.name, Del); ADDOP(c, END_FINALLY); @@ -2725,11 +2836,11 @@ compiler_try_except(struct compiler *c, stmt_ty s) ADDOP(c, POP_TOP); ADDOP(c, POP_TOP); compiler_use_next_block(c, cleanup_body); - if (!compiler_push_fblock(c, FINALLY_TRY, cleanup_body)) + if (!compiler_push_fblock(c, HANDLER_CLEANUP, cleanup_body, NULL)) return 0; VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body); ADDOP(c, POP_EXCEPT); - compiler_pop_fblock(c, FINALLY_TRY, cleanup_body); + compiler_pop_fblock(c, HANDLER_CLEANUP, cleanup_body); } ADDOP_JREL(c, JUMP_FORWARD, end); compiler_use_next_block(c, except); @@ -2806,8 +2917,8 @@ compiler_import(struct compiler *c, stmt_ty s) alias_ty alias = (alias_ty)asdl_seq_GET(s->v.Import.names, i); int r; - ADDOP_O(c, LOAD_CONST, _PyLong_Zero, consts); - ADDOP_O(c, LOAD_CONST, Py_None, consts); + ADDOP_LOAD_CONST(c, _PyLong_Zero); + ADDOP_LOAD_CONST(c, Py_None); ADDOP_NAME(c, IMPORT_NAME, alias->name, names); if (alias->asname) { @@ -2839,7 +2950,7 @@ static int compiler_from_import(struct compiler *c, stmt_ty s) { Py_ssize_t i, n = asdl_seq_LEN(s->v.ImportFrom.names); - PyObject *level, *names; + PyObject *names; static PyObject *empty_string; if (!empty_string) { @@ -2848,11 +2959,7 @@ compiler_from_import(struct compiler *c, stmt_ty s) return 0; } - level = PyLong_FromLong(s->v.ImportFrom.level); - if (!level) { - return 0; - } - ADDOP_N(c, LOAD_CONST, level, consts); + ADDOP_LOAD_CONST_NEW(c, PyLong_FromLong(s->v.ImportFrom.level)); names = PyTuple_New(n); if (!names) @@ -2871,7 +2978,7 @@ compiler_from_import(struct compiler *c, stmt_ty s) return compiler_error(c, "from __future__ imports must occur " "at the beginning of the file"); } - ADDOP_N(c, LOAD_CONST, names, consts); + ADDOP_LOAD_CONST_NEW(c, names); if (s->v.ImportFrom.module) { ADDOP_NAME(c, IMPORT_NAME, s->v.ImportFrom.module, names); @@ -2981,18 +3088,7 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s) case ClassDef_kind: return compiler_class(c, s); case Return_kind: - if (c->u->u_ste->ste_type != FunctionBlock) - return compiler_error(c, "'return' outside function"); - if (s->v.Return.value) { - if (c->u->u_ste->ste_coroutine && c->u->u_ste->ste_generator) - return compiler_error( - c, "'return' with value in async generator"); - VISIT(c, expr, s->v.Return.value); - } - else - ADDOP_O(c, LOAD_CONST, Py_None, consts); - ADDOP(c, RETURN_VALUE); - break; + return compiler_return(c, s); case Delete_kind: VISIT_SEQ(c, expr, s->v.Delete.targets) break; @@ -3044,10 +3140,7 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s) case Pass_kind: break; case Break_kind: - if (!compiler_in_loop(c)) - return compiler_error(c, "'break' outside loop"); - ADDOP(c, BREAK_LOOP); - break; + return compiler_break(c); case Continue_kind: return compiler_continue(c); case With_kind: @@ -3441,7 +3534,7 @@ compiler_subdict(struct compiler *c, expr_ty e, Py_ssize_t begin, Py_ssize_t end Py_INCREF(key); PyTuple_SET_ITEM(keys, i - begin, key); } - ADDOP_N(c, LOAD_CONST, keys, consts); + ADDOP_LOAD_CONST_NEW(c, keys); ADDOP_I(c, BUILD_CONST_KEY_MAP, n); } else { @@ -3651,14 +3744,14 @@ compiler_subkwargs(struct compiler *c, asdl_seq *keywords, Py_ssize_t begin, Py_ Py_INCREF(key); PyTuple_SET_ITEM(keys, i - begin, key); } - ADDOP_N(c, LOAD_CONST, keys, consts); + ADDOP_LOAD_CONST_NEW(c, keys); ADDOP_I(c, BUILD_CONST_KEY_MAP, n); } else { /* a for loop only executes once */ for (i = begin; i < end; i++) { kw = asdl_seq_GET(keywords, i); - ADDOP_O(c, LOAD_CONST, kw->arg, consts); + ADDOP_LOAD_CONST(c, kw->arg); VISIT(c, expr, kw->value); } ADDOP_I(c, BUILD_MAP, n); @@ -3768,7 +3861,7 @@ compiler_call_helper(struct compiler *c, Py_INCREF(kw->arg); PyTuple_SET_ITEM(names, i, kw->arg); } - ADDOP_N(c, LOAD_CONST, names, consts); + ADDOP_LOAD_CONST_NEW(c, names); ADDOP_I(c, CALL_FUNCTION_KW, n + nelts + nkwelts); return 1; } @@ -3787,8 +3880,6 @@ compiler_call_helper(struct compiler *c, The LC/SC version returns the populated container, while the GE version is flagged in symtable.c as a generator, so it returns the generator object when the function is called. - This code *knows* that the loop cannot contain break, continue, or return, - so it cheats and skips the SETUP_LOOP/POP_BLOCK steps used in normal loops. Possible cleanups: - iterate over the generator sequence instead of using recursion @@ -3906,27 +3997,14 @@ compiler_async_comprehension_generator(struct compiler *c, asdl_seq *generators, int gen_index, expr_ty elt, expr_ty val, int type) { - _Py_IDENTIFIER(StopAsyncIteration); - comprehension_ty gen; - basicblock *if_cleanup, *try, - *after_try, *except, *try_cleanup; + basicblock *start, *if_cleanup, *except; Py_ssize_t i, n; - - PyObject *stop_aiter_error = _PyUnicode_FromId(&PyId_StopAsyncIteration); - if (stop_aiter_error == NULL) { - return 0; - } - - try = compiler_new_block(c); - after_try = compiler_new_block(c); + start = compiler_new_block(c); except = compiler_new_block(c); if_cleanup = compiler_new_block(c); - try_cleanup = compiler_new_block(c); - if (if_cleanup == NULL || - try == NULL || after_try == NULL || - except == NULL || try_cleanup == NULL) { + if (start == NULL || if_cleanup == NULL || except == NULL) { return 0; } @@ -3943,30 +4021,14 @@ compiler_async_comprehension_generator(struct compiler *c, ADDOP(c, GET_AITER); } - compiler_use_next_block(c, try); - - - ADDOP_JREL(c, SETUP_EXCEPT, except); - if (!compiler_push_fblock(c, EXCEPT, try)) - return 0; + compiler_use_next_block(c, start); + ADDOP_JREL(c, SETUP_FINALLY, except); ADDOP(c, GET_ANEXT); - ADDOP_O(c, LOAD_CONST, Py_None, consts); + ADDOP_LOAD_CONST(c, Py_None); ADDOP(c, YIELD_FROM); - VISIT(c, expr, gen->target); ADDOP(c, POP_BLOCK); - compiler_pop_fblock(c, EXCEPT, try); - ADDOP_JREL(c, JUMP_FORWARD, after_try); - - - compiler_use_next_block(c, except); - ADDOP(c, DUP_TOP); - ADDOP_O(c, LOAD_GLOBAL, stop_aiter_error, names); - ADDOP_I(c, COMPARE_OP, PyCmp_EXC_MATCH); - ADDOP_JABS(c, POP_JUMP_IF_TRUE, try_cleanup); - ADDOP(c, END_FINALLY); - - compiler_use_next_block(c, after_try); + VISIT(c, expr, gen->target); n = asdl_seq_LEN(gen->ifs); for (i = 0; i < n; i++) { @@ -4011,14 +4073,10 @@ compiler_async_comprehension_generator(struct compiler *c, } } compiler_use_next_block(c, if_cleanup); - ADDOP_JABS(c, JUMP_ABSOLUTE, try); + ADDOP_JABS(c, JUMP_ABSOLUTE, start); - compiler_use_next_block(c, try_cleanup); - ADDOP(c, POP_TOP); - ADDOP(c, POP_TOP); - ADDOP(c, POP_TOP); - ADDOP(c, POP_EXCEPT); /* for SETUP_EXCEPT */ - ADDOP(c, POP_TOP); + compiler_use_next_block(c, except); + ADDOP(c, END_ASYNC_FOR); return 1; } @@ -4107,7 +4165,7 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type, if (is_async_generator && type != COMP_GENEXP) { ADDOP(c, GET_AWAITABLE); - ADDOP_O(c, LOAD_CONST, Py_None, consts); + ADDOP_LOAD_CONST(c, Py_None); ADDOP(c, YIELD_FROM); } @@ -4125,7 +4183,7 @@ compiler_genexp(struct compiler *c, expr_ty e) { static identifier name; if (!name) { - name = PyUnicode_FromString("<genexpr>"); + name = PyUnicode_InternFromString("<genexpr>"); if (!name) return 0; } @@ -4140,7 +4198,7 @@ compiler_listcomp(struct compiler *c, expr_ty e) { static identifier name; if (!name) { - name = PyUnicode_FromString("<listcomp>"); + name = PyUnicode_InternFromString("<listcomp>"); if (!name) return 0; } @@ -4155,7 +4213,7 @@ compiler_setcomp(struct compiler *c, expr_ty e) { static identifier name; if (!name) { - name = PyUnicode_FromString("<setcomp>"); + name = PyUnicode_InternFromString("<setcomp>"); if (!name) return 0; } @@ -4171,7 +4229,7 @@ compiler_dictcomp(struct compiler *c, expr_ty e) { static identifier name; if (!name) { - name = PyUnicode_FromString("<dictcomp>"); + name = PyUnicode_InternFromString("<dictcomp>"); if (!name) return 0; } @@ -4250,14 +4308,14 @@ compiler_async_with(struct compiler *c, stmt_ty s, int pos) ADDOP(c, BEFORE_ASYNC_WITH); ADDOP(c, GET_AWAITABLE); - ADDOP_O(c, LOAD_CONST, Py_None, consts); + ADDOP_LOAD_CONST(c, Py_None); ADDOP(c, YIELD_FROM); ADDOP_JREL(c, SETUP_ASYNC_WITH, finally); /* SETUP_ASYNC_WITH pushes a finally block. */ compiler_use_next_block(c, block); - if (!compiler_push_fblock(c, FINALLY_TRY, block)) { + if (!compiler_push_fblock(c, ASYNC_WITH, block, finally)) { return 0; } @@ -4278,11 +4336,11 @@ compiler_async_with(struct compiler *c, stmt_ty s, int pos) /* End of try block; start the finally block */ ADDOP(c, POP_BLOCK); - compiler_pop_fblock(c, FINALLY_TRY, block); + ADDOP(c, BEGIN_FINALLY); + compiler_pop_fblock(c, ASYNC_WITH, block); - ADDOP_O(c, LOAD_CONST, Py_None, consts); compiler_use_next_block(c, finally); - if (!compiler_push_fblock(c, FINALLY_END, finally)) + if (!compiler_push_fblock(c, FINALLY_END, finally, NULL)) return 0; /* Finally block starts; context.__exit__ is on the stack under @@ -4291,7 +4349,7 @@ compiler_async_with(struct compiler *c, stmt_ty s, int pos) ADDOP(c, WITH_CLEANUP_START); ADDOP(c, GET_AWAITABLE); - ADDOP_O(c, LOAD_CONST, Py_None, consts); + ADDOP_LOAD_CONST(c, Py_None); ADDOP(c, YIELD_FROM); ADDOP(c, WITH_CLEANUP_FINISH); @@ -4345,7 +4403,7 @@ compiler_with(struct compiler *c, stmt_ty s, int pos) /* SETUP_WITH pushes a finally block. */ compiler_use_next_block(c, block); - if (!compiler_push_fblock(c, FINALLY_TRY, block)) { + if (!compiler_push_fblock(c, WITH, block, finally)) { return 0; } @@ -4366,11 +4424,11 @@ compiler_with(struct compiler *c, stmt_ty s, int pos) /* End of try block; start the finally block */ ADDOP(c, POP_BLOCK); - compiler_pop_fblock(c, FINALLY_TRY, block); + ADDOP(c, BEGIN_FINALLY); + compiler_pop_fblock(c, WITH, block); - ADDOP_O(c, LOAD_CONST, Py_None, consts); compiler_use_next_block(c, finally); - if (!compiler_push_fblock(c, FINALLY_END, finally)) + if (!compiler_push_fblock(c, FINALLY_END, finally, NULL)) return 0; /* Finally block starts; context.__exit__ is on the stack under @@ -4432,7 +4490,7 @@ compiler_visit_expr(struct compiler *c, expr_ty e) VISIT(c, expr, e->v.Yield.value); } else { - ADDOP_O(c, LOAD_CONST, Py_None, consts); + ADDOP_LOAD_CONST(c, Py_None); } ADDOP(c, YIELD_VALUE); break; @@ -4445,7 +4503,7 @@ compiler_visit_expr(struct compiler *c, expr_ty e) VISIT(c, expr, e->v.YieldFrom.value); ADDOP(c, GET_YIELD_FROM_ITER); - ADDOP_O(c, LOAD_CONST, Py_None, consts); + ADDOP_LOAD_CONST(c, Py_None); ADDOP(c, YIELD_FROM); break; case Await_kind: @@ -4458,7 +4516,7 @@ compiler_visit_expr(struct compiler *c, expr_ty e) VISIT(c, expr, e->v.Await.value); ADDOP(c, GET_AWAITABLE); - ADDOP_O(c, LOAD_CONST, Py_None, consts); + ADDOP_LOAD_CONST(c, Py_None); ADDOP(c, YIELD_FROM); break; case Compare_kind: @@ -4466,26 +4524,26 @@ compiler_visit_expr(struct compiler *c, expr_ty e) case Call_kind: return compiler_call(c, e); case Constant_kind: - ADDOP_O(c, LOAD_CONST, e->v.Constant.value, consts); + ADDOP_LOAD_CONST(c, e->v.Constant.value); break; case Num_kind: - ADDOP_O(c, LOAD_CONST, e->v.Num.n, consts); + ADDOP_LOAD_CONST(c, e->v.Num.n); break; case Str_kind: - ADDOP_O(c, LOAD_CONST, e->v.Str.s, consts); + ADDOP_LOAD_CONST(c, e->v.Str.s); break; case JoinedStr_kind: return compiler_joined_str(c, e); case FormattedValue_kind: return compiler_formatted_value(c, e); case Bytes_kind: - ADDOP_O(c, LOAD_CONST, e->v.Bytes.s, consts); + ADDOP_LOAD_CONST(c, e->v.Bytes.s); break; case Ellipsis_kind: - ADDOP_O(c, LOAD_CONST, Py_Ellipsis, consts); + ADDOP_LOAD_CONST(c, Py_Ellipsis); break; case NameConstant_kind: - ADDOP_O(c, LOAD_CONST, e->v.NameConstant.value, consts); + ADDOP_LOAD_CONST(c, e->v.NameConstant.value); break; /* The following exprs can be assignment targets. */ case Attribute_kind: @@ -4722,10 +4780,7 @@ compiler_annassign(struct compiler *c, stmt_ty s) } ADDOP_NAME(c, LOAD_NAME, __annotations__, names); mangled = _Py_Mangle(c->u->u_private, targ->v.Name.id); - if (!mangled) { - return 0; - } - ADDOP_N(c, LOAD_CONST, mangled, consts); + ADDOP_LOAD_CONST_NEW(c, mangled); ADDOP(c, STORE_SUBSCR); } break; @@ -4755,41 +4810,6 @@ compiler_annassign(struct compiler *c, stmt_ty s) return 1; } -static int -compiler_push_fblock(struct compiler *c, enum fblocktype t, basicblock *b) -{ - struct fblockinfo *f; - if (c->u->u_nfblocks >= CO_MAXBLOCKS) { - PyErr_SetString(PyExc_SyntaxError, - "too many statically nested blocks"); - return 0; - } - f = &c->u->u_fblock[c->u->u_nfblocks++]; - f->fb_type = t; - f->fb_block = b; - return 1; -} - -static void -compiler_pop_fblock(struct compiler *c, enum fblocktype t, basicblock *b) -{ - struct compiler_unit *u = c->u; - assert(u->u_nfblocks > 0); - u->u_nfblocks--; - assert(u->u_fblock[u->u_nfblocks].fb_type == t); - assert(u->u_fblock[u->u_nfblocks].fb_block == b); -} - -static int -compiler_in_loop(struct compiler *c) { - int i; - struct compiler_unit *u = c->u; - for (i = 0; i < u->u_nfblocks; ++i) { - if (u->u_fblock[i].fb_type == LOOP) - return 1; - } - return 0; -} /* Raises a SyntaxError and returns 0. If something goes wrong, a different exception may be raised. */ @@ -4860,14 +4880,14 @@ compiler_slice(struct compiler *c, slice_ty s, expr_context_ty ctx) VISIT(c, expr, s->v.Slice.lower); } else { - ADDOP_O(c, LOAD_CONST, Py_None, consts); + ADDOP_LOAD_CONST(c, Py_None); } if (s->v.Slice.upper) { VISIT(c, expr, s->v.Slice.upper); } else { - ADDOP_O(c, LOAD_CONST, Py_None, consts); + ADDOP_LOAD_CONST(c, Py_None); } if (s->v.Slice.step) { @@ -4984,9 +5004,7 @@ dfs(struct compiler *c, basicblock *b, struct assembler *a, int end) Py_LOCAL_INLINE(void) stackdepth_push(basicblock ***sp, basicblock *b, int depth) { - /* XXX b->b_startdepth > depth only for the target of SETUP_FINALLY, - * SETUP_WITH and SETUP_ASYNC_WITH. */ - assert(b->b_startdepth < 0 || b->b_startdepth >= depth); + assert(b->b_startdepth < 0 || b->b_startdepth == depth); if (b->b_startdepth < depth) { assert(b->b_startdepth < 0); b->b_startdepth = depth; @@ -5043,15 +5061,11 @@ stackdepth(struct compiler *c) maxdepth = target_depth; } assert(target_depth >= 0); /* invalid code or bug in stackdepth() */ - if (instr->i_opcode == CONTINUE_LOOP) { - /* Pops a variable number of values from the stack, - * but the target should be already proceeding. - */ + if (instr->i_opcode == CALL_FINALLY) { assert(instr->i_target->b_startdepth >= 0); - assert(instr->i_target->b_startdepth <= depth); - /* remaining code is dead */ - next = NULL; - break; + assert(instr->i_target->b_startdepth >= target_depth); + depth = new_depth; + continue; } stackdepth_push(&sp, instr->i_target, target_depth); } @@ -5059,8 +5073,7 @@ stackdepth(struct compiler *c) if (instr->i_opcode == JUMP_ABSOLUTE || instr->i_opcode == JUMP_FORWARD || instr->i_opcode == RETURN_VALUE || - instr->i_opcode == RAISE_VARARGS || - instr->i_opcode == BREAK_LOOP) + instr->i_opcode == RAISE_VARARGS) { /* remaining code is dead */ next = NULL; @@ -5324,10 +5337,6 @@ dict_keys_inorder(PyObject *dict, Py_ssize_t offset) return NULL; while (PyDict_Next(dict, &pos, &k, &v)) { i = PyLong_AS_LONG(v); - /* The keys of the dictionary are tuples. (see compiler_add_o - * and _PyCode_ConstantKey). The object we want is always second, - * though. */ - k = PyTuple_GET_ITEM(k, 1); Py_INCREF(k); assert((i - offset) < size); assert((i - offset) >= 0); @@ -5336,6 +5345,31 @@ dict_keys_inorder(PyObject *dict, Py_ssize_t offset) return tuple; } +static PyObject * +consts_dict_keys_inorder(PyObject *dict) +{ + PyObject *consts, *k, *v; + Py_ssize_t i, pos = 0, size = PyDict_GET_SIZE(dict); + + consts = PyList_New(size); /* PyCode_Optimize() requires a list */ + if (consts == NULL) + return NULL; + while (PyDict_Next(dict, &pos, &k, &v)) { + i = PyLong_AS_LONG(v); + /* The keys of the dictionary can be tuples wrapping a contant. + * (see compiler_add_o and _PyCode_ConstantKey). In that case + * the object we want is always second. */ + if (PyTuple_CheckExact(k)) { + k = PyTuple_GET_ITEM(k, 1); + } + Py_INCREF(k); + assert(i < size); + assert(i >= 0); + PyList_SET_ITEM(consts, i, k); + } + return consts; +} + static int compute_code_flags(struct compiler *c) { @@ -5380,12 +5414,7 @@ makecode(struct compiler *c, struct assembler *a) int flags; int argcount, kwonlyargcount, maxdepth; - tmp = dict_keys_inorder(c->u->u_consts, 0); - if (!tmp) - goto error; - consts = PySequence_List(tmp); /* optimize_code requires a list */ - Py_DECREF(tmp); - + consts = consts_dict_keys_inorder(c->u->u_consts); names = dict_keys_inorder(c->u->u_names, 0); varnames = dict_keys_inorder(c->u->u_varnames, 0); if (!consts || !names || !varnames) @@ -5394,7 +5423,7 @@ makecode(struct compiler *c, struct assembler *a) cellvars = dict_keys_inorder(c->u->u_cellvars, 0); if (!cellvars) goto error; - freevars = dict_keys_inorder(c->u->u_freevars, PyTuple_Size(cellvars)); + freevars = dict_keys_inorder(c->u->u_freevars, PyTuple_GET_SIZE(cellvars)); if (!freevars) goto error; @@ -5490,7 +5519,7 @@ assemble(struct compiler *c, int addNone) if (!c->u->u_curblock->b_return) { NEXT_BLOCK(c); if (addNone) - ADDOP_O(c, LOAD_CONST, Py_None, consts); + ADDOP_LOAD_CONST(c, Py_None); ADDOP(c, RETURN_VALUE); } diff --git a/Python/context.c b/Python/context.c index b727748ee73987..8ee048ccdd5c59 100644 --- a/Python/context.c +++ b/Python/context.c @@ -940,6 +940,10 @@ contextvar_cls_getitem(PyObject *self, PyObject *args) Py_RETURN_NONE; } +static PyMemberDef PyContextVar_members[] = { + {"name", T_OBJECT, offsetof(PyContextVar, var_name), READONLY}, + {NULL} +}; static PyMethodDef PyContextVar_methods[] = { _CONTEXTVARS_CONTEXTVAR_GET_METHODDEF @@ -955,6 +959,7 @@ PyTypeObject PyContextVar_Type = { "ContextVar", sizeof(PyContextVar), .tp_methods = PyContextVar_methods, + .tp_members = PyContextVar_members, .tp_dealloc = (destructor)contextvar_tp_dealloc, .tp_getattro = PyObject_GenericGetAttr, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, diff --git a/Python/errors.c b/Python/errors.c index 15e6ba05714337..98910b44908764 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -947,7 +947,7 @@ PyErr_WriteUnraisable(PyObject *obj) _Py_IDENTIFIER(__module__); PyObject *f, *t, *v, *tb; PyObject *moduleName = NULL; - char* className; + const char *className; PyErr_Fetch(&t, &v, &tb); @@ -977,7 +977,7 @@ PyErr_WriteUnraisable(PyObject *obj) assert(PyExceptionClass_Check(t)); className = PyExceptionClass_Name(t); if (className != NULL) { - char *dot = strrchr(className, '.'); + const char *dot = strrchr(className, '.'); if (dot != NULL) className = dot+1; } diff --git a/Python/future.c b/Python/future.c index 03a97c865a82f8..1d10204d71d258 100644 --- a/Python/future.c +++ b/Python/future.c @@ -5,6 +5,7 @@ #include "graminit.h" #include "code.h" #include "symtable.h" +#include "ast.h" #define UNDEFINED_FUTURE_FEATURE "future feature %.100s is not defined" #define ERR_LATE_FUTURE \ @@ -80,11 +81,7 @@ future_parse(PyFutureFeatures *ff, mod_ty mod, PyObject *filename) */ i = 0; - first = (stmt_ty)asdl_seq_GET(mod->v.Module.body, i); - if (first->kind == Expr_kind - && (first->v.Expr.value->kind == Str_kind - || (first->v.Expr.value->kind == Constant_kind - && PyUnicode_CheckExact(first->v.Expr.value->v.Constant.value)))) + if (_PyAST_GetDocString(mod->v.Module.body) != NULL) i++; for (; i < asdl_seq_LEN(mod->v.Module.body); i++) { diff --git a/Python/hamt.c b/Python/hamt.c index f8bce5961afc61..562f777ea0bf86 100644 --- a/Python/hamt.c +++ b/Python/hamt.c @@ -2348,7 +2348,7 @@ _PyHamt_Without(PyHamtObject *o, PyObject *key) return NULL; } - PyHamtNode *new_root; + PyHamtNode *new_root = NULL; hamt_without_t res = hamt_node_without( (PyHamtNode *)(o->h_root), diff --git a/Python/import.c b/Python/import.c index 70384b188f2eca..939aa436432caf 100644 --- a/Python/import.c +++ b/Python/import.c @@ -92,7 +92,7 @@ _PyImportHooks_Init(void) _PyInitError _PyImportZip_Init(void) { - PyObject *path_hooks, *zimpimport; + PyObject *path_hooks, *zipimport; int err = 0; path_hooks = PySys_GetObject("path_hooks"); @@ -104,17 +104,17 @@ _PyImportZip_Init(void) if (Py_VerboseFlag) PySys_WriteStderr("# installing zipimport hook\n"); - zimpimport = PyImport_ImportModule("zipimport"); - if (zimpimport == NULL) { + zipimport = PyImport_ImportModule("zipimport"); + if (zipimport == NULL) { PyErr_Clear(); /* No zip import module -- okay */ if (Py_VerboseFlag) PySys_WriteStderr("# can't import zipimport\n"); } else { _Py_IDENTIFIER(zipimporter); - PyObject *zipimporter = _PyObject_GetAttrId(zimpimport, + PyObject *zipimporter = _PyObject_GetAttrId(zipimport, &PyId_zipimporter); - Py_DECREF(zimpimport); + Py_DECREF(zipimport); if (zipimporter == NULL) { PyErr_Clear(); /* No zipimporter object -- okay */ if (Py_VerboseFlag) @@ -417,14 +417,14 @@ PyImport_Cleanup(void) if (Py_VerboseFlag) PySys_WriteStderr("# clear builtins._\n"); if (PyDict_SetItemString(interp->builtins, "_", Py_None) < 0) { - PyErr_Clear(); + PyErr_WriteUnraisable(NULL); } for (p = sys_deletes; *p != NULL; p++) { if (Py_VerboseFlag) PySys_WriteStderr("# clear sys.%s\n", *p); if (PyDict_SetItemString(interp->sysdict, *p, Py_None) < 0) { - PyErr_Clear(); + PyErr_WriteUnraisable(NULL); } } for (p = sys_files; *p != NULL; p+=2) { @@ -434,7 +434,7 @@ PyImport_Cleanup(void) if (value == NULL) value = Py_None; if (PyDict_SetItemString(interp->sysdict, *p, value) < 0) { - PyErr_Clear(); + PyErr_WriteUnraisable(NULL); } } @@ -443,8 +443,9 @@ PyImport_Cleanup(void) for diagnosis messages (in verbose mode), while the weakref helps detect those modules which have been held alive. */ weaklist = PyList_New(0); - if (weaklist == NULL) - PyErr_Clear(); + if (weaklist == NULL) { + PyErr_WriteUnraisable(NULL); + } #define STORE_MODULE_WEAKREF(name, mod) \ if (weaklist != NULL) { \ @@ -452,13 +453,13 @@ PyImport_Cleanup(void) if (wr) { \ PyObject *tup = PyTuple_Pack(2, name, wr); \ if (!tup || PyList_Append(weaklist, tup) < 0) { \ - PyErr_Clear(); \ + PyErr_WriteUnraisable(NULL); \ } \ Py_XDECREF(tup); \ Py_DECREF(wr); \ } \ else { \ - PyErr_Clear(); \ + PyErr_WriteUnraisable(NULL); \ } \ } #define CLEAR_MODULE(name, mod) \ @@ -467,7 +468,7 @@ PyImport_Cleanup(void) PySys_FormatStderr("# cleanup[2] removing %U\n", name); \ STORE_MODULE_WEAKREF(name, mod); \ if (PyObject_SetItem(modules, name, Py_None) < 0) { \ - PyErr_Clear(); \ + PyErr_WriteUnraisable(NULL); \ } \ } @@ -482,13 +483,13 @@ PyImport_Cleanup(void) else { PyObject *iterator = PyObject_GetIter(modules); if (iterator == NULL) { - PyErr_Clear(); + PyErr_WriteUnraisable(NULL); } else { while ((key = PyIter_Next(iterator))) { value = PyObject_GetItem(modules, key); if (value == NULL) { - PyErr_Clear(); + PyErr_WriteUnraisable(NULL); continue; } CLEAR_MODULE(key, value); @@ -496,7 +497,7 @@ PyImport_Cleanup(void) Py_DECREF(key); } if (PyErr_Occurred()) { - PyErr_Clear(); + PyErr_WriteUnraisable(NULL); } Py_DECREF(iterator); } @@ -508,17 +509,20 @@ PyImport_Cleanup(void) } else { _Py_IDENTIFIER(clear); - if (_PyObject_CallMethodId(modules, &PyId_clear, "") == NULL) - PyErr_Clear(); + if (_PyObject_CallMethodId(modules, &PyId_clear, "") == NULL) { + PyErr_WriteUnraisable(NULL); + } } /* Restore the original builtins dict, to ensure that any user data gets cleared. */ dict = PyDict_Copy(interp->builtins); - if (dict == NULL) - PyErr_Clear(); + if (dict == NULL) { + PyErr_WriteUnraisable(NULL); + } PyDict_Clear(interp->builtins); - if (PyDict_Update(interp->builtins, interp->builtins_copy)) + if (PyDict_Update(interp->builtins, interp->builtins_copy)) { PyErr_Clear(); + } Py_XDECREF(dict); /* Clear module dict copies stored in the interpreter state */ _PyState_ClearModules(); @@ -1826,10 +1830,21 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals, } } else { - final_mod = _PyObject_CallMethodIdObjArgs(interp->importlib, - &PyId__handle_fromlist, mod, - fromlist, interp->import_func, - NULL); + _Py_IDENTIFIER(__path__); + PyObject *path; + if (_PyObject_LookupAttrId(mod, &PyId___path__, &path) < 0) { + goto error; + } + if (path) { + Py_DECREF(path); + final_mod = _PyObject_CallMethodIdObjArgs( + interp->importlib, &PyId__handle_fromlist, + mod, fromlist, interp->import_func, NULL); + } + else { + final_mod = mod; + Py_INCREF(mod); + } } error: diff --git a/Python/importlib.h b/Python/importlib.h index 0a92e69f62d236..1e45cb2518c69b 100644 --- a/Python/importlib.h +++ b/Python/importlib.h @@ -53,97 +53,97 @@ const unsigned char _Py_M__importlib[] = { 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,78,99,2,0,0,0,0,0,0,0,3,0, - 0,0,7,0,0,0,67,0,0,0,115,60,0,0,0,120, - 40,100,1,68,0,93,32,125,2,116,0,124,1,124,2,131, - 2,114,6,116,1,124,0,124,2,116,2,124,1,124,2,131, - 2,131,3,1,0,113,6,87,0,124,0,106,3,160,4,124, - 1,106,3,161,1,1,0,100,2,83,0,41,3,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,41,4, - 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,218,7,114,101,112,108,97, - 99,101,169,0,114,10,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,5,95,119,114,97,112,27, - 0,0,0,115,8,0,0,0,0,2,10,1,10,1,22,1, - 114,12,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,12,0,0,0,116, - 0,116,1,131,1,124,0,131,1,83,0,41,1,78,41,2, - 218,4,116,121,112,101,218,3,115,121,115,41,1,218,4,110, - 97,109,101,114,10,0,0,0,114,10,0,0,0,114,11,0, - 0,0,218,11,95,110,101,119,95,109,111,100,117,108,101,35, - 0,0,0,115,2,0,0,0,0,1,114,16,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,12,0,0,0,101,0,90,1,100,0,90, - 2,100,1,83,0,41,2,218,14,95,68,101,97,100,108,111, - 99,107,69,114,114,111,114,78,41,3,114,1,0,0,0,114, - 0,0,0,0,114,2,0,0,0,114,10,0,0,0,114,10, - 0,0,0,114,10,0,0,0,114,11,0,0,0,114,17,0, - 0,0,48,0,0,0,115,2,0,0,0,8,1,114,17,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,56,0,0,0,101,0,90,1, - 100,0,90,2,100,1,90,3,100,2,100,3,132,0,90,4, - 100,4,100,5,132,0,90,5,100,6,100,7,132,0,90,6, - 100,8,100,9,132,0,90,7,100,10,100,11,132,0,90,8, - 100,12,83,0,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,48,0,0,0,116,0,160,1,161,0,124,0, - 95,2,116,0,160,1,161,0,124,0,95,3,124,1,124,0, - 95,4,100,0,124,0,95,5,100,1,124,0,95,6,100,1, - 124,0,95,7,100,0,83,0,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,15,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,218,4,115,101,108,102,114,15,0,0, - 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, - 218,8,95,95,105,110,105,116,95,95,58,0,0,0,115,12, - 0,0,0,0,1,10,1,10,1,6,1,6,1,6,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,3,0,0,0,67,0,0,0,115,64,0,0,0,116, - 0,160,1,161,0,125,1,124,0,106,2,125,2,120,44,116, - 3,160,4,124,2,161,1,125,3,124,3,100,0,107,8,114, - 38,100,1,83,0,124,3,106,2,125,2,124,2,124,1,107, - 2,114,16,100,2,83,0,113,16,87,0,100,0,83,0,41, - 3,78,70,84,41,5,114,20,0,0,0,218,9,103,101,116, - 95,105,100,101,110,116,114,23,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,26,0,0,0,90,2,109,101,218,3,116,105,100,114,21, - 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, - 0,0,218,12,104,97,115,95,100,101,97,100,108,111,99,107, - 66,0,0,0,115,18,0,0,0,0,2,8,1,6,1,2, - 1,10,1,8,1,4,1,6,1,8,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,9,0,0,0,67,0,0,0,115,168,0,0,0,116, - 0,160,1,161,0,125,1,124,0,116,2,124,1,60,0,122, - 138,120,132,124,0,106,3,143,96,1,0,124,0,106,4,100, - 1,107,2,115,48,124,0,106,5,124,1,107,2,114,72,124, - 1,124,0,95,5,124,0,4,0,106,4,100,2,55,0,2, - 0,95,4,100,3,83,0,124,0,160,6,161,0,114,92,116, - 7,100,4,124,0,22,0,131,1,130,1,124,0,106,8,160, - 9,100,5,161,1,114,118,124,0,4,0,106,10,100,2,55, - 0,2,0,95,10,87,0,100,6,81,0,82,0,88,0,124, - 0,106,8,160,9,161,0,1,0,124,0,106,8,160,11,161, - 0,1,0,113,20,87,0,87,0,100,6,116,2,124,1,61, + 0,0,7,0,0,0,67,0,0,0,115,56,0,0,0,100, + 1,68,0,93,32,125,2,116,0,124,1,124,2,131,2,114, + 4,116,1,124,0,124,2,116,2,124,1,124,2,131,2,131, + 3,1,0,113,4,124,0,106,3,160,4,124,1,106,3,161, + 1,1,0,100,2,83,0,41,3,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,41,4,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,218,7,114,101,112,108,97,99,101,169,0, + 114,10,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,5,95,119,114,97,112,27,0,0,0,115, + 8,0,0,0,0,2,8,1,10,1,20,1,114,12,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,12,0,0,0,116,0,116,1,131, + 1,124,0,131,1,83,0,41,1,78,41,2,218,4,116,121, + 112,101,218,3,115,121,115,41,1,218,4,110,97,109,101,114, + 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,11, + 95,110,101,119,95,109,111,100,117,108,101,35,0,0,0,115, + 2,0,0,0,0,1,114,16,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,12,0,0,0,101,0,90,1,100,0,90,2,100,1,83, + 0,41,2,218,14,95,68,101,97,100,108,111,99,107,69,114, + 114,111,114,78,41,3,114,1,0,0,0,114,0,0,0,0, + 114,2,0,0,0,114,10,0,0,0,114,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,114,17,0,0,0,48,0, + 0,0,115,2,0,0,0,8,1,114,17,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,56,0,0,0,101,0,90,1,100,0,90,2, + 100,1,90,3,100,2,100,3,132,0,90,4,100,4,100,5, + 132,0,90,5,100,6,100,7,132,0,90,6,100,8,100,9, + 132,0,90,7,100,10,100,11,132,0,90,8,100,12,83,0, + 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, + 48,0,0,0,116,0,160,1,161,0,124,0,95,2,116,0, + 160,1,161,0,124,0,95,3,124,1,124,0,95,4,100,0, + 124,0,95,5,100,1,124,0,95,6,100,1,124,0,95,7, + 100,0,83,0,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,15,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,218,4,115,101,108,102,114,15,0,0,0,114,10,0, + 0,0,114,10,0,0,0,114,11,0,0,0,218,8,95,95, + 105,110,105,116,95,95,58,0,0,0,115,12,0,0,0,0, + 1,10,1,10,1,6,1,6,1,6,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,3,0, + 0,0,67,0,0,0,115,60,0,0,0,116,0,160,1,161, + 0,125,1,124,0,106,2,125,2,116,3,160,4,124,2,161, + 1,125,3,124,3,100,0,107,8,114,36,100,1,83,0,124, + 3,106,2,125,2,124,2,124,1,107,2,114,14,100,2,83, + 0,113,14,100,0,83,0,41,3,78,70,84,41,5,114,20, + 0,0,0,218,9,103,101,116,95,105,100,101,110,116,114,23, + 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,26,0,0,0,90,2,109, + 101,218,3,116,105,100,114,21,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,11,0,0,0,218,12,104,97,115,95, + 100,101,97,100,108,111,99,107,66,0,0,0,115,16,0,0, + 0,0,2,8,1,6,2,10,1,8,1,4,1,6,1,8, + 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,9,0,0,0,67,0,0,0, + 115,178,0,0,0,116,0,160,1,161,0,125,1,124,0,116, + 2,124,1,60,0,122,148,124,0,106,3,143,110,1,0,124, + 0,106,4,100,1,107,2,115,46,124,0,106,5,124,1,107, + 2,114,84,124,1,124,0,95,5,124,0,4,0,106,4,100, + 2,55,0,2,0,95,4,87,0,53,0,81,0,82,0,163, + 0,87,0,162,86,100,3,83,0,124,0,160,6,161,0,114, + 104,116,7,100,4,124,0,22,0,131,1,130,1,124,0,106, + 8,160,9,100,5,161,1,114,130,124,0,4,0,106,10,100, + 2,55,0,2,0,95,10,87,0,53,0,81,0,82,0,88, + 0,124,0,106,8,160,9,161,0,1,0,124,0,106,8,160, + 11,161,0,1,0,113,18,87,0,53,0,116,2,124,1,61, 0,88,0,100,6,83,0,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, @@ -165,112 +165,63 @@ const unsigned char _Py_M__importlib[] = { 114,101,114,25,0,0,0,218,7,114,101,108,101,97,115,101, 41,2,114,26,0,0,0,114,31,0,0,0,114,10,0,0, 0,114,10,0,0,0,114,11,0,0,0,114,34,0,0,0, - 78,0,0,0,115,32,0,0,0,0,6,8,1,8,1,2, - 1,2,1,8,1,20,1,6,1,14,1,4,1,8,1,12, - 1,12,1,24,2,10,1,18,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,9,0,0,0,67, - 0,0,0,115,122,0,0,0,116,0,160,1,161,0,125,1, - 124,0,106,2,143,98,1,0,124,0,106,3,124,1,107,3, - 114,34,116,4,100,1,131,1,130,1,124,0,106,5,100,2, - 107,4,115,48,116,6,130,1,124,0,4,0,106,5,100,3, - 56,0,2,0,95,5,124,0,106,5,100,2,107,2,114,108, - 100,0,124,0,95,3,124,0,106,7,114,108,124,0,4,0, - 106,7,100,3,56,0,2,0,95,7,124,0,106,8,160,9, - 161,0,1,0,87,0,100,0,81,0,82,0,88,0,100,0, - 83,0,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,19,0,0,0,114,33,0,0,0, - 41,10,114,20,0,0,0,114,28,0,0,0,114,21,0,0, - 0,114,23,0,0,0,218,12,82,117,110,116,105,109,101,69, - 114,114,111,114,114,24,0,0,0,218,14,65,115,115,101,114, - 116,105,111,110,69,114,114,111,114,114,25,0,0,0,114,22, - 0,0,0,114,35,0,0,0,41,2,114,26,0,0,0,114, - 31,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, - 0,0,0,114,35,0,0,0,103,0,0,0,115,22,0,0, - 0,0,1,8,1,8,1,10,1,8,1,14,1,14,1,10, - 1,6,1,6,1,14,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,5,0,0,0,67,0,0, - 0,115,18,0,0,0,100,1,160,0,124,0,106,1,116,2, - 124,0,131,1,161,2,83,0,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,218,6,102,111,114,109,97,116,114,15, - 0,0,0,218,2,105,100,41,1,114,26,0,0,0,114,10, - 0,0,0,114,10,0,0,0,114,11,0,0,0,218,8,95, - 95,114,101,112,114,95,95,116,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,1,0,0,0, - 114,0,0,0,0,114,2,0,0,0,114,3,0,0,0,114, - 27,0,0,0,114,32,0,0,0,114,34,0,0,0,114,35, - 0,0,0,114,40,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,10,0,0,0,114,11,0,0,0,114,18,0,0, - 0,52,0,0,0,115,12,0,0,0,8,4,4,2,8,8, - 8,12,8,25,8,13,114,18,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,48,0,0,0,101,0,90,1,100,0,90,2,100,1,90, - 3,100,2,100,3,132,0,90,4,100,4,100,5,132,0,90, - 5,100,6,100,7,132,0,90,6,100,8,100,9,132,0,90, - 7,100,10,83,0,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,16,0,0,0,124,1,124,0,95, - 0,100,1,124,0,95,1,100,0,83,0,41,2,78,114,19, - 0,0,0,41,2,114,15,0,0,0,114,24,0,0,0,41, - 2,114,26,0,0,0,114,15,0,0,0,114,10,0,0,0, - 114,10,0,0,0,114,11,0,0,0,114,27,0,0,0,124, - 0,0,0,115,4,0,0,0,0,1,6,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,18,0,0, - 0,124,0,4,0,106,0,100,1,55,0,2,0,95,0,100, - 2,83,0,41,3,78,114,33,0,0,0,84,41,1,114,24, - 0,0,0,41,1,114,26,0,0,0,114,10,0,0,0,114, - 10,0,0,0,114,11,0,0,0,114,34,0,0,0,128,0, - 0,0,115,4,0,0,0,0,1,14,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,36,0,0,0,124, - 0,106,0,100,1,107,2,114,18,116,1,100,2,131,1,130, - 1,124,0,4,0,106,0,100,3,56,0,2,0,95,0,100, - 0,83,0,41,4,78,114,19,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,33,0,0, - 0,41,2,114,24,0,0,0,114,36,0,0,0,41,1,114, - 26,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, - 0,0,0,114,35,0,0,0,132,0,0,0,115,6,0,0, - 0,0,1,10,1,8,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,5,0, - 0,0,67,0,0,0,115,18,0,0,0,100,1,160,0,124, - 0,106,1,116,2,124,0,131,1,161,2,83,0,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,38,0,0,0,114,15,0,0,0,114,39,0,0,0,41, - 1,114,26,0,0,0,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,114,40,0,0,0,137,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,1,0,0,0,114,0,0,0,0,114,2,0, - 0,0,114,3,0,0,0,114,27,0,0,0,114,34,0,0, - 0,114,35,0,0,0,114,40,0,0,0,114,10,0,0,0, - 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, - 41,0,0,0,120,0,0,0,115,10,0,0,0,8,2,4, - 2,8,4,8,4,8,5,114,41,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,36,0,0,0,101,0,90,1,100,0,90,2,100,1, - 100,2,132,0,90,3,100,3,100,4,132,0,90,4,100,5, - 100,6,132,0,90,5,100,7,83,0,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,16,0,0,0,124,1,124,0,95,0, - 100,0,124,0,95,1,100,0,83,0,41,1,78,41,2,218, - 5,95,110,97,109,101,218,5,95,108,111,99,107,41,2,114, + 78,0,0,0,115,30,0,0,0,0,6,8,1,8,1,2, + 2,8,1,20,1,6,1,14,1,18,1,8,1,12,1,12, + 1,24,2,10,1,16,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,9,0,0,0,67,0,0, + 0,115,122,0,0,0,116,0,160,1,161,0,125,1,124,0, + 106,2,143,98,1,0,124,0,106,3,124,1,107,3,114,34, + 116,4,100,1,131,1,130,1,124,0,106,5,100,2,107,4, + 115,48,116,6,130,1,124,0,4,0,106,5,100,3,56,0, + 2,0,95,5,124,0,106,5,100,2,107,2,114,108,100,0, + 124,0,95,3,124,0,106,7,114,108,124,0,4,0,106,7, + 100,3,56,0,2,0,95,7,124,0,106,8,160,9,161,0, + 1,0,87,0,53,0,81,0,82,0,88,0,100,0,83,0, + 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,19,0,0,0,114,33,0,0,0,41,10, + 114,20,0,0,0,114,28,0,0,0,114,21,0,0,0,114, + 23,0,0,0,218,12,82,117,110,116,105,109,101,69,114,114, + 111,114,114,24,0,0,0,218,14,65,115,115,101,114,116,105, + 111,110,69,114,114,111,114,114,25,0,0,0,114,22,0,0, + 0,114,35,0,0,0,41,2,114,26,0,0,0,114,31,0, + 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, + 0,114,35,0,0,0,103,0,0,0,115,22,0,0,0,0, + 1,8,1,8,1,10,1,8,1,14,1,14,1,10,1,6, + 1,6,1,14,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,5,0,0,0,67,0,0,0,115, + 18,0,0,0,100,1,160,0,124,0,106,1,116,2,124,0, + 131,1,161,2,83,0,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,218,6,102,111,114,109,97,116,114,15,0,0, + 0,218,2,105,100,41,1,114,26,0,0,0,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,218,8,95,95,114, + 101,112,114,95,95,116,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,1,0,0,0,114,0, + 0,0,0,114,2,0,0,0,114,3,0,0,0,114,27,0, + 0,0,114,32,0,0,0,114,34,0,0,0,114,35,0,0, + 0,114,40,0,0,0,114,10,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,11,0,0,0,114,18,0,0,0,52, + 0,0,0,115,12,0,0,0,8,4,4,2,8,8,8,12, + 8,25,8,13,114,18,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,48, + 0,0,0,101,0,90,1,100,0,90,2,100,1,90,3,100, + 2,100,3,132,0,90,4,100,4,100,5,132,0,90,5,100, + 6,100,7,132,0,90,6,100,8,100,9,132,0,90,7,100, + 10,83,0,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,16,0,0,0,124,1,124,0,95,0,100, + 1,124,0,95,1,100,0,83,0,41,2,78,114,19,0,0, + 0,41,2,114,15,0,0,0,114,24,0,0,0,41,2,114, 26,0,0,0,114,15,0,0,0,114,10,0,0,0,114,10, 0,0,0,114,11,0,0,0,114,27,0,0,0,143,0,0, 0,115,4,0,0,0,0,1,6,1,122,27,95,77,111,100, @@ -282,1149 +233,1204 @@ const unsigned char _Py_M__importlib[] = { 218,16,95,103,101,116,95,109,111,100,117,108,101,95,108,111, 99,107,114,43,0,0,0,114,44,0,0,0,114,34,0,0, 0,41,1,114,26,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,218,9,95,95,101,110,116,101,114, - 95,95,147,0,0,0,115,4,0,0,0,0,1,12,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,2,0,0,0,79,0, - 0,0,115,14,0,0,0,124,0,106,0,160,1,161,0,1, - 0,100,0,83,0,41,1,78,41,2,114,44,0,0,0,114, - 35,0,0,0,41,3,114,26,0,0,0,218,4,97,114,103, - 115,90,6,107,119,97,114,103,115,114,10,0,0,0,114,10, - 0,0,0,114,11,0,0,0,218,8,95,95,101,120,105,116, - 95,95,151,0,0,0,115,2,0,0,0,0,1,122,27,95, + 0,0,114,11,0,0,0,114,34,0,0,0,128,0,0,0, + 115,4,0,0,0,0,1,14,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,36,0,0,0,124,0,106, + 0,100,1,107,2,114,18,116,1,100,2,131,1,130,1,124, + 0,4,0,106,0,100,3,56,0,2,0,95,0,100,0,83, + 0,41,4,78,114,19,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,33,0,0,0,41, + 2,114,24,0,0,0,114,36,0,0,0,41,1,114,26,0, + 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, + 0,114,35,0,0,0,132,0,0,0,115,6,0,0,0,0, + 1,10,1,8,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,5,0,0,0, + 67,0,0,0,115,18,0,0,0,100,1,160,0,124,0,106, + 1,116,2,124,0,131,1,161,2,83,0,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,38, + 0,0,0,114,15,0,0,0,114,39,0,0,0,41,1,114, + 26,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, + 0,0,0,114,40,0,0,0,137,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,1,0,0,0,114,0,0,0,0,114,2,0,0,0, + 114,3,0,0,0,114,27,0,0,0,114,34,0,0,0,114, + 35,0,0,0,114,40,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,114,41,0, + 0,0,120,0,0,0,115,10,0,0,0,8,2,4,2,8, + 4,8,4,8,5,114,41,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, + 36,0,0,0,101,0,90,1,100,0,90,2,100,1,100,2, + 132,0,90,3,100,3,100,4,132,0,90,4,100,5,100,6, + 132,0,90,5,100,7,83,0,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,16,0,0,0,124,1,124,0,95,0,100,0, + 124,0,95,1,100,0,83,0,41,1,78,41,2,218,5,95, + 110,97,109,101,218,5,95,108,111,99,107,41,2,114,26,0, + 0,0,114,15,0,0,0,114,10,0,0,0,114,10,0,0, + 0,114,11,0,0,0,114,27,0,0,0,143,0,0,0,115, + 4,0,0,0,0,1,6,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,2,0,0,0,67,0,0,0,115,26,0,0,0,116, + 0,124,0,106,1,131,1,124,0,95,2,124,0,106,2,160, + 3,161,0,1,0,100,0,83,0,41,1,78,41,4,218,16, + 95,103,101,116,95,109,111,100,117,108,101,95,108,111,99,107, + 114,43,0,0,0,114,44,0,0,0,114,34,0,0,0,41, + 1,114,26,0,0,0,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,218,9,95,95,101,110,116,101,114,95,95, + 147,0,0,0,115,4,0,0,0,0,1,12,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,120,105,116,95,95,78,41,6,114,1,0, + 114,46,95,95,101,110,116,101,114,95,95,99,1,0,0,0, + 0,0,0,0,3,0,0,0,2,0,0,0,79,0,0,0, + 115,14,0,0,0,124,0,106,0,160,1,161,0,1,0,100, + 0,83,0,41,1,78,41,2,114,44,0,0,0,114,35,0, + 0,0,41,3,114,26,0,0,0,218,4,97,114,103,115,90, + 6,107,119,97,114,103,115,114,10,0,0,0,114,10,0,0, + 0,114,11,0,0,0,218,8,95,95,101,120,105,116,95,95, + 151,0,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,1,0,0,0, + 114,0,0,0,0,114,2,0,0,0,114,27,0,0,0,114, + 46,0,0,0,114,48,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,114,42,0, + 0,0,141,0,0,0,115,6,0,0,0,8,2,8,4,8, + 4,114,42,0,0,0,99,1,0,0,0,0,0,0,0,3, + 0,0,0,8,0,0,0,67,0,0,0,115,130,0,0,0, + 116,0,160,1,161,0,1,0,122,106,122,14,116,2,124,0, + 25,0,131,0,125,1,87,0,110,24,4,0,116,3,107,10, + 114,48,1,0,1,0,1,0,100,1,125,1,89,0,110,2, + 88,0,124,1,100,1,107,8,114,112,116,4,100,1,107,8, + 114,76,116,5,124,0,131,1,125,1,110,8,116,6,124,0, + 131,1,125,1,124,0,102,1,100,2,100,3,132,1,125,2, + 116,7,160,8,124,1,124,2,161,2,116,2,124,0,60,0, + 87,0,53,0,116,0,160,9,161,0,1,0,88,0,124,1, + 83,0,41,4,122,139,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,65,99,113,117,105,114,101,47,114,101,108,101,97,115, + 101,32,105,110,116,101,114,110,97,108,108,121,32,116,104,101, + 32,103,108,111,98,97,108,32,105,109,112,111,114,116,32,108, + 111,99,107,32,116,111,32,112,114,111,116,101,99,116,10,32, + 32,32,32,95,109,111,100,117,108,101,95,108,111,99,107,115, + 46,78,99,2,0,0,0,0,0,0,0,2,0,0,0,8, + 0,0,0,83,0,0,0,115,48,0,0,0,116,0,160,1, + 161,0,1,0,122,24,116,2,160,3,124,1,161,1,124,0, + 107,8,114,30,116,2,124,1,61,0,87,0,53,0,116,0, + 160,4,161,0,1,0,88,0,100,0,83,0,41,1,78,41, + 5,218,4,95,105,109,112,218,12,97,99,113,117,105,114,101, + 95,108,111,99,107,218,13,95,109,111,100,117,108,101,95,108, + 111,99,107,115,114,30,0,0,0,218,12,114,101,108,101,97, + 115,101,95,108,111,99,107,41,2,218,3,114,101,102,114,15, + 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,218,2,99,98,176,0,0,0,115,10,0,0,0,0, + 1,8,1,2,4,14,1,10,2,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,10,114,49,0,0,0,114,50, + 0,0,0,114,51,0,0,0,218,8,75,101,121,69,114,114, + 111,114,114,20,0,0,0,114,41,0,0,0,114,18,0,0, + 0,218,8,95,119,101,97,107,114,101,102,114,53,0,0,0, + 114,52,0,0,0,41,3,114,15,0,0,0,114,21,0,0, + 0,114,54,0,0,0,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,114,45,0,0,0,157,0,0,0,115,28, + 0,0,0,0,6,8,1,2,1,2,1,14,1,14,1,10, + 2,8,1,8,1,10,2,8,2,12,11,20,2,10,2,114, + 45,0,0,0,99,1,0,0,0,0,0,0,0,2,0,0, + 0,8,0,0,0,67,0,0,0,115,54,0,0,0,116,0, + 124,0,131,1,125,1,122,12,124,1,160,1,161,0,1,0, + 87,0,110,20,4,0,116,2,107,10,114,40,1,0,1,0, + 1,0,89,0,110,10,88,0,124,1,160,3,161,0,1,0, + 100,1,83,0,41,2,122,189,65,99,113,117,105,114,101,115, + 32,116,104,101,110,32,114,101,108,101,97,115,101,115,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,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,32,32,32,32,78,41,4,114,45,0,0,0,114,34,0, + 0,0,114,17,0,0,0,114,35,0,0,0,41,2,114,15, + 0,0,0,114,21,0,0,0,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,218,19,95,108,111,99,107,95,117, + 110,108,111,99,107,95,109,111,100,117,108,101,194,0,0,0, + 115,12,0,0,0,0,6,8,1,2,1,12,1,14,3,6, + 2,114,57,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,10,0,0,0, + 124,0,124,1,124,2,142,1,83,0,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, + 10,0,0,0,41,3,218,1,102,114,47,0,0,0,90,4, + 107,119,100,115,114,10,0,0,0,114,10,0,0,0,114,11, + 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,211,0, + 0,0,115,2,0,0,0,0,8,114,59,0,0,0,114,33, + 0,0,0,41,1,218,9,118,101,114,98,111,115,105,116,121, + 99,1,0,0,0,1,0,0,0,3,0,0,0,4,0,0, + 0,71,0,0,0,115,54,0,0,0,116,0,106,1,106,2, + 124,1,107,5,114,50,124,0,160,3,100,1,161,1,115,30, + 100,2,124,0,23,0,125,0,116,4,124,0,106,5,124,2, + 142,0,116,0,106,6,100,3,141,2,1,0,100,4,83,0, + 41,5,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,41,2,250,1,35,122,7,105,109,112,111,114,116,32,122, + 2,35,32,41,1,90,4,102,105,108,101,78,41,7,114,14, + 0,0,0,218,5,102,108,97,103,115,218,7,118,101,114,98, + 111,115,101,218,10,115,116,97,114,116,115,119,105,116,104,218, + 5,112,114,105,110,116,114,38,0,0,0,218,6,115,116,100, + 101,114,114,41,3,218,7,109,101,115,115,97,103,101,114,60, + 0,0,0,114,47,0,0,0,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,218,16,95,118,101,114,98,111,115, + 101,95,109,101,115,115,97,103,101,222,0,0,0,115,8,0, + 0,0,0,2,12,1,10,1,8,1,114,68,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,26,0,0,0,135,0,102,1,100,1,100, + 2,132,8,125,1,116,0,124,1,136,0,131,2,1,0,124, + 1,83,0,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,38,0, + 0,0,124,1,116,0,106,1,107,7,114,28,116,2,100,1, + 160,3,124,1,161,1,124,1,100,2,141,2,130,1,136,0, + 124,0,124,1,131,2,83,0,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,41,1,114,15,0,0, + 0,41,4,114,14,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,218,11, + 73,109,112,111,114,116,69,114,114,111,114,114,38,0,0,0, + 41,2,114,26,0,0,0,218,8,102,117,108,108,110,97,109, + 101,41,1,218,3,102,120,110,114,10,0,0,0,114,11,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,232,0,0, + 0,115,8,0,0,0,0,1,10,1,10,1,8,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,12,0,0,0,41,2,114,72,0, + 0,0,114,73,0,0,0,114,10,0,0,0,41,1,114,72, + 0,0,0,114,11,0,0,0,218,17,95,114,101,113,117,105, + 114,101,115,95,98,117,105,108,116,105,110,230,0,0,0,115, + 6,0,0,0,0,2,12,5,10,1,114,74,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,26,0,0,0,135,0,102,1,100,1,100, + 2,132,8,125,1,116,0,124,1,136,0,131,2,1,0,124, + 1,83,0,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,38,0,0,0, + 116,0,160,1,124,1,161,1,115,28,116,2,100,1,160,3, + 124,1,161,1,124,1,100,2,141,2,130,1,136,0,124,0, + 124,1,131,2,83,0,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,41,1,114,15,0,0,0,41,4,114, + 49,0,0,0,218,9,105,115,95,102,114,111,122,101,110,114, + 70,0,0,0,114,38,0,0,0,41,2,114,26,0,0,0, + 114,71,0,0,0,41,1,114,72,0,0,0,114,10,0,0, + 0,114,11,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, + 243,0,0,0,115,8,0,0,0,0,1,10,1,10,1,8, + 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,12,0,0,0,41,2,114,72, + 0,0,0,114,76,0,0,0,114,10,0,0,0,41,1,114, + 72,0,0,0,114,11,0,0,0,218,16,95,114,101,113,117, + 105,114,101,115,95,102,114,111,122,101,110,241,0,0,0,115, + 6,0,0,0,0,2,12,5,10,1,114,77,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,62,0,0,0,116,0,124,1,124,0,131, + 2,125,2,124,1,116,1,106,2,107,6,114,50,116,1,106, + 2,124,1,25,0,125,3,116,3,124,2,124,3,131,2,1, + 0,116,1,106,2,124,1,25,0,83,0,116,4,124,2,131, + 1,83,0,100,1,83,0,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,14,0,0,0,218,7,109,111,100,117,108,101,115,218,5, + 95,101,120,101,99,218,5,95,108,111,97,100,41,4,114,26, + 0,0,0,114,71,0,0,0,218,4,115,112,101,99,218,6, + 109,111,100,117,108,101,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,218,17,95,108,111,97,100,95,109,111,100, + 117,108,101,95,115,104,105,109,253,0,0,0,115,12,0,0, + 0,0,6,10,1,10,1,10,1,10,1,10,2,114,84,0, + 0,0,99,1,0,0,0,0,0,0,0,5,0,0,0,8, + 0,0,0,67,0,0,0,115,226,0,0,0,116,0,124,0, + 100,1,100,0,131,3,125,1,116,1,124,1,100,2,131,2, + 114,56,122,12,124,1,160,2,124,0,161,1,87,0,83,0, + 4,0,116,3,107,10,114,54,1,0,1,0,1,0,89,0, + 110,2,88,0,122,10,124,0,106,4,125,2,87,0,110,20, + 4,0,116,5,107,10,114,86,1,0,1,0,1,0,89,0, + 110,18,88,0,124,2,100,0,107,9,114,104,116,6,124,2, + 131,1,83,0,122,10,124,0,106,7,125,3,87,0,110,24, + 4,0,116,5,107,10,114,138,1,0,1,0,1,0,100,3, + 125,3,89,0,110,2,88,0,122,10,124,0,106,8,125,4, + 87,0,110,58,4,0,116,5,107,10,114,208,1,0,1,0, + 1,0,124,1,100,0,107,8,114,188,100,4,160,9,124,3, + 161,1,6,0,89,0,83,0,100,5,160,9,124,3,124,1, + 161,2,6,0,89,0,83,0,89,0,110,14,88,0,100,6, + 160,9,124,3,124,4,161,2,83,0,100,0,83,0,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,6,0, + 0,0,114,4,0,0,0,114,86,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,1,0,0,0,218,8, + 95,95,102,105,108,101,95,95,114,38,0,0,0,41,5,114, + 83,0,0,0,218,6,108,111,97,100,101,114,114,82,0,0, + 0,114,15,0,0,0,218,8,102,105,108,101,110,97,109,101, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,218, + 12,95,109,111,100,117,108,101,95,114,101,112,114,13,1,0, + 0,115,46,0,0,0,0,2,12,1,10,4,2,1,12,1, + 14,1,6,1,2,1,10,1,14,1,6,2,8,1,8,4, + 2,1,10,1,14,1,10,1,2,1,10,1,14,1,8,1, + 14,2,22,2,114,95,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,36, + 0,0,0,101,0,90,1,100,0,90,2,100,1,100,2,132, + 0,90,3,100,3,100,4,132,0,90,4,100,5,100,6,132, + 0,90,5,100,7,83,0,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,18,0,0,0,124,1,124,0,95,0,124,1,106,1, + 124,0,95,2,100,0,83,0,41,1,78,41,3,218,7,95, + 109,111,100,117,108,101,114,89,0,0,0,218,5,95,115,112, + 101,99,41,2,114,26,0,0,0,114,83,0,0,0,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,114,27,0, + 0,0,51,1,0,0,115,4,0,0,0,0,1,6,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,28,0,0,0,100,1,124,0,106,0,95,1,124,0,106, + 2,116,3,106,4,124,0,106,0,106,5,60,0,100,0,83, + 0,41,2,78,84,41,6,114,98,0,0,0,218,13,95,105, + 110,105,116,105,97,108,105,122,105,110,103,114,97,0,0,0, + 114,14,0,0,0,114,79,0,0,0,114,15,0,0,0,41, + 1,114,26,0,0,0,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,114,46,0,0,0,55,1,0,0,115,4, + 0,0,0,0,4,8,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,8,0,0,0,71,0,0,0,115,98,0,0,0,122,82, + 124,0,106,0,125,2,116,1,100,1,100,2,132,0,124,1, + 68,0,131,1,131,1,114,64,122,14,116,2,106,3,124,2, + 106,4,61,0,87,0,113,80,4,0,116,5,107,10,114,60, + 1,0,1,0,1,0,89,0,113,80,88,0,110,16,116,6, + 100,3,124,2,106,4,124,2,106,7,131,3,1,0,87,0, + 53,0,100,4,124,0,106,0,95,8,88,0,100,0,83,0, + 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,22,0,0,0,124,0,93, + 14,125,1,124,1,100,0,107,9,86,0,1,0,113,2,100, + 0,83,0,41,1,78,114,10,0,0,0,41,2,90,2,46, + 48,90,3,97,114,103,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,218,9,60,103,101,110,101,120,112,114,62, + 65,1,0,0,115,2,0,0,0,4,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,98,0,0,0,218,3,97,110,121,114,14,0,0,0, + 114,79,0,0,0,114,15,0,0,0,114,55,0,0,0,114, + 68,0,0,0,114,93,0,0,0,114,99,0,0,0,41,3, + 114,26,0,0,0,114,47,0,0,0,114,82,0,0,0,114, + 10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,48, + 0,0,0,62,1,0,0,115,18,0,0,0,0,1,2,1, + 6,1,18,1,2,1,14,1,14,1,8,2,20,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,1,0, 0,0,114,0,0,0,0,114,2,0,0,0,114,27,0,0, 0,114,46,0,0,0,114,48,0,0,0,114,10,0,0,0, 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, - 42,0,0,0,141,0,0,0,115,6,0,0,0,8,2,8, - 4,8,4,114,42,0,0,0,99,1,0,0,0,0,0,0, - 0,3,0,0,0,8,0,0,0,67,0,0,0,115,130,0, - 0,0,116,0,160,1,161,0,1,0,122,106,121,14,116,2, - 124,0,25,0,131,0,125,1,87,0,110,24,4,0,116,3, - 107,10,114,48,1,0,1,0,1,0,100,1,125,1,89,0, - 110,2,88,0,124,1,100,1,107,8,114,112,116,4,100,1, - 107,8,114,76,116,5,124,0,131,1,125,1,110,8,116,6, - 124,0,131,1,125,1,124,0,102,1,100,2,100,3,132,1, - 125,2,116,7,160,8,124,1,124,2,161,2,116,2,124,0, - 60,0,87,0,100,1,116,0,160,9,161,0,1,0,88,0, - 124,1,83,0,41,4,122,139,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,65,99,113,117,105,114,101,47,114,101,108,101, - 97,115,101,32,105,110,116,101,114,110,97,108,108,121,32,116, - 104,101,32,103,108,111,98,97,108,32,105,109,112,111,114,116, - 32,108,111,99,107,32,116,111,32,112,114,111,116,101,99,116, - 10,32,32,32,32,95,109,111,100,117,108,101,95,108,111,99, - 107,115,46,78,99,2,0,0,0,0,0,0,0,2,0,0, - 0,8,0,0,0,83,0,0,0,115,48,0,0,0,116,0, - 160,1,161,0,1,0,122,24,116,2,160,3,124,1,161,1, - 124,0,107,8,114,30,116,2,124,1,61,0,87,0,100,0, - 116,0,160,4,161,0,1,0,88,0,100,0,83,0,41,1, - 78,41,5,218,4,95,105,109,112,218,12,97,99,113,117,105, - 114,101,95,108,111,99,107,218,13,95,109,111,100,117,108,101, - 95,108,111,99,107,115,114,30,0,0,0,218,12,114,101,108, - 101,97,115,101,95,108,111,99,107,41,2,218,3,114,101,102, - 114,15,0,0,0,114,10,0,0,0,114,10,0,0,0,114, - 11,0,0,0,218,2,99,98,176,0,0,0,115,10,0,0, - 0,0,1,8,1,2,4,14,1,10,2,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,10,114,49,0,0,0, - 114,50,0,0,0,114,51,0,0,0,218,8,75,101,121,69, - 114,114,111,114,114,20,0,0,0,114,41,0,0,0,114,18, - 0,0,0,218,8,95,119,101,97,107,114,101,102,114,53,0, - 0,0,114,52,0,0,0,41,3,114,15,0,0,0,114,21, - 0,0,0,114,54,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,114,45,0,0,0,157,0,0,0, - 115,28,0,0,0,0,6,8,1,2,1,2,1,14,1,14, - 1,10,2,8,1,8,1,10,2,8,2,12,11,20,2,10, - 2,114,45,0,0,0,99,1,0,0,0,0,0,0,0,2, - 0,0,0,8,0,0,0,67,0,0,0,115,54,0,0,0, - 116,0,124,0,131,1,125,1,121,12,124,1,160,1,161,0, - 1,0,87,0,110,20,4,0,116,2,107,10,114,40,1,0, - 1,0,1,0,89,0,110,10,88,0,124,1,160,3,161,0, - 1,0,100,1,83,0,41,2,122,189,65,99,113,117,105,114, - 101,115,32,116,104,101,110,32,114,101,108,101,97,115,101,115, - 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,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,32,32,32,32,78,41,4,114,45,0,0,0,114, - 34,0,0,0,114,17,0,0,0,114,35,0,0,0,41,2, - 114,15,0,0,0,114,21,0,0,0,114,10,0,0,0,114, - 10,0,0,0,114,11,0,0,0,218,19,95,108,111,99,107, - 95,117,110,108,111,99,107,95,109,111,100,117,108,101,194,0, - 0,0,115,12,0,0,0,0,6,8,1,2,1,12,1,14, - 3,6,2,114,57,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,10,0, - 0,0,124,0,124,1,124,2,142,1,83,0,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,10,0,0,0,41,3,218,1,102,114,47,0,0,0, - 90,4,107,119,100,115,114,10,0,0,0,114,10,0,0,0, - 114,11,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, - 211,0,0,0,115,2,0,0,0,0,8,114,59,0,0,0, - 114,33,0,0,0,41,1,218,9,118,101,114,98,111,115,105, - 116,121,99,1,0,0,0,1,0,0,0,3,0,0,0,4, - 0,0,0,71,0,0,0,115,54,0,0,0,116,0,106,1, - 106,2,124,1,107,5,114,50,124,0,160,3,100,1,161,1, - 115,30,100,2,124,0,23,0,125,0,116,4,124,0,106,5, - 124,2,142,0,116,0,106,6,100,3,141,2,1,0,100,4, - 83,0,41,5,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,41,2,250,1,35,122,7,105,109,112,111,114,116, - 32,122,2,35,32,41,1,90,4,102,105,108,101,78,41,7, - 114,14,0,0,0,218,5,102,108,97,103,115,218,7,118,101, - 114,98,111,115,101,218,10,115,116,97,114,116,115,119,105,116, - 104,218,5,112,114,105,110,116,114,38,0,0,0,218,6,115, - 116,100,101,114,114,41,3,218,7,109,101,115,115,97,103,101, - 114,60,0,0,0,114,47,0,0,0,114,10,0,0,0,114, - 10,0,0,0,114,11,0,0,0,218,16,95,118,101,114,98, - 111,115,101,95,109,101,115,115,97,103,101,222,0,0,0,115, - 8,0,0,0,0,2,12,1,10,1,8,1,114,68,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,26,0,0,0,135,0,102,1,100, - 1,100,2,132,8,125,1,116,0,124,1,136,0,131,2,1, - 0,124,1,83,0,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, - 38,0,0,0,124,1,116,0,106,1,107,7,114,28,116,2, - 100,1,160,3,124,1,161,1,124,1,100,2,141,2,130,1, - 136,0,124,0,124,1,131,2,83,0,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,41,1,114,15, - 0,0,0,41,4,114,14,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, - 218,11,73,109,112,111,114,116,69,114,114,111,114,114,38,0, - 0,0,41,2,114,26,0,0,0,218,8,102,117,108,108,110, - 97,109,101,41,1,218,3,102,120,110,114,10,0,0,0,114, - 11,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,232, - 0,0,0,115,8,0,0,0,0,1,10,1,10,1,8,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,12,0,0,0,41,2,114, - 72,0,0,0,114,73,0,0,0,114,10,0,0,0,41,1, - 114,72,0,0,0,114,11,0,0,0,218,17,95,114,101,113, - 117,105,114,101,115,95,98,117,105,108,116,105,110,230,0,0, - 0,115,6,0,0,0,0,2,12,5,10,1,114,74,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,26,0,0,0,135,0,102,1,100, - 1,100,2,132,8,125,1,116,0,124,1,136,0,131,2,1, - 0,124,1,83,0,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,38,0, - 0,0,116,0,160,1,124,1,161,1,115,28,116,2,100,1, - 160,3,124,1,161,1,124,1,100,2,141,2,130,1,136,0, - 124,0,124,1,131,2,83,0,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,41,1,114,15,0,0,0,41, - 4,114,49,0,0,0,218,9,105,115,95,102,114,111,122,101, - 110,114,70,0,0,0,114,38,0,0,0,41,2,114,26,0, - 0,0,114,71,0,0,0,41,1,114,72,0,0,0,114,10, - 0,0,0,114,11,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,243,0,0,0,115,8,0,0,0,0,1,10,1,10, - 1,8,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,12,0,0,0,41,2, - 114,72,0,0,0,114,76,0,0,0,114,10,0,0,0,41, - 1,114,72,0,0,0,114,11,0,0,0,218,16,95,114,101, - 113,117,105,114,101,115,95,102,114,111,122,101,110,241,0,0, - 0,115,6,0,0,0,0,2,12,5,10,1,114,77,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,62,0,0,0,116,0,124,1,124, - 0,131,2,125,2,124,1,116,1,106,2,107,6,114,50,116, - 1,106,2,124,1,25,0,125,3,116,3,124,2,124,3,131, - 2,1,0,116,1,106,2,124,1,25,0,83,0,116,4,124, - 2,131,1,83,0,100,1,83,0,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,14,0,0,0,218,7,109,111,100,117,108,101,115, - 218,5,95,101,120,101,99,218,5,95,108,111,97,100,41,4, - 114,26,0,0,0,114,71,0,0,0,218,4,115,112,101,99, - 218,6,109,111,100,117,108,101,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,218,17,95,108,111,97,100,95,109, - 111,100,117,108,101,95,115,104,105,109,253,0,0,0,115,12, - 0,0,0,0,6,10,1,10,1,10,1,10,1,10,2,114, - 84,0,0,0,99,1,0,0,0,0,0,0,0,5,0,0, - 0,8,0,0,0,67,0,0,0,115,216,0,0,0,116,0, - 124,0,100,1,100,0,131,3,125,1,116,1,124,1,100,2, - 131,2,114,54,121,10,124,1,160,2,124,0,161,1,83,0, - 4,0,116,3,107,10,114,52,1,0,1,0,1,0,89,0, - 110,2,88,0,121,10,124,0,106,4,125,2,87,0,110,20, - 4,0,116,5,107,10,114,84,1,0,1,0,1,0,89,0, - 110,18,88,0,124,2,100,0,107,9,114,102,116,6,124,2, - 131,1,83,0,121,10,124,0,106,7,125,3,87,0,110,24, - 4,0,116,5,107,10,114,136,1,0,1,0,1,0,100,3, - 125,3,89,0,110,2,88,0,121,10,124,0,106,8,125,4, - 87,0,110,50,4,0,116,5,107,10,114,198,1,0,1,0, - 1,0,124,1,100,0,107,8,114,182,100,4,160,9,124,3, - 161,1,83,0,100,5,160,9,124,3,124,1,161,2,83,0, - 89,0,110,14,88,0,100,6,160,9,124,3,124,4,161,2, - 83,0,100,0,83,0,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,6,0,0,0,114,4,0,0,0,114, - 86,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,1,0,0,0,218,8,95,95,102,105,108,101,95,95, - 114,38,0,0,0,41,5,114,83,0,0,0,218,6,108,111, - 97,100,101,114,114,82,0,0,0,114,15,0,0,0,218,8, - 102,105,108,101,110,97,109,101,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,218,12,95,109,111,100,117,108,101, - 95,114,101,112,114,13,1,0,0,115,46,0,0,0,0,2, - 12,1,10,4,2,1,10,1,14,1,6,1,2,1,10,1, - 14,1,6,2,8,1,8,4,2,1,10,1,14,1,10,1, - 2,1,10,1,14,1,8,1,10,2,18,2,114,95,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,36,0,0,0,101,0,90,1,100, - 0,90,2,100,1,100,2,132,0,90,3,100,3,100,4,132, - 0,90,4,100,5,100,6,132,0,90,5,100,7,83,0,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,18,0,0,0,124,1, - 124,0,95,0,124,1,106,1,124,0,95,2,100,0,83,0, - 41,1,78,41,3,218,7,95,109,111,100,117,108,101,114,89, - 0,0,0,218,5,95,115,112,101,99,41,2,114,26,0,0, - 0,114,83,0,0,0,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,114,27,0,0,0,51,1,0,0,115,4, - 0,0,0,0,1,6,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,28,0,0,0,100,1,124, - 0,106,0,95,1,124,0,106,2,116,3,106,4,124,0,106, - 0,106,5,60,0,100,0,83,0,41,2,78,84,41,6,114, - 98,0,0,0,218,13,95,105,110,105,116,105,97,108,105,122, - 105,110,103,114,97,0,0,0,114,14,0,0,0,114,79,0, - 0,0,114,15,0,0,0,41,1,114,26,0,0,0,114,10, - 0,0,0,114,10,0,0,0,114,11,0,0,0,114,46,0, - 0,0,55,1,0,0,115,4,0,0,0,0,4,8,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,8,0,0,0,71,0,0, - 0,115,98,0,0,0,122,82,124,0,106,0,125,2,116,1, - 100,1,100,2,132,0,124,1,68,0,131,1,131,1,114,64, - 121,14,116,2,106,3,124,2,106,4,61,0,87,0,113,80, - 4,0,116,5,107,10,114,60,1,0,1,0,1,0,89,0, - 113,80,88,0,110,16,116,6,100,3,124,2,106,4,124,2, - 106,7,131,3,1,0,87,0,100,0,100,4,124,0,106,0, - 95,8,88,0,100,0,83,0,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,22,0,0,0,124,0,93,14,125,1,124,1,100,0,107, - 9,86,0,1,0,113,2,100,0,83,0,41,1,78,114,10, - 0,0,0,41,2,90,2,46,48,90,3,97,114,103,114,10, - 0,0,0,114,10,0,0,0,114,11,0,0,0,250,9,60, - 103,101,110,101,120,112,114,62,65,1,0,0,115,2,0,0, - 0,4,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,98,0,0,0,218,3, - 97,110,121,114,14,0,0,0,114,79,0,0,0,114,15,0, - 0,0,114,55,0,0,0,114,68,0,0,0,114,93,0,0, - 0,114,99,0,0,0,41,3,114,26,0,0,0,114,47,0, - 0,0,114,82,0,0,0,114,10,0,0,0,114,10,0,0, - 0,114,11,0,0,0,114,48,0,0,0,62,1,0,0,115, - 18,0,0,0,0,1,2,1,6,1,18,1,2,1,14,1, - 14,1,8,2,20,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,1,0,0,0,114,0,0,0,0,114, - 2,0,0,0,114,27,0,0,0,114,46,0,0,0,114,48, - 0,0,0,114,10,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,114,96,0,0,0,49,1,0,0, - 115,6,0,0,0,8,2,8,4,8,7,114,96,0,0,0, - 99,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0, - 0,64,0,0,0,115,114,0,0,0,101,0,90,1,100,0, - 90,2,100,1,90,3,100,2,100,2,100,2,100,3,156,3, - 100,4,100,5,132,2,90,4,100,6,100,7,132,0,90,5, - 100,8,100,9,132,0,90,6,101,7,100,10,100,11,132,0, - 131,1,90,8,101,8,106,9,100,12,100,11,132,0,131,1, - 90,8,101,7,100,13,100,14,132,0,131,1,90,10,101,7, - 100,15,100,16,132,0,131,1,90,11,101,11,106,9,100,17, - 100,16,132,0,131,1,90,11,100,2,83,0,41,18,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,78, - 41,3,218,6,111,114,105,103,105,110,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,54,0,0,0,124,1, - 124,0,95,0,124,2,124,0,95,1,124,3,124,0,95,2, - 124,4,124,0,95,3,124,5,114,32,103,0,110,2,100,0, - 124,0,95,4,100,1,124,0,95,5,100,0,124,0,95,6, - 100,0,83,0,41,2,78,70,41,7,114,15,0,0,0,114, - 93,0,0,0,114,103,0,0,0,114,104,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,26,0,0,0,114,15,0,0,0,114,93, - 0,0,0,114,103,0,0,0,114,104,0,0,0,114,105,0, - 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, - 0,114,27,0,0,0,113,1,0,0,115,14,0,0,0,0, - 2,6,1,6,1,6,1,6,1,14,3,6,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,6, - 0,0,0,67,0,0,0,115,102,0,0,0,100,1,160,0, - 124,0,106,1,161,1,100,2,160,0,124,0,106,2,161,1, - 103,2,125,1,124,0,106,3,100,0,107,9,114,52,124,1, - 160,4,100,3,160,0,124,0,106,3,161,1,161,1,1,0, - 124,0,106,5,100,0,107,9,114,80,124,1,160,4,100,4, - 160,0,124,0,106,5,161,1,161,1,1,0,100,5,160,0, - 124,0,106,6,106,7,100,6,160,8,124,1,161,1,161,2, - 83,0,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,38,0,0,0,114,15,0,0, - 0,114,93,0,0,0,114,103,0,0,0,218,6,97,112,112, - 101,110,100,114,106,0,0,0,218,9,95,95,99,108,97,115, - 115,95,95,114,1,0,0,0,218,4,106,111,105,110,41,2, - 114,26,0,0,0,114,47,0,0,0,114,10,0,0,0,114, - 10,0,0,0,114,11,0,0,0,114,40,0,0,0,125,1, - 0,0,115,16,0,0,0,0,1,10,1,14,1,10,1,18, - 1,10,1,8,1,10,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,8,0,0,0,67,0,0, - 0,115,102,0,0,0,124,0,106,0,125,2,121,70,124,0, - 106,1,124,1,106,1,107,2,111,76,124,0,106,2,124,1, - 106,2,107,2,111,76,124,0,106,3,124,1,106,3,107,2, - 111,76,124,2,124,1,106,0,107,2,111,76,124,0,106,4, - 124,1,106,4,107,2,111,76,124,0,106,5,124,1,106,5, - 107,2,83,0,4,0,116,6,107,10,114,96,1,0,1,0, - 1,0,100,1,83,0,88,0,100,0,83,0,41,2,78,70, - 41,7,114,106,0,0,0,114,15,0,0,0,114,93,0,0, - 0,114,103,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,90,0,0, - 0,41,3,114,26,0,0,0,90,5,111,116,104,101,114,90, - 4,115,109,115,108,114,10,0,0,0,114,10,0,0,0,114, - 11,0,0,0,218,6,95,95,101,113,95,95,135,1,0,0, - 115,20,0,0,0,0,1,6,1,2,1,12,1,12,1,12, - 1,10,1,12,1,12,1,14,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,1,0,0,0,3,0,0,0,67,0,0, - 0,115,58,0,0,0,124,0,106,0,100,0,107,8,114,52, - 124,0,106,1,100,0,107,9,114,52,124,0,106,2,114,52, - 116,3,100,0,107,8,114,38,116,4,130,1,116,3,160,5, - 124,0,106,1,161,1,124,0,95,0,124,0,106,0,83,0, - 41,1,78,41,6,114,108,0,0,0,114,103,0,0,0,114, - 107,0,0,0,218,19,95,98,111,111,116,115,116,114,97,112, - 95,101,120,116,101,114,110,97,108,218,19,78,111,116,73,109, - 112,108,101,109,101,110,116,101,100,69,114,114,111,114,90,11, - 95,103,101,116,95,99,97,99,104,101,100,41,1,114,26,0, + 96,0,0,0,49,1,0,0,115,6,0,0,0,8,2,8, + 4,8,7,114,96,0,0,0,99,0,0,0,0,0,0,0, + 0,0,0,0,0,4,0,0,0,64,0,0,0,115,114,0, + 0,0,101,0,90,1,100,0,90,2,100,1,90,3,100,2, + 100,2,100,2,100,3,156,3,100,4,100,5,132,2,90,4, + 100,6,100,7,132,0,90,5,100,8,100,9,132,0,90,6, + 101,7,100,10,100,11,132,0,131,1,90,8,101,8,106,9, + 100,12,100,11,132,0,131,1,90,8,101,7,100,13,100,14, + 132,0,131,1,90,10,101,7,100,15,100,16,132,0,131,1, + 90,11,101,11,106,9,100,17,100,16,132,0,131,1,90,11, + 100,2,83,0,41,18,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,78,41,3,218,6,111,114,105,103, + 105,110,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,54,0,0,0,124,1,124,0,95,0,124,2,124,0, + 95,1,124,3,124,0,95,2,124,4,124,0,95,3,124,5, + 114,32,103,0,110,2,100,0,124,0,95,4,100,1,124,0, + 95,5,100,0,124,0,95,6,100,0,83,0,41,2,78,70, + 41,7,114,15,0,0,0,114,93,0,0,0,114,103,0,0, + 0,114,104,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,26,0,0, + 0,114,15,0,0,0,114,93,0,0,0,114,103,0,0,0, + 114,104,0,0,0,114,105,0,0,0,114,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,114,27,0,0,0,113,1, + 0,0,115,14,0,0,0,0,2,6,1,6,1,6,1,6, + 1,14,3,6,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,6,0,0,0,67,0,0,0,115, + 102,0,0,0,100,1,160,0,124,0,106,1,161,1,100,2, + 160,0,124,0,106,2,161,1,103,2,125,1,124,0,106,3, + 100,0,107,9,114,52,124,1,160,4,100,3,160,0,124,0, + 106,3,161,1,161,1,1,0,124,0,106,5,100,0,107,9, + 114,80,124,1,160,4,100,4,160,0,124,0,106,5,161,1, + 161,1,1,0,100,5,160,0,124,0,106,6,106,7,100,6, + 160,8,124,1,161,1,161,2,83,0,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, + 38,0,0,0,114,15,0,0,0,114,93,0,0,0,114,103, + 0,0,0,218,6,97,112,112,101,110,100,114,106,0,0,0, + 218,9,95,95,99,108,97,115,115,95,95,114,1,0,0,0, + 218,4,106,111,105,110,41,2,114,26,0,0,0,114,47,0, 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, - 0,114,112,0,0,0,147,1,0,0,115,12,0,0,0,0, - 2,10,1,16,1,8,1,4,1,14,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,10,0,0,0,124,1,124,0,95,0,100,0, - 83,0,41,1,78,41,1,114,108,0,0,0,41,2,114,26, - 0,0,0,114,112,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,114,112,0,0,0,156,1,0,0, - 115,2,0,0,0,0,2,99,1,0,0,0,0,0,0,0, - 1,0,0,0,3,0,0,0,67,0,0,0,115,36,0,0, - 0,124,0,106,0,100,1,107,8,114,26,124,0,106,1,160, - 2,100,2,161,1,100,3,25,0,83,0,124,0,106,1,83, - 0,100,1,83,0,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,218,1,46,114,19,0, - 0,0,41,3,114,106,0,0,0,114,15,0,0,0,218,10, - 114,112,97,114,116,105,116,105,111,110,41,1,114,26,0,0, - 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, - 218,6,112,97,114,101,110,116,160,1,0,0,115,6,0,0, - 0,0,3,10,1,16,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, - 6,0,0,0,124,0,106,0,83,0,41,1,78,41,1,114, - 107,0,0,0,41,1,114,26,0,0,0,114,10,0,0,0, - 114,10,0,0,0,114,11,0,0,0,114,113,0,0,0,168, - 1,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,14,0,0,0,116,0,124, - 1,131,1,124,0,95,1,100,0,83,0,41,1,78,41,2, - 218,4,98,111,111,108,114,107,0,0,0,41,2,114,26,0, - 0,0,218,5,118,97,108,117,101,114,10,0,0,0,114,10, - 0,0,0,114,11,0,0,0,114,113,0,0,0,172,1,0, - 0,115,2,0,0,0,0,2,41,12,114,1,0,0,0,114, - 0,0,0,0,114,2,0,0,0,114,3,0,0,0,114,27, - 0,0,0,114,40,0,0,0,114,114,0,0,0,218,8,112, - 114,111,112,101,114,116,121,114,112,0,0,0,218,6,115,101, - 116,116,101,114,114,119,0,0,0,114,113,0,0,0,114,10, + 0,114,40,0,0,0,125,1,0,0,115,16,0,0,0,0, + 1,10,1,14,1,10,1,18,1,10,1,8,1,10,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,8,0,0,0,67,0,0,0,115,106,0,0,0,124,0, + 106,0,125,2,122,72,124,0,106,1,124,1,106,1,107,2, + 111,76,124,0,106,2,124,1,106,2,107,2,111,76,124,0, + 106,3,124,1,106,3,107,2,111,76,124,2,124,1,106,0, + 107,2,111,76,124,0,106,4,124,1,106,4,107,2,111,76, + 124,0,106,5,124,1,106,5,107,2,87,0,83,0,4,0, + 116,6,107,10,114,100,1,0,1,0,1,0,89,0,100,1, + 83,0,88,0,100,0,83,0,41,2,78,70,41,7,114,106, + 0,0,0,114,15,0,0,0,114,93,0,0,0,114,103,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,90,0,0,0,41,3,114, + 26,0,0,0,90,5,111,116,104,101,114,90,4,115,109,115, + 108,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, + 218,6,95,95,101,113,95,95,135,1,0,0,115,20,0,0, + 0,0,1,6,1,2,1,12,1,12,1,12,1,10,1,12, + 1,14,1,14,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,1,0,0,0,3,0,0,0,67,0,0,0,115,58,0, + 0,0,124,0,106,0,100,0,107,8,114,52,124,0,106,1, + 100,0,107,9,114,52,124,0,106,2,114,52,116,3,100,0, + 107,8,114,38,116,4,130,1,116,3,160,5,124,0,106,1, + 161,1,124,0,95,0,124,0,106,0,83,0,41,1,78,41, + 6,114,108,0,0,0,114,103,0,0,0,114,107,0,0,0, + 218,19,95,98,111,111,116,115,116,114,97,112,95,101,120,116, + 101,114,110,97,108,218,19,78,111,116,73,109,112,108,101,109, + 101,110,116,101,100,69,114,114,111,114,90,11,95,103,101,116, + 95,99,97,99,104,101,100,41,1,114,26,0,0,0,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,114,112,0, + 0,0,147,1,0,0,115,12,0,0,0,0,2,10,1,16, + 1,8,1,4,1,14,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, + 10,0,0,0,124,1,124,0,95,0,100,0,83,0,41,1, + 78,41,1,114,108,0,0,0,41,2,114,26,0,0,0,114, + 112,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, + 0,0,0,114,112,0,0,0,156,1,0,0,115,2,0,0, + 0,0,2,99,1,0,0,0,0,0,0,0,1,0,0,0, + 3,0,0,0,67,0,0,0,115,36,0,0,0,124,0,106, + 0,100,1,107,8,114,26,124,0,106,1,160,2,100,2,161, + 1,100,3,25,0,83,0,124,0,106,1,83,0,100,1,83, + 0,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,218,1,46,114,19,0,0,0,41,3, + 114,106,0,0,0,114,15,0,0,0,218,10,114,112,97,114, + 116,105,116,105,111,110,41,1,114,26,0,0,0,114,10,0, + 0,0,114,10,0,0,0,114,11,0,0,0,218,6,112,97, + 114,101,110,116,160,1,0,0,115,6,0,0,0,0,3,10, + 1,16,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,6,0,0,0, + 124,0,106,0,83,0,41,1,78,41,1,114,107,0,0,0, + 41,1,114,26,0,0,0,114,10,0,0,0,114,10,0,0, + 0,114,11,0,0,0,114,113,0,0,0,168,1,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,14,0,0,0,116,0,124,1,131,1,124, + 0,95,1,100,0,83,0,41,1,78,41,2,218,4,98,111, + 111,108,114,107,0,0,0,41,2,114,26,0,0,0,218,5, + 118,97,108,117,101,114,10,0,0,0,114,10,0,0,0,114, + 11,0,0,0,114,113,0,0,0,172,1,0,0,115,2,0, + 0,0,0,2,41,12,114,1,0,0,0,114,0,0,0,0, + 114,2,0,0,0,114,3,0,0,0,114,27,0,0,0,114, + 40,0,0,0,114,114,0,0,0,218,8,112,114,111,112,101, + 114,116,121,114,112,0,0,0,218,6,115,101,116,116,101,114, + 114,119,0,0,0,114,113,0,0,0,114,10,0,0,0,114, + 10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,102, + 0,0,0,76,1,0,0,115,20,0,0,0,8,35,4,2, + 4,1,14,11,8,10,8,12,12,9,14,4,12,8,12,4, + 114,102,0,0,0,41,2,114,103,0,0,0,114,105,0,0, + 0,99,2,0,0,0,2,0,0,0,6,0,0,0,8,0, + 0,0,67,0,0,0,115,154,0,0,0,116,0,124,1,100, + 1,131,2,114,74,116,1,100,2,107,8,114,22,116,2,130, + 1,116,1,106,3,125,4,124,3,100,2,107,8,114,48,124, + 4,124,0,124,1,100,3,141,2,83,0,124,3,114,56,103, + 0,110,2,100,2,125,5,124,4,124,0,124,1,124,5,100, + 4,141,3,83,0,124,3,100,2,107,8,114,138,116,0,124, + 1,100,5,131,2,114,134,122,14,124,1,160,4,124,0,161, + 1,125,3,87,0,113,138,4,0,116,5,107,10,114,130,1, + 0,1,0,1,0,100,2,125,3,89,0,113,138,88,0,110, + 4,100,6,125,3,116,6,124,0,124,1,124,2,124,3,100, + 7,141,4,83,0,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,90,12, + 103,101,116,95,102,105,108,101,110,97,109,101,78,41,1,114, + 93,0,0,0,41,2,114,93,0,0,0,114,106,0,0,0, + 114,105,0,0,0,70,41,2,114,103,0,0,0,114,105,0, + 0,0,41,7,114,4,0,0,0,114,115,0,0,0,114,116, + 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,105,0,0, + 0,114,70,0,0,0,114,102,0,0,0,41,6,114,15,0, + 0,0,114,93,0,0,0,114,103,0,0,0,114,105,0,0, + 0,114,124,0,0,0,90,6,115,101,97,114,99,104,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,114,78,0, + 0,0,177,1,0,0,115,34,0,0,0,0,2,10,1,8, + 1,4,1,6,2,8,1,12,1,12,1,6,1,8,2,8, + 1,10,1,2,1,14,1,14,1,12,3,4,2,114,78,0, + 0,0,99,3,0,0,0,0,0,0,0,8,0,0,0,8, + 0,0,0,67,0,0,0,115,56,1,0,0,122,10,124,0, + 106,0,125,3,87,0,110,20,4,0,116,1,107,10,114,30, + 1,0,1,0,1,0,89,0,110,14,88,0,124,3,100,0, + 107,9,114,44,124,3,83,0,124,0,106,2,125,4,124,1, + 100,0,107,8,114,90,122,10,124,0,106,3,125,1,87,0, + 110,20,4,0,116,1,107,10,114,88,1,0,1,0,1,0, + 89,0,110,2,88,0,122,10,124,0,106,4,125,5,87,0, + 110,24,4,0,116,1,107,10,114,124,1,0,1,0,1,0, + 100,0,125,5,89,0,110,2,88,0,124,2,100,0,107,8, + 114,184,124,5,100,0,107,8,114,180,122,10,124,1,106,5, + 125,2,87,0,113,184,4,0,116,1,107,10,114,176,1,0, + 1,0,1,0,100,0,125,2,89,0,113,184,88,0,110,4, + 124,5,125,2,122,10,124,0,106,6,125,6,87,0,110,24, + 4,0,116,1,107,10,114,218,1,0,1,0,1,0,100,0, + 125,6,89,0,110,2,88,0,122,14,116,7,124,0,106,8, + 131,1,125,7,87,0,110,26,4,0,116,1,107,10,144,1, + 114,4,1,0,1,0,1,0,100,0,125,7,89,0,110,2, + 88,0,116,9,124,4,124,1,124,2,100,1,141,3,125,3, + 124,5,100,0,107,8,144,1,114,34,100,2,110,2,100,3, + 124,3,95,10,124,6,124,3,95,11,124,7,124,3,95,12, + 124,3,83,0,41,4,78,41,1,114,103,0,0,0,70,84, + 41,13,114,89,0,0,0,114,90,0,0,0,114,1,0,0, + 0,114,85,0,0,0,114,92,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,102,0,0,0,114,107,0,0,0,114,112,0,0,0,114, + 106,0,0,0,41,8,114,83,0,0,0,114,93,0,0,0, + 114,103,0,0,0,114,82,0,0,0,114,15,0,0,0,90, + 8,108,111,99,97,116,105,111,110,114,112,0,0,0,114,106, 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, - 0,0,114,102,0,0,0,76,1,0,0,115,20,0,0,0, - 8,35,4,2,4,1,14,11,8,10,8,12,12,9,14,4, - 12,8,12,4,114,102,0,0,0,41,2,114,103,0,0,0, - 114,105,0,0,0,99,2,0,0,0,2,0,0,0,6,0, - 0,0,8,0,0,0,67,0,0,0,115,154,0,0,0,116, - 0,124,1,100,1,131,2,114,74,116,1,100,2,107,8,114, - 22,116,2,130,1,116,1,106,3,125,4,124,3,100,2,107, - 8,114,48,124,4,124,0,124,1,100,3,141,2,83,0,124, - 3,114,56,103,0,110,2,100,2,125,5,124,4,124,0,124, - 1,124,5,100,4,141,3,83,0,124,3,100,2,107,8,114, - 138,116,0,124,1,100,5,131,2,114,134,121,14,124,1,160, - 4,124,0,161,1,125,3,87,0,113,138,4,0,116,5,107, - 10,114,130,1,0,1,0,1,0,100,2,125,3,89,0,113, - 138,88,0,110,4,100,6,125,3,116,6,124,0,124,1,124, - 2,124,3,100,7,141,4,83,0,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,90,12,103,101,116,95,102,105,108,101,110,97,109,101, - 78,41,1,114,93,0,0,0,41,2,114,93,0,0,0,114, - 106,0,0,0,114,105,0,0,0,70,41,2,114,103,0,0, - 0,114,105,0,0,0,41,7,114,4,0,0,0,114,115,0, - 0,0,114,116,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,105,0,0,0,114,70,0,0,0,114,102,0,0,0,41, - 6,114,15,0,0,0,114,93,0,0,0,114,103,0,0,0, - 114,105,0,0,0,114,124,0,0,0,90,6,115,101,97,114, - 99,104,114,10,0,0,0,114,10,0,0,0,114,11,0,0, - 0,114,78,0,0,0,177,1,0,0,115,34,0,0,0,0, - 2,10,1,8,1,4,1,6,2,8,1,12,1,12,1,6, - 1,8,2,8,1,10,1,2,1,14,1,14,1,12,3,4, - 2,114,78,0,0,0,99,3,0,0,0,0,0,0,0,8, - 0,0,0,8,0,0,0,67,0,0,0,115,56,1,0,0, - 121,10,124,0,106,0,125,3,87,0,110,20,4,0,116,1, - 107,10,114,30,1,0,1,0,1,0,89,0,110,14,88,0, - 124,3,100,0,107,9,114,44,124,3,83,0,124,0,106,2, - 125,4,124,1,100,0,107,8,114,90,121,10,124,0,106,3, - 125,1,87,0,110,20,4,0,116,1,107,10,114,88,1,0, - 1,0,1,0,89,0,110,2,88,0,121,10,124,0,106,4, - 125,5,87,0,110,24,4,0,116,1,107,10,114,124,1,0, - 1,0,1,0,100,0,125,5,89,0,110,2,88,0,124,2, - 100,0,107,8,114,184,124,5,100,0,107,8,114,180,121,10, - 124,1,106,5,125,2,87,0,113,184,4,0,116,1,107,10, - 114,176,1,0,1,0,1,0,100,0,125,2,89,0,113,184, - 88,0,110,4,124,5,125,2,121,10,124,0,106,6,125,6, - 87,0,110,24,4,0,116,1,107,10,114,218,1,0,1,0, - 1,0,100,0,125,6,89,0,110,2,88,0,121,14,116,7, - 124,0,106,8,131,1,125,7,87,0,110,26,4,0,116,1, - 107,10,144,1,114,4,1,0,1,0,1,0,100,0,125,7, - 89,0,110,2,88,0,116,9,124,4,124,1,124,2,100,1, - 141,3,125,3,124,5,100,0,107,8,144,1,114,34,100,2, - 110,2,100,3,124,3,95,10,124,6,124,3,95,11,124,7, - 124,3,95,12,124,3,83,0,41,4,78,41,1,114,103,0, - 0,0,70,84,41,13,114,89,0,0,0,114,90,0,0,0, - 114,1,0,0,0,114,85,0,0,0,114,92,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,102,0,0,0,114,107,0,0,0,114,112, - 0,0,0,114,106,0,0,0,41,8,114,83,0,0,0,114, - 93,0,0,0,114,103,0,0,0,114,82,0,0,0,114,15, - 0,0,0,90,8,108,111,99,97,116,105,111,110,114,112,0, - 0,0,114,106,0,0,0,114,10,0,0,0,114,10,0,0, - 0,114,11,0,0,0,218,17,95,115,112,101,99,95,102,114, - 111,109,95,109,111,100,117,108,101,203,1,0,0,115,72,0, - 0,0,0,2,2,1,10,1,14,1,6,2,8,1,4,2, - 6,1,8,1,2,1,10,1,14,2,6,1,2,1,10,1, - 14,1,10,1,8,1,8,1,2,1,10,1,14,1,12,2, - 4,1,2,1,10,1,14,1,10,1,2,1,14,1,16,1, - 10,2,14,1,20,1,6,1,6,1,114,128,0,0,0,70, - 41,1,218,8,111,118,101,114,114,105,100,101,99,2,0,0, - 0,1,0,0,0,5,0,0,0,8,0,0,0,67,0,0, - 0,115,226,1,0,0,124,2,115,20,116,0,124,1,100,1, - 100,0,131,3,100,0,107,8,114,54,121,12,124,0,106,1, - 124,1,95,2,87,0,110,20,4,0,116,3,107,10,114,52, - 1,0,1,0,1,0,89,0,110,2,88,0,124,2,115,74, - 116,0,124,1,100,2,100,0,131,3,100,0,107,8,114,178, - 124,0,106,4,125,3,124,3,100,0,107,8,114,146,124,0, - 106,5,100,0,107,9,114,146,116,6,100,0,107,8,114,110, - 116,7,130,1,116,6,106,8,125,4,124,4,160,9,124,4, - 161,1,125,3,124,0,106,5,124,3,95,10,124,3,124,0, - 95,4,100,0,124,1,95,11,121,10,124,3,124,1,95,12, - 87,0,110,20,4,0,116,3,107,10,114,176,1,0,1,0, - 1,0,89,0,110,2,88,0,124,2,115,198,116,0,124,1, - 100,3,100,0,131,3,100,0,107,8,114,232,121,12,124,0, - 106,13,124,1,95,14,87,0,110,20,4,0,116,3,107,10, - 114,230,1,0,1,0,1,0,89,0,110,2,88,0,121,10, - 124,0,124,1,95,15,87,0,110,22,4,0,116,3,107,10, - 144,1,114,8,1,0,1,0,1,0,89,0,110,2,88,0, - 124,2,144,1,115,34,116,0,124,1,100,4,100,0,131,3, - 100,0,107,8,144,1,114,82,124,0,106,5,100,0,107,9, - 144,1,114,82,121,12,124,0,106,5,124,1,95,16,87,0, - 110,22,4,0,116,3,107,10,144,1,114,80,1,0,1,0, - 1,0,89,0,110,2,88,0,124,0,106,17,144,1,114,222, - 124,2,144,1,115,114,116,0,124,1,100,5,100,0,131,3, - 100,0,107,8,144,1,114,150,121,12,124,0,106,18,124,1, - 95,11,87,0,110,22,4,0,116,3,107,10,144,1,114,148, + 0,0,218,17,95,115,112,101,99,95,102,114,111,109,95,109, + 111,100,117,108,101,203,1,0,0,115,72,0,0,0,0,2, + 2,1,10,1,14,1,6,2,8,1,4,2,6,1,8,1, + 2,1,10,1,14,2,6,1,2,1,10,1,14,1,10,1, + 8,1,8,1,2,1,10,1,14,1,12,2,4,1,2,1, + 10,1,14,1,10,1,2,1,14,1,16,1,10,2,14,1, + 20,1,6,1,6,1,114,128,0,0,0,70,41,1,218,8, + 111,118,101,114,114,105,100,101,99,2,0,0,0,1,0,0, + 0,5,0,0,0,8,0,0,0,67,0,0,0,115,226,1, + 0,0,124,2,115,20,116,0,124,1,100,1,100,0,131,3, + 100,0,107,8,114,54,122,12,124,0,106,1,124,1,95,2, + 87,0,110,20,4,0,116,3,107,10,114,52,1,0,1,0, + 1,0,89,0,110,2,88,0,124,2,115,74,116,0,124,1, + 100,2,100,0,131,3,100,0,107,8,114,178,124,0,106,4, + 125,3,124,3,100,0,107,8,114,146,124,0,106,5,100,0, + 107,9,114,146,116,6,100,0,107,8,114,110,116,7,130,1, + 116,6,106,8,125,4,124,4,160,9,124,4,161,1,125,3, + 124,0,106,5,124,3,95,10,124,3,124,0,95,4,100,0, + 124,1,95,11,122,10,124,3,124,1,95,12,87,0,110,20, + 4,0,116,3,107,10,114,176,1,0,1,0,1,0,89,0, + 110,2,88,0,124,2,115,198,116,0,124,1,100,3,100,0, + 131,3,100,0,107,8,114,232,122,12,124,0,106,13,124,1, + 95,14,87,0,110,20,4,0,116,3,107,10,114,230,1,0, + 1,0,1,0,89,0,110,2,88,0,122,10,124,0,124,1, + 95,15,87,0,110,22,4,0,116,3,107,10,144,1,114,8, 1,0,1,0,1,0,89,0,110,2,88,0,124,2,144,1, - 115,174,116,0,124,1,100,6,100,0,131,3,100,0,107,8, - 144,1,114,222,124,0,106,19,100,0,107,9,144,1,114,222, - 121,12,124,0,106,19,124,1,95,20,87,0,110,22,4,0, - 116,3,107,10,144,1,114,220,1,0,1,0,1,0,89,0, - 110,2,88,0,124,1,83,0,41,7,78,114,1,0,0,0, - 114,85,0,0,0,218,11,95,95,112,97,99,107,97,103,101, - 95,95,114,127,0,0,0,114,92,0,0,0,114,125,0,0, - 0,41,21,114,6,0,0,0,114,15,0,0,0,114,1,0, - 0,0,114,90,0,0,0,114,93,0,0,0,114,106,0,0, - 0,114,115,0,0,0,114,116,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,90,5,95,112,97,116,104,114,92,0, - 0,0,114,85,0,0,0,114,119,0,0,0,114,130,0,0, - 0,114,89,0,0,0,114,127,0,0,0,114,113,0,0,0, - 114,103,0,0,0,114,112,0,0,0,114,125,0,0,0,41, - 5,114,82,0,0,0,114,83,0,0,0,114,129,0,0,0, - 114,93,0,0,0,114,131,0,0,0,114,10,0,0,0,114, - 10,0,0,0,114,11,0,0,0,218,18,95,105,110,105,116, - 95,109,111,100,117,108,101,95,97,116,116,114,115,248,1,0, - 0,115,96,0,0,0,0,4,20,1,2,1,12,1,14,1, - 6,2,20,1,6,1,8,2,10,1,8,1,4,1,6,2, - 10,1,8,1,6,11,6,1,2,1,10,1,14,1,6,2, - 20,1,2,1,12,1,14,1,6,2,2,1,10,1,16,1, - 6,2,24,1,12,1,2,1,12,1,16,1,6,2,8,1, - 24,1,2,1,12,1,16,1,6,2,24,1,12,1,2,1, - 12,1,16,1,6,1,114,133,0,0,0,99,1,0,0,0, - 0,0,0,0,2,0,0,0,3,0,0,0,67,0,0,0, - 115,82,0,0,0,100,1,125,1,116,0,124,0,106,1,100, - 2,131,2,114,30,124,0,106,1,160,2,124,0,161,1,125, - 1,110,20,116,0,124,0,106,1,100,3,131,2,114,50,116, - 3,100,4,131,1,130,1,124,1,100,1,107,8,114,68,116, - 4,124,0,106,5,131,1,125,1,116,6,124,0,124,1,131, - 2,1,0,124,1,83,0,41,5,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,66,108,111,97,100,101,114,115,32,116,104,97, - 116,32,100,101,102,105,110,101,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,41,7,114,4,0,0,0,114,93, - 0,0,0,114,134,0,0,0,114,70,0,0,0,114,16,0, - 0,0,114,15,0,0,0,114,133,0,0,0,41,2,114,82, + 115,34,116,0,124,1,100,4,100,0,131,3,100,0,107,8, + 144,1,114,82,124,0,106,5,100,0,107,9,144,1,114,82, + 122,12,124,0,106,5,124,1,95,16,87,0,110,22,4,0, + 116,3,107,10,144,1,114,80,1,0,1,0,1,0,89,0, + 110,2,88,0,124,0,106,17,144,1,114,222,124,2,144,1, + 115,114,116,0,124,1,100,5,100,0,131,3,100,0,107,8, + 144,1,114,150,122,12,124,0,106,18,124,1,95,11,87,0, + 110,22,4,0,116,3,107,10,144,1,114,148,1,0,1,0, + 1,0,89,0,110,2,88,0,124,2,144,1,115,174,116,0, + 124,1,100,6,100,0,131,3,100,0,107,8,144,1,114,222, + 124,0,106,19,100,0,107,9,144,1,114,222,122,12,124,0, + 106,19,124,1,95,20,87,0,110,22,4,0,116,3,107,10, + 144,1,114,220,1,0,1,0,1,0,89,0,110,2,88,0, + 124,1,83,0,41,7,78,114,1,0,0,0,114,85,0,0, + 0,218,11,95,95,112,97,99,107,97,103,101,95,95,114,127, + 0,0,0,114,92,0,0,0,114,125,0,0,0,41,21,114, + 6,0,0,0,114,15,0,0,0,114,1,0,0,0,114,90, + 0,0,0,114,93,0,0,0,114,106,0,0,0,114,115,0, + 0,0,114,116,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,90,5,95,112,97,116,104,114,92,0,0,0,114,85, + 0,0,0,114,119,0,0,0,114,130,0,0,0,114,89,0, + 0,0,114,127,0,0,0,114,113,0,0,0,114,103,0,0, + 0,114,112,0,0,0,114,125,0,0,0,41,5,114,82,0, + 0,0,114,83,0,0,0,114,129,0,0,0,114,93,0,0, + 0,114,131,0,0,0,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,218,18,95,105,110,105,116,95,109,111,100, + 117,108,101,95,97,116,116,114,115,248,1,0,0,115,96,0, + 0,0,0,4,20,1,2,1,12,1,14,1,6,2,20,1, + 6,1,8,2,10,1,8,1,4,1,6,2,10,1,8,1, + 6,11,6,1,2,1,10,1,14,1,6,2,20,1,2,1, + 12,1,14,1,6,2,2,1,10,1,16,1,6,2,24,1, + 12,1,2,1,12,1,16,1,6,2,8,1,24,1,2,1, + 12,1,16,1,6,2,24,1,12,1,2,1,12,1,16,1, + 6,1,114,133,0,0,0,99,1,0,0,0,0,0,0,0, + 2,0,0,0,3,0,0,0,67,0,0,0,115,82,0,0, + 0,100,1,125,1,116,0,124,0,106,1,100,2,131,2,114, + 30,124,0,106,1,160,2,124,0,161,1,125,1,110,20,116, + 0,124,0,106,1,100,3,131,2,114,50,116,3,100,4,131, + 1,130,1,124,1,100,1,107,8,114,68,116,4,124,0,106, + 5,131,1,125,1,116,6,124,0,124,1,131,2,1,0,124, + 1,83,0,41,5,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, + 66,108,111,97,100,101,114,115,32,116,104,97,116,32,100,101, + 102,105,110,101,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,41,7,114,4,0,0,0,114,93,0,0,0,114, + 134,0,0,0,114,70,0,0,0,114,16,0,0,0,114,15, + 0,0,0,114,133,0,0,0,41,2,114,82,0,0,0,114, + 83,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, + 0,0,0,218,16,109,111,100,117,108,101,95,102,114,111,109, + 95,115,112,101,99,64,2,0,0,115,18,0,0,0,0,3, + 4,1,12,3,14,1,12,1,8,2,8,1,10,1,10,1, + 114,136,0,0,0,99,1,0,0,0,0,0,0,0,2,0, + 0,0,4,0,0,0,67,0,0,0,115,106,0,0,0,124, + 0,106,0,100,1,107,8,114,14,100,2,110,4,124,0,106, + 0,125,1,124,0,106,1,100,1,107,8,114,66,124,0,106, + 2,100,1,107,8,114,50,100,3,160,3,124,1,161,1,83, + 0,100,4,160,3,124,1,124,0,106,2,161,2,83,0,110, + 36,124,0,106,4,114,86,100,5,160,3,124,1,124,0,106, + 1,161,2,83,0,100,6,160,3,124,0,106,0,124,0,106, + 1,161,2,83,0,100,1,83,0,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,87,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,15,0, + 0,0,114,103,0,0,0,114,93,0,0,0,114,38,0,0, + 0,114,113,0,0,0,41,2,114,82,0,0,0,114,15,0, + 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, + 0,114,91,0,0,0,81,2,0,0,115,16,0,0,0,0, + 3,20,1,10,1,10,1,10,2,16,2,6,1,14,2,114, + 91,0,0,0,99,2,0,0,0,0,0,0,0,4,0,0, + 0,10,0,0,0,67,0,0,0,115,190,0,0,0,124,0, + 106,0,125,2,116,1,124,2,131,1,143,160,1,0,116,2, + 106,3,160,4,124,2,161,1,124,1,107,9,114,54,100,1, + 160,5,124,2,161,1,125,3,116,6,124,3,124,2,100,2, + 141,2,130,1,124,0,106,7,100,3,107,8,114,118,124,0, + 106,8,100,3,107,8,114,88,116,6,100,4,124,0,106,0, + 100,2,141,2,130,1,116,9,124,0,124,1,100,5,100,6, + 141,3,1,0,124,1,87,0,2,0,53,0,81,0,82,0, + 163,0,83,0,116,9,124,0,124,1,100,5,100,6,141,3, + 1,0,116,10,124,0,106,7,100,7,131,2,115,158,124,0, + 106,7,160,11,124,2,161,1,1,0,110,12,124,0,106,7, + 160,12,124,1,161,1,1,0,87,0,53,0,81,0,82,0, + 88,0,116,2,106,3,124,2,25,0,83,0,41,8,122,70, + 69,120,101,99,117,116,101,32,116,104,101,32,115,112,101,99, + 39,115,32,115,112,101,99,105,102,105,101,100,32,109,111,100, + 117,108,101,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,41,1,114,15,0,0,0,78,122,14, + 109,105,115,115,105,110,103,32,108,111,97,100,101,114,84,41, + 1,114,129,0,0,0,114,135,0,0,0,41,13,114,15,0, + 0,0,114,42,0,0,0,114,14,0,0,0,114,79,0,0, + 0,114,30,0,0,0,114,38,0,0,0,114,70,0,0,0, + 114,93,0,0,0,114,106,0,0,0,114,133,0,0,0,114, + 4,0,0,0,218,11,108,111,97,100,95,109,111,100,117,108, + 101,114,135,0,0,0,41,4,114,82,0,0,0,114,83,0, + 0,0,114,15,0,0,0,218,3,109,115,103,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,114,80,0,0,0, + 98,2,0,0,115,30,0,0,0,0,2,6,1,10,1,16, + 1,10,1,12,1,10,1,10,1,14,2,14,1,16,1,14, + 1,12,4,14,2,22,1,114,80,0,0,0,99,1,0,0, + 0,0,0,0,0,2,0,0,0,8,0,0,0,67,0,0, + 0,115,206,0,0,0,124,0,106,0,160,1,124,0,106,2, + 161,1,1,0,116,3,106,4,124,0,106,2,25,0,125,1, + 116,5,124,1,100,1,100,0,131,3,100,0,107,8,114,76, + 122,12,124,0,106,0,124,1,95,6,87,0,110,20,4,0, + 116,7,107,10,114,74,1,0,1,0,1,0,89,0,110,2, + 88,0,116,5,124,1,100,2,100,0,131,3,100,0,107,8, + 114,154,122,40,124,1,106,8,124,1,95,9,116,10,124,1, + 100,3,131,2,115,130,124,0,106,2,160,11,100,4,161,1, + 100,5,25,0,124,1,95,9,87,0,110,20,4,0,116,7, + 107,10,114,152,1,0,1,0,1,0,89,0,110,2,88,0, + 116,5,124,1,100,6,100,0,131,3,100,0,107,8,114,202, + 122,10,124,0,124,1,95,12,87,0,110,20,4,0,116,7, + 107,10,114,200,1,0,1,0,1,0,89,0,110,2,88,0, + 124,1,83,0,41,7,78,114,85,0,0,0,114,130,0,0, + 0,114,127,0,0,0,114,117,0,0,0,114,19,0,0,0, + 114,89,0,0,0,41,13,114,93,0,0,0,114,137,0,0, + 0,114,15,0,0,0,114,14,0,0,0,114,79,0,0,0, + 114,6,0,0,0,114,85,0,0,0,114,90,0,0,0,114, + 1,0,0,0,114,130,0,0,0,114,4,0,0,0,114,118, + 0,0,0,114,89,0,0,0,41,2,114,82,0,0,0,114, + 83,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, + 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,122,2, + 0,0,115,40,0,0,0,0,4,14,2,12,1,16,1,2, + 1,12,1,14,1,6,1,16,1,2,4,8,1,10,1,22, + 1,14,1,6,1,16,1,2,1,10,1,14,1,6,1,114, + 139,0,0,0,99,1,0,0,0,0,0,0,0,2,0,0, + 0,9,0,0,0,67,0,0,0,115,118,0,0,0,124,0, + 106,0,100,0,107,9,114,30,116,1,124,0,106,0,100,1, + 131,2,115,30,116,2,124,0,131,1,83,0,116,3,124,0, + 131,1,125,1,116,4,124,1,131,1,143,54,1,0,124,0, + 106,0,100,0,107,8,114,84,124,0,106,5,100,0,107,8, + 114,96,116,6,100,2,124,0,106,7,100,3,141,2,130,1, + 110,12,124,0,106,0,160,8,124,1,161,1,1,0,87,0, + 53,0,81,0,82,0,88,0,116,9,106,10,124,0,106,7, + 25,0,83,0,41,4,78,114,135,0,0,0,122,14,109,105, + 115,115,105,110,103,32,108,111,97,100,101,114,41,1,114,15, + 0,0,0,41,11,114,93,0,0,0,114,4,0,0,0,114, + 139,0,0,0,114,136,0,0,0,114,96,0,0,0,114,106, + 0,0,0,114,70,0,0,0,114,15,0,0,0,114,135,0, + 0,0,114,14,0,0,0,114,79,0,0,0,41,2,114,82, 0,0,0,114,83,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,218,16,109,111,100,117,108,101,95, - 102,114,111,109,95,115,112,101,99,64,2,0,0,115,18,0, - 0,0,0,3,4,1,12,3,14,1,12,1,8,2,8,1, - 10,1,10,1,114,136,0,0,0,99,1,0,0,0,0,0, - 0,0,2,0,0,0,4,0,0,0,67,0,0,0,115,106, - 0,0,0,124,0,106,0,100,1,107,8,114,14,100,2,110, - 4,124,0,106,0,125,1,124,0,106,1,100,1,107,8,114, - 66,124,0,106,2,100,1,107,8,114,50,100,3,160,3,124, - 1,161,1,83,0,100,4,160,3,124,1,124,0,106,2,161, - 2,83,0,110,36,124,0,106,4,114,86,100,5,160,3,124, - 1,124,0,106,1,161,2,83,0,100,6,160,3,124,0,106, - 0,124,0,106,1,161,2,83,0,100,1,83,0,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,87,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,15,0,0,0,114,103,0,0,0,114,93,0,0,0, - 114,38,0,0,0,114,113,0,0,0,41,2,114,82,0,0, - 0,114,15,0,0,0,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,114,91,0,0,0,81,2,0,0,115,16, - 0,0,0,0,3,20,1,10,1,10,1,10,2,16,2,6, - 1,14,2,114,91,0,0,0,99,2,0,0,0,0,0,0, - 0,4,0,0,0,9,0,0,0,67,0,0,0,115,178,0, - 0,0,124,0,106,0,125,2,116,1,124,2,131,1,143,148, - 1,0,116,2,106,3,160,4,124,2,161,1,124,1,107,9, - 114,54,100,1,160,5,124,2,161,1,125,3,116,6,124,3, - 124,2,100,2,141,2,130,1,124,0,106,7,100,3,107,8, - 114,106,124,0,106,8,100,3,107,8,114,88,116,6,100,4, - 124,0,106,0,100,2,141,2,130,1,116,9,124,0,124,1, - 100,5,100,6,141,3,1,0,124,1,83,0,116,9,124,0, - 124,1,100,5,100,6,141,3,1,0,116,10,124,0,106,7, - 100,7,131,2,115,146,124,0,106,7,160,11,124,2,161,1, - 1,0,110,12,124,0,106,7,160,12,124,1,161,1,1,0, - 87,0,100,3,81,0,82,0,88,0,116,2,106,3,124,2, - 25,0,83,0,41,8,122,70,69,120,101,99,117,116,101,32, - 116,104,101,32,115,112,101,99,39,115,32,115,112,101,99,105, - 102,105,101,100,32,109,111,100,117,108,101,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,41,1, - 114,15,0,0,0,78,122,14,109,105,115,115,105,110,103,32, - 108,111,97,100,101,114,84,41,1,114,129,0,0,0,114,135, - 0,0,0,41,13,114,15,0,0,0,114,42,0,0,0,114, - 14,0,0,0,114,79,0,0,0,114,30,0,0,0,114,38, - 0,0,0,114,70,0,0,0,114,93,0,0,0,114,106,0, - 0,0,114,133,0,0,0,114,4,0,0,0,218,11,108,111, - 97,100,95,109,111,100,117,108,101,114,135,0,0,0,41,4, - 114,82,0,0,0,114,83,0,0,0,114,15,0,0,0,218, - 3,109,115,103,114,10,0,0,0,114,10,0,0,0,114,11, - 0,0,0,114,80,0,0,0,98,2,0,0,115,30,0,0, - 0,0,2,6,1,10,1,16,1,10,1,12,1,10,1,10, - 1,14,2,14,1,4,1,14,1,12,4,14,2,22,1,114, - 80,0,0,0,99,1,0,0,0,0,0,0,0,2,0,0, - 0,8,0,0,0,67,0,0,0,115,206,0,0,0,124,0, - 106,0,160,1,124,0,106,2,161,1,1,0,116,3,106,4, - 124,0,106,2,25,0,125,1,116,5,124,1,100,1,100,0, - 131,3,100,0,107,8,114,76,121,12,124,0,106,0,124,1, - 95,6,87,0,110,20,4,0,116,7,107,10,114,74,1,0, - 1,0,1,0,89,0,110,2,88,0,116,5,124,1,100,2, - 100,0,131,3,100,0,107,8,114,154,121,40,124,1,106,8, - 124,1,95,9,116,10,124,1,100,3,131,2,115,130,124,0, - 106,2,160,11,100,4,161,1,100,5,25,0,124,1,95,9, - 87,0,110,20,4,0,116,7,107,10,114,152,1,0,1,0, - 1,0,89,0,110,2,88,0,116,5,124,1,100,6,100,0, - 131,3,100,0,107,8,114,202,121,10,124,0,124,1,95,12, - 87,0,110,20,4,0,116,7,107,10,114,200,1,0,1,0, - 1,0,89,0,110,2,88,0,124,1,83,0,41,7,78,114, - 85,0,0,0,114,130,0,0,0,114,127,0,0,0,114,117, - 0,0,0,114,19,0,0,0,114,89,0,0,0,41,13,114, - 93,0,0,0,114,137,0,0,0,114,15,0,0,0,114,14, - 0,0,0,114,79,0,0,0,114,6,0,0,0,114,85,0, - 0,0,114,90,0,0,0,114,1,0,0,0,114,130,0,0, - 0,114,4,0,0,0,114,118,0,0,0,114,89,0,0,0, - 41,2,114,82,0,0,0,114,83,0,0,0,114,10,0,0, - 0,114,10,0,0,0,114,11,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,122,2,0,0,115,40,0,0,0,0, - 4,14,2,12,1,16,1,2,1,12,1,14,1,6,1,16, - 1,2,4,8,1,10,1,22,1,14,1,6,1,16,1,2, - 1,10,1,14,1,6,1,114,139,0,0,0,99,1,0,0, - 0,0,0,0,0,2,0,0,0,9,0,0,0,67,0,0, - 0,115,118,0,0,0,124,0,106,0,100,0,107,9,114,30, - 116,1,124,0,106,0,100,1,131,2,115,30,116,2,124,0, - 131,1,83,0,116,3,124,0,131,1,125,1,116,4,124,1, - 131,1,143,54,1,0,124,0,106,0,100,0,107,8,114,84, - 124,0,106,5,100,0,107,8,114,96,116,6,100,2,124,0, - 106,7,100,3,141,2,130,1,110,12,124,0,106,0,160,8, - 124,1,161,1,1,0,87,0,100,0,81,0,82,0,88,0, - 116,9,106,10,124,0,106,7,25,0,83,0,41,4,78,114, - 135,0,0,0,122,14,109,105,115,115,105,110,103,32,108,111, - 97,100,101,114,41,1,114,15,0,0,0,41,11,114,93,0, - 0,0,114,4,0,0,0,114,139,0,0,0,114,136,0,0, - 0,114,96,0,0,0,114,106,0,0,0,114,70,0,0,0, - 114,15,0,0,0,114,135,0,0,0,114,14,0,0,0,114, - 79,0,0,0,41,2,114,82,0,0,0,114,83,0,0,0, - 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,218, - 14,95,108,111,97,100,95,117,110,108,111,99,107,101,100,151, - 2,0,0,115,20,0,0,0,0,2,10,2,12,1,8,2, - 8,1,10,1,10,1,10,1,16,3,22,5,114,140,0,0, - 0,99,1,0,0,0,0,0,0,0,1,0,0,0,9,0, - 0,0,67,0,0,0,115,30,0,0,0,116,0,124,0,106, - 1,131,1,143,10,1,0,116,2,124,0,131,1,83,0,81, - 0,82,0,88,0,100,1,83,0,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,3,114, - 42,0,0,0,114,15,0,0,0,114,140,0,0,0,41,1, - 114,82,0,0,0,114,10,0,0,0,114,10,0,0,0,114, - 11,0,0,0,114,81,0,0,0,174,2,0,0,115,4,0, - 0,0,0,9,12,1,114,81,0,0,0,99,0,0,0,0, + 0,0,114,11,0,0,0,218,14,95,108,111,97,100,95,117, + 110,108,111,99,107,101,100,151,2,0,0,115,20,0,0,0, + 0,2,10,2,12,1,8,2,8,1,10,1,10,1,10,1, + 16,3,22,5,114,140,0,0,0,99,1,0,0,0,0,0, + 0,0,1,0,0,0,10,0,0,0,67,0,0,0,115,42, + 0,0,0,116,0,124,0,106,1,131,1,143,22,1,0,116, + 2,124,0,131,1,87,0,2,0,53,0,81,0,82,0,163, + 0,83,0,81,0,82,0,88,0,100,1,83,0,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,3,114,42,0,0,0,114,15,0,0,0,114,140,0, + 0,0,41,1,114,82,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,114,81,0,0,0,174,2,0, + 0,115,4,0,0,0,0,9,12,1,114,81,0,0,0,99, + 0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0, + 64,0,0,0,115,136,0,0,0,101,0,90,1,100,0,90, + 2,100,1,90,3,101,4,100,2,100,3,132,0,131,1,90, + 5,101,6,100,19,100,5,100,6,132,1,131,1,90,7,101, + 6,100,20,100,7,100,8,132,1,131,1,90,8,101,6,100, + 9,100,10,132,0,131,1,90,9,101,6,100,11,100,12,132, + 0,131,1,90,10,101,6,101,11,100,13,100,14,132,0,131, + 1,131,1,90,12,101,6,101,11,100,15,100,16,132,0,131, + 1,131,1,90,13,101,6,101,11,100,17,100,18,132,0,131, + 1,131,1,90,14,101,6,101,15,131,1,90,16,100,4,83, + 0,41,21,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,3,0,0,0,67,0,0,0,115,12,0,0,0, + 100,1,160,0,124,0,106,1,161,1,83,0,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, + 38,0,0,0,114,1,0,0,0,41,1,114,83,0,0,0, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, + 86,0,0,0,198,2,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,44,0,0,0,124,2,100,0,107,9,114,12,100, + 0,83,0,116,0,160,1,124,1,161,1,114,36,116,2,124, + 1,124,0,100,1,100,2,141,3,83,0,100,0,83,0,100, + 0,83,0,41,3,78,122,8,98,117,105,108,116,45,105,110, + 41,1,114,103,0,0,0,41,3,114,49,0,0,0,90,10, + 105,115,95,98,117,105,108,116,105,110,114,78,0,0,0,41, + 4,218,3,99,108,115,114,71,0,0,0,218,4,112,97,116, + 104,218,6,116,97,114,103,101,116,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,218,9,102,105,110,100,95,115, + 112,101,99,207,2,0,0,115,10,0,0,0,0,2,8,1, + 4,1,10,1,14,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,4,0, + 0,0,67,0,0,0,115,30,0,0,0,124,0,160,0,124, + 1,124,2,161,2,125,3,124,3,100,1,107,9,114,26,124, + 3,106,1,83,0,100,1,83,0,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, + 145,0,0,0,114,93,0,0,0,41,4,114,142,0,0,0, + 114,71,0,0,0,114,143,0,0,0,114,82,0,0,0,114, + 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,11, + 102,105,110,100,95,109,111,100,117,108,101,216,2,0,0,115, + 4,0,0,0,0,9,12,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,2,0, + 0,0,4,0,0,0,67,0,0,0,115,46,0,0,0,124, + 1,106,0,116,1,106,2,107,7,114,34,116,3,100,1,160, + 4,124,1,106,0,161,1,124,1,106,0,100,2,141,2,130, + 1,116,5,116,6,106,7,124,1,131,2,83,0,41,3,122, + 24,67,114,101,97,116,101,32,97,32,98,117,105,108,116,45, + 105,110,32,109,111,100,117,108,101,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,41,1,114,15,0,0,0,41, + 8,114,15,0,0,0,114,14,0,0,0,114,69,0,0,0, + 114,70,0,0,0,114,38,0,0,0,114,59,0,0,0,114, + 49,0,0,0,90,14,99,114,101,97,116,101,95,98,117,105, + 108,116,105,110,41,2,114,26,0,0,0,114,82,0,0,0, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, + 134,0,0,0,228,2,0,0,115,8,0,0,0,0,3,12, + 1,12,1,10,1,122,29,66,117,105,108,116,105,110,73,109, + 112,111,114,116,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,3,0,0,0,67,0,0,0,115,16,0,0,0,116,0, + 116,1,106,2,124,1,131,2,1,0,100,1,83,0,41,2, + 122,22,69,120,101,99,32,97,32,98,117,105,108,116,45,105, + 110,32,109,111,100,117,108,101,78,41,3,114,59,0,0,0, + 114,49,0,0,0,90,12,101,120,101,99,95,98,117,105,108, + 116,105,110,41,2,114,26,0,0,0,114,83,0,0,0,114, + 10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,135, + 0,0,0,236,2,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, + 101,120,101,99,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,83,0,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,10,0,0,0,41,2,114,142, + 0,0,0,114,71,0,0,0,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,218,8,103,101,116,95,99,111,100, + 101,241,2,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,83,0,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,10,0,0,0,41,2,114,142,0,0,0,114,71,0, + 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, + 0,218,10,103,101,116,95,115,111,117,114,99,101,247,2,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, + 83,0,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,10,0,0,0, + 41,2,114,142,0,0,0,114,71,0,0,0,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,114,105,0,0,0, + 253,2,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,2,78,78,41,1,78,41,17, + 114,1,0,0,0,114,0,0,0,0,114,2,0,0,0,114, + 3,0,0,0,218,12,115,116,97,116,105,99,109,101,116,104, + 111,100,114,86,0,0,0,218,11,99,108,97,115,115,109,101, + 116,104,111,100,114,145,0,0,0,114,146,0,0,0,114,134, + 0,0,0,114,135,0,0,0,114,74,0,0,0,114,147,0, + 0,0,114,148,0,0,0,114,105,0,0,0,114,84,0,0, + 0,114,137,0,0,0,114,10,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,11,0,0,0,114,141,0,0,0,189, + 2,0,0,115,30,0,0,0,8,7,4,2,12,9,2,1, + 12,8,2,1,12,11,12,8,12,5,2,1,14,5,2,1, + 14,5,2,1,14,5,114,141,0,0,0,99,0,0,0,0, 0,0,0,0,0,0,0,0,4,0,0,0,64,0,0,0, - 115,136,0,0,0,101,0,90,1,100,0,90,2,100,1,90, + 115,140,0,0,0,101,0,90,1,100,0,90,2,100,1,90, 3,101,4,100,2,100,3,132,0,131,1,90,5,101,6,100, - 19,100,5,100,6,132,1,131,1,90,7,101,6,100,20,100, + 21,100,5,100,6,132,1,131,1,90,7,101,6,100,22,100, 7,100,8,132,1,131,1,90,8,101,6,100,9,100,10,132, - 0,131,1,90,9,101,6,100,11,100,12,132,0,131,1,90, - 10,101,6,101,11,100,13,100,14,132,0,131,1,131,1,90, - 12,101,6,101,11,100,15,100,16,132,0,131,1,131,1,90, - 13,101,6,101,11,100,17,100,18,132,0,131,1,131,1,90, - 14,101,6,101,15,131,1,90,16,100,4,83,0,41,21,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,3, - 0,0,0,67,0,0,0,115,12,0,0,0,100,1,160,0, - 124,0,106,1,161,1,83,0,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,38,0,0,0, - 114,1,0,0,0,41,1,114,83,0,0,0,114,10,0,0, - 0,114,10,0,0,0,114,11,0,0,0,114,86,0,0,0, - 198,2,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,44, - 0,0,0,124,2,100,0,107,9,114,12,100,0,83,0,116, - 0,160,1,124,1,161,1,114,36,116,2,124,1,124,0,100, + 0,131,1,90,9,101,4,100,11,100,12,132,0,131,1,90, + 10,101,6,100,13,100,14,132,0,131,1,90,11,101,6,101, + 12,100,15,100,16,132,0,131,1,131,1,90,13,101,6,101, + 12,100,17,100,18,132,0,131,1,131,1,90,14,101,6,101, + 12,100,19,100,20,132,0,131,1,131,1,90,15,100,4,83, + 0,41,23,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, + 3,0,0,0,67,0,0,0,115,12,0,0,0,100,1,160, + 0,124,0,106,1,161,1,83,0,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,38,0,0,0,114, + 1,0,0,0,41,1,218,1,109,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,114,86,0,0,0,15,3,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,32,0,0,0,116, + 0,160,1,124,1,161,1,114,24,116,2,124,1,124,0,100, 1,100,2,141,3,83,0,100,0,83,0,100,0,83,0,41, - 3,78,122,8,98,117,105,108,116,45,105,110,41,1,114,103, - 0,0,0,41,3,114,49,0,0,0,90,10,105,115,95,98, - 117,105,108,116,105,110,114,78,0,0,0,41,4,218,3,99, - 108,115,114,71,0,0,0,218,4,112,97,116,104,218,6,116, - 97,114,103,101,116,114,10,0,0,0,114,10,0,0,0,114, - 11,0,0,0,218,9,102,105,110,100,95,115,112,101,99,207, - 2,0,0,115,10,0,0,0,0,2,8,1,4,1,10,1, - 14,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,4,0,0,0,67,0, - 0,0,115,30,0,0,0,124,0,160,0,124,1,124,2,161, - 2,125,3,124,3,100,1,107,9,114,26,124,3,106,1,83, - 0,100,1,83,0,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,145,0,0,0, - 114,93,0,0,0,41,4,114,142,0,0,0,114,71,0,0, - 0,114,143,0,0,0,114,82,0,0,0,114,10,0,0,0, - 114,10,0,0,0,114,11,0,0,0,218,11,102,105,110,100, - 95,109,111,100,117,108,101,216,2,0,0,115,4,0,0,0, - 0,9,12,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,2,0,0,0,4,0, - 0,0,67,0,0,0,115,46,0,0,0,124,1,106,0,116, - 1,106,2,107,7,114,34,116,3,100,1,160,4,124,1,106, - 0,161,1,124,1,106,0,100,2,141,2,130,1,116,5,116, - 6,106,7,124,1,131,2,83,0,41,3,122,24,67,114,101, - 97,116,101,32,97,32,98,117,105,108,116,45,105,110,32,109, - 111,100,117,108,101,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,41,1,114,15,0,0,0,41,8,114,15,0, - 0,0,114,14,0,0,0,114,69,0,0,0,114,70,0,0, - 0,114,38,0,0,0,114,59,0,0,0,114,49,0,0,0, - 90,14,99,114,101,97,116,101,95,98,117,105,108,116,105,110, - 41,2,114,26,0,0,0,114,82,0,0,0,114,10,0,0, - 0,114,10,0,0,0,114,11,0,0,0,114,134,0,0,0, - 228,2,0,0,115,8,0,0,0,0,3,12,1,12,1,10, - 1,122,29,66,117,105,108,116,105,110,73,109,112,111,114,116, - 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,3,0,0, - 0,67,0,0,0,115,16,0,0,0,116,0,116,1,106,2, - 124,1,131,2,1,0,100,1,83,0,41,2,122,22,69,120, - 101,99,32,97,32,98,117,105,108,116,45,105,110,32,109,111, - 100,117,108,101,78,41,3,114,59,0,0,0,114,49,0,0, - 0,90,12,101,120,101,99,95,98,117,105,108,116,105,110,41, - 2,114,26,0,0,0,114,83,0,0,0,114,10,0,0,0, - 114,10,0,0,0,114,11,0,0,0,114,135,0,0,0,236, - 2,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,101,120,101,99, - 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,83,0,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,10,0,0,0,41,2,114,142,0,0,0,114, - 71,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, - 0,0,0,218,8,103,101,116,95,99,111,100,101,241,2,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,83,0, - 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,10,0, - 0,0,41,2,114,142,0,0,0,114,71,0,0,0,114,10, - 0,0,0,114,10,0,0,0,114,11,0,0,0,218,10,103, - 101,116,95,115,111,117,114,99,101,247,2,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,83,0,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,10,0,0,0,41,2,114,142, - 0,0,0,114,71,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,114,105,0,0,0,253,2,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,2,78,78,41,1,78,41,17,114,1,0,0, - 0,114,0,0,0,0,114,2,0,0,0,114,3,0,0,0, - 218,12,115,116,97,116,105,99,109,101,116,104,111,100,114,86, - 0,0,0,218,11,99,108,97,115,115,109,101,116,104,111,100, - 114,145,0,0,0,114,146,0,0,0,114,134,0,0,0,114, - 135,0,0,0,114,74,0,0,0,114,147,0,0,0,114,148, - 0,0,0,114,105,0,0,0,114,84,0,0,0,114,137,0, - 0,0,114,10,0,0,0,114,10,0,0,0,114,10,0,0, - 0,114,11,0,0,0,114,141,0,0,0,189,2,0,0,115, - 30,0,0,0,8,7,4,2,12,9,2,1,12,8,2,1, - 12,11,12,8,12,5,2,1,14,5,2,1,14,5,2,1, - 14,5,114,141,0,0,0,99,0,0,0,0,0,0,0,0, - 0,0,0,0,4,0,0,0,64,0,0,0,115,140,0,0, - 0,101,0,90,1,100,0,90,2,100,1,90,3,101,4,100, - 2,100,3,132,0,131,1,90,5,101,6,100,21,100,5,100, - 6,132,1,131,1,90,7,101,6,100,22,100,7,100,8,132, - 1,131,1,90,8,101,6,100,9,100,10,132,0,131,1,90, - 9,101,4,100,11,100,12,132,0,131,1,90,10,101,6,100, - 13,100,14,132,0,131,1,90,11,101,6,101,12,100,15,100, - 16,132,0,131,1,131,1,90,13,101,6,101,12,100,17,100, - 18,132,0,131,1,131,1,90,14,101,6,101,12,100,19,100, - 20,132,0,131,1,131,1,90,15,100,4,83,0,41,23,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,3,0,0,0, - 67,0,0,0,115,12,0,0,0,100,1,160,0,124,0,106, - 1,161,1,83,0,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,38,0,0,0,114,1,0,0,0, - 41,1,218,1,109,114,10,0,0,0,114,10,0,0,0,114, - 11,0,0,0,114,86,0,0,0,15,3,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,32,0,0,0,116,0,160,1,124, - 1,161,1,114,24,116,2,124,1,124,0,100,1,100,2,141, - 3,83,0,100,0,83,0,100,0,83,0,41,3,78,90,6, - 102,114,111,122,101,110,41,1,114,103,0,0,0,41,3,114, - 49,0,0,0,114,75,0,0,0,114,78,0,0,0,41,4, - 114,142,0,0,0,114,71,0,0,0,114,143,0,0,0,114, - 144,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, - 0,0,0,114,145,0,0,0,24,3,0,0,115,6,0,0, - 0,0,2,10,1,14,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,3,0, - 0,0,67,0,0,0,115,18,0,0,0,116,0,160,1,124, - 1,161,1,114,14,124,0,83,0,100,1,83,0,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,49,0,0,0,114,75,0,0,0,41,3,114,142,0, - 0,0,114,71,0,0,0,114,143,0,0,0,114,10,0,0, - 0,114,10,0,0,0,114,11,0,0,0,114,146,0,0,0, - 31,3,0,0,115,2,0,0,0,0,7,122,26,70,114,111, + 3,78,90,6,102,114,111,122,101,110,41,1,114,103,0,0, + 0,41,3,114,49,0,0,0,114,75,0,0,0,114,78,0, + 0,0,41,4,114,142,0,0,0,114,71,0,0,0,114,143, + 0,0,0,114,144,0,0,0,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,114,145,0,0,0,24,3,0,0, + 115,6,0,0,0,0,2,10,1,14,2,122,24,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,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,83,0,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,10,0,0,0,41,2,114,142,0,0,0, - 114,82,0,0,0,114,10,0,0,0,114,10,0,0,0,114, - 11,0,0,0,114,134,0,0,0,40,3,0,0,115,2,0, - 0,0,0,2,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,64,0,0,0,124,0,106,0, - 106,1,125,1,116,2,160,3,124,1,161,1,115,36,116,4, - 100,1,160,5,124,1,161,1,124,1,100,2,141,2,130,1, - 116,6,116,2,106,7,124,1,131,2,125,2,116,8,124,2, - 124,0,106,9,131,2,1,0,100,0,83,0,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,41,1,114,15, - 0,0,0,41,10,114,89,0,0,0,114,15,0,0,0,114, - 49,0,0,0,114,75,0,0,0,114,70,0,0,0,114,38, - 0,0,0,114,59,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,7,0,0,0,41,3,114,83,0,0,0,114,15,0, - 0,0,218,4,99,111,100,101,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,114,135,0,0,0,44,3,0,0, - 115,12,0,0,0,0,2,8,1,10,1,10,1,8,1,12, - 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,10,0,0,0,116,0,124,0,124,1,131,2,83, - 0,41,1,122,95,76,111,97,100,32,97,32,102,114,111,122, + 95,115,112,101,99,99,3,0,0,0,0,0,0,0,3,0, + 0,0,3,0,0,0,67,0,0,0,115,18,0,0,0,116, + 0,160,1,124,1,161,1,114,14,124,0,83,0,100,1,83, + 0,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,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,84,0,0,0,41,2,114,142,0, - 0,0,114,71,0,0,0,114,10,0,0,0,114,10,0,0, - 0,114,11,0,0,0,114,137,0,0,0,53,3,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,3, - 0,0,0,67,0,0,0,115,10,0,0,0,116,0,160,1, - 124,1,161,1,83,0,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,49,0,0,0,114,153, - 0,0,0,41,2,114,142,0,0,0,114,71,0,0,0,114, - 10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,147, - 0,0,0,62,3,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,83,0,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,10,0,0,0,41,2,114,142,0,0,0,114,71,0,0, - 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, - 114,148,0,0,0,68,3,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,3,0,0,0,67,0,0,0, - 115,10,0,0,0,116,0,160,1,124,1,161,1,83,0,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,49,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,142,0, - 0,0,114,71,0,0,0,114,10,0,0,0,114,10,0,0, - 0,114,11,0,0,0,114,105,0,0,0,74,3,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,2,78,78,41,1,78,41,16,114,1,0,0,0,114, - 0,0,0,0,114,2,0,0,0,114,3,0,0,0,114,149, - 0,0,0,114,86,0,0,0,114,150,0,0,0,114,145,0, - 0,0,114,146,0,0,0,114,134,0,0,0,114,135,0,0, - 0,114,137,0,0,0,114,77,0,0,0,114,147,0,0,0, - 114,148,0,0,0,114,105,0,0,0,114,10,0,0,0,114, - 10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,151, - 0,0,0,6,3,0,0,115,30,0,0,0,8,7,4,2, - 12,9,2,1,12,6,2,1,12,8,12,4,12,9,12,9, - 2,1,14,5,2,1,14,5,2,1,114,151,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,32,0,0,0,101,0,90,1,100,0,90, - 2,100,1,90,3,100,2,100,3,132,0,90,4,100,4,100, - 5,132,0,90,5,100,6,83,0,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,2,0,0,0,67,0,0,0,115,12,0,0,0,116, - 0,160,1,161,0,1,0,100,1,83,0,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,49,0,0,0,114, - 50,0,0,0,41,1,114,26,0,0,0,114,10,0,0,0, - 114,10,0,0,0,114,11,0,0,0,114,46,0,0,0,87, - 3,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,2,0,0,0,67,0,0,0,115,12,0, - 0,0,116,0,160,1,161,0,1,0,100,1,83,0,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,49,0,0,0,114,52,0,0,0,41,4,114,26,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,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,114,48,0,0,0,91,3,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,1,0,0,0,114,0,0,0,0,114, - 2,0,0,0,114,3,0,0,0,114,46,0,0,0,114,48, - 0,0,0,114,10,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,114,156,0,0,0,83,3,0,0, - 115,6,0,0,0,8,2,4,2,8,4,114,156,0,0,0, - 99,3,0,0,0,0,0,0,0,5,0,0,0,5,0,0, - 0,67,0,0,0,115,64,0,0,0,124,1,160,0,100,1, - 124,2,100,2,24,0,161,2,125,3,116,1,124,3,131,1, - 124,2,107,0,114,36,116,2,100,3,131,1,130,1,124,3, - 100,4,25,0,125,4,124,0,114,60,100,5,160,3,124,4, - 124,0,161,2,83,0,124,4,83,0,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,117,0,0,0,114,33,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,19, - 0,0,0,122,5,123,125,46,123,125,41,4,218,6,114,115, - 112,108,105,116,218,3,108,101,110,218,10,86,97,108,117,101, - 69,114,114,111,114,114,38,0,0,0,41,5,114,15,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,10,0, - 0,0,114,10,0,0,0,114,11,0,0,0,218,13,95,114, - 101,115,111,108,118,101,95,110,97,109,101,96,3,0,0,115, - 10,0,0,0,0,2,16,1,12,1,8,1,8,1,114,162, - 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,34,0,0,0,124,0,160, - 0,124,1,124,2,161,2,125,3,124,3,100,0,107,8,114, - 24,100,0,83,0,116,1,124,1,124,3,131,2,83,0,41, - 1,78,41,2,114,146,0,0,0,114,78,0,0,0,41,4, - 218,6,102,105,110,100,101,114,114,15,0,0,0,114,143,0, - 0,0,114,93,0,0,0,114,10,0,0,0,114,10,0,0, - 0,114,11,0,0,0,218,17,95,102,105,110,100,95,115,112, - 101,99,95,108,101,103,97,99,121,105,3,0,0,115,8,0, - 0,0,0,3,12,1,8,1,4,1,114,164,0,0,0,99, - 3,0,0,0,0,0,0,0,10,0,0,0,10,0,0,0, - 67,0,0,0,115,240,0,0,0,116,0,106,1,125,3,124, - 3,100,1,107,8,114,22,116,2,100,2,131,1,130,1,124, - 3,115,38,116,3,160,4,100,3,116,5,161,2,1,0,124, - 0,116,0,106,6,107,6,125,4,120,186,124,3,68,0,93, - 174,125,5,116,7,131,0,143,72,1,0,121,10,124,5,106, - 8,125,6,87,0,110,42,4,0,116,9,107,10,114,118,1, - 0,1,0,1,0,116,10,124,5,124,0,124,1,131,3,125, - 7,124,7,100,1,107,8,114,114,119,54,89,0,110,14,88, - 0,124,6,124,0,124,1,124,2,131,3,125,7,87,0,100, - 1,81,0,82,0,88,0,124,7,100,1,107,9,114,54,124, - 4,115,224,124,0,116,0,106,6,107,6,114,224,116,0,106, - 6,124,0,25,0,125,8,121,10,124,8,106,11,125,9,87, - 0,110,20,4,0,116,9,107,10,114,204,1,0,1,0,1, - 0,124,7,83,0,88,0,124,9,100,1,107,8,114,218,124, - 7,83,0,124,9,83,0,113,54,124,7,83,0,113,54,87, - 0,100,1,83,0,100,1,83,0,41,4,122,21,70,105,110, + 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,49,0,0,0,114,75,0,0,0,41, + 3,114,142,0,0,0,114,71,0,0,0,114,143,0,0,0, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, + 146,0,0,0,31,3,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,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,83,0,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,10,0,0,0,41,2,114, + 142,0,0,0,114,82,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,114,134,0,0,0,40,3,0, + 0,115,2,0,0,0,0,2,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,64,0,0,0, + 124,0,106,0,106,1,125,1,116,2,160,3,124,1,161,1, + 115,36,116,4,100,1,160,5,124,1,161,1,124,1,100,2, + 141,2,130,1,116,6,116,2,106,7,124,1,131,2,125,2, + 116,8,124,2,124,0,106,9,131,2,1,0,100,0,83,0, + 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, + 41,1,114,15,0,0,0,41,10,114,89,0,0,0,114,15, + 0,0,0,114,49,0,0,0,114,75,0,0,0,114,70,0, + 0,0,114,38,0,0,0,114,59,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,7,0,0,0,41,3,114,83,0,0, + 0,114,15,0,0,0,218,4,99,111,100,101,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,114,135,0,0,0, + 44,3,0,0,115,12,0,0,0,0,2,8,1,10,1,10, + 1,8,1,12,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,10,0,0,0,116,0,124,0,124, + 1,131,2,83,0,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,84,0,0,0,41, + 2,114,142,0,0,0,114,71,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,11,0,0,0,114,137,0,0,0,53, + 3,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,3,0,0,0,67,0,0,0,115,10,0,0,0, + 116,0,160,1,124,1,161,1,83,0,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,49,0, + 0,0,114,153,0,0,0,41,2,114,142,0,0,0,114,71, + 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,114,147,0,0,0,62,3,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,83,0,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,10,0,0,0,41,2,114,142,0,0,0, + 114,71,0,0,0,114,10,0,0,0,114,10,0,0,0,114, + 11,0,0,0,114,148,0,0,0,68,3,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,3,0,0,0, + 67,0,0,0,115,10,0,0,0,116,0,160,1,124,1,161, + 1,83,0,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,49,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,142,0,0,0,114,71,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,11,0,0,0,114,105,0,0,0,74, + 3,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,2,78,78,41,1,78,41,16,114,1, + 0,0,0,114,0,0,0,0,114,2,0,0,0,114,3,0, + 0,0,114,149,0,0,0,114,86,0,0,0,114,150,0,0, + 0,114,145,0,0,0,114,146,0,0,0,114,134,0,0,0, + 114,135,0,0,0,114,137,0,0,0,114,77,0,0,0,114, + 147,0,0,0,114,148,0,0,0,114,105,0,0,0,114,10, + 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,114,151,0,0,0,6,3,0,0,115,30,0,0,0, + 8,7,4,2,12,9,2,1,12,6,2,1,12,8,12,4, + 12,9,12,9,2,1,14,5,2,1,14,5,2,1,114,151, + 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,32,0,0,0,101,0,90, + 1,100,0,90,2,100,1,90,3,100,2,100,3,132,0,90, + 4,100,4,100,5,132,0,90,5,100,6,83,0,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,2,0,0,0,67,0,0,0,115,12, + 0,0,0,116,0,160,1,161,0,1,0,100,1,83,0,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,49, + 0,0,0,114,50,0,0,0,41,1,114,26,0,0,0,114, + 10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,46, + 0,0,0,87,3,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,2,0,0,0,67,0,0, + 0,115,12,0,0,0,116,0,160,1,161,0,1,0,100,1, + 83,0,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,49,0,0,0,114,52,0,0,0,41, + 4,114,26,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,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,114,48,0,0,0,91,3, + 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,1,0,0,0,114,0, + 0,0,0,114,2,0,0,0,114,3,0,0,0,114,46,0, + 0,0,114,48,0,0,0,114,10,0,0,0,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,114,156,0,0,0, + 83,3,0,0,115,6,0,0,0,8,2,4,2,8,4,114, + 156,0,0,0,99,3,0,0,0,0,0,0,0,5,0,0, + 0,5,0,0,0,67,0,0,0,115,64,0,0,0,124,1, + 160,0,100,1,124,2,100,2,24,0,161,2,125,3,116,1, + 124,3,131,1,124,2,107,0,114,36,116,2,100,3,131,1, + 130,1,124,3,100,4,25,0,125,4,124,0,114,60,100,5, + 160,3,124,4,124,0,161,2,83,0,124,4,83,0,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,117,0,0,0,114,33,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,19,0,0,0,122,5,123,125,46,123,125,41,4, + 218,6,114,115,112,108,105,116,218,3,108,101,110,218,10,86, + 97,108,117,101,69,114,114,111,114,114,38,0,0,0,41,5, + 114,15,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,10,0,0,0,114,10,0,0,0,114,11,0,0,0, + 218,13,95,114,101,115,111,108,118,101,95,110,97,109,101,96, + 3,0,0,115,10,0,0,0,0,2,16,1,12,1,8,1, + 8,1,114,162,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,34,0,0, + 0,124,0,160,0,124,1,124,2,161,2,125,3,124,3,100, + 0,107,8,114,24,100,0,83,0,116,1,124,1,124,3,131, + 2,83,0,41,1,78,41,2,114,146,0,0,0,114,78,0, + 0,0,41,4,218,6,102,105,110,100,101,114,114,15,0,0, + 0,114,143,0,0,0,114,93,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,11,0,0,0,218,17,95,102,105,110, + 100,95,115,112,101,99,95,108,101,103,97,99,121,105,3,0, + 0,115,8,0,0,0,0,3,12,1,8,1,4,1,114,164, + 0,0,0,99,3,0,0,0,0,0,0,0,10,0,0,0, + 10,0,0,0,67,0,0,0,115,12,1,0,0,116,0,106, + 1,125,3,124,3,100,1,107,8,114,22,116,2,100,2,131, + 1,130,1,124,3,115,38,116,3,160,4,100,3,116,5,161, + 2,1,0,124,0,116,0,106,6,107,6,125,4,124,3,68, + 0,93,210,125,5,116,7,131,0,143,84,1,0,122,10,124, + 5,106,8,125,6,87,0,110,54,4,0,116,9,107,10,114, + 128,1,0,1,0,1,0,116,10,124,5,124,0,124,1,131, + 3,125,7,124,7,100,1,107,8,114,124,89,0,87,0,53, + 0,81,0,82,0,163,0,113,52,89,0,110,14,88,0,124, + 6,124,0,124,1,124,2,131,3,125,7,87,0,53,0,81, + 0,82,0,88,0,124,7,100,1,107,9,114,52,124,4,144, + 0,115,254,124,0,116,0,106,6,107,6,144,0,114,254,116, + 0,106,6,124,0,25,0,125,8,122,10,124,8,106,11,125, + 9,87,0,110,28,4,0,116,9,107,10,114,226,1,0,1, + 0,1,0,124,7,6,0,89,0,2,0,1,0,83,0,88, + 0,124,9,100,1,107,8,114,244,124,7,2,0,1,0,83, + 0,124,9,2,0,1,0,83,0,113,52,124,7,2,0,1, + 0,83,0,113,52,100,1,83,0,41,4,122,21,70,105,110, 100,32,97,32,109,111,100,117,108,101,39,115,32,115,112,101, 99,46,78,122,53,115,121,115,46,109,101,116,97,95,112,97, 116,104,32,105,115,32,78,111,110,101,44,32,80,121,116,104, @@ -1443,9 +1449,9 @@ const unsigned char _Py_M__importlib[] = { 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, 218,10,95,102,105,110,100,95,115,112,101,99,114,3,0,0, 115,54,0,0,0,0,2,6,1,8,2,8,3,4,1,12, - 5,10,1,10,1,8,1,2,1,10,1,14,1,12,1,8, - 1,8,2,22,1,8,2,14,1,10,1,2,1,10,1,14, - 4,6,2,8,1,4,2,6,2,8,2,114,169,0,0,0, + 5,10,1,8,1,8,1,2,1,10,1,14,1,12,1,8, + 1,20,2,22,1,8,2,18,1,10,1,2,1,10,1,14, + 4,14,2,8,1,8,2,10,2,10,2,114,169,0,0,0, 99,3,0,0,0,0,0,0,0,3,0,0,0,5,0,0, 0,67,0,0,0,115,108,0,0,0,116,0,124,0,116,1, 131,2,115,28,116,2,100,1,160,3,116,4,124,0,131,1, @@ -1482,7 +1488,7 @@ const unsigned char _Py_M__importlib[] = { 100,2,25,0,125,3,124,3,114,134,124,3,116,1,106,2, 107,7,114,42,116,3,124,1,124,3,131,2,1,0,124,0, 116,1,106,2,107,6,114,62,116,1,106,2,124,0,25,0, - 83,0,116,1,106,2,124,3,25,0,125,4,121,10,124,4, + 83,0,116,1,106,2,124,3,25,0,125,4,122,10,124,4, 106,4,125,2,87,0,110,50,4,0,116,5,107,10,114,132, 1,0,1,0,1,0,116,6,100,3,23,0,160,7,124,0, 124,3,161,2,125,5,116,8,124,5,124,0,100,4,141,2, @@ -1510,315 +1516,316 @@ const unsigned char _Py_M__importlib[] = { 4,1,14,1,4,1,10,1,10,2,10,1,10,1,10,1, 2,1,10,1,14,1,16,1,20,1,10,1,8,1,20,2, 8,1,4,2,10,1,22,1,114,178,0,0,0,99,2,0, - 0,0,0,0,0,0,4,0,0,0,9,0,0,0,67,0, - 0,0,115,94,0,0,0,116,0,124,0,131,1,143,38,1, + 0,0,0,0,0,0,4,0,0,0,10,0,0,0,67,0, + 0,0,115,106,0,0,0,116,0,124,0,131,1,143,50,1, 0,116,1,106,2,160,3,124,0,116,4,161,2,125,2,124, - 2,116,4,107,8,114,42,116,5,124,0,124,1,131,2,83, - 0,87,0,100,1,81,0,82,0,88,0,124,2,100,1,107, - 8,114,82,100,2,160,6,124,0,161,1,125,3,116,7,124, - 3,124,0,100,3,141,2,130,1,116,8,124,0,131,1,1, - 0,124,2,83,0,41,4,122,25,70,105,110,100,32,97,110, - 100,32,108,111,97,100,32,116,104,101,32,109,111,100,117,108, - 101,46,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,41,1,114, - 15,0,0,0,41,9,114,42,0,0,0,114,14,0,0,0, - 114,79,0,0,0,114,30,0,0,0,218,14,95,78,69,69, - 68,83,95,76,79,65,68,73,78,71,114,178,0,0,0,114, - 38,0,0,0,114,176,0,0,0,114,57,0,0,0,41,4, - 114,15,0,0,0,114,177,0,0,0,114,83,0,0,0,114, - 67,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, - 0,0,0,218,14,95,102,105,110,100,95,97,110,100,95,108, - 111,97,100,210,3,0,0,115,20,0,0,0,0,2,10,1, - 14,1,8,1,20,2,8,1,4,1,6,1,12,2,8,1, - 114,180,0,0,0,114,19,0,0,0,99,3,0,0,0,0, - 0,0,0,3,0,0,0,4,0,0,0,67,0,0,0,115, - 42,0,0,0,116,0,124,0,124,1,124,2,131,3,1,0, - 124,2,100,1,107,4,114,32,116,1,124,0,124,1,124,2, - 131,3,125,0,116,2,124,0,116,3,131,2,83,0,41,2, - 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,19,0,0,0,41,4,114,173, - 0,0,0,114,162,0,0,0,114,180,0,0,0,218,11,95, - 103,99,100,95,105,109,112,111,114,116,41,3,114,15,0,0, - 0,114,160,0,0,0,114,161,0,0,0,114,10,0,0,0, - 114,10,0,0,0,114,11,0,0,0,114,181,0,0,0,226, - 3,0,0,115,8,0,0,0,0,9,12,1,8,1,12,1, - 114,181,0,0,0,41,1,218,9,114,101,99,117,114,115,105, - 118,101,99,3,0,0,0,1,0,0,0,8,0,0,0,11, - 0,0,0,67,0,0,0,115,234,0,0,0,116,0,124,0, - 100,1,131,2,114,230,120,218,124,1,68,0,93,210,125,4, - 116,1,124,4,116,2,131,2,115,78,124,3,114,46,124,0, - 106,3,100,2,23,0,125,5,110,4,100,3,125,5,116,4, - 100,4,124,5,155,0,100,5,116,5,124,4,131,1,106,3, - 155,0,157,4,131,1,130,1,113,16,124,4,100,6,107,2, - 114,120,124,3,115,226,116,0,124,0,100,7,131,2,114,226, - 116,6,124,0,124,0,106,7,124,2,100,8,100,9,141,4, - 1,0,113,16,116,0,124,0,124,4,131,2,115,16,100,10, - 160,8,124,0,106,3,124,4,161,2,125,6,121,14,116,9, - 124,2,124,6,131,2,1,0,87,0,113,16,4,0,116,10, - 107,10,114,224,1,0,125,7,1,0,122,36,124,7,106,11, - 124,6,107,2,114,206,116,12,106,13,160,14,124,6,116,15, - 161,2,100,11,107,9,114,206,119,16,130,0,87,0,100,11, - 100,11,125,7,126,7,88,0,89,0,113,16,88,0,113,16, - 87,0,124,0,83,0,41,12,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,127,0,0,0,122,8,46, - 95,95,97,108,108,95,95,122,13,96,96,102,114,111,109,32, - 108,105,115,116,39,39,122,8,73,116,101,109,32,105,110,32, - 122,18,32,109,117,115,116,32,98,101,32,115,116,114,44,32, - 110,111,116,32,250,1,42,218,7,95,95,97,108,108,95,95, - 84,41,1,114,182,0,0,0,122,5,123,125,46,123,125,78, - 41,16,114,4,0,0,0,114,170,0,0,0,114,171,0,0, - 0,114,1,0,0,0,114,172,0,0,0,114,13,0,0,0, - 218,16,95,104,97,110,100,108,101,95,102,114,111,109,108,105, - 115,116,114,184,0,0,0,114,38,0,0,0,114,59,0,0, - 0,114,176,0,0,0,114,15,0,0,0,114,14,0,0,0, - 114,79,0,0,0,114,30,0,0,0,114,179,0,0,0,41, - 8,114,83,0,0,0,218,8,102,114,111,109,108,105,115,116, - 114,177,0,0,0,114,182,0,0,0,218,1,120,90,5,119, - 104,101,114,101,90,9,102,114,111,109,95,110,97,109,101,90, - 3,101,120,99,114,10,0,0,0,114,10,0,0,0,114,11, - 0,0,0,114,185,0,0,0,241,3,0,0,115,42,0,0, - 0,0,10,10,1,10,1,10,1,4,1,12,2,4,1,28, - 2,8,1,14,1,10,1,10,1,10,1,14,1,2,1,14, - 1,16,4,10,1,18,1,2,1,24,1,114,185,0,0,0, - 99,1,0,0,0,0,0,0,0,3,0,0,0,6,0,0, - 0,67,0,0,0,115,146,0,0,0,124,0,160,0,100,1, - 161,1,125,1,124,0,160,0,100,2,161,1,125,2,124,1, - 100,3,107,9,114,82,124,2,100,3,107,9,114,78,124,1, - 124,2,106,1,107,3,114,78,116,2,106,3,100,4,124,1, - 155,2,100,5,124,2,106,1,155,2,100,6,157,5,116,4, - 100,7,100,8,141,3,1,0,124,1,83,0,124,2,100,3, - 107,9,114,96,124,2,106,1,83,0,116,2,106,3,100,9, - 116,4,100,7,100,8,141,3,1,0,124,0,100,10,25,0, - 125,1,100,11,124,0,107,7,114,142,124,1,160,5,100,12, - 161,1,100,13,25,0,125,1,124,1,83,0,41,14,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,130,0,0,0,114,89,0,0, - 0,78,122,32,95,95,112,97,99,107,97,103,101,95,95,32, - 33,61,32,95,95,115,112,101,99,95,95,46,112,97,114,101, - 110,116,32,40,122,4,32,33,61,32,250,1,41,233,3,0, - 0,0,41,1,90,10,115,116,97,99,107,108,101,118,101,108, - 122,89,99,97,110,39,116,32,114,101,115,111,108,118,101,32, - 112,97,99,107,97,103,101,32,102,114,111,109,32,95,95,115, - 112,101,99,95,95,32,111,114,32,95,95,112,97,99,107,97, - 103,101,95,95,44,32,102,97,108,108,105,110,103,32,98,97, - 99,107,32,111,110,32,95,95,110,97,109,101,95,95,32,97, - 110,100,32,95,95,112,97,116,104,95,95,114,1,0,0,0, - 114,127,0,0,0,114,117,0,0,0,114,19,0,0,0,41, - 6,114,30,0,0,0,114,119,0,0,0,114,166,0,0,0, - 114,167,0,0,0,114,168,0,0,0,114,118,0,0,0,41, - 3,218,7,103,108,111,98,97,108,115,114,160,0,0,0,114, - 82,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, - 0,0,0,218,17,95,99,97,108,99,95,95,95,112,97,99, - 107,97,103,101,95,95,23,4,0,0,115,30,0,0,0,0, - 7,10,1,10,1,8,1,18,1,22,2,10,1,4,1,8, - 1,6,2,6,2,10,1,8,1,8,1,14,1,114,191,0, - 0,0,114,10,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,166,0,0, - 0,124,4,100,1,107,2,114,18,116,0,124,0,131,1,125, - 5,110,36,124,1,100,2,107,9,114,30,124,1,110,2,105, - 0,125,6,116,1,124,6,131,1,125,7,116,0,124,0,124, - 7,124,4,131,3,125,5,124,3,115,150,124,4,100,1,107, - 2,114,84,116,0,124,0,160,2,100,3,161,1,100,1,25, - 0,131,1,83,0,124,0,115,92,124,5,83,0,116,3,124, - 0,131,1,116,3,124,0,160,2,100,3,161,1,100,1,25, - 0,131,1,24,0,125,8,116,4,106,5,124,5,106,6,100, - 2,116,3,124,5,106,6,131,1,124,8,24,0,133,2,25, - 0,25,0,83,0,110,12,116,7,124,5,124,3,116,0,131, - 3,83,0,100,2,83,0,41,4,97,215,1,0,0,73,109, - 112,111,114,116,32,97,32,109,111,100,117,108,101,46,10,10, - 32,32,32,32,84,104,101,32,39,103,108,111,98,97,108,115, - 39,32,97,114,103,117,109,101,110,116,32,105,115,32,117,115, - 101,100,32,116,111,32,105,110,102,101,114,32,119,104,101,114, - 101,32,116,104,101,32,105,109,112,111,114,116,32,105,115,32, - 111,99,99,117,114,114,105,110,103,32,102,114,111,109,10,32, - 32,32,32,116,111,32,104,97,110,100,108,101,32,114,101,108, - 97,116,105,118,101,32,105,109,112,111,114,116,115,46,32,84, - 104,101,32,39,108,111,99,97,108,115,39,32,97,114,103,117, - 109,101,110,116,32,105,115,32,105,103,110,111,114,101,100,46, - 32,84,104,101,10,32,32,32,32,39,102,114,111,109,108,105, - 115,116,39,32,97,114,103,117,109,101,110,116,32,115,112,101, - 99,105,102,105,101,115,32,119,104,97,116,32,115,104,111,117, - 108,100,32,101,120,105,115,116,32,97,115,32,97,116,116,114, - 105,98,117,116,101,115,32,111,110,32,116,104,101,32,109,111, - 100,117,108,101,10,32,32,32,32,98,101,105,110,103,32,105, - 109,112,111,114,116,101,100,32,40,101,46,103,46,32,96,96, - 102,114,111,109,32,109,111,100,117,108,101,32,105,109,112,111, - 114,116,32,60,102,114,111,109,108,105,115,116,62,96,96,41, - 46,32,32,84,104,101,32,39,108,101,118,101,108,39,10,32, - 32,32,32,97,114,103,117,109,101,110,116,32,114,101,112,114, - 101,115,101,110,116,115,32,116,104,101,32,112,97,99,107,97, - 103,101,32,108,111,99,97,116,105,111,110,32,116,111,32,105, - 109,112,111,114,116,32,102,114,111,109,32,105,110,32,97,32, - 114,101,108,97,116,105,118,101,10,32,32,32,32,105,109,112, - 111,114,116,32,40,101,46,103,46,32,96,96,102,114,111,109, - 32,46,46,112,107,103,32,105,109,112,111,114,116,32,109,111, - 100,96,96,32,119,111,117,108,100,32,104,97,118,101,32,97, - 32,39,108,101,118,101,108,39,32,111,102,32,50,41,46,10, - 10,32,32,32,32,114,19,0,0,0,78,114,117,0,0,0, - 41,8,114,181,0,0,0,114,191,0,0,0,218,9,112,97, + 2,116,4,107,8,114,54,116,5,124,0,124,1,131,2,87, + 0,2,0,53,0,81,0,82,0,163,0,83,0,87,0,53, + 0,81,0,82,0,88,0,124,2,100,1,107,8,114,94,100, + 2,160,6,124,0,161,1,125,3,116,7,124,3,124,0,100, + 3,141,2,130,1,116,8,124,0,131,1,1,0,124,2,83, + 0,41,4,122,25,70,105,110,100,32,97,110,100,32,108,111, + 97,100,32,116,104,101,32,109,111,100,117,108,101,46,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,41,1,114,15,0,0,0, + 41,9,114,42,0,0,0,114,14,0,0,0,114,79,0,0, + 0,114,30,0,0,0,218,14,95,78,69,69,68,83,95,76, + 79,65,68,73,78,71,114,178,0,0,0,114,38,0,0,0, + 114,176,0,0,0,114,57,0,0,0,41,4,114,15,0,0, + 0,114,177,0,0,0,114,83,0,0,0,114,67,0,0,0, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,218, + 14,95,102,105,110,100,95,97,110,100,95,108,111,97,100,210, + 3,0,0,115,20,0,0,0,0,2,10,1,14,1,8,1, + 32,2,8,1,4,1,6,1,12,2,8,1,114,180,0,0, + 0,114,19,0,0,0,99,3,0,0,0,0,0,0,0,3, + 0,0,0,4,0,0,0,67,0,0,0,115,42,0,0,0, + 116,0,124,0,124,1,124,2,131,3,1,0,124,2,100,1, + 107,4,114,32,116,1,124,0,124,1,124,2,131,3,125,0, + 116,2,124,0,116,3,131,2,83,0,41,2,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,19,0,0,0,41,4,114,173,0,0,0,114, + 162,0,0,0,114,180,0,0,0,218,11,95,103,99,100,95, + 105,109,112,111,114,116,41,3,114,15,0,0,0,114,160,0, + 0,0,114,161,0,0,0,114,10,0,0,0,114,10,0,0, + 0,114,11,0,0,0,114,181,0,0,0,226,3,0,0,115, + 8,0,0,0,0,9,12,1,8,1,12,1,114,181,0,0, + 0,41,1,218,9,114,101,99,117,114,115,105,118,101,99,3, + 0,0,0,1,0,0,0,8,0,0,0,11,0,0,0,67, + 0,0,0,115,226,0,0,0,124,1,68,0,93,216,125,4, + 116,0,124,4,116,1,131,2,115,66,124,3,114,34,124,0, + 106,2,100,1,23,0,125,5,110,4,100,2,125,5,116,3, + 100,3,124,5,155,0,100,4,116,4,124,4,131,1,106,2, + 155,0,157,4,131,1,130,1,113,4,124,4,100,5,107,2, + 114,108,124,3,115,220,116,5,124,0,100,6,131,2,114,220, + 116,6,124,0,124,0,106,7,124,2,100,7,100,8,141,4, + 1,0,113,4,116,5,124,0,124,4,131,2,115,4,100,9, + 160,8,124,0,106,2,124,4,161,2,125,6,122,14,116,9, + 124,2,124,6,131,2,1,0,87,0,113,4,4,0,116,10, + 107,10,114,218,1,0,125,7,1,0,122,42,124,7,106,11, + 124,6,107,2,114,200,116,12,106,13,160,14,124,6,116,15, + 161,2,100,10,107,9,114,200,87,0,89,0,162,8,113,4, + 130,0,87,0,53,0,100,10,125,7,126,7,88,0,89,0, + 113,4,88,0,113,4,124,0,83,0,41,11,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,122,8,46,95, + 95,97,108,108,95,95,122,13,96,96,102,114,111,109,32,108, + 105,115,116,39,39,122,8,73,116,101,109,32,105,110,32,122, + 18,32,109,117,115,116,32,98,101,32,115,116,114,44,32,110, + 111,116,32,250,1,42,218,7,95,95,97,108,108,95,95,84, + 41,1,114,182,0,0,0,122,5,123,125,46,123,125,78,41, + 16,114,170,0,0,0,114,171,0,0,0,114,1,0,0,0, + 114,172,0,0,0,114,13,0,0,0,114,4,0,0,0,218, + 16,95,104,97,110,100,108,101,95,102,114,111,109,108,105,115, + 116,114,184,0,0,0,114,38,0,0,0,114,59,0,0,0, + 114,176,0,0,0,114,15,0,0,0,114,14,0,0,0,114, + 79,0,0,0,114,30,0,0,0,114,179,0,0,0,41,8, + 114,83,0,0,0,218,8,102,114,111,109,108,105,115,116,114, + 177,0,0,0,114,182,0,0,0,218,1,120,90,5,119,104, + 101,114,101,90,9,102,114,111,109,95,110,97,109,101,90,3, + 101,120,99,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,114,185,0,0,0,241,3,0,0,115,40,0,0,0, + 0,10,8,1,10,1,4,1,12,2,4,1,28,2,8,1, + 14,1,10,1,10,1,10,1,14,1,2,1,14,1,16,4, + 10,1,18,1,8,1,22,1,114,185,0,0,0,99,1,0, + 0,0,0,0,0,0,3,0,0,0,6,0,0,0,67,0, + 0,0,115,146,0,0,0,124,0,160,0,100,1,161,1,125, + 1,124,0,160,0,100,2,161,1,125,2,124,1,100,3,107, + 9,114,82,124,2,100,3,107,9,114,78,124,1,124,2,106, + 1,107,3,114,78,116,2,106,3,100,4,124,1,155,2,100, + 5,124,2,106,1,155,2,100,6,157,5,116,4,100,7,100, + 8,141,3,1,0,124,1,83,0,124,2,100,3,107,9,114, + 96,124,2,106,1,83,0,116,2,106,3,100,9,116,4,100, + 7,100,8,141,3,1,0,124,0,100,10,25,0,125,1,100, + 11,124,0,107,7,114,142,124,1,160,5,100,12,161,1,100, + 13,25,0,125,1,124,1,83,0,41,14,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,130,0,0,0,114,89,0,0,0,78,122, + 32,95,95,112,97,99,107,97,103,101,95,95,32,33,61,32, + 95,95,115,112,101,99,95,95,46,112,97,114,101,110,116,32, + 40,122,4,32,33,61,32,250,1,41,233,3,0,0,0,41, + 1,90,10,115,116,97,99,107,108,101,118,101,108,122,89,99, + 97,110,39,116,32,114,101,115,111,108,118,101,32,112,97,99, + 107,97,103,101,32,102,114,111,109,32,95,95,115,112,101,99, + 95,95,32,111,114,32,95,95,112,97,99,107,97,103,101,95, + 95,44,32,102,97,108,108,105,110,103,32,98,97,99,107,32, + 111,110,32,95,95,110,97,109,101,95,95,32,97,110,100,32, + 95,95,112,97,116,104,95,95,114,1,0,0,0,114,127,0, + 0,0,114,117,0,0,0,114,19,0,0,0,41,6,114,30, + 0,0,0,114,119,0,0,0,114,166,0,0,0,114,167,0, + 0,0,114,168,0,0,0,114,118,0,0,0,41,3,218,7, + 103,108,111,98,97,108,115,114,160,0,0,0,114,82,0,0, + 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, + 218,17,95,99,97,108,99,95,95,95,112,97,99,107,97,103, + 101,95,95,22,4,0,0,115,30,0,0,0,0,7,10,1, + 10,1,8,1,18,1,22,2,10,1,4,1,8,1,6,2, + 6,2,10,1,8,1,8,1,14,1,114,191,0,0,0,114, + 10,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,180,0,0,0,124,4, + 100,1,107,2,114,18,116,0,124,0,131,1,125,5,110,36, + 124,1,100,2,107,9,114,30,124,1,110,2,105,0,125,6, + 116,1,124,6,131,1,125,7,116,0,124,0,124,7,124,4, + 131,3,125,5,124,3,115,150,124,4,100,1,107,2,114,84, + 116,0,124,0,160,2,100,3,161,1,100,1,25,0,131,1, + 83,0,124,0,115,92,124,5,83,0,116,3,124,0,131,1, + 116,3,124,0,160,2,100,3,161,1,100,1,25,0,131,1, + 24,0,125,8,116,4,106,5,124,5,106,6,100,2,116,3, + 124,5,106,6,131,1,124,8,24,0,133,2,25,0,25,0, + 83,0,110,26,116,7,124,5,100,4,131,2,114,172,116,8, + 124,5,124,3,116,0,131,3,83,0,124,5,83,0,100,2, + 83,0,41,5,97,215,1,0,0,73,109,112,111,114,116,32, + 97,32,109,111,100,117,108,101,46,10,10,32,32,32,32,84, + 104,101,32,39,103,108,111,98,97,108,115,39,32,97,114,103, + 117,109,101,110,116,32,105,115,32,117,115,101,100,32,116,111, + 32,105,110,102,101,114,32,119,104,101,114,101,32,116,104,101, + 32,105,109,112,111,114,116,32,105,115,32,111,99,99,117,114, + 114,105,110,103,32,102,114,111,109,10,32,32,32,32,116,111, + 32,104,97,110,100,108,101,32,114,101,108,97,116,105,118,101, + 32,105,109,112,111,114,116,115,46,32,84,104,101,32,39,108, + 111,99,97,108,115,39,32,97,114,103,117,109,101,110,116,32, + 105,115,32,105,103,110,111,114,101,100,46,32,84,104,101,10, + 32,32,32,32,39,102,114,111,109,108,105,115,116,39,32,97, + 114,103,117,109,101,110,116,32,115,112,101,99,105,102,105,101, + 115,32,119,104,97,116,32,115,104,111,117,108,100,32,101,120, + 105,115,116,32,97,115,32,97,116,116,114,105,98,117,116,101, + 115,32,111,110,32,116,104,101,32,109,111,100,117,108,101,10, + 32,32,32,32,98,101,105,110,103,32,105,109,112,111,114,116, + 101,100,32,40,101,46,103,46,32,96,96,102,114,111,109,32, + 109,111,100,117,108,101,32,105,109,112,111,114,116,32,60,102, + 114,111,109,108,105,115,116,62,96,96,41,46,32,32,84,104, + 101,32,39,108,101,118,101,108,39,10,32,32,32,32,97,114, + 103,117,109,101,110,116,32,114,101,112,114,101,115,101,110,116, + 115,32,116,104,101,32,112,97,99,107,97,103,101,32,108,111, + 99,97,116,105,111,110,32,116,111,32,105,109,112,111,114,116, + 32,102,114,111,109,32,105,110,32,97,32,114,101,108,97,116, + 105,118,101,10,32,32,32,32,105,109,112,111,114,116,32,40, + 101,46,103,46,32,96,96,102,114,111,109,32,46,46,112,107, + 103,32,105,109,112,111,114,116,32,109,111,100,96,96,32,119, + 111,117,108,100,32,104,97,118,101,32,97,32,39,108,101,118, + 101,108,39,32,111,102,32,50,41,46,10,10,32,32,32,32, + 114,19,0,0,0,78,114,117,0,0,0,114,127,0,0,0, + 41,9,114,181,0,0,0,114,191,0,0,0,218,9,112,97, 114,116,105,116,105,111,110,114,158,0,0,0,114,14,0,0, - 0,114,79,0,0,0,114,1,0,0,0,114,185,0,0,0, - 41,9,114,15,0,0,0,114,190,0,0,0,218,6,108,111, - 99,97,108,115,114,186,0,0,0,114,161,0,0,0,114,83, - 0,0,0,90,8,103,108,111,98,97,108,115,95,114,160,0, - 0,0,90,7,99,117,116,95,111,102,102,114,10,0,0,0, - 114,10,0,0,0,114,11,0,0,0,218,10,95,95,105,109, - 112,111,114,116,95,95,50,4,0,0,115,26,0,0,0,0, - 11,8,1,10,2,16,1,8,1,12,1,4,3,8,1,18, - 1,4,1,4,4,26,3,32,2,114,194,0,0,0,99,1, - 0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,67, - 0,0,0,115,38,0,0,0,116,0,160,1,124,0,161,1, - 125,1,124,1,100,0,107,8,114,30,116,2,100,1,124,0, - 23,0,131,1,130,1,116,3,124,1,131,1,83,0,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,141, - 0,0,0,114,145,0,0,0,114,70,0,0,0,114,140,0, - 0,0,41,2,114,15,0,0,0,114,82,0,0,0,114,10, - 0,0,0,114,10,0,0,0,114,11,0,0,0,218,18,95, - 98,117,105,108,116,105,110,95,102,114,111,109,95,110,97,109, - 101,85,4,0,0,115,8,0,0,0,0,1,10,1,8,1, - 12,1,114,195,0,0,0,99,2,0,0,0,0,0,0,0, - 10,0,0,0,5,0,0,0,67,0,0,0,115,174,0,0, - 0,124,1,97,0,124,0,97,1,116,2,116,1,131,1,125, - 2,120,86,116,1,106,3,160,4,161,0,68,0,93,72,92, - 2,125,3,125,4,116,5,124,4,124,2,131,2,114,28,124, - 3,116,1,106,6,107,6,114,62,116,7,125,5,110,18,116, - 0,160,8,124,3,161,1,114,28,116,9,125,5,110,2,113, - 28,116,10,124,4,124,5,131,2,125,6,116,11,124,6,124, - 4,131,2,1,0,113,28,87,0,116,1,106,3,116,12,25, - 0,125,7,120,54,100,1,68,0,93,46,125,8,124,8,116, - 1,106,3,107,7,114,144,116,13,124,8,131,1,125,9,110, - 10,116,1,106,3,124,8,25,0,125,9,116,14,124,7,124, - 8,124,9,131,3,1,0,113,120,87,0,100,2,83,0,41, - 3,122,250,83,101,116,117,112,32,105,109,112,111,114,116,108, - 105,98,32,98,121,32,105,109,112,111,114,116,105,110,103,32, - 110,101,101,100,101,100,32,98,117,105,108,116,45,105,110,32, - 109,111,100,117,108,101,115,32,97,110,100,32,105,110,106,101, - 99,116,105,110,103,32,116,104,101,109,10,32,32,32,32,105, - 110,116,111,32,116,104,101,32,103,108,111,98,97,108,32,110, - 97,109,101,115,112,97,99,101,46,10,10,32,32,32,32,65, - 115,32,115,121,115,32,105,115,32,110,101,101,100,101,100,32, - 102,111,114,32,115,121,115,46,109,111,100,117,108,101,115,32, - 97,99,99,101,115,115,32,97,110,100,32,95,105,109,112,32, - 105,115,32,110,101,101,100,101,100,32,116,111,32,108,111,97, - 100,32,98,117,105,108,116,45,105,110,10,32,32,32,32,109, - 111,100,117,108,101,115,44,32,116,104,111,115,101,32,116,119, - 111,32,109,111,100,117,108,101,115,32,109,117,115,116,32,98, - 101,32,101,120,112,108,105,99,105,116,108,121,32,112,97,115, - 115,101,100,32,105,110,46,10,10,32,32,32,32,41,3,114, - 20,0,0,0,114,166,0,0,0,114,56,0,0,0,78,41, - 15,114,49,0,0,0,114,14,0,0,0,114,13,0,0,0, - 114,79,0,0,0,218,5,105,116,101,109,115,114,170,0,0, - 0,114,69,0,0,0,114,141,0,0,0,114,75,0,0,0, - 114,151,0,0,0,114,128,0,0,0,114,133,0,0,0,114, - 1,0,0,0,114,195,0,0,0,114,5,0,0,0,41,10, - 218,10,115,121,115,95,109,111,100,117,108,101,218,11,95,105, - 109,112,95,109,111,100,117,108,101,90,11,109,111,100,117,108, - 101,95,116,121,112,101,114,15,0,0,0,114,83,0,0,0, - 114,93,0,0,0,114,82,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,114,10,0,0,0,114,10,0,0,0,114, - 11,0,0,0,218,6,95,115,101,116,117,112,92,4,0,0, - 115,36,0,0,0,0,9,4,1,4,3,8,1,20,1,10, - 1,10,1,6,1,10,1,6,2,2,1,10,1,14,3,10, - 1,10,1,10,1,10,2,10,1,114,199,0,0,0,99,2, - 0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,67, - 0,0,0,115,38,0,0,0,116,0,124,0,124,1,131,2, - 1,0,116,1,106,2,160,3,116,4,161,1,1,0,116,1, - 106,2,160,3,116,5,161,1,1,0,100,1,83,0,41,2, - 122,48,73,110,115,116,97,108,108,32,105,109,112,111,114,116, - 101,114,115,32,102,111,114,32,98,117,105,108,116,105,110,32, - 97,110,100,32,102,114,111,122,101,110,32,109,111,100,117,108, - 101,115,78,41,6,114,199,0,0,0,114,14,0,0,0,114, - 165,0,0,0,114,109,0,0,0,114,141,0,0,0,114,151, - 0,0,0,41,2,114,197,0,0,0,114,198,0,0,0,114, - 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,8, - 95,105,110,115,116,97,108,108,127,4,0,0,115,6,0,0, - 0,0,2,10,2,12,1,114,200,0,0,0,99,0,0,0, - 0,0,0,0,0,1,0,0,0,4,0,0,0,67,0,0, - 0,115,32,0,0,0,100,1,100,2,108,0,125,0,124,0, - 97,1,124,0,160,2,116,3,106,4,116,5,25,0,161,1, - 1,0,100,2,83,0,41,3,122,57,73,110,115,116,97,108, - 108,32,105,109,112,111,114,116,101,114,115,32,116,104,97,116, - 32,114,101,113,117,105,114,101,32,101,120,116,101,114,110,97, - 108,32,102,105,108,101,115,121,115,116,101,109,32,97,99,99, - 101,115,115,114,19,0,0,0,78,41,6,218,26,95,102,114, - 111,122,101,110,95,105,109,112,111,114,116,108,105,98,95,101, - 120,116,101,114,110,97,108,114,115,0,0,0,114,200,0,0, - 0,114,14,0,0,0,114,79,0,0,0,114,1,0,0,0, - 41,1,114,201,0,0,0,114,10,0,0,0,114,10,0,0, - 0,114,11,0,0,0,218,27,95,105,110,115,116,97,108,108, - 95,101,120,116,101,114,110,97,108,95,105,109,112,111,114,116, - 101,114,115,135,4,0,0,115,6,0,0,0,0,3,8,1, - 4,1,114,202,0,0,0,41,2,78,78,41,1,78,41,2, - 78,114,19,0,0,0,41,4,78,78,114,10,0,0,0,114, - 19,0,0,0,41,51,114,3,0,0,0,114,115,0,0,0, - 114,12,0,0,0,114,16,0,0,0,114,51,0,0,0,114, - 29,0,0,0,114,36,0,0,0,114,17,0,0,0,114,18, - 0,0,0,114,41,0,0,0,114,42,0,0,0,114,45,0, - 0,0,114,57,0,0,0,114,59,0,0,0,114,68,0,0, - 0,114,74,0,0,0,114,77,0,0,0,114,84,0,0,0, - 114,95,0,0,0,114,96,0,0,0,114,102,0,0,0,114, - 78,0,0,0,114,128,0,0,0,114,133,0,0,0,114,136, - 0,0,0,114,91,0,0,0,114,80,0,0,0,114,139,0, - 0,0,114,140,0,0,0,114,81,0,0,0,114,141,0,0, - 0,114,151,0,0,0,114,156,0,0,0,114,162,0,0,0, - 114,164,0,0,0,114,169,0,0,0,114,173,0,0,0,90, - 15,95,69,82,82,95,77,83,71,95,80,82,69,70,73,88, - 114,175,0,0,0,114,178,0,0,0,218,6,111,98,106,101, - 99,116,114,179,0,0,0,114,180,0,0,0,114,181,0,0, - 0,114,185,0,0,0,114,191,0,0,0,114,194,0,0,0, - 114,195,0,0,0,114,199,0,0,0,114,200,0,0,0,114, - 202,0,0,0,114,10,0,0,0,114,10,0,0,0,114,10, - 0,0,0,114,11,0,0,0,218,8,60,109,111,100,117,108, - 101,62,8,0,0,0,115,96,0,0,0,4,17,4,2,8, - 8,8,8,4,2,4,3,16,4,14,68,14,21,14,16,8, - 37,8,17,8,11,14,8,8,11,8,12,8,16,8,36,14, - 27,14,101,16,26,10,45,14,72,8,17,8,17,8,24,8, - 29,8,23,8,15,14,73,14,77,14,13,8,9,8,9,10, - 47,8,16,4,1,8,2,8,27,6,3,8,16,10,15,14, - 38,8,27,10,35,8,7,8,35,8,8, + 0,114,79,0,0,0,114,1,0,0,0,114,4,0,0,0, + 114,185,0,0,0,41,9,114,15,0,0,0,114,190,0,0, + 0,218,6,108,111,99,97,108,115,114,186,0,0,0,114,161, + 0,0,0,114,83,0,0,0,90,8,103,108,111,98,97,108, + 115,95,114,160,0,0,0,90,7,99,117,116,95,111,102,102, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,218, + 10,95,95,105,109,112,111,114,116,95,95,49,4,0,0,115, + 30,0,0,0,0,11,8,1,10,2,16,1,8,1,12,1, + 4,3,8,1,18,1,4,1,4,4,26,3,32,1,10,1, + 12,2,114,194,0,0,0,99,1,0,0,0,0,0,0,0, + 2,0,0,0,3,0,0,0,67,0,0,0,115,38,0,0, + 0,116,0,160,1,124,0,161,1,125,1,124,1,100,0,107, + 8,114,30,116,2,100,1,124,0,23,0,131,1,130,1,116, + 3,124,1,131,1,83,0,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,141,0,0,0,114,145,0,0, + 0,114,70,0,0,0,114,140,0,0,0,41,2,114,15,0, + 0,0,114,82,0,0,0,114,10,0,0,0,114,10,0,0, + 0,114,11,0,0,0,218,18,95,98,117,105,108,116,105,110, + 95,102,114,111,109,95,110,97,109,101,86,4,0,0,115,8, + 0,0,0,0,1,10,1,8,1,12,1,114,195,0,0,0, + 99,2,0,0,0,0,0,0,0,10,0,0,0,5,0,0, + 0,67,0,0,0,115,166,0,0,0,124,1,97,0,124,0, + 97,1,116,2,116,1,131,1,125,2,116,1,106,3,160,4, + 161,0,68,0,93,72,92,2,125,3,125,4,116,5,124,4, + 124,2,131,2,114,26,124,3,116,1,106,6,107,6,114,60, + 116,7,125,5,110,18,116,0,160,8,124,3,161,1,114,26, + 116,9,125,5,110,2,113,26,116,10,124,4,124,5,131,2, + 125,6,116,11,124,6,124,4,131,2,1,0,113,26,116,1, + 106,3,116,12,25,0,125,7,100,1,68,0,93,46,125,8, + 124,8,116,1,106,3,107,7,114,138,116,13,124,8,131,1, + 125,9,110,10,116,1,106,3,124,8,25,0,125,9,116,14, + 124,7,124,8,124,9,131,3,1,0,113,114,100,2,83,0, + 41,3,122,250,83,101,116,117,112,32,105,109,112,111,114,116, + 108,105,98,32,98,121,32,105,109,112,111,114,116,105,110,103, + 32,110,101,101,100,101,100,32,98,117,105,108,116,45,105,110, + 32,109,111,100,117,108,101,115,32,97,110,100,32,105,110,106, + 101,99,116,105,110,103,32,116,104,101,109,10,32,32,32,32, + 105,110,116,111,32,116,104,101,32,103,108,111,98,97,108,32, + 110,97,109,101,115,112,97,99,101,46,10,10,32,32,32,32, + 65,115,32,115,121,115,32,105,115,32,110,101,101,100,101,100, + 32,102,111,114,32,115,121,115,46,109,111,100,117,108,101,115, + 32,97,99,99,101,115,115,32,97,110,100,32,95,105,109,112, + 32,105,115,32,110,101,101,100,101,100,32,116,111,32,108,111, + 97,100,32,98,117,105,108,116,45,105,110,10,32,32,32,32, + 109,111,100,117,108,101,115,44,32,116,104,111,115,101,32,116, + 119,111,32,109,111,100,117,108,101,115,32,109,117,115,116,32, + 98,101,32,101,120,112,108,105,99,105,116,108,121,32,112,97, + 115,115,101,100,32,105,110,46,10,10,32,32,32,32,41,3, + 114,20,0,0,0,114,166,0,0,0,114,56,0,0,0,78, + 41,15,114,49,0,0,0,114,14,0,0,0,114,13,0,0, + 0,114,79,0,0,0,218,5,105,116,101,109,115,114,170,0, + 0,0,114,69,0,0,0,114,141,0,0,0,114,75,0,0, + 0,114,151,0,0,0,114,128,0,0,0,114,133,0,0,0, + 114,1,0,0,0,114,195,0,0,0,114,5,0,0,0,41, + 10,218,10,115,121,115,95,109,111,100,117,108,101,218,11,95, + 105,109,112,95,109,111,100,117,108,101,90,11,109,111,100,117, + 108,101,95,116,121,112,101,114,15,0,0,0,114,83,0,0, + 0,114,93,0,0,0,114,82,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,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,218,6,95,115,101,116,117,112,93,4,0, + 0,115,36,0,0,0,0,9,4,1,4,3,8,1,18,1, + 10,1,10,1,6,1,10,1,6,2,2,1,10,1,12,3, + 10,1,8,1,10,1,10,2,10,1,114,199,0,0,0,99, + 2,0,0,0,0,0,0,0,2,0,0,0,3,0,0,0, + 67,0,0,0,115,38,0,0,0,116,0,124,0,124,1,131, + 2,1,0,116,1,106,2,160,3,116,4,161,1,1,0,116, + 1,106,2,160,3,116,5,161,1,1,0,100,1,83,0,41, + 2,122,48,73,110,115,116,97,108,108,32,105,109,112,111,114, + 116,101,114,115,32,102,111,114,32,98,117,105,108,116,105,110, + 32,97,110,100,32,102,114,111,122,101,110,32,109,111,100,117, + 108,101,115,78,41,6,114,199,0,0,0,114,14,0,0,0, + 114,165,0,0,0,114,109,0,0,0,114,141,0,0,0,114, + 151,0,0,0,41,2,114,197,0,0,0,114,198,0,0,0, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,218, + 8,95,105,110,115,116,97,108,108,128,4,0,0,115,6,0, + 0,0,0,2,10,2,12,1,114,200,0,0,0,99,0,0, + 0,0,0,0,0,0,1,0,0,0,4,0,0,0,67,0, + 0,0,115,32,0,0,0,100,1,100,2,108,0,125,0,124, + 0,97,1,124,0,160,2,116,3,106,4,116,5,25,0,161, + 1,1,0,100,2,83,0,41,3,122,57,73,110,115,116,97, + 108,108,32,105,109,112,111,114,116,101,114,115,32,116,104,97, + 116,32,114,101,113,117,105,114,101,32,101,120,116,101,114,110, + 97,108,32,102,105,108,101,115,121,115,116,101,109,32,97,99, + 99,101,115,115,114,19,0,0,0,78,41,6,218,26,95,102, + 114,111,122,101,110,95,105,109,112,111,114,116,108,105,98,95, + 101,120,116,101,114,110,97,108,114,115,0,0,0,114,200,0, + 0,0,114,14,0,0,0,114,79,0,0,0,114,1,0,0, + 0,41,1,114,201,0,0,0,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,218,27,95,105,110,115,116,97,108, + 108,95,101,120,116,101,114,110,97,108,95,105,109,112,111,114, + 116,101,114,115,136,4,0,0,115,6,0,0,0,0,3,8, + 1,4,1,114,202,0,0,0,41,2,78,78,41,1,78,41, + 2,78,114,19,0,0,0,41,4,78,78,114,10,0,0,0, + 114,19,0,0,0,41,51,114,3,0,0,0,114,115,0,0, + 0,114,12,0,0,0,114,16,0,0,0,114,51,0,0,0, + 114,29,0,0,0,114,36,0,0,0,114,17,0,0,0,114, + 18,0,0,0,114,41,0,0,0,114,42,0,0,0,114,45, + 0,0,0,114,57,0,0,0,114,59,0,0,0,114,68,0, + 0,0,114,74,0,0,0,114,77,0,0,0,114,84,0,0, + 0,114,95,0,0,0,114,96,0,0,0,114,102,0,0,0, + 114,78,0,0,0,114,128,0,0,0,114,133,0,0,0,114, + 136,0,0,0,114,91,0,0,0,114,80,0,0,0,114,139, + 0,0,0,114,140,0,0,0,114,81,0,0,0,114,141,0, + 0,0,114,151,0,0,0,114,156,0,0,0,114,162,0,0, + 0,114,164,0,0,0,114,169,0,0,0,114,173,0,0,0, + 90,15,95,69,82,82,95,77,83,71,95,80,82,69,70,73, + 88,114,175,0,0,0,114,178,0,0,0,218,6,111,98,106, + 101,99,116,114,179,0,0,0,114,180,0,0,0,114,181,0, + 0,0,114,185,0,0,0,114,191,0,0,0,114,194,0,0, + 0,114,195,0,0,0,114,199,0,0,0,114,200,0,0,0, + 114,202,0,0,0,114,10,0,0,0,114,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,218,8,60,109,111,100,117, + 108,101,62,8,0,0,0,115,96,0,0,0,4,17,4,2, + 8,8,8,8,4,2,4,3,16,4,14,68,14,21,14,16, + 8,37,8,17,8,11,14,8,8,11,8,12,8,16,8,36, + 14,27,14,101,16,26,10,45,14,72,8,17,8,17,8,24, + 8,29,8,23,8,15,14,73,14,77,14,13,8,9,8,9, + 10,47,8,16,4,1,8,2,8,27,6,3,8,16,10,15, + 14,37,8,27,10,37,8,7,8,35,8,8, }; diff --git a/Python/importlib_external.h b/Python/importlib_external.h index df1564e72f28d3..8674b2193a0e73 100644 --- a/Python/importlib_external.h +++ b/Python/importlib_external.h @@ -1,536 +1,573 @@ /* Auto-generated by Programs/_freeze_importlib.c */ const unsigned char _Py_M__importlib_external[] = { 99,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0, - 0,64,0,0,0,115,16,2,0,0,100,0,90,0,100,1, + 0,64,0,0,0,115,24,2,0,0,100,0,90,0,100,1, 90,1,100,2,90,2,101,2,101,1,23,0,90,3,100,3, 100,4,132,0,90,4,100,5,100,6,132,0,90,5,100,7, 100,8,132,0,90,6,100,9,100,10,132,0,90,7,100,11, 100,12,132,0,90,8,100,13,100,14,132,0,90,9,100,15, 100,16,132,0,90,10,100,17,100,18,132,0,90,11,100,19, - 100,20,132,0,90,12,100,97,100,22,100,23,132,1,90,13, - 101,14,101,13,106,15,131,1,90,16,100,24,160,17,100,25, - 100,26,161,2,100,27,23,0,90,18,101,19,160,20,101,18, - 100,26,161,2,90,21,100,28,90,22,100,29,90,23,100,30, - 103,1,90,24,100,31,103,1,90,25,101,25,4,0,90,26, - 90,27,100,98,100,32,100,33,156,1,100,34,100,35,132,3, - 90,28,100,36,100,37,132,0,90,29,100,38,100,39,132,0, + 100,20,132,0,90,12,100,21,100,22,132,0,90,13,100,99, + 100,24,100,25,132,1,90,14,101,15,101,14,106,16,131,1, + 90,17,100,26,160,18,100,27,100,28,161,2,100,29,23,0, + 90,19,101,20,160,21,101,19,100,28,161,2,90,22,100,30, + 90,23,100,31,90,24,100,32,103,1,90,25,100,33,103,1, + 90,26,101,26,4,0,90,27,90,28,100,100,100,34,100,35, + 156,1,100,36,100,37,132,3,90,29,100,38,100,39,132,0, 90,30,100,40,100,41,132,0,90,31,100,42,100,43,132,0, 90,32,100,44,100,45,132,0,90,33,100,46,100,47,132,0, 90,34,100,48,100,49,132,0,90,35,100,50,100,51,132,0, - 90,36,100,52,100,53,132,0,90,37,100,99,100,54,100,55, - 132,1,90,38,100,100,100,57,100,58,132,1,90,39,100,101, - 100,60,100,61,132,1,90,40,100,62,100,63,132,0,90,41, - 101,42,131,0,90,43,100,102,100,32,101,43,100,64,156,2, - 100,65,100,66,132,3,90,44,71,0,100,67,100,68,132,0, - 100,68,131,2,90,45,71,0,100,69,100,70,132,0,100,70, - 131,2,90,46,71,0,100,71,100,72,132,0,100,72,101,46, - 131,3,90,47,71,0,100,73,100,74,132,0,100,74,131,2, - 90,48,71,0,100,75,100,76,132,0,100,76,101,48,101,47, - 131,4,90,49,71,0,100,77,100,78,132,0,100,78,101,48, - 101,46,131,4,90,50,103,0,90,51,71,0,100,79,100,80, - 132,0,100,80,101,48,101,46,131,4,90,52,71,0,100,81, - 100,82,132,0,100,82,131,2,90,53,71,0,100,83,100,84, - 132,0,100,84,131,2,90,54,71,0,100,85,100,86,132,0, - 100,86,131,2,90,55,71,0,100,87,100,88,132,0,100,88, - 131,2,90,56,100,103,100,89,100,90,132,1,90,57,100,91, - 100,92,132,0,90,58,100,93,100,94,132,0,90,59,100,95, - 100,96,132,0,90,60,100,32,83,0,41,104,97,94,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,112,97,116,104,45,98,97,115, - 101,100,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,41, - 1,218,3,119,105,110,41,2,90,6,99,121,103,119,105,110, - 90,6,100,97,114,119,105,110,99,0,0,0,0,0,0,0, - 0,1,0,0,0,3,0,0,0,3,0,0,0,115,60,0, - 0,0,116,0,106,1,160,2,116,3,161,1,114,48,116,0, - 106,1,160,2,116,4,161,1,114,30,100,1,137,0,110,4, - 100,2,137,0,135,0,102,1,100,3,100,4,132,8,125,0, - 110,8,100,5,100,4,132,0,125,0,124,0,83,0,41,6, - 78,90,12,80,89,84,72,79,78,67,65,83,69,79,75,115, - 12,0,0,0,80,89,84,72,79,78,67,65,83,69,79,75, - 99,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0, - 0,19,0,0,0,115,10,0,0,0,136,0,116,0,106,1, - 107,6,83,0,41,1,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,41,2,218, - 3,95,111,115,90,7,101,110,118,105,114,111,110,169,0,41, - 1,218,3,107,101,121,114,2,0,0,0,250,38,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,95,101,120,116,101,114,110, - 97,108,62,218,11,95,114,101,108,97,120,95,99,97,115,101, - 36,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,83,0, - 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,2,0,0,0,114, - 2,0,0,0,114,2,0,0,0,114,2,0,0,0,114,4, - 0,0,0,114,5,0,0,0,40,0,0,0,115,2,0,0, - 0,0,2,41,5,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,218,35,95, - 67,65,83,69,95,73,78,83,69,78,83,73,84,73,86,69, - 95,80,76,65,84,70,79,82,77,83,95,83,84,82,95,75, - 69,89,41,1,114,5,0,0,0,114,2,0,0,0,41,1, - 114,3,0,0,0,114,4,0,0,0,218,16,95,109,97,107, - 101,95,114,101,108,97,120,95,99,97,115,101,29,0,0,0, - 115,14,0,0,0,0,1,12,1,12,1,6,2,4,2,14, - 4,8,3,114,11,0,0,0,99,1,0,0,0,0,0,0, - 0,1,0,0,0,4,0,0,0,67,0,0,0,115,20,0, - 0,0,116,0,124,0,131,1,100,1,64,0,160,1,100,2, - 100,3,161,2,83,0,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,2,0,0,0,114,2,0,0,0,114,4,0,0, - 0,218,7,95,119,95,108,111,110,103,46,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,4,0,0,0,67,0,0,0,115, - 12,0,0,0,116,0,160,1,124,0,100,1,161,2,83,0, - 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,2,0,0,0,114,2,0, - 0,0,114,4,0,0,0,218,7,95,114,95,108,111,110,103, - 51,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,4,0,0, - 0,71,0,0,0,115,20,0,0,0,116,0,160,1,100,1, - 100,2,132,0,124,0,68,0,131,1,161,1,83,0,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,5,0, - 0,0,83,0,0,0,115,26,0,0,0,103,0,124,0,93, - 18,125,1,124,1,114,4,124,1,160,0,116,1,161,1,145, - 2,113,4,83,0,114,2,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,2,0,0,0,114,2,0,0,0,114,4,0,0,0, - 250,10,60,108,105,115,116,99,111,109,112,62,58,0,0,0, - 115,2,0,0,0,6,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,2,0,0,0,114,2,0,0, - 0,114,4,0,0,0,218,10,95,112,97,116,104,95,106,111, - 105,110,56,0,0,0,115,4,0,0,0,0,2,10,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,96,0,0,0,116,0, - 116,1,131,1,100,1,107,2,114,36,124,0,160,2,116,3, - 161,1,92,3,125,1,125,2,125,3,124,1,124,3,102,2, - 83,0,120,50,116,4,124,0,131,1,68,0,93,38,125,4, - 124,4,116,1,107,6,114,46,124,0,106,5,124,4,100,1, - 100,2,141,2,92,2,125,1,125,3,124,1,124,3,102,2, - 83,0,113,46,87,0,100,3,124,0,102,2,83,0,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,41,1,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,2,0,0,0,114,2,0,0,0,114,4,0,0,0, - 218,11,95,112,97,116,104,95,115,112,108,105,116,62,0,0, - 0,115,16,0,0,0,0,2,12,1,16,1,8,1,14,1, - 8,1,18,1,12,1,114,38,0,0,0,99,1,0,0,0, + 90,36,100,52,100,53,132,0,90,37,100,54,100,55,132,0, + 90,38,100,101,100,56,100,57,132,1,90,39,100,102,100,59, + 100,60,132,1,90,40,100,103,100,62,100,63,132,1,90,41, + 100,64,100,65,132,0,90,42,101,43,131,0,90,44,100,104, + 100,34,101,44,100,66,156,2,100,67,100,68,132,3,90,45, + 71,0,100,69,100,70,132,0,100,70,131,2,90,46,71,0, + 100,71,100,72,132,0,100,72,131,2,90,47,71,0,100,73, + 100,74,132,0,100,74,101,47,131,3,90,48,71,0,100,75, + 100,76,132,0,100,76,131,2,90,49,71,0,100,77,100,78, + 132,0,100,78,101,49,101,48,131,4,90,50,71,0,100,79, + 100,80,132,0,100,80,101,49,101,47,131,4,90,51,103,0, + 90,52,71,0,100,81,100,82,132,0,100,82,101,49,101,47, + 131,4,90,53,71,0,100,83,100,84,132,0,100,84,131,2, + 90,54,71,0,100,85,100,86,132,0,100,86,131,2,90,55, + 71,0,100,87,100,88,132,0,100,88,131,2,90,56,71,0, + 100,89,100,90,132,0,100,90,131,2,90,57,100,105,100,91, + 100,92,132,1,90,58,100,93,100,94,132,0,90,59,100,95, + 100,96,132,0,90,60,100,97,100,98,132,0,90,61,100,34, + 83,0,41,106,97,94,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, + 112,97,116,104,45,98,97,115,101,100,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,41,1,218,3,119,105,110,41,2, + 90,6,99,121,103,119,105,110,90,6,100,97,114,119,105,110, + 99,0,0,0,0,0,0,0,0,1,0,0,0,3,0,0, + 0,3,0,0,0,115,60,0,0,0,116,0,106,1,160,2, + 116,3,161,1,114,48,116,0,106,1,160,2,116,4,161,1, + 114,30,100,1,137,0,110,4,100,2,137,0,135,0,102,1, + 100,3,100,4,132,8,125,0,110,8,100,5,100,4,132,0, + 125,0,124,0,83,0,41,6,78,90,12,80,89,84,72,79, + 78,67,65,83,69,79,75,115,12,0,0,0,80,89,84,72, + 79,78,67,65,83,69,79,75,99,0,0,0,0,0,0,0, + 0,0,0,0,0,2,0,0,0,19,0,0,0,115,10,0, + 0,0,136,0,116,0,106,1,107,6,83,0,41,1,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,41,2,218,3,95,111,115,90,7,101,110, + 118,105,114,111,110,169,0,41,1,218,3,107,101,121,114,2, + 0,0,0,250,38,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,95,101,120,116,101,114,110,97,108,62,218,11,95,114,101, + 108,97,120,95,99,97,115,101,36,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,83,0,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,2,0,0,0,114,2,0,0,0,114,2,0,0, + 0,114,2,0,0,0,114,4,0,0,0,114,5,0,0,0, + 40,0,0,0,115,2,0,0,0,0,2,41,5,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,218,35,95,67,65,83,69,95,73,78,83, + 69,78,83,73,84,73,86,69,95,80,76,65,84,70,79,82, + 77,83,95,83,84,82,95,75,69,89,41,1,114,5,0,0, + 0,114,2,0,0,0,41,1,114,3,0,0,0,114,4,0, + 0,0,218,16,95,109,97,107,101,95,114,101,108,97,120,95, + 99,97,115,101,29,0,0,0,115,14,0,0,0,0,1,12, + 1,12,1,6,2,4,2,14,4,8,3,114,11,0,0,0, + 99,1,0,0,0,0,0,0,0,1,0,0,0,4,0,0, + 0,67,0,0,0,115,20,0,0,0,116,0,124,0,131,1, + 100,1,64,0,160,1,100,2,100,3,161,2,83,0,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,2,0,0,0,114, + 2,0,0,0,114,4,0,0,0,218,7,95,119,95,108,111, + 110,103,46,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,4, + 0,0,0,67,0,0,0,115,12,0,0,0,116,0,160,1, + 124,0,100,1,161,2,83,0,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,2,0,0,0,114,2,0,0,0,114,4,0,0,0,218, + 7,95,114,95,108,111,110,103,51,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,4,0,0,0,71,0,0,0,115,20,0, + 0,0,116,0,160,1,100,1,100,2,132,0,124,0,68,0, + 131,1,161,1,83,0,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,5,0,0,0,83,0,0,0,115,26, + 0,0,0,103,0,124,0,93,18,125,1,124,1,114,4,124, + 1,160,0,116,1,161,1,145,2,113,4,83,0,114,2,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,2,0,0,0,114,2, + 0,0,0,114,4,0,0,0,218,10,60,108,105,115,116,99, + 111,109,112,62,58,0,0,0,115,2,0,0,0,6,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, + 2,0,0,0,114,2,0,0,0,114,4,0,0,0,218,10, + 95,112,97,116,104,95,106,111,105,110,56,0,0,0,115,4, + 0,0,0,0,2,10,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,96,0,0,0,116,0,116,1,131,1,100,1,107,2, + 114,36,124,0,160,2,116,3,161,1,92,3,125,1,125,2, + 125,3,124,1,124,3,102,2,83,0,116,4,124,0,131,1, + 68,0,93,42,125,4,124,4,116,1,107,6,114,44,124,0, + 106,5,124,4,100,1,100,2,141,2,92,2,125,1,125,3, + 124,1,124,3,102,2,2,0,1,0,83,0,113,44,100,3, + 124,0,102,2,83,0,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,41, + 1,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,2,0,0,0,114,2, + 0,0,0,114,4,0,0,0,218,11,95,112,97,116,104,95, + 115,112,108,105,116,62,0,0,0,115,16,0,0,0,0,2, + 12,1,16,1,8,1,12,1,8,1,18,1,14,1,114,38, + 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,10,0,0,0,116,0,160, + 1,124,0,161,1,83,0,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,1,0,0,0, + 90,4,115,116,97,116,41,1,114,35,0,0,0,114,2,0, + 0,0,114,2,0,0,0,114,4,0,0,0,218,10,95,112, + 97,116,104,95,115,116,97,116,74,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,8,0,0,0,67,0,0,0,115,50,0, + 0,0,122,12,116,0,124,0,131,1,125,2,87,0,110,22, + 4,0,116,1,107,10,114,34,1,0,1,0,1,0,89,0, + 100,1,83,0,88,0,124,2,106,2,100,2,64,0,124,1, + 107,2,83,0,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,2,0,0,0,114,2,0,0,0,114,4,0,0,0,218, + 18,95,112,97,116,104,95,105,115,95,109,111,100,101,95,116, + 121,112,101,84,0,0,0,115,10,0,0,0,0,2,2,1, + 12,1,14,1,8,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,10,0,0,0,116,0,160,1,124,0,161,1,83,0,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,1,0,0,0,90,4,115,116,97,116,41,1, + 115,10,0,0,0,116,0,124,0,100,1,131,2,83,0,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,2,0,0,0,114,2,0,0,0,114, - 4,0,0,0,218,10,95,112,97,116,104,95,115,116,97,116, - 74,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,8,0,0, - 0,67,0,0,0,115,48,0,0,0,121,12,116,0,124,0, - 131,1,125,2,87,0,110,20,4,0,116,1,107,10,114,32, - 1,0,1,0,1,0,100,1,83,0,88,0,124,2,106,2, - 100,2,64,0,124,1,107,2,83,0,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,2,0,0,0,114,2,0,0,0, - 114,4,0,0,0,218,18,95,112,97,116,104,95,105,115,95, - 109,111,100,101,95,116,121,112,101,84,0,0,0,115,10,0, - 0,0,0,2,2,1,12,1,14,1,6,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,10,0,0,0,116,0,124,0,100, - 1,131,2,83,0,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,2,0,0,0, - 114,2,0,0,0,114,4,0,0,0,218,12,95,112,97,116, - 104,95,105,115,102,105,108,101,93,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,22,0, - 0,0,124,0,115,12,116,0,160,1,161,0,125,0,116,2, - 124,0,100,1,131,2,83,0,41,2,122,30,82,101,112,108, + 4,0,0,0,218,12,95,112,97,116,104,95,105,115,102,105, + 108,101,93,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,22,0,0,0,124,0,115,12, + 116,0,160,1,161,0,125,0,116,2,124,0,100,1,131,2, + 83,0,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,1,0,0,0, + 218,6,103,101,116,99,119,100,114,43,0,0,0,41,1,114, + 35,0,0,0,114,2,0,0,0,114,2,0,0,0,114,4, + 0,0,0,218,11,95,112,97,116,104,95,105,115,100,105,114, + 98,0,0,0,115,6,0,0,0,0,2,4,1,8,1,114, + 46,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,124,0, + 160,0,116,1,161,1,112,24,124,0,100,1,100,2,133,2, + 25,0,116,2,107,6,83,0,41,3,122,142,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,1,0,0,0,218,6,103,101,116,99,119,100,114,43, - 0,0,0,41,1,114,35,0,0,0,114,2,0,0,0,114, - 2,0,0,0,114,4,0,0,0,218,11,95,112,97,116,104, - 95,105,115,100,105,114,98,0,0,0,115,6,0,0,0,0, - 2,4,1,8,1,114,46,0,0,0,233,182,1,0,0,99, - 3,0,0,0,0,0,0,0,6,0,0,0,11,0,0,0, - 67,0,0,0,115,162,0,0,0,100,1,160,0,124,0,116, - 1,124,0,131,1,161,2,125,3,116,2,160,3,124,3,116, - 2,106,4,116,2,106,5,66,0,116,2,106,6,66,0,124, - 2,100,2,64,0,161,3,125,4,121,50,116,7,160,8,124, - 4,100,3,161,2,143,16,125,5,124,5,160,9,124,1,161, - 1,1,0,87,0,100,4,81,0,82,0,88,0,116,2,160, - 10,124,3,124,0,161,2,1,0,87,0,110,58,4,0,116, - 11,107,10,114,156,1,0,1,0,1,0,121,14,116,2,160, - 12,124,3,161,1,1,0,87,0,110,20,4,0,116,11,107, - 10,114,148,1,0,1,0,1,0,89,0,110,2,88,0,130, - 0,89,0,110,2,88,0,100,4,83,0,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,1,0,0,0,218,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,2,0,0,0,114,2,0,0,0, - 114,4,0,0,0,218,13,95,119,114,105,116,101,95,97,116, - 111,109,105,99,105,0,0,0,115,26,0,0,0,0,5,16, - 1,6,1,26,1,2,3,14,1,20,1,16,1,14,1,2, - 1,14,1,14,1,6,1,114,57,0,0,0,105,66,13,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, - 4,111,112,116,45,122,3,46,112,121,122,4,46,112,121,99, - 78,41,1,218,12,111,112,116,105,109,105,122,97,116,105,111, - 110,99,2,0,0,0,1,0,0,0,11,0,0,0,6,0, - 0,0,67,0,0,0,115,244,0,0,0,124,1,100,1,107, - 9,114,52,116,0,160,1,100,2,116,2,161,2,1,0,124, - 2,100,1,107,9,114,40,100,3,125,3,116,3,124,3,131, - 1,130,1,124,1,114,48,100,4,110,2,100,5,125,2,116, - 4,160,5,124,0,161,1,125,0,116,6,124,0,131,1,92, - 2,125,4,125,5,124,5,160,7,100,6,161,1,92,3,125, - 6,125,7,125,8,116,8,106,9,106,10,125,9,124,9,100, - 1,107,8,114,114,116,11,100,7,131,1,130,1,100,4,160, - 12,124,6,114,126,124,6,110,2,124,8,124,7,124,9,103, - 3,161,1,125,10,124,2,100,1,107,8,114,172,116,8,106, - 13,106,14,100,8,107,2,114,164,100,4,125,2,110,8,116, - 8,106,13,106,14,125,2,116,15,124,2,131,1,125,2,124, - 2,100,4,107,3,114,224,124,2,160,16,161,0,115,210,116, - 17,100,9,160,18,124,2,161,1,131,1,130,1,100,10,160, - 18,124,10,116,19,124,2,161,3,125,10,116,20,124,4,116, - 21,124,10,116,22,100,8,25,0,23,0,131,3,83,0,41, - 11,97,254,2,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,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,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,10,10, - 32,32,32,32,84,104,101,32,39,111,112,116,105,109,105,122, - 97,116,105,111,110,39,32,112,97,114,97,109,101,116,101,114, - 32,99,111,110,116,114,111,108,115,32,116,104,101,32,112,114, - 101,115,117,109,101,100,32,111,112,116,105,109,105,122,97,116, - 105,111,110,32,108,101,118,101,108,32,111,102,10,32,32,32, - 32,116,104,101,32,98,121,116,101,99,111,100,101,32,102,105, - 108,101,46,32,73,102,32,39,111,112,116,105,109,105,122,97, - 116,105,111,110,39,32,105,115,32,110,111,116,32,78,111,110, - 101,44,32,116,104,101,32,115,116,114,105,110,103,32,114,101, - 112,114,101,115,101,110,116,97,116,105,111,110,10,32,32,32, - 32,111,102,32,116,104,101,32,97,114,103,117,109,101,110,116, - 32,105,115,32,116,97,107,101,110,32,97,110,100,32,118,101, - 114,105,102,105,101,100,32,116,111,32,98,101,32,97,108,112, - 104,97,110,117,109,101,114,105,99,32,40,101,108,115,101,32, - 86,97,108,117,101,69,114,114,111,114,10,32,32,32,32,105, - 115,32,114,97,105,115,101,100,41,46,10,10,32,32,32,32, - 84,104,101,32,100,101,98,117,103,95,111,118,101,114,114,105, - 100,101,32,112,97,114,97,109,101,116,101,114,32,105,115,32, - 100,101,112,114,101,99,97,116,101,100,46,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,10,32,32,32,32,97, - 32,84,114,117,101,32,118,97,108,117,101,32,105,115,32,116, - 104,101,32,115,97,109,101,32,97,115,32,115,101,116,116,105, - 110,103,32,39,111,112,116,105,109,105,122,97,116,105,111,110, - 39,32,116,111,32,116,104,101,32,101,109,112,116,121,32,115, - 116,114,105,110,103,10,32,32,32,32,119,104,105,108,101,32, - 97,32,70,97,108,115,101,32,118,97,108,117,101,32,105,115, - 32,101,113,117,105,118,97,108,101,110,116,32,116,111,32,115, - 101,116,116,105,110,103,32,39,111,112,116,105,109,105,122,97, - 116,105,111,110,39,32,116,111,32,39,49,39,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,122,70,116,104,101,32,100,101,98,117,103, - 95,111,118,101,114,114,105,100,101,32,112,97,114,97,109,101, - 116,101,114,32,105,115,32,100,101,112,114,101,99,97,116,101, - 100,59,32,117,115,101,32,39,111,112,116,105,109,105,122,97, - 116,105,111,110,39,32,105,110,115,116,101,97,100,122,50,100, - 101,98,117,103,95,111,118,101,114,114,105,100,101,32,111,114, - 32,111,112,116,105,109,105,122,97,116,105,111,110,32,109,117, - 115,116,32,98,101,32,115,101,116,32,116,111,32,78,111,110, - 101,114,30,0,0,0,114,29,0,0,0,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,233,0,0,0,0,122,24,123,33,114,125,32, - 105,115,32,110,111,116,32,97,108,112,104,97,110,117,109,101, - 114,105,99,122,7,123,125,46,123,125,123,125,41,23,218,9, - 95,119,97,114,110,105,110,103,115,218,4,119,97,114,110,218, - 18,68,101,112,114,101,99,97,116,105,111,110,87,97,114,110, - 105,110,103,218,9,84,121,112,101,69,114,114,111,114,114,1, - 0,0,0,218,6,102,115,112,97,116,104,114,38,0,0,0, - 114,32,0,0,0,114,6,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,218, - 5,102,108,97,103,115,218,8,111,112,116,105,109,105,122,101, - 218,3,115,116,114,218,7,105,115,97,108,110,117,109,218,10, - 86,97,108,117,101,69,114,114,111,114,114,48,0,0,0,218, - 4,95,79,80,84,114,28,0,0,0,218,8,95,80,89,67, - 65,67,72,69,218,17,66,89,84,69,67,79,68,69,95,83, - 85,70,70,73,88,69,83,41,11,114,35,0,0,0,90,14, - 100,101,98,117,103,95,111,118,101,114,114,105,100,101,114,59, - 0,0,0,218,7,109,101,115,115,97,103,101,218,4,104,101, - 97,100,114,37,0,0,0,90,4,98,97,115,101,218,3,115, - 101,112,218,4,114,101,115,116,90,3,116,97,103,90,15,97, - 108,109,111,115,116,95,102,105,108,101,110,97,109,101,114,2, - 0,0,0,114,2,0,0,0,114,4,0,0,0,218,17,99, - 97,99,104,101,95,102,114,111,109,95,115,111,117,114,99,101, - 15,1,0,0,115,48,0,0,0,0,18,8,1,6,1,6, - 1,8,1,4,1,8,1,12,1,10,1,12,1,16,1,8, - 1,8,1,8,1,24,1,8,1,12,1,6,2,8,1,8, - 1,8,1,8,1,14,1,14,1,114,82,0,0,0,99,1, - 0,0,0,0,0,0,0,8,0,0,0,5,0,0,0,67, - 0,0,0,115,230,0,0,0,116,0,106,1,106,2,100,1, + 97,116,104,46,105,115,97,98,115,46,10,10,32,32,32,32, + 67,111,110,115,105,100,101,114,115,32,97,32,87,105,110,100, + 111,119,115,32,100,114,105,118,101,45,114,101,108,97,116,105, + 118,101,32,112,97,116,104,32,40,110,111,32,100,114,105,118, + 101,44,32,98,117,116,32,115,116,97,114,116,115,32,119,105, + 116,104,32,115,108,97,115,104,41,32,116,111,10,32,32,32, + 32,115,116,105,108,108,32,98,101,32,34,97,98,115,111,108, + 117,116,101,34,46,10,32,32,32,32,114,29,0,0,0,233, + 3,0,0,0,41,3,114,8,0,0,0,114,21,0,0,0, + 218,20,95,112,97,116,104,115,101,112,115,95,119,105,116,104, + 95,99,111,108,111,110,41,1,114,35,0,0,0,114,2,0, + 0,0,114,2,0,0,0,114,4,0,0,0,218,11,95,112, + 97,116,104,95,105,115,97,98,115,105,0,0,0,115,2,0, + 0,0,0,6,114,49,0,0,0,233,182,1,0,0,99,3, + 0,0,0,0,0,0,0,6,0,0,0,11,0,0,0,67, + 0,0,0,115,162,0,0,0,100,1,160,0,124,0,116,1, + 124,0,131,1,161,2,125,3,116,2,160,3,124,3,116,2, + 106,4,116,2,106,5,66,0,116,2,106,6,66,0,124,2, + 100,2,64,0,161,3,125,4,122,50,116,7,160,8,124,4, + 100,3,161,2,143,16,125,5,124,5,160,9,124,1,161,1, + 1,0,87,0,53,0,81,0,82,0,88,0,116,2,160,10, + 124,3,124,0,161,2,1,0,87,0,110,58,4,0,116,11, + 107,10,114,156,1,0,1,0,1,0,122,14,116,2,160,12, + 124,3,161,1,1,0,87,0,110,20,4,0,116,11,107,10, + 114,148,1,0,1,0,1,0,89,0,110,2,88,0,130,0, + 89,0,110,2,88,0,100,4,83,0,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, + 1,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,2,0,0,0,114,2,0,0,0,114, + 4,0,0,0,218,13,95,119,114,105,116,101,95,97,116,111, + 109,105,99,114,0,0,0,115,26,0,0,0,0,5,16,1, + 6,1,26,1,2,3,14,1,20,1,16,1,14,1,2,1, + 14,1,14,1,6,1,114,59,0,0,0,105,73,13,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,4, + 111,112,116,45,122,3,46,112,121,122,4,46,112,121,99,78, + 41,1,218,12,111,112,116,105,109,105,122,97,116,105,111,110, + 99,2,0,0,0,1,0,0,0,12,0,0,0,5,0,0, + 0,67,0,0,0,115,88,1,0,0,124,1,100,1,107,9, + 114,52,116,0,160,1,100,2,116,2,161,2,1,0,124,2, + 100,1,107,9,114,40,100,3,125,3,116,3,124,3,131,1, + 130,1,124,1,114,48,100,4,110,2,100,5,125,2,116,4, + 160,5,124,0,161,1,125,0,116,6,124,0,131,1,92,2, + 125,4,125,5,124,5,160,7,100,6,161,1,92,3,125,6, + 125,7,125,8,116,8,106,9,106,10,125,9,124,9,100,1, + 107,8,114,114,116,11,100,7,131,1,130,1,100,4,160,12, + 124,6,114,126,124,6,110,2,124,8,124,7,124,9,103,3, + 161,1,125,10,124,2,100,1,107,8,114,172,116,8,106,13, + 106,14,100,8,107,2,114,164,100,4,125,2,110,8,116,8, + 106,13,106,14,125,2,116,15,124,2,131,1,125,2,124,2, + 100,4,107,3,114,224,124,2,160,16,161,0,115,210,116,17, + 100,9,160,18,124,2,161,1,131,1,130,1,100,10,160,18, + 124,10,116,19,124,2,161,3,125,10,124,10,116,20,100,8, + 25,0,23,0,125,11,116,8,106,21,100,1,107,9,144,1, + 114,76,116,22,124,4,131,1,144,1,115,16,116,23,116,4, + 160,24,161,0,124,4,131,2,125,4,124,4,100,5,25,0, + 100,11,107,2,144,1,114,56,124,4,100,8,25,0,116,25, + 107,7,144,1,114,56,124,4,100,12,100,1,133,2,25,0, + 125,4,116,23,116,8,106,21,124,4,160,26,116,25,161,1, + 124,11,131,3,83,0,116,23,124,4,116,27,124,11,131,3, + 83,0,41,13,97,254,2,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,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,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,10,10,32,32,32,32,84,104,101,32,39,111,112,116,105, + 109,105,122,97,116,105,111,110,39,32,112,97,114,97,109,101, + 116,101,114,32,99,111,110,116,114,111,108,115,32,116,104,101, + 32,112,114,101,115,117,109,101,100,32,111,112,116,105,109,105, + 122,97,116,105,111,110,32,108,101,118,101,108,32,111,102,10, + 32,32,32,32,116,104,101,32,98,121,116,101,99,111,100,101, + 32,102,105,108,101,46,32,73,102,32,39,111,112,116,105,109, + 105,122,97,116,105,111,110,39,32,105,115,32,110,111,116,32, + 78,111,110,101,44,32,116,104,101,32,115,116,114,105,110,103, + 32,114,101,112,114,101,115,101,110,116,97,116,105,111,110,10, + 32,32,32,32,111,102,32,116,104,101,32,97,114,103,117,109, + 101,110,116,32,105,115,32,116,97,107,101,110,32,97,110,100, + 32,118,101,114,105,102,105,101,100,32,116,111,32,98,101,32, + 97,108,112,104,97,110,117,109,101,114,105,99,32,40,101,108, + 115,101,32,86,97,108,117,101,69,114,114,111,114,10,32,32, + 32,32,105,115,32,114,97,105,115,101,100,41,46,10,10,32, + 32,32,32,84,104,101,32,100,101,98,117,103,95,111,118,101, + 114,114,105,100,101,32,112,97,114,97,109,101,116,101,114,32, + 105,115,32,100,101,112,114,101,99,97,116,101,100,46,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,10,32,32, + 32,32,97,32,84,114,117,101,32,118,97,108,117,101,32,105, + 115,32,116,104,101,32,115,97,109,101,32,97,115,32,115,101, + 116,116,105,110,103,32,39,111,112,116,105,109,105,122,97,116, + 105,111,110,39,32,116,111,32,116,104,101,32,101,109,112,116, + 121,32,115,116,114,105,110,103,10,32,32,32,32,119,104,105, + 108,101,32,97,32,70,97,108,115,101,32,118,97,108,117,101, + 32,105,115,32,101,113,117,105,118,97,108,101,110,116,32,116, + 111,32,115,101,116,116,105,110,103,32,39,111,112,116,105,109, + 105,122,97,116,105,111,110,39,32,116,111,32,39,49,39,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,122,70,116,104,101,32,100,101, + 98,117,103,95,111,118,101,114,114,105,100,101,32,112,97,114, + 97,109,101,116,101,114,32,105,115,32,100,101,112,114,101,99, + 97,116,101,100,59,32,117,115,101,32,39,111,112,116,105,109, + 105,122,97,116,105,111,110,39,32,105,110,115,116,101,97,100, + 122,50,100,101,98,117,103,95,111,118,101,114,114,105,100,101, + 32,111,114,32,111,112,116,105,109,105,122,97,116,105,111,110, + 32,109,117,115,116,32,98,101,32,115,101,116,32,116,111,32, + 78,111,110,101,114,30,0,0,0,114,29,0,0,0,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,233,0,0,0,0,122,24,123,33, + 114,125,32,105,115,32,110,111,116,32,97,108,112,104,97,110, + 117,109,101,114,105,99,122,7,123,125,46,123,125,123,125,250, + 1,58,114,60,0,0,0,41,28,218,9,95,119,97,114,110, + 105,110,103,115,218,4,119,97,114,110,218,18,68,101,112,114, + 101,99,97,116,105,111,110,87,97,114,110,105,110,103,218,9, + 84,121,112,101,69,114,114,111,114,114,1,0,0,0,218,6, + 102,115,112,97,116,104,114,38,0,0,0,114,32,0,0,0, + 114,6,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,218,5,102,108,97,103, + 115,218,8,111,112,116,105,109,105,122,101,218,3,115,116,114, + 218,7,105,115,97,108,110,117,109,218,10,86,97,108,117,101, + 69,114,114,111,114,114,51,0,0,0,218,4,95,79,80,84, + 218,17,66,89,84,69,67,79,68,69,95,83,85,70,70,73, + 88,69,83,218,14,112,121,99,97,99,104,101,95,112,114,101, + 102,105,120,114,49,0,0,0,114,28,0,0,0,114,45,0, + 0,0,114,21,0,0,0,218,6,108,115,116,114,105,112,218, + 8,95,80,89,67,65,67,72,69,41,12,114,35,0,0,0, + 90,14,100,101,98,117,103,95,111,118,101,114,114,105,100,101, + 114,61,0,0,0,218,7,109,101,115,115,97,103,101,218,4, + 104,101,97,100,114,37,0,0,0,90,4,98,97,115,101,218, + 3,115,101,112,218,4,114,101,115,116,90,3,116,97,103,90, + 15,97,108,109,111,115,116,95,102,105,108,101,110,97,109,101, + 218,8,102,105,108,101,110,97,109,101,114,2,0,0,0,114, + 2,0,0,0,114,4,0,0,0,218,17,99,97,99,104,101, + 95,102,114,111,109,95,115,111,117,114,99,101,26,1,0,0, + 115,68,0,0,0,0,18,8,1,6,1,6,1,8,1,4, + 1,8,1,12,1,10,1,12,1,16,1,8,1,8,1,8, + 1,24,1,8,1,12,1,6,2,8,1,8,1,8,1,8, + 1,14,1,14,1,12,1,12,9,10,1,14,5,28,1,12, + 4,2,1,4,1,8,1,6,2,114,88,0,0,0,99,1, + 0,0,0,0,0,0,0,10,0,0,0,5,0,0,0,67, + 0,0,0,115,46,1,0,0,116,0,106,1,106,2,100,1, 107,8,114,20,116,3,100,2,131,1,130,1,116,4,160,5, 124,0,161,1,125,0,116,6,124,0,131,1,92,2,125,1, - 125,2,116,6,124,1,131,1,92,2,125,1,125,3,124,3, - 116,7,107,3,114,78,116,8,100,3,160,9,116,7,124,0, - 161,2,131,1,130,1,124,2,160,10,100,4,161,1,125,4, - 124,4,100,5,107,7,114,112,116,8,100,6,160,9,124,2, - 161,1,131,1,130,1,110,86,124,4,100,7,107,2,114,198, - 124,2,160,11,100,4,100,8,161,2,100,9,25,0,125,5, - 124,5,160,12,116,13,161,1,115,160,116,8,100,10,160,9, - 116,13,161,1,131,1,130,1,124,5,116,14,116,13,131,1, - 100,1,133,2,25,0,125,6,124,6,160,15,161,0,115,198, - 116,8,100,11,160,9,124,5,161,1,131,1,130,1,124,2, - 160,16,100,4,161,1,100,12,25,0,125,7,116,17,124,1, - 124,7,116,18,100,12,25,0,23,0,131,2,83,0,41,13, - 97,110,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,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,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,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,47,52,56,56,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,60,0,0,0,62,2,0,0,0,114,58,0,0,0, - 233,3,0,0,0,122,33,101,120,112,101,99,116,101,100,32, - 111,110,108,121,32,50,32,111,114,32,51,32,100,111,116,115, - 32,105,110,32,123,33,114,125,114,83,0,0,0,114,58,0, - 0,0,233,254,255,255,255,122,57,111,112,116,105,109,105,122, + 125,2,100,3,125,3,116,0,106,7,100,1,107,9,114,102, + 116,0,106,7,160,8,116,9,161,1,125,4,124,1,160,10, + 124,4,116,11,23,0,161,1,114,102,124,1,116,12,124,4, + 131,1,100,1,133,2,25,0,125,1,100,4,125,3,124,3, + 115,144,116,6,124,1,131,1,92,2,125,1,125,5,124,5, + 116,13,107,3,114,144,116,14,116,13,155,0,100,5,124,0, + 155,2,157,3,131,1,130,1,124,2,160,15,100,6,161,1, + 125,6,124,6,100,7,107,7,114,178,116,14,100,8,124,2, + 155,2,157,2,131,1,130,1,110,92,124,6,100,9,107,2, + 144,1,114,14,124,2,160,16,100,6,100,10,161,2,100,11, + 25,0,125,7,124,7,160,10,116,17,161,1,115,228,116,14, + 100,12,116,17,155,2,157,2,131,1,130,1,124,7,116,12, + 116,17,131,1,100,1,133,2,25,0,125,8,124,8,160,18, + 161,0,144,1,115,14,116,14,100,13,124,7,155,2,100,14, + 157,3,131,1,130,1,124,2,160,19,100,6,161,1,100,15, + 25,0,125,9,116,20,124,1,124,9,116,21,100,15,25,0, + 23,0,131,2,83,0,41,16,97,110,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,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,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,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,47,52, + 56,56,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,70,84,122,31,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,114,62,0,0,0,62,2,0,0,0,114, + 60,0,0,0,114,47,0,0,0,122,29,101,120,112,101,99, + 116,101,100,32,111,110,108,121,32,50,32,111,114,32,51,32, + 100,111,116,115,32,105,110,32,114,47,0,0,0,114,60,0, + 0,0,233,254,255,255,255,122,53,111,112,116,105,109,105,122, 97,116,105,111,110,32,112,111,114,116,105,111,110,32,111,102, 32,102,105,108,101,110,97,109,101,32,100,111,101,115,32,110, - 111,116,32,115,116,97,114,116,32,119,105,116,104,32,123,33, - 114,125,122,52,111,112,116,105,109,105,122,97,116,105,111,110, - 32,108,101,118,101,108,32,123,33,114,125,32,105,115,32,110, - 111,116,32,97,110,32,97,108,112,104,97,110,117,109,101,114, - 105,99,32,118,97,108,117,101,114,61,0,0,0,41,19,114, - 6,0,0,0,114,67,0,0,0,114,68,0,0,0,114,69, - 0,0,0,114,1,0,0,0,114,66,0,0,0,114,38,0, - 0,0,114,76,0,0,0,114,74,0,0,0,114,48,0,0, - 0,218,5,99,111,117,110,116,114,34,0,0,0,114,8,0, - 0,0,114,75,0,0,0,114,31,0,0,0,114,73,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,8,114,35,0,0,0,114,79,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,9,100,111,116,95,99, - 111,117,110,116,114,59,0,0,0,90,9,111,112,116,95,108, - 101,118,101,108,90,13,98,97,115,101,95,102,105,108,101,110, - 97,109,101,114,2,0,0,0,114,2,0,0,0,114,4,0, - 0,0,218,17,115,111,117,114,99,101,95,102,114,111,109,95, - 99,97,99,104,101,60,1,0,0,115,46,0,0,0,0,9, - 12,1,8,1,10,1,12,1,12,1,8,1,6,1,10,1, - 10,1,8,1,6,1,10,1,8,1,16,1,10,1,6,1, - 8,1,16,1,8,1,6,1,8,1,14,1,114,88,0,0, - 0,99,1,0,0,0,0,0,0,0,5,0,0,0,9,0, - 0,0,67,0,0,0,115,126,0,0,0,116,0,124,0,131, - 1,100,1,107,2,114,16,100,2,83,0,124,0,160,1,100, - 3,161,1,92,3,125,1,125,2,125,3,124,1,114,56,124, - 3,160,2,161,0,100,4,100,5,133,2,25,0,100,6,107, - 3,114,60,124,0,83,0,121,12,116,3,124,0,131,1,125, - 4,87,0,110,36,4,0,116,4,116,5,102,2,107,10,114, - 108,1,0,1,0,1,0,124,0,100,2,100,5,133,2,25, - 0,125,4,89,0,110,2,88,0,116,6,124,4,131,1,114, - 122,124,4,83,0,124,0,83,0,41,7,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,61,0,0,0,78,114, - 60,0,0,0,233,253,255,255,255,233,255,255,255,255,90,2, - 112,121,41,7,114,31,0,0,0,114,32,0,0,0,218,5, - 108,111,119,101,114,114,88,0,0,0,114,69,0,0,0,114, - 74,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,81,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,2,0,0, - 0,114,2,0,0,0,114,4,0,0,0,218,15,95,103,101, - 116,95,115,111,117,114,99,101,102,105,108,101,94,1,0,0, - 115,20,0,0,0,0,7,12,1,4,1,16,1,24,1,4, - 1,2,1,12,1,18,1,18,1,114,94,0,0,0,99,1, - 0,0,0,0,0,0,0,1,0,0,0,8,0,0,0,67, - 0,0,0,115,72,0,0,0,124,0,160,0,116,1,116,2, - 131,1,161,1,114,46,121,8,116,3,124,0,131,1,83,0, - 4,0,116,4,107,10,114,42,1,0,1,0,1,0,89,0, - 113,68,88,0,110,22,124,0,160,0,116,1,116,5,131,1, - 161,1,114,64,124,0,83,0,100,0,83,0,100,0,83,0, - 41,1,78,41,6,218,8,101,110,100,115,119,105,116,104,218, - 5,116,117,112,108,101,114,87,0,0,0,114,82,0,0,0, - 114,69,0,0,0,114,77,0,0,0,41,1,218,8,102,105, - 108,101,110,97,109,101,114,2,0,0,0,114,2,0,0,0, - 114,4,0,0,0,218,11,95,103,101,116,95,99,97,99,104, - 101,100,113,1,0,0,115,16,0,0,0,0,1,14,1,2, - 1,8,1,14,1,8,1,14,1,4,2,114,98,0,0,0, - 99,1,0,0,0,0,0,0,0,2,0,0,0,8,0,0, - 0,67,0,0,0,115,52,0,0,0,121,14,116,0,124,0, - 131,1,106,1,125,1,87,0,110,24,4,0,116,2,107,10, - 114,38,1,0,1,0,1,0,100,1,125,1,89,0,110,2, - 88,0,124,1,100,2,79,0,125,1,124,1,83,0,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,2,0,0, - 0,114,2,0,0,0,114,4,0,0,0,218,10,95,99,97, - 108,99,95,109,111,100,101,125,1,0,0,115,12,0,0,0, - 0,2,2,1,14,1,14,1,10,3,8,1,114,100,0,0, - 0,99,1,0,0,0,0,0,0,0,3,0,0,0,8,0, - 0,0,3,0,0,0,115,68,0,0,0,100,6,135,0,102, - 1,100,2,100,3,132,9,125,1,121,10,116,0,106,1,125, - 2,87,0,110,28,4,0,116,2,107,10,114,52,1,0,1, - 0,1,0,100,4,100,5,132,0,125,2,89,0,110,2,88, - 0,124,2,124,1,136,0,131,2,1,0,124,1,83,0,41, - 7,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,4,0,0, - 0,31,0,0,0,115,66,0,0,0,124,1,100,0,107,8, - 114,16,124,0,106,0,125,1,110,32,124,0,106,0,124,1, - 107,3,114,48,116,1,100,1,124,0,106,0,124,1,102,2, - 22,0,124,1,100,2,141,2,130,1,136,0,124,0,124,1, - 102,2,124,2,158,2,124,3,142,1,83,0,41,3,78,122, - 30,108,111,97,100,101,114,32,102,111,114,32,37,115,32,99, - 97,110,110,111,116,32,104,97,110,100,108,101,32,37,115,41, - 1,218,4,110,97,109,101,41,2,114,101,0,0,0,218,11, - 73,109,112,111,114,116,69,114,114,111,114,41,4,218,4,115, - 101,108,102,114,101,0,0,0,218,4,97,114,103,115,90,6, - 107,119,97,114,103,115,41,1,218,6,109,101,116,104,111,100, - 114,2,0,0,0,114,4,0,0,0,218,19,95,99,104,101, - 99,107,95,110,97,109,101,95,119,114,97,112,112,101,114,145, - 1,0,0,115,12,0,0,0,0,1,8,1,8,1,10,1, - 4,1,18,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,99,2, - 0,0,0,0,0,0,0,3,0,0,0,7,0,0,0,83, - 0,0,0,115,60,0,0,0,120,40,100,1,68,0,93,32, - 125,2,116,0,124,1,124,2,131,2,114,6,116,1,124,0, - 124,2,116,2,124,1,124,2,131,2,131,3,1,0,113,6, - 87,0,124,0,106,3,160,4,124,1,106,3,161,1,1,0, + 111,116,32,115,116,97,114,116,32,119,105,116,104,32,122,19, + 111,112,116,105,109,105,122,97,116,105,111,110,32,108,101,118, + 101,108,32,122,29,32,105,115,32,110,111,116,32,97,110,32, + 97,108,112,104,97,110,117,109,101,114,105,99,32,118,97,108, + 117,101,114,63,0,0,0,41,22,114,6,0,0,0,114,70, + 0,0,0,114,71,0,0,0,114,72,0,0,0,114,1,0, + 0,0,114,69,0,0,0,114,38,0,0,0,114,80,0,0, + 0,114,20,0,0,0,114,21,0,0,0,114,8,0,0,0, + 114,25,0,0,0,114,31,0,0,0,114,82,0,0,0,114, + 77,0,0,0,218,5,99,111,117,110,116,114,34,0,0,0, + 114,78,0,0,0,114,76,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,10,114,35,0, + 0,0,114,84,0,0,0,90,16,112,121,99,97,99,104,101, + 95,102,105,108,101,110,97,109,101,90,23,102,111,117,110,100, + 95,105,110,95,112,121,99,97,99,104,101,95,112,114,101,102, + 105,120,90,13,115,116,114,105,112,112,101,100,95,112,97,116, + 104,90,7,112,121,99,97,99,104,101,90,9,100,111,116,95, + 99,111,117,110,116,114,61,0,0,0,90,9,111,112,116,95, + 108,101,118,101,108,90,13,98,97,115,101,95,102,105,108,101, + 110,97,109,101,114,2,0,0,0,114,2,0,0,0,114,4, + 0,0,0,218,17,115,111,117,114,99,101,95,102,114,111,109, + 95,99,97,99,104,101,97,1,0,0,115,52,0,0,0,0, + 9,12,1,8,1,10,1,12,1,4,1,10,1,12,1,14, + 1,16,1,4,1,4,1,12,1,8,1,18,2,10,1,8, + 1,16,1,10,1,16,1,10,1,14,2,16,1,10,1,16, + 2,14,1,114,93,0,0,0,99,1,0,0,0,0,0,0, + 0,5,0,0,0,9,0,0,0,67,0,0,0,115,126,0, + 0,0,116,0,124,0,131,1,100,1,107,2,114,16,100,2, + 83,0,124,0,160,1,100,3,161,1,92,3,125,1,125,2, + 125,3,124,1,114,56,124,3,160,2,161,0,100,4,100,5, + 133,2,25,0,100,6,107,3,114,60,124,0,83,0,122,12, + 116,3,124,0,131,1,125,4,87,0,110,36,4,0,116,4, + 116,5,102,2,107,10,114,108,1,0,1,0,1,0,124,0, + 100,2,100,5,133,2,25,0,125,4,89,0,110,2,88,0, + 116,6,124,4,131,1,114,122,124,4,83,0,124,0,83,0, + 41,7,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,63,0,0,0,78,114,62,0,0,0,233,253,255,255,255, + 233,255,255,255,255,90,2,112,121,41,7,114,31,0,0,0, + 114,32,0,0,0,218,5,108,111,119,101,114,114,93,0,0, + 0,114,72,0,0,0,114,77,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,86,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,2,0,0,0,114,2,0,0,0,114,4,0, + 0,0,218,15,95,103,101,116,95,115,111,117,114,99,101,102, + 105,108,101,137,1,0,0,115,20,0,0,0,0,7,12,1, + 4,1,16,1,24,1,4,1,2,1,12,1,18,1,18,1, + 114,99,0,0,0,99,1,0,0,0,0,0,0,0,1,0, + 0,0,8,0,0,0,67,0,0,0,115,74,0,0,0,124, + 0,160,0,116,1,116,2,131,1,161,1,114,48,122,10,116, + 3,124,0,131,1,87,0,83,0,4,0,116,4,107,10,114, + 44,1,0,1,0,1,0,89,0,113,70,88,0,110,22,124, + 0,160,0,116,1,116,5,131,1,161,1,114,66,124,0,83, + 0,100,0,83,0,100,0,83,0,41,1,78,41,6,218,8, + 101,110,100,115,119,105,116,104,218,5,116,117,112,108,101,114, + 92,0,0,0,114,88,0,0,0,114,72,0,0,0,114,79, + 0,0,0,41,1,114,87,0,0,0,114,2,0,0,0,114, + 2,0,0,0,114,4,0,0,0,218,11,95,103,101,116,95, + 99,97,99,104,101,100,156,1,0,0,115,16,0,0,0,0, + 1,14,1,2,1,10,1,14,1,8,1,14,1,4,2,114, + 102,0,0,0,99,1,0,0,0,0,0,0,0,2,0,0, + 0,8,0,0,0,67,0,0,0,115,52,0,0,0,122,14, + 116,0,124,0,131,1,106,1,125,1,87,0,110,24,4,0, + 116,2,107,10,114,38,1,0,1,0,1,0,100,1,125,1, + 89,0,110,2,88,0,124,1,100,2,79,0,125,1,124,1, + 83,0,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,2,0,0,0,114,2,0,0,0,114,4,0,0,0,218, + 10,95,99,97,108,99,95,109,111,100,101,168,1,0,0,115, + 12,0,0,0,0,2,2,1,14,1,14,1,10,3,8,1, + 114,104,0,0,0,99,1,0,0,0,0,0,0,0,3,0, + 0,0,8,0,0,0,3,0,0,0,115,68,0,0,0,100, + 6,135,0,102,1,100,2,100,3,132,9,125,1,122,10,116, + 0,106,1,125,2,87,0,110,28,4,0,116,2,107,10,114, + 52,1,0,1,0,1,0,100,4,100,5,132,0,125,2,89, + 0,110,2,88,0,124,2,124,1,136,0,131,2,1,0,124, + 1,83,0,41,7,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,4,0,0,0,31,0,0,0,115,66,0,0,0,124,1, + 100,0,107,8,114,16,124,0,106,0,125,1,110,32,124,0, + 106,0,124,1,107,3,114,48,116,1,100,1,124,0,106,0, + 124,1,102,2,22,0,124,1,100,2,141,2,130,1,136,0, + 124,0,124,1,102,2,124,2,158,2,124,3,142,1,83,0, + 41,3,78,122,30,108,111,97,100,101,114,32,102,111,114,32, + 37,115,32,99,97,110,110,111,116,32,104,97,110,100,108,101, + 32,37,115,41,1,218,4,110,97,109,101,41,2,114,105,0, + 0,0,218,11,73,109,112,111,114,116,69,114,114,111,114,41, + 4,218,4,115,101,108,102,114,105,0,0,0,218,4,97,114, + 103,115,90,6,107,119,97,114,103,115,41,1,218,6,109,101, + 116,104,111,100,114,2,0,0,0,114,4,0,0,0,218,19, + 95,99,104,101,99,107,95,110,97,109,101,95,119,114,97,112, + 112,101,114,188,1,0,0,115,12,0,0,0,0,1,8,1, + 8,1,10,1,4,1,18,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,99,2,0,0,0,0,0,0,0,3,0,0,0,7, + 0,0,0,83,0,0,0,115,56,0,0,0,100,1,68,0, + 93,32,125,2,116,0,124,1,124,2,131,2,114,4,116,1, + 124,0,124,2,116,2,124,1,124,2,131,2,131,3,1,0, + 113,4,124,0,106,3,160,4,124,1,106,3,161,1,1,0, 100,0,83,0,41,2,78,41,4,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, @@ -538,18 +575,18 @@ const unsigned char _Py_M__importlib_external[] = { 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,54,0,0,0,114,2,0,0,0,114,2,0,0,0, - 114,4,0,0,0,218,5,95,119,114,97,112,156,1,0,0, - 115,8,0,0,0,0,1,10,1,10,1,22,1,122,26,95, + 100,114,56,0,0,0,114,2,0,0,0,114,2,0,0,0, + 114,4,0,0,0,218,5,95,119,114,97,112,199,1,0,0, + 115,8,0,0,0,0,1,8,1,10,1,20,1,122,26,95, 99,104,101,99,107,95,110,97,109,101,46,60,108,111,99,97, 108,115,62,46,95,119,114,97,112,41,1,78,41,3,218,10, - 95,98,111,111,116,115,116,114,97,112,114,116,0,0,0,218, - 9,78,97,109,101,69,114,114,111,114,41,3,114,105,0,0, - 0,114,106,0,0,0,114,116,0,0,0,114,2,0,0,0, - 41,1,114,105,0,0,0,114,4,0,0,0,218,11,95,99, - 104,101,99,107,95,110,97,109,101,137,1,0,0,115,14,0, + 95,98,111,111,116,115,116,114,97,112,114,120,0,0,0,218, + 9,78,97,109,101,69,114,114,111,114,41,3,114,109,0,0, + 0,114,110,0,0,0,114,120,0,0,0,114,2,0,0,0, + 41,1,114,109,0,0,0,114,4,0,0,0,218,11,95,99, + 104,101,99,107,95,110,97,109,101,180,1,0,0,115,14,0, 0,0,0,8,14,7,2,1,10,1,14,2,14,5,10,1, - 114,119,0,0,0,99,2,0,0,0,0,0,0,0,5,0, + 114,123,0,0,0,99,2,0,0,0,0,0,0,0,5,0, 0,0,6,0,0,0,67,0,0,0,115,60,0,0,0,124, 0,160,0,124,1,161,1,92,2,125,2,125,3,124,2,100, 1,107,8,114,56,116,1,124,3,131,1,114,56,100,2,125, @@ -567,16 +604,16 @@ const unsigned char _Py_M__importlib_external[] = { 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,61,0,0,0,41,6, + 32,95,95,105,110,105,116,95,95,114,63,0,0,0,41,6, 218,11,102,105,110,100,95,108,111,97,100,101,114,114,31,0, - 0,0,114,62,0,0,0,114,63,0,0,0,114,48,0,0, + 0,0,114,65,0,0,0,114,66,0,0,0,114,51,0,0, 0,218,13,73,109,112,111,114,116,87,97,114,110,105,110,103, - 41,5,114,103,0,0,0,218,8,102,117,108,108,110,97,109, + 41,5,114,107,0,0,0,218,8,102,117,108,108,110,97,109, 101,218,6,108,111,97,100,101,114,218,8,112,111,114,116,105, 111,110,115,218,3,109,115,103,114,2,0,0,0,114,2,0, 0,0,114,4,0,0,0,218,17,95,102,105,110,100,95,109, - 111,100,117,108,101,95,115,104,105,109,165,1,0,0,115,10, - 0,0,0,0,10,14,1,16,1,4,1,22,1,114,126,0, + 111,100,117,108,101,95,115,104,105,109,208,1,0,0,115,10, + 0,0,0,0,10,14,1,16,1,4,1,22,1,114,130,0, 0,0,99,3,0,0,0,0,0,0,0,6,0,0,0,4, 0,0,0,67,0,0,0,115,158,0,0,0,124,0,100,1, 100,2,133,2,25,0,125,3,124,3,116,0,107,3,114,60, @@ -634,17 +671,17 @@ const unsigned char _Py_M__importlib_external[] = { 97,100,101,114,32,111,102,32,233,8,0,0,0,233,252,255, 255,255,122,14,105,110,118,97,108,105,100,32,102,108,97,103, 115,32,122,4,32,105,110,32,41,7,218,12,77,65,71,73, - 67,95,78,85,77,66,69,82,114,117,0,0,0,218,16,95, + 67,95,78,85,77,66,69,82,114,121,0,0,0,218,16,95, 118,101,114,98,111,115,101,95,109,101,115,115,97,103,101,114, - 102,0,0,0,114,31,0,0,0,218,8,69,79,70,69,114, - 114,111,114,114,19,0,0,0,41,6,114,55,0,0,0,114, - 101,0,0,0,218,11,101,120,99,95,100,101,116,97,105,108, - 115,90,5,109,97,103,105,99,114,78,0,0,0,114,70,0, + 106,0,0,0,114,31,0,0,0,218,8,69,79,70,69,114, + 114,111,114,114,19,0,0,0,41,6,114,57,0,0,0,114, + 105,0,0,0,218,11,101,120,99,95,100,101,116,97,105,108, + 115,90,5,109,97,103,105,99,114,83,0,0,0,114,73,0, 0,0,114,2,0,0,0,114,2,0,0,0,114,4,0,0, 0,218,13,95,99,108,97,115,115,105,102,121,95,112,121,99, - 182,1,0,0,115,28,0,0,0,0,16,12,1,8,1,16, + 225,1,0,0,115,28,0,0,0,0,16,12,1,8,1,16, 1,12,1,12,1,12,1,10,1,12,1,8,1,16,2,8, - 1,16,1,12,1,114,134,0,0,0,99,5,0,0,0,0, + 1,16,1,12,1,114,138,0,0,0,99,5,0,0,0,0, 0,0,0,6,0,0,0,4,0,0,0,67,0,0,0,115, 112,0,0,0,116,0,124,0,100,1,100,2,133,2,25,0, 131,1,124,1,100,3,64,0,107,3,114,58,100,4,124,3, @@ -686,19 +723,19 @@ const unsigned char _Py_M__importlib_external[] = { 111,114,116,69,114,114,111,114,32,105,115,32,114,97,105,115, 101,100,32,105,102,32,116,104,101,32,98,121,116,101,99,111, 100,101,32,105,115,32,115,116,97,108,101,46,10,10,32,32, - 32,32,114,128,0,0,0,233,12,0,0,0,108,3,0,0, + 32,32,114,132,0,0,0,233,12,0,0,0,108,3,0,0, 0,255,127,255,127,3,0,122,22,98,121,116,101,99,111,100, 101,32,105,115,32,115,116,97,108,101,32,102,111,114,32,122, - 2,123,125,78,114,127,0,0,0,41,4,114,19,0,0,0, - 114,117,0,0,0,114,131,0,0,0,114,102,0,0,0,41, - 6,114,55,0,0,0,218,12,115,111,117,114,99,101,95,109, + 2,123,125,78,114,131,0,0,0,41,4,114,19,0,0,0, + 114,121,0,0,0,114,135,0,0,0,114,106,0,0,0,41, + 6,114,57,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,101,0,0,0,114,133,0,0,0,114,78,0,0,0, + 101,114,105,0,0,0,114,137,0,0,0,114,83,0,0,0, 114,2,0,0,0,114,2,0,0,0,114,4,0,0,0,218, 23,95,118,97,108,105,100,97,116,101,95,116,105,109,101,115, - 116,97,109,112,95,112,121,99,215,1,0,0,115,14,0,0, + 116,97,109,112,95,112,121,99,2,2,0,0,115,14,0,0, 0,0,19,24,1,10,1,12,1,12,1,8,1,24,1,114, - 138,0,0,0,99,4,0,0,0,0,0,0,0,4,0,0, + 142,0,0,0,99,4,0,0,0,0,0,0,0,4,0,0, 0,3,0,0,0,67,0,0,0,115,38,0,0,0,124,0, 100,1,100,2,133,2,25,0,124,1,107,3,114,34,116,0, 100,3,124,2,155,2,157,2,102,1,124,3,142,1,130,1, @@ -733,17 +770,17 @@ const unsigned char _Py_M__importlib_external[] = { 10,10,32,32,32,32,65,110,32,73,109,112,111,114,116,69, 114,114,111,114,32,105,115,32,114,97,105,115,101,100,32,105, 102,32,116,104,101,32,98,121,116,101,99,111,100,101,32,105, - 115,32,115,116,97,108,101,46,10,10,32,32,32,32,114,128, - 0,0,0,114,127,0,0,0,122,46,104,97,115,104,32,105, + 115,32,115,116,97,108,101,46,10,10,32,32,32,32,114,132, + 0,0,0,114,131,0,0,0,122,46,104,97,115,104,32,105, 110,32,98,121,116,101,99,111,100,101,32,100,111,101,115,110, 39,116,32,109,97,116,99,104,32,104,97,115,104,32,111,102, - 32,115,111,117,114,99,101,32,78,41,1,114,102,0,0,0, - 41,4,114,55,0,0,0,218,11,115,111,117,114,99,101,95, - 104,97,115,104,114,101,0,0,0,114,133,0,0,0,114,2, + 32,115,111,117,114,99,101,32,78,41,1,114,106,0,0,0, + 41,4,114,57,0,0,0,218,11,115,111,117,114,99,101,95, + 104,97,115,104,114,105,0,0,0,114,137,0,0,0,114,2, 0,0,0,114,2,0,0,0,114,4,0,0,0,218,18,95, 118,97,108,105,100,97,116,101,95,104,97,115,104,95,112,121, - 99,243,1,0,0,115,8,0,0,0,0,17,16,1,2,1, - 10,1,114,140,0,0,0,99,4,0,0,0,0,0,0,0, + 99,30,2,0,0,115,8,0,0,0,0,17,16,1,2,1, + 10,1,114,144,0,0,0,99,4,0,0,0,0,0,0,0, 5,0,0,0,5,0,0,0,67,0,0,0,115,80,0,0, 0,116,0,160,1,124,0,161,1,125,4,116,2,124,4,116, 3,131,2,114,56,116,4,160,5,100,1,124,2,161,2,1, @@ -755,19 +792,19 @@ const unsigned char _Py_M__importlib_external[] = { 110,32,97,32,112,121,99,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,41,2,114,101,0,0,0, + 116,32,105,110,32,123,33,114,125,41,2,114,105,0,0,0, 114,35,0,0,0,41,10,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, - 117,0,0,0,114,131,0,0,0,218,4,95,105,109,112,90, + 121,0,0,0,114,135,0,0,0,218,4,95,105,109,112,90, 16,95,102,105,120,95,99,111,95,102,105,108,101,110,97,109, - 101,114,102,0,0,0,114,48,0,0,0,41,5,114,55,0, - 0,0,114,101,0,0,0,114,92,0,0,0,114,93,0,0, + 101,114,106,0,0,0,114,51,0,0,0,41,5,114,57,0, + 0,0,114,105,0,0,0,114,97,0,0,0,114,98,0,0, 0,218,4,99,111,100,101,114,2,0,0,0,114,2,0,0, 0,114,4,0,0,0,218,17,95,99,111,109,112,105,108,101, - 95,98,121,116,101,99,111,100,101,11,2,0,0,115,16,0, + 95,98,121,116,101,99,111,100,101,54,2,0,0,115,16,0, 0,0,0,2,10,1,10,1,12,1,8,1,12,1,4,2, - 10,1,114,146,0,0,0,114,61,0,0,0,99,3,0,0, + 10,1,114,150,0,0,0,114,63,0,0,0,99,3,0,0, 0,0,0,0,0,4,0,0,0,5,0,0,0,67,0,0, 0,115,70,0,0,0,116,0,116,1,131,1,125,3,124,3, 160,2,116,3,100,1,131,1,161,1,1,0,124,3,160,2, @@ -776,16 +813,16 @@ const unsigned char _Py_M__importlib_external[] = { 124,0,161,1,161,1,1,0,124,3,83,0,41,2,122,43, 80,114,111,100,117,99,101,32,116,104,101,32,100,97,116,97, 32,102,111,114,32,97,32,116,105,109,101,115,116,97,109,112, - 45,98,97,115,101,100,32,112,121,99,46,114,61,0,0,0, - 41,6,218,9,98,121,116,101,97,114,114,97,121,114,130,0, + 45,98,97,115,101,100,32,112,121,99,46,114,63,0,0,0, + 41,6,218,9,98,121,116,101,97,114,114,97,121,114,134,0, 0,0,218,6,101,120,116,101,110,100,114,17,0,0,0,114, - 141,0,0,0,218,5,100,117,109,112,115,41,4,114,145,0, - 0,0,218,5,109,116,105,109,101,114,137,0,0,0,114,55, + 145,0,0,0,218,5,100,117,109,112,115,41,4,114,149,0, + 0,0,218,5,109,116,105,109,101,114,141,0,0,0,114,57, 0,0,0,114,2,0,0,0,114,2,0,0,0,114,4,0, 0,0,218,22,95,99,111,100,101,95,116,111,95,116,105,109, - 101,115,116,97,109,112,95,112,121,99,24,2,0,0,115,12, + 101,115,116,97,109,112,95,112,121,99,67,2,0,0,115,12, 0,0,0,0,2,8,1,14,1,14,1,14,1,16,1,114, - 151,0,0,0,84,99,3,0,0,0,0,0,0,0,5,0, + 155,0,0,0,84,99,3,0,0,0,0,0,0,0,5,0, 0,0,5,0,0,0,67,0,0,0,115,80,0,0,0,116, 0,116,1,131,1,125,3,100,1,124,2,100,1,62,0,66, 0,125,4,124,3,160,2,116,3,124,4,131,1,161,1,1, @@ -794,17 +831,17 @@ const unsigned char _Py_M__importlib_external[] = { 6,160,7,124,0,161,1,161,1,1,0,124,3,83,0,41, 3,122,38,80,114,111,100,117,99,101,32,116,104,101,32,100, 97,116,97,32,102,111,114,32,97,32,104,97,115,104,45,98, - 97,115,101,100,32,112,121,99,46,114,29,0,0,0,114,128, - 0,0,0,41,8,114,147,0,0,0,114,130,0,0,0,114, - 148,0,0,0,114,17,0,0,0,114,31,0,0,0,218,14, - 65,115,115,101,114,116,105,111,110,69,114,114,111,114,114,141, - 0,0,0,114,149,0,0,0,41,5,114,145,0,0,0,114, - 139,0,0,0,90,7,99,104,101,99,107,101,100,114,55,0, - 0,0,114,70,0,0,0,114,2,0,0,0,114,2,0,0, + 97,115,101,100,32,112,121,99,46,114,29,0,0,0,114,132, + 0,0,0,41,8,114,151,0,0,0,114,134,0,0,0,114, + 152,0,0,0,114,17,0,0,0,114,31,0,0,0,218,14, + 65,115,115,101,114,116,105,111,110,69,114,114,111,114,114,145, + 0,0,0,114,153,0,0,0,41,5,114,149,0,0,0,114, + 143,0,0,0,90,7,99,104,101,99,107,101,100,114,57,0, + 0,0,114,73,0,0,0,114,2,0,0,0,114,2,0,0, 0,114,4,0,0,0,218,17,95,99,111,100,101,95,116,111, - 95,104,97,115,104,95,112,121,99,34,2,0,0,115,14,0, + 95,104,97,115,104,95,112,121,99,77,2,0,0,115,14,0, 0,0,0,2,8,1,12,1,14,1,16,1,10,1,16,1, - 114,153,0,0,0,99,1,0,0,0,0,0,0,0,5,0, + 114,157,0,0,0,99,1,0,0,0,0,0,0,0,5,0, 0,0,6,0,0,0,67,0,0,0,115,62,0,0,0,100, 1,100,2,108,0,125,1,116,1,160,2,124,0,161,1,106, 3,125,2,124,1,160,4,124,2,161,1,125,3,116,1,160, @@ -817,366 +854,343 @@ const unsigned char _Py_M__importlib_external[] = { 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,61,0,0,0,78, - 84,41,7,218,8,116,111,107,101,110,105,122,101,114,51,0, + 100,105,110,103,46,10,32,32,32,32,114,63,0,0,0,78, + 84,41,7,218,8,116,111,107,101,110,105,122,101,114,53,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,154,0,0,0,90,21, + 114,99,101,95,98,121,116,101,115,114,158,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,2,0,0,0,114,2,0,0,0,114,4,0,0,0,218, - 13,100,101,99,111,100,101,95,115,111,117,114,99,101,45,2, + 13,100,101,99,111,100,101,95,115,111,117,114,99,101,88,2, 0,0,115,10,0,0,0,0,5,8,1,12,1,10,1,12, - 1,114,158,0,0,0,41,2,114,123,0,0,0,218,26,115, + 1,114,162,0,0,0,41,2,114,127,0,0,0,218,26,115, 117,98,109,111,100,117,108,101,95,115,101,97,114,99,104,95, 108,111,99,97,116,105,111,110,115,99,2,0,0,0,2,0, - 0,0,9,0,0,0,8,0,0,0,67,0,0,0,115,18, + 0,0,9,0,0,0,8,0,0,0,67,0,0,0,115,16, 1,0,0,124,1,100,1,107,8,114,60,100,2,125,1,116, - 0,124,2,100,3,131,2,114,70,121,14,124,2,160,1,124, + 0,124,2,100,3,131,2,114,70,122,14,124,2,160,1,124, 0,161,1,125,1,87,0,113,70,4,0,116,2,107,10,114, 56,1,0,1,0,1,0,89,0,113,70,88,0,110,10,116, 3,160,4,124,1,161,1,125,1,116,5,106,6,124,0,124, 2,124,1,100,4,141,3,125,4,100,5,124,4,95,7,124, - 2,100,1,107,8,114,156,120,54,116,8,131,0,68,0,93, - 40,92,2,125,5,125,6,124,1,160,9,116,10,124,6,131, - 1,161,1,114,108,124,5,124,0,124,1,131,2,125,2,124, - 2,124,4,95,11,80,0,113,108,87,0,100,1,83,0,124, - 3,116,12,107,8,114,222,116,0,124,2,100,6,131,2,114, - 228,121,14,124,2,160,13,124,0,161,1,125,7,87,0,110, - 20,4,0,116,2,107,10,114,208,1,0,1,0,1,0,89, - 0,113,228,88,0,124,7,114,228,103,0,124,4,95,14,110, - 6,124,3,124,4,95,14,124,4,106,14,103,0,107,2,144, - 1,114,14,124,1,144,1,114,14,116,15,124,1,131,1,100, - 7,25,0,125,8,124,4,106,14,160,16,124,8,161,1,1, - 0,124,4,83,0,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,218,12,103,101,116,95,102,105,108,101,110, - 97,109,101,41,1,218,6,111,114,105,103,105,110,84,218,10, - 105,115,95,112,97,99,107,97,103,101,114,61,0,0,0,41, - 17,114,111,0,0,0,114,160,0,0,0,114,102,0,0,0, - 114,1,0,0,0,114,66,0,0,0,114,117,0,0,0,218, - 10,77,111,100,117,108,101,83,112,101,99,90,13,95,115,101, - 116,95,102,105,108,101,97,116,116,114,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,95,0,0,0,114,96,0,0, - 0,114,123,0,0,0,218,9,95,80,79,80,85,76,65,84, - 69,114,162,0,0,0,114,159,0,0,0,114,38,0,0,0, - 218,6,97,112,112,101,110,100,41,9,114,101,0,0,0,90, - 8,108,111,99,97,116,105,111,110,114,123,0,0,0,114,159, - 0,0,0,218,4,115,112,101,99,218,12,108,111,97,100,101, - 114,95,99,108,97,115,115,218,8,115,117,102,102,105,120,101, - 115,114,162,0,0,0,90,7,100,105,114,110,97,109,101,114, - 2,0,0,0,114,2,0,0,0,114,4,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,62,2,0,0,115,62,0,0,0, - 0,12,8,4,4,1,10,2,2,1,14,1,14,1,8,2, - 10,8,16,1,6,3,8,1,16,1,14,1,10,1,6,1, - 6,2,4,3,8,2,10,1,2,1,14,1,14,1,6,2, - 4,1,8,2,6,1,12,1,6,1,12,1,12,2,114,170, - 0,0,0,99,0,0,0,0,0,0,0,0,0,0,0,0, - 4,0,0,0,64,0,0,0,115,80,0,0,0,101,0,90, - 1,100,0,90,2,100,1,90,3,100,2,90,4,100,3,90, - 5,100,4,90,6,101,7,100,5,100,6,132,0,131,1,90, - 8,101,7,100,7,100,8,132,0,131,1,90,9,101,7,100, - 14,100,10,100,11,132,1,131,1,90,10,101,7,100,15,100, - 12,100,13,132,1,131,1,90,11,100,9,83,0,41,16,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,8,0,0,0,67,0,0,0,115,50,0,0, - 0,121,14,116,0,160,1,116,0,106,2,124,1,161,2,83, - 0,4,0,116,3,107,10,114,44,1,0,1,0,1,0,116, - 0,160,1,116,0,106,4,124,1,161,2,83,0,88,0,100, - 0,83,0,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,218,3,99,108,115,114,3,0, - 0,0,114,2,0,0,0,114,2,0,0,0,114,4,0,0, - 0,218,14,95,111,112,101,110,95,114,101,103,105,115,116,114, - 121,142,2,0,0,115,8,0,0,0,0,2,2,1,14,1, - 14,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,9,0,0,0,67,0,0,0,115,112,0, - 0,0,124,0,106,0,114,14,124,0,106,1,125,2,110,6, - 124,0,106,2,125,2,124,2,106,3,124,1,100,1,116,4, - 106,5,100,0,100,2,133,2,25,0,22,0,100,3,141,2, - 125,3,121,38,124,0,160,6,124,3,161,1,143,18,125,4, - 116,7,160,8,124,4,100,4,161,2,125,5,87,0,100,0, - 81,0,82,0,88,0,87,0,110,20,4,0,116,9,107,10, - 114,106,1,0,1,0,1,0,100,0,83,0,88,0,124,5, - 83,0,41,5,78,122,5,37,100,46,37,100,114,58,0,0, - 0,41,2,114,122,0,0,0,90,11,115,121,115,95,118,101, - 114,115,105,111,110,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,48,0,0,0, - 114,6,0,0,0,218,12,118,101,114,115,105,111,110,95,105, - 110,102,111,114,174,0,0,0,114,172,0,0,0,90,10,81, - 117,101,114,121,86,97,108,117,101,114,40,0,0,0,41,6, - 114,173,0,0,0,114,122,0,0,0,90,12,114,101,103,105, - 115,116,114,121,95,107,101,121,114,3,0,0,0,90,4,104, - 107,101,121,218,8,102,105,108,101,112,97,116,104,114,2,0, - 0,0,114,2,0,0,0,114,4,0,0,0,218,16,95,115, - 101,97,114,99,104,95,114,101,103,105,115,116,114,121,149,2, - 0,0,115,22,0,0,0,0,2,6,1,8,2,6,1,6, - 1,22,1,2,1,12,1,26,1,14,1,6,1,122,38,87, + 2,100,1,107,8,114,154,116,8,131,0,68,0,93,42,92, + 2,125,5,125,6,124,1,160,9,116,10,124,6,131,1,161, + 1,114,106,124,5,124,0,124,1,131,2,125,2,124,2,124, + 4,95,11,1,0,113,154,113,106,100,1,83,0,124,3,116, + 12,107,8,114,220,116,0,124,2,100,6,131,2,114,226,122, + 14,124,2,160,13,124,0,161,1,125,7,87,0,110,20,4, + 0,116,2,107,10,114,206,1,0,1,0,1,0,89,0,113, + 226,88,0,124,7,114,226,103,0,124,4,95,14,110,6,124, + 3,124,4,95,14,124,4,106,14,103,0,107,2,144,1,114, + 12,124,1,144,1,114,12,116,15,124,1,131,1,100,7,25, + 0,125,8,124,4,106,14,160,16,124,8,161,1,1,0,124, + 4,83,0,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,218,12,103,101,116,95,102,105,108,101,110,97,109, + 101,41,1,218,6,111,114,105,103,105,110,84,218,10,105,115, + 95,112,97,99,107,97,103,101,114,63,0,0,0,41,17,114, + 115,0,0,0,114,164,0,0,0,114,106,0,0,0,114,1, + 0,0,0,114,69,0,0,0,114,121,0,0,0,218,10,77, + 111,100,117,108,101,83,112,101,99,90,13,95,115,101,116,95, + 102,105,108,101,97,116,116,114,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,100,0,0,0,114,101,0,0,0,114, + 127,0,0,0,218,9,95,80,79,80,85,76,65,84,69,114, + 166,0,0,0,114,163,0,0,0,114,38,0,0,0,218,6, + 97,112,112,101,110,100,41,9,114,105,0,0,0,90,8,108, + 111,99,97,116,105,111,110,114,127,0,0,0,114,163,0,0, + 0,218,4,115,112,101,99,218,12,108,111,97,100,101,114,95, + 99,108,97,115,115,218,8,115,117,102,102,105,120,101,115,114, + 166,0,0,0,90,7,100,105,114,110,97,109,101,114,2,0, + 0,0,114,2,0,0,0,114,4,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,105,2,0,0,115,62,0,0,0,0,12, + 8,4,4,1,10,2,2,1,14,1,14,1,8,2,10,8, + 16,1,6,3,8,1,14,1,14,1,10,1,6,1,6,2, + 4,3,8,2,10,1,2,1,14,1,14,1,6,2,4,1, + 8,2,6,1,12,1,6,1,12,1,12,2,114,174,0,0, + 0,99,0,0,0,0,0,0,0,0,0,0,0,0,4,0, + 0,0,64,0,0,0,115,80,0,0,0,101,0,90,1,100, + 0,90,2,100,1,90,3,100,2,90,4,100,3,90,5,100, + 4,90,6,101,7,100,5,100,6,132,0,131,1,90,8,101, + 7,100,7,100,8,132,0,131,1,90,9,101,7,100,14,100, + 10,100,11,132,1,131,1,90,10,101,7,100,15,100,12,100, + 13,132,1,131,1,90,11,100,9,83,0,41,16,218,21,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,8,0,0,0,67,0,0,0,115,120,0,0,0, - 124,0,160,0,124,1,161,1,125,4,124,4,100,0,107,8, - 114,22,100,0,83,0,121,12,116,1,124,4,131,1,1,0, - 87,0,110,20,4,0,116,2,107,10,114,54,1,0,1,0, - 1,0,100,0,83,0,88,0,120,58,116,3,131,0,68,0, - 93,48,92,2,125,5,125,6,124,4,160,4,116,5,124,6, - 131,1,161,1,114,64,116,6,106,7,124,1,124,5,124,1, - 124,4,131,2,124,4,100,1,141,3,125,7,124,7,83,0, - 113,64,87,0,100,0,83,0,41,2,78,41,1,114,161,0, - 0,0,41,8,114,180,0,0,0,114,39,0,0,0,114,40, - 0,0,0,114,164,0,0,0,114,95,0,0,0,114,96,0, - 0,0,114,117,0,0,0,218,16,115,112,101,99,95,102,114, - 111,109,95,108,111,97,100,101,114,41,8,114,173,0,0,0, - 114,122,0,0,0,114,35,0,0,0,218,6,116,97,114,103, - 101,116,114,179,0,0,0,114,123,0,0,0,114,169,0,0, - 0,114,167,0,0,0,114,2,0,0,0,114,2,0,0,0, - 114,4,0,0,0,218,9,102,105,110,100,95,115,112,101,99, - 164,2,0,0,115,26,0,0,0,0,2,10,1,8,1,4, - 1,2,1,12,1,14,1,6,1,16,1,14,1,6,1,8, - 1,8,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,4,0,0,0,67,0,0,0,115,34,0,0,0,124,0, - 160,0,124,1,124,2,161,2,125,3,124,3,100,1,107,9, - 114,26,124,3,106,1,83,0,100,1,83,0,100,1,83,0, - 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,183,0,0,0,114,123,0,0,0,41,4,114, - 173,0,0,0,114,122,0,0,0,114,35,0,0,0,114,167, - 0,0,0,114,2,0,0,0,114,2,0,0,0,114,4,0, - 0,0,218,11,102,105,110,100,95,109,111,100,117,108,101,180, - 2,0,0,115,8,0,0,0,0,7,12,1,8,1,6,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,2,78,78,41,1,78,41,12,114,108,0,0, - 0,114,107,0,0,0,114,109,0,0,0,114,110,0,0,0, - 114,177,0,0,0,114,176,0,0,0,114,175,0,0,0,218, - 11,99,108,97,115,115,109,101,116,104,111,100,114,174,0,0, - 0,114,180,0,0,0,114,183,0,0,0,114,184,0,0,0, - 114,2,0,0,0,114,2,0,0,0,114,2,0,0,0,114, - 4,0,0,0,114,171,0,0,0,130,2,0,0,115,20,0, - 0,0,8,2,4,3,4,3,4,2,4,2,12,7,12,15, - 2,1,12,15,2,1,114,171,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,48,0,0,0,101,0,90,1,100,0,90,2,100,1,90, - 3,100,2,100,3,132,0,90,4,100,4,100,5,132,0,90, - 5,100,6,100,7,132,0,90,6,100,8,100,9,132,0,90, - 7,100,10,83,0,41,11,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,4,0,0,0,67,0,0,0, - 115,64,0,0,0,116,0,124,0,160,1,124,1,161,1,131, - 1,100,1,25,0,125,2,124,2,160,2,100,2,100,1,161, - 2,100,3,25,0,125,3,124,1,160,3,100,2,161,1,100, - 4,25,0,125,4,124,3,100,5,107,2,111,62,124,4,100, - 5,107,3,83,0,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,60,0,0,0, - 114,61,0,0,0,114,58,0,0,0,218,8,95,95,105,110, - 105,116,95,95,41,4,114,38,0,0,0,114,160,0,0,0, - 114,34,0,0,0,114,32,0,0,0,41,5,114,103,0,0, - 0,114,122,0,0,0,114,97,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,2,0,0,0,114,2,0,0,0,114, - 4,0,0,0,114,162,0,0,0,199,2,0,0,115,8,0, - 0,0,0,3,18,1,16,1,14,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, - 83,0,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,2,0,0,0,41,2,114,103,0,0,0,114,167,0, - 0,0,114,2,0,0,0,114,2,0,0,0,114,4,0,0, - 0,218,13,99,114,101,97,116,101,95,109,111,100,117,108,101, - 207,2,0,0,115,2,0,0,0,0,1,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,5,0,0,0,67,0,0,0,115,56,0, - 0,0,124,0,160,0,124,1,106,1,161,1,125,2,124,2, - 100,1,107,8,114,36,116,2,100,2,160,3,124,1,106,1, - 161,1,131,1,130,1,116,4,160,5,116,6,124,2,124,1, - 106,7,161,3,1,0,100,1,83,0,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,8,218,8,103,101,116,95, - 99,111,100,101,114,108,0,0,0,114,102,0,0,0,114,48, - 0,0,0,114,117,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,218,4,101,120,101,99,114,114,0,0,0,41,3, - 114,103,0,0,0,218,6,109,111,100,117,108,101,114,145,0, - 0,0,114,2,0,0,0,114,2,0,0,0,114,4,0,0, - 0,218,11,101,120,101,99,95,109,111,100,117,108,101,210,2, - 0,0,115,10,0,0,0,0,2,12,1,8,1,6,1,10, - 1,122,25,95,76,111,97,100,101,114,66,97,115,105,99,115, - 46,101,120,101,99,95,109,111,100,117,108,101,99,2,0,0, - 0,0,0,0,0,2,0,0,0,4,0,0,0,67,0,0, - 0,115,12,0,0,0,116,0,160,1,124,0,124,1,161,2, - 83,0,41,1,122,26,84,104,105,115,32,109,111,100,117,108, - 101,32,105,115,32,100,101,112,114,101,99,97,116,101,100,46, - 41,2,114,117,0,0,0,218,17,95,108,111,97,100,95,109, - 111,100,117,108,101,95,115,104,105,109,41,2,114,103,0,0, - 0,114,122,0,0,0,114,2,0,0,0,114,2,0,0,0, - 114,4,0,0,0,218,11,108,111,97,100,95,109,111,100,117, - 108,101,218,2,0,0,115,2,0,0,0,0,2,122,25,95, - 76,111,97,100,101,114,66,97,115,105,99,115,46,108,111,97, - 100,95,109,111,100,117,108,101,78,41,8,114,108,0,0,0, - 114,107,0,0,0,114,109,0,0,0,114,110,0,0,0,114, - 162,0,0,0,114,188,0,0,0,114,193,0,0,0,114,195, - 0,0,0,114,2,0,0,0,114,2,0,0,0,114,2,0, - 0,0,114,4,0,0,0,114,186,0,0,0,194,2,0,0, - 115,10,0,0,0,8,3,4,2,8,8,8,3,8,8,114, - 186,0,0,0,99,0,0,0,0,0,0,0,0,0,0,0, - 0,3,0,0,0,64,0,0,0,115,74,0,0,0,101,0, - 90,1,100,0,90,2,100,1,100,2,132,0,90,3,100,3, - 100,4,132,0,90,4,100,5,100,6,132,0,90,5,100,7, - 100,8,132,0,90,6,100,9,100,10,132,0,90,7,100,11, - 100,12,156,1,100,13,100,14,132,2,90,8,100,15,100,16, - 132,0,90,9,100,17,83,0,41,18,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,8,0, - 0,0,116,0,130,1,100,1,83,0,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,79, - 83,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,114,40,0,0,0,41,2,114,103,0,0,0,114, - 35,0,0,0,114,2,0,0,0,114,2,0,0,0,114,4, - 0,0,0,218,10,112,97,116,104,95,109,116,105,109,101,225, - 2,0,0,115,2,0,0,0,0,6,122,23,83,111,117,114, - 99,101,76,111,97,100,101,114,46,112,97,116,104,95,109,116, - 105,109,101,99,2,0,0,0,0,0,0,0,2,0,0,0, - 4,0,0,0,67,0,0,0,115,14,0,0,0,100,1,124, - 0,160,0,124,1,161,1,105,1,83,0,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,79,83,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,150,0,0, - 0,41,1,114,197,0,0,0,41,2,114,103,0,0,0,114, - 35,0,0,0,114,2,0,0,0,114,2,0,0,0,114,4, - 0,0,0,218,10,112,97,116,104,95,115,116,97,116,115,233, - 2,0,0,115,2,0,0,0,0,11,122,23,83,111,117,114, - 99,101,76,111,97,100,101,114,46,112,97,116,104,95,115,116, - 97,116,115,99,4,0,0,0,0,0,0,0,4,0,0,0, - 4,0,0,0,67,0,0,0,115,12,0,0,0,124,0,160, - 0,124,2,124,3,161,2,83,0,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, - 103,0,0,0,114,93,0,0,0,90,10,99,97,99,104,101, - 95,112,97,116,104,114,55,0,0,0,114,2,0,0,0,114, - 2,0,0,0,114,4,0,0,0,218,15,95,99,97,99,104, - 101,95,98,121,116,101,99,111,100,101,246,2,0,0,115,2, - 0,0,0,0,8,122,28,83,111,117,114,99,101,76,111,97, - 100,101,114,46,95,99,97,99,104,101,95,98,121,116,101,99, - 111,100,101,99,3,0,0,0,0,0,0,0,3,0,0,0, - 1,0,0,0,67,0,0,0,115,4,0,0,0,100,1,83, - 0,41,2,122,150,79,112,116,105,111,110,97,108,32,109,101, + 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,8,0,0,0,67,0,0,0,115,56,0,0,0,122, + 16,116,0,160,1,116,0,106,2,124,1,161,2,87,0,83, + 0,4,0,116,3,107,10,114,50,1,0,1,0,1,0,116, + 0,160,1,116,0,106,4,124,1,161,2,6,0,89,0,83, + 0,88,0,100,0,83,0,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,218,3,99,108, + 115,114,3,0,0,0,114,2,0,0,0,114,2,0,0,0, + 114,4,0,0,0,218,14,95,111,112,101,110,95,114,101,103, + 105,115,116,114,121,185,2,0,0,115,8,0,0,0,0,2, + 2,1,16,1,14,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,9,0,0,0,67,0,0, + 0,115,114,0,0,0,124,0,106,0,114,14,124,0,106,1, + 125,2,110,6,124,0,106,2,125,2,124,2,106,3,124,1, + 100,1,116,4,106,5,100,0,100,2,133,2,25,0,22,0, + 100,3,141,2,125,3,122,38,124,0,160,6,124,3,161,1, + 143,18,125,4,116,7,160,8,124,4,100,4,161,2,125,5, + 87,0,53,0,81,0,82,0,88,0,87,0,110,22,4,0, + 116,9,107,10,114,108,1,0,1,0,1,0,89,0,100,0, + 83,0,88,0,124,5,83,0,41,5,78,122,5,37,100,46, + 37,100,114,60,0,0,0,41,2,114,126,0,0,0,90,11, + 115,121,115,95,118,101,114,115,105,111,110,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,51,0,0,0,114,6,0,0,0,218,12,118,101,114, + 115,105,111,110,95,105,110,102,111,114,178,0,0,0,114,176, + 0,0,0,90,10,81,117,101,114,121,86,97,108,117,101,114, + 40,0,0,0,41,6,114,177,0,0,0,114,126,0,0,0, + 90,12,114,101,103,105,115,116,114,121,95,107,101,121,114,3, + 0,0,0,90,4,104,107,101,121,218,8,102,105,108,101,112, + 97,116,104,114,2,0,0,0,114,2,0,0,0,114,4,0, + 0,0,218,16,95,115,101,97,114,99,104,95,114,101,103,105, + 115,116,114,121,192,2,0,0,115,22,0,0,0,0,2,6, + 1,8,2,6,1,6,1,22,1,2,1,12,1,26,1,14, + 1,8,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,8,0,0,0,67,0,0, + 0,115,122,0,0,0,124,0,160,0,124,1,161,1,125,4, + 124,4,100,0,107,8,114,22,100,0,83,0,122,12,116,1, + 124,4,131,1,1,0,87,0,110,22,4,0,116,2,107,10, + 114,56,1,0,1,0,1,0,89,0,100,0,83,0,88,0, + 116,3,131,0,68,0,93,52,92,2,125,5,125,6,124,4, + 160,4,116,5,124,6,131,1,161,1,114,64,116,6,106,7, + 124,1,124,5,124,1,124,4,131,2,124,4,100,1,141,3, + 125,7,124,7,2,0,1,0,83,0,113,64,100,0,83,0, + 41,2,78,41,1,114,165,0,0,0,41,8,114,184,0,0, + 0,114,39,0,0,0,114,40,0,0,0,114,168,0,0,0, + 114,100,0,0,0,114,101,0,0,0,114,121,0,0,0,218, + 16,115,112,101,99,95,102,114,111,109,95,108,111,97,100,101, + 114,41,8,114,177,0,0,0,114,126,0,0,0,114,35,0, + 0,0,218,6,116,97,114,103,101,116,114,183,0,0,0,114, + 127,0,0,0,114,173,0,0,0,114,171,0,0,0,114,2, + 0,0,0,114,2,0,0,0,114,4,0,0,0,218,9,102, + 105,110,100,95,115,112,101,99,207,2,0,0,115,26,0,0, + 0,0,2,10,1,8,1,4,1,2,1,12,1,14,1,8, + 1,14,1,14,1,6,1,8,1,8,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,4,0,0,0,67,0,0, + 0,115,34,0,0,0,124,0,160,0,124,1,124,2,161,2, + 125,3,124,3,100,1,107,9,114,26,124,3,106,1,83,0, + 100,1,83,0,100,1,83,0,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,187,0,0,0, + 114,127,0,0,0,41,4,114,177,0,0,0,114,126,0,0, + 0,114,35,0,0,0,114,171,0,0,0,114,2,0,0,0, + 114,2,0,0,0,114,4,0,0,0,218,11,102,105,110,100, + 95,109,111,100,117,108,101,223,2,0,0,115,8,0,0,0, + 0,7,12,1,8,1,6,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,2,78,78,41, + 1,78,41,12,114,112,0,0,0,114,111,0,0,0,114,113, + 0,0,0,114,114,0,0,0,114,181,0,0,0,114,180,0, + 0,0,114,179,0,0,0,218,11,99,108,97,115,115,109,101, + 116,104,111,100,114,178,0,0,0,114,184,0,0,0,114,187, + 0,0,0,114,188,0,0,0,114,2,0,0,0,114,2,0, + 0,0,114,2,0,0,0,114,4,0,0,0,114,175,0,0, + 0,173,2,0,0,115,20,0,0,0,8,2,4,3,4,3, + 4,2,4,2,12,7,12,15,2,1,12,15,2,1,114,175, + 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,48,0,0,0,101,0,90, + 1,100,0,90,2,100,1,90,3,100,2,100,3,132,0,90, + 4,100,4,100,5,132,0,90,5,100,6,100,7,132,0,90, + 6,100,8,100,9,132,0,90,7,100,10,83,0,41,11,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, + 4,0,0,0,67,0,0,0,115,64,0,0,0,116,0,124, + 0,160,1,124,1,161,1,131,1,100,1,25,0,125,2,124, + 2,160,2,100,2,100,1,161,2,100,3,25,0,125,3,124, + 1,160,3,100,2,161,1,100,4,25,0,125,4,124,3,100, + 5,107,2,111,62,124,4,100,5,107,3,83,0,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,62,0,0,0,114,63,0,0,0,114,60,0, + 0,0,218,8,95,95,105,110,105,116,95,95,41,4,114,38, + 0,0,0,114,164,0,0,0,114,34,0,0,0,114,32,0, + 0,0,41,5,114,107,0,0,0,114,126,0,0,0,114,87, + 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,2,0, + 0,0,114,2,0,0,0,114,4,0,0,0,114,166,0,0, + 0,242,2,0,0,115,8,0,0,0,0,3,18,1,16,1, + 14,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,83,0,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,2,0,0,0,41,2, + 114,107,0,0,0,114,171,0,0,0,114,2,0,0,0,114, + 2,0,0,0,114,4,0,0,0,218,13,99,114,101,97,116, + 101,95,109,111,100,117,108,101,250,2,0,0,115,2,0,0, + 0,0,1,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,5,0,0, + 0,67,0,0,0,115,56,0,0,0,124,0,160,0,124,1, + 106,1,161,1,125,2,124,2,100,1,107,8,114,36,116,2, + 100,2,160,3,124,1,106,1,161,1,131,1,130,1,116,4, + 160,5,116,6,124,2,124,1,106,7,161,3,1,0,100,1, + 83,0,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,8,218,8,103,101,116,95,99,111,100,101,114,112,0,0, + 0,114,106,0,0,0,114,51,0,0,0,114,121,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,218,4,101,120,101, + 99,114,118,0,0,0,41,3,114,107,0,0,0,218,6,109, + 111,100,117,108,101,114,149,0,0,0,114,2,0,0,0,114, + 2,0,0,0,114,4,0,0,0,218,11,101,120,101,99,95, + 109,111,100,117,108,101,253,2,0,0,115,10,0,0,0,0, + 2,12,1,8,1,6,1,10,1,122,25,95,76,111,97,100, + 101,114,66,97,115,105,99,115,46,101,120,101,99,95,109,111, + 100,117,108,101,99,2,0,0,0,0,0,0,0,2,0,0, + 0,4,0,0,0,67,0,0,0,115,12,0,0,0,116,0, + 160,1,124,0,124,1,161,2,83,0,41,1,122,26,84,104, + 105,115,32,109,111,100,117,108,101,32,105,115,32,100,101,112, + 114,101,99,97,116,101,100,46,41,2,114,121,0,0,0,218, + 17,95,108,111,97,100,95,109,111,100,117,108,101,95,115,104, + 105,109,41,2,114,107,0,0,0,114,126,0,0,0,114,2, + 0,0,0,114,2,0,0,0,114,4,0,0,0,218,11,108, + 111,97,100,95,109,111,100,117,108,101,5,3,0,0,115,2, + 0,0,0,0,2,122,25,95,76,111,97,100,101,114,66,97, + 115,105,99,115,46,108,111,97,100,95,109,111,100,117,108,101, + 78,41,8,114,112,0,0,0,114,111,0,0,0,114,113,0, + 0,0,114,114,0,0,0,114,166,0,0,0,114,192,0,0, + 0,114,197,0,0,0,114,199,0,0,0,114,2,0,0,0, + 114,2,0,0,0,114,2,0,0,0,114,4,0,0,0,114, + 190,0,0,0,237,2,0,0,115,10,0,0,0,8,3,4, + 2,8,8,8,3,8,8,114,190,0,0,0,99,0,0,0, + 0,0,0,0,0,0,0,0,0,3,0,0,0,64,0,0, + 0,115,74,0,0,0,101,0,90,1,100,0,90,2,100,1, + 100,2,132,0,90,3,100,3,100,4,132,0,90,4,100,5, + 100,6,132,0,90,5,100,7,100,8,132,0,90,6,100,9, + 100,10,132,0,90,7,100,11,100,12,156,1,100,13,100,14, + 132,2,90,8,100,15,100,16,132,0,90,9,100,17,83,0, + 41,18,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,8,0,0,0,116,0,130,1,100,1, + 83,0,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,79,83,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,114,40,0,0,0, + 41,2,114,107,0,0,0,114,35,0,0,0,114,2,0,0, + 0,114,2,0,0,0,114,4,0,0,0,218,10,112,97,116, + 104,95,109,116,105,109,101,12,3,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,4,0,0,0,67,0,0,0, + 115,14,0,0,0,100,1,124,0,160,0,124,1,161,1,105, + 1,83,0,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,79,83,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,154,0,0,0,41,1,114,201,0,0,0, + 41,2,114,107,0,0,0,114,35,0,0,0,114,2,0,0, + 0,114,2,0,0,0,114,4,0,0,0,218,10,112,97,116, + 104,95,115,116,97,116,115,20,3,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,4,0,0,0,67,0,0,0, + 115,12,0,0,0,124,0,160,0,124,2,124,3,161,2,83, + 0,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, @@ -1185,379 +1199,397 @@ const unsigned char _Py_M__importlib_external[] = { 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,2,0,0, - 0,41,3,114,103,0,0,0,114,35,0,0,0,114,55,0, + 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,107,0,0,0,114,98,0,0, + 0,90,10,99,97,99,104,101,95,112,97,116,104,114,57,0, 0,0,114,2,0,0,0,114,2,0,0,0,114,4,0,0, - 0,114,199,0,0,0,0,3,0,0,115,2,0,0,0,0, - 4,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,10,0,0,0,67,0,0,0,115,82,0, - 0,0,124,0,160,0,124,1,161,1,125,2,121,14,124,0, - 160,1,124,2,161,1,125,3,87,0,110,48,4,0,116,2, - 107,10,114,72,1,0,125,4,1,0,122,18,116,3,100,1, - 124,1,100,2,141,2,124,4,130,2,87,0,100,3,100,3, - 125,4,126,4,88,0,89,0,110,2,88,0,116,4,124,3, - 131,1,83,0,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,41,1,114,101,0,0,0,78,41,5,114, - 160,0,0,0,218,8,103,101,116,95,100,97,116,97,114,40, - 0,0,0,114,102,0,0,0,114,158,0,0,0,41,5,114, - 103,0,0,0,114,122,0,0,0,114,35,0,0,0,114,156, - 0,0,0,218,3,101,120,99,114,2,0,0,0,114,2,0, - 0,0,114,4,0,0,0,218,10,103,101,116,95,115,111,117, - 114,99,101,7,3,0,0,115,14,0,0,0,0,2,10,1, - 2,1,14,1,16,1,4,1,28,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,114,90,0,0,0,41,1,218,9,95,111,112,116, - 105,109,105,122,101,99,3,0,0,0,1,0,0,0,4,0, - 0,0,8,0,0,0,67,0,0,0,115,22,0,0,0,116, - 0,106,1,116,2,124,1,124,2,100,1,100,2,124,3,100, - 3,141,6,83,0,41,4,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,191,0,0,0, - 84,41,2,218,12,100,111,110,116,95,105,110,104,101,114,105, - 116,114,71,0,0,0,41,3,114,117,0,0,0,114,190,0, - 0,0,218,7,99,111,109,112,105,108,101,41,4,114,103,0, - 0,0,114,55,0,0,0,114,35,0,0,0,114,204,0,0, - 0,114,2,0,0,0,114,2,0,0,0,114,4,0,0,0, - 218,14,115,111,117,114,99,101,95,116,111,95,99,111,100,101, - 17,3,0,0,115,4,0,0,0,0,5,12,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,15,0,0,0,9,0,0,0,67,0,0,0,115, - 46,2,0,0,124,0,160,0,124,1,161,1,125,2,100,1, - 125,3,100,1,125,4,100,1,125,5,100,2,125,6,100,3, - 125,7,121,12,116,1,124,2,131,1,125,8,87,0,110,26, - 4,0,116,2,107,10,114,68,1,0,1,0,1,0,100,1, - 125,8,89,0,144,1,110,48,88,0,121,14,124,0,160,3, - 124,2,161,1,125,9,87,0,110,22,4,0,116,4,107,10, - 114,106,1,0,1,0,1,0,89,0,144,1,110,10,88,0, - 116,5,124,9,100,4,25,0,131,1,125,3,121,14,124,0, - 160,6,124,8,161,1,125,10,87,0,110,20,4,0,116,4, - 107,10,114,154,1,0,1,0,1,0,89,0,110,218,88,0, - 124,1,124,8,100,5,156,2,125,11,121,148,116,7,124,10, - 124,1,124,11,131,3,125,12,116,8,124,10,131,1,100,6, - 100,1,133,2,25,0,125,13,124,12,100,7,64,0,100,8, - 107,3,125,6,124,6,144,1,114,36,124,12,100,9,64,0, - 100,8,107,3,125,7,116,9,106,10,100,10,107,3,144,1, - 114,56,124,7,115,254,116,9,106,10,100,11,107,2,144,1, - 114,56,124,0,160,6,124,2,161,1,125,4,116,9,160,11, - 116,12,124,4,161,2,125,5,116,13,124,10,124,5,124,1, - 124,11,131,4,1,0,110,20,116,14,124,10,124,3,124,9, - 100,12,25,0,124,1,124,11,131,5,1,0,87,0,110,26, - 4,0,116,15,116,16,102,2,107,10,144,1,114,84,1,0, - 1,0,1,0,89,0,110,32,88,0,116,17,160,18,100,13, - 124,8,124,2,161,3,1,0,116,19,124,13,124,1,124,8, - 124,2,100,14,141,4,83,0,124,4,100,1,107,8,144,1, - 114,136,124,0,160,6,124,2,161,1,125,4,124,0,160,20, - 124,4,124,2,161,2,125,14,116,17,160,18,100,15,124,2, - 161,2,1,0,116,21,106,22,144,2,115,42,124,8,100,1, - 107,9,144,2,114,42,124,3,100,1,107,9,144,2,114,42, - 124,6,144,1,114,228,124,5,100,1,107,8,144,1,114,214, - 116,9,160,11,124,4,161,1,125,5,116,23,124,14,124,5, - 124,7,131,3,125,10,110,16,116,24,124,14,124,3,116,25, - 124,4,131,1,131,3,125,10,121,30,124,0,160,26,124,2, - 124,8,124,10,161,3,1,0,116,17,160,18,100,16,124,8, - 161,2,1,0,87,0,110,22,4,0,116,2,107,10,144,2, - 114,40,1,0,1,0,1,0,89,0,110,2,88,0,124,14, - 83,0,41,17,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,70,84,114,150,0,0,0,41,2,114,101, - 0,0,0,114,35,0,0,0,114,127,0,0,0,114,29,0, - 0,0,114,61,0,0,0,114,58,0,0,0,90,5,110,101, - 118,101,114,90,6,97,108,119,97,121,115,218,4,115,105,122, - 101,122,13,123,125,32,109,97,116,99,104,101,115,32,123,125, - 41,3,114,101,0,0,0,114,92,0,0,0,114,93,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,27,114,160,0,0,0,114,82,0,0,0,114,69, - 0,0,0,114,198,0,0,0,114,40,0,0,0,114,14,0, - 0,0,114,201,0,0,0,114,134,0,0,0,218,10,109,101, - 109,111,114,121,118,105,101,119,114,144,0,0,0,90,21,99, - 104,101,99,107,95,104,97,115,104,95,98,97,115,101,100,95, - 112,121,99,115,114,139,0,0,0,218,17,95,82,65,87,95, - 77,65,71,73,67,95,78,85,77,66,69,82,114,140,0,0, - 0,114,138,0,0,0,114,102,0,0,0,114,132,0,0,0, - 114,117,0,0,0,114,131,0,0,0,114,146,0,0,0,114, - 207,0,0,0,114,6,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,153, - 0,0,0,114,151,0,0,0,114,31,0,0,0,114,200,0, - 0,0,41,15,114,103,0,0,0,114,122,0,0,0,114,93, - 0,0,0,114,136,0,0,0,114,156,0,0,0,114,139,0, - 0,0,90,10,104,97,115,104,95,98,97,115,101,100,90,12, - 99,104,101,99,107,95,115,111,117,114,99,101,114,92,0,0, - 0,218,2,115,116,114,55,0,0,0,114,133,0,0,0,114, - 70,0,0,0,90,10,98,121,116,101,115,95,100,97,116,97, - 90,11,99,111,100,101,95,111,98,106,101,99,116,114,2,0, - 0,0,114,2,0,0,0,114,4,0,0,0,114,189,0,0, - 0,25,3,0,0,115,134,0,0,0,0,7,10,1,4,1, - 4,1,4,1,4,1,4,1,2,1,12,1,14,1,12,2, - 2,1,14,1,14,1,8,2,12,1,2,1,14,1,14,1, - 6,3,2,1,8,2,2,1,12,1,16,1,12,1,6,1, - 12,1,12,1,4,1,12,1,10,1,4,1,2,1,6,2, - 8,1,8,2,2,1,2,1,2,1,6,1,2,1,10,2, - 20,1,6,2,8,1,6,1,6,1,2,1,8,1,10,1, - 10,1,12,1,12,1,18,1,10,1,6,1,10,1,10,1, - 14,2,6,1,10,1,2,1,14,1,16,1,16,1,6,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,41,10,114,108,0,0,0,114, - 107,0,0,0,114,109,0,0,0,114,197,0,0,0,114,198, - 0,0,0,114,200,0,0,0,114,199,0,0,0,114,203,0, - 0,0,114,207,0,0,0,114,189,0,0,0,114,2,0,0, - 0,114,2,0,0,0,114,2,0,0,0,114,4,0,0,0, - 114,196,0,0,0,223,2,0,0,115,14,0,0,0,8,2, - 8,8,8,13,8,10,8,7,8,10,14,8,114,196,0,0, - 0,99,0,0,0,0,0,0,0,0,0,0,0,0,4,0, - 0,0,0,0,0,0,115,124,0,0,0,101,0,90,1,100, - 0,90,2,100,1,90,3,100,2,100,3,132,0,90,4,100, - 4,100,5,132,0,90,5,100,6,100,7,132,0,90,6,101, - 7,135,0,102,1,100,8,100,9,132,8,131,1,90,8,101, - 7,100,10,100,11,132,0,131,1,90,9,100,12,100,13,132, - 0,90,10,101,7,100,14,100,15,132,0,131,1,90,11,100, - 16,100,17,132,0,90,12,100,18,100,19,132,0,90,13,100, - 20,100,21,132,0,90,14,100,22,100,23,132,0,90,15,135, - 0,4,0,90,16,83,0,41,24,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,16,0,0,0,124,1,124,0,95,0,124,2, - 124,0,95,1,100,1,83,0,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,101,0,0,0,114, - 35,0,0,0,41,3,114,103,0,0,0,114,122,0,0,0, - 114,35,0,0,0,114,2,0,0,0,114,2,0,0,0,114, - 4,0,0,0,114,187,0,0,0,116,3,0,0,115,4,0, - 0,0,0,3,6,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,24,0,0,0,124,0,106,0,124,1,106,0,107,2,111, - 22,124,0,106,1,124,1,106,1,107,2,83,0,41,1,78, - 41,2,218,9,95,95,99,108,97,115,115,95,95,114,114,0, - 0,0,41,2,114,103,0,0,0,218,5,111,116,104,101,114, + 0,218,15,95,99,97,99,104,101,95,98,121,116,101,99,111, + 100,101,33,3,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,83,0,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,2,0,0,0,41,3,114,107,0,0,0, + 114,35,0,0,0,114,57,0,0,0,114,2,0,0,0,114, + 2,0,0,0,114,4,0,0,0,114,203,0,0,0,43,3, + 0,0,115,2,0,0,0,0,4,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,10,0,0, + 0,67,0,0,0,115,82,0,0,0,124,0,160,0,124,1, + 161,1,125,2,122,14,124,0,160,1,124,2,161,1,125,3, + 87,0,110,48,4,0,116,2,107,10,114,72,1,0,125,4, + 1,0,122,18,116,3,100,1,124,1,100,2,141,2,124,4, + 130,2,87,0,53,0,100,3,125,4,126,4,88,0,89,0, + 110,2,88,0,116,4,124,3,131,1,83,0,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,41,1,114, + 105,0,0,0,78,41,5,114,164,0,0,0,218,8,103,101, + 116,95,100,97,116,97,114,40,0,0,0,114,106,0,0,0, + 114,162,0,0,0,41,5,114,107,0,0,0,114,126,0,0, + 0,114,35,0,0,0,114,160,0,0,0,218,3,101,120,99, 114,2,0,0,0,114,2,0,0,0,114,4,0,0,0,218, - 6,95,95,101,113,95,95,122,3,0,0,115,4,0,0,0, - 0,1,12,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,20,0,0, - 0,116,0,124,0,106,1,131,1,116,0,124,0,106,2,131, - 1,65,0,83,0,41,1,78,41,3,218,4,104,97,115,104, - 114,101,0,0,0,114,35,0,0,0,41,1,114,103,0,0, - 0,114,2,0,0,0,114,2,0,0,0,114,4,0,0,0, - 218,8,95,95,104,97,115,104,95,95,126,3,0,0,115,2, - 0,0,0,0,1,122,19,70,105,108,101,76,111,97,100,101, - 114,46,95,95,104,97,115,104,95,95,99,2,0,0,0,0, - 0,0,0,2,0,0,0,3,0,0,0,3,0,0,0,115, - 16,0,0,0,116,0,116,1,124,0,131,2,160,2,124,1, - 161,1,83,0,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,213,0,0,0,114,195,0,0,0,41, - 2,114,103,0,0,0,114,122,0,0,0,41,1,114,214,0, - 0,0,114,2,0,0,0,114,4,0,0,0,114,195,0,0, - 0,129,3,0,0,115,2,0,0,0,0,10,122,22,70,105, - 108,101,76,111,97,100,101,114,46,108,111,97,100,95,109,111, - 100,117,108,101,99,2,0,0,0,0,0,0,0,2,0,0, - 0,1,0,0,0,67,0,0,0,115,6,0,0,0,124,0, - 106,0,83,0,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,103,0,0,0, - 114,122,0,0,0,114,2,0,0,0,114,2,0,0,0,114, - 4,0,0,0,114,160,0,0,0,141,3,0,0,115,2,0, - 0,0,0,3,122,23,70,105,108,101,76,111,97,100,101,114, - 46,103,101,116,95,102,105,108,101,110,97,109,101,99,2,0, - 0,0,0,0,0,0,3,0,0,0,9,0,0,0,67,0, - 0,0,115,76,0,0,0,116,0,124,0,116,1,116,2,102, - 2,131,2,114,46,116,3,160,4,116,5,124,1,131,1,161, - 1,143,10,125,2,124,2,160,6,161,0,83,0,81,0,82, - 0,88,0,110,26,116,7,124,1,100,2,131,2,143,10,125, - 2,124,2,160,6,161,0,83,0,81,0,82,0,88,0,100, - 1,83,0,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,78,90, - 2,114,98,41,8,114,142,0,0,0,114,196,0,0,0,218, - 19,69,120,116,101,110,115,105,111,110,70,105,108,101,76,111, - 97,100,101,114,114,144,0,0,0,90,15,111,112,101,110,95, - 102,111,114,95,105,109,112,111,114,116,114,72,0,0,0,90, - 4,114,101,97,100,114,50,0,0,0,41,3,114,103,0,0, - 0,114,35,0,0,0,114,56,0,0,0,114,2,0,0,0, - 114,2,0,0,0,114,4,0,0,0,114,201,0,0,0,146, - 3,0,0,115,10,0,0,0,0,2,14,1,16,1,16,2, - 12,1,122,19,70,105,108,101,76,111,97,100,101,114,46,103, - 101,116,95,100,97,116,97,99,2,0,0,0,0,0,0,0, - 2,0,0,0,3,0,0,0,67,0,0,0,115,18,0,0, - 0,124,0,160,0,124,1,161,1,114,14,124,0,83,0,100, - 0,83,0,41,1,78,41,1,114,162,0,0,0,41,2,114, - 103,0,0,0,114,192,0,0,0,114,2,0,0,0,114,2, - 0,0,0,114,4,0,0,0,218,19,103,101,116,95,114,101, - 115,111,117,114,99,101,95,114,101,97,100,101,114,157,3,0, - 0,115,6,0,0,0,0,2,10,1,4,1,122,30,70,105, - 108,101,76,111,97,100,101,114,46,103,101,116,95,114,101,115, - 111,117,114,99,101,95,114,101,97,100,101,114,99,2,0,0, - 0,0,0,0,0,3,0,0,0,4,0,0,0,67,0,0, - 0,115,32,0,0,0,116,0,116,1,124,0,106,2,131,1, - 100,1,25,0,124,1,131,2,125,2,116,3,160,4,124,2, - 100,2,161,2,83,0,41,3,78,114,61,0,0,0,218,1, - 114,41,5,114,28,0,0,0,114,38,0,0,0,114,35,0, - 0,0,114,51,0,0,0,114,52,0,0,0,41,3,114,103, - 0,0,0,218,8,114,101,115,111,117,114,99,101,114,35,0, - 0,0,114,2,0,0,0,114,2,0,0,0,114,4,0,0, - 0,218,13,111,112,101,110,95,114,101,115,111,117,114,99,101, - 163,3,0,0,115,4,0,0,0,0,1,20,1,122,24,70, - 105,108,101,76,111,97,100,101,114,46,111,112,101,110,95,114, - 101,115,111,117,114,99,101,99,2,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,160,0,124,1,161,1,115,14,116,1,130,1,116, - 2,116,3,124,0,106,4,131,1,100,1,25,0,124,1,131, - 2,125,2,124,2,83,0,41,2,78,114,61,0,0,0,41, - 5,218,11,105,115,95,114,101,115,111,117,114,99,101,218,17, - 70,105,108,101,78,111,116,70,111,117,110,100,69,114,114,111, - 114,114,28,0,0,0,114,38,0,0,0,114,35,0,0,0, - 41,3,114,103,0,0,0,114,223,0,0,0,114,35,0,0, - 0,114,2,0,0,0,114,2,0,0,0,114,4,0,0,0, - 218,13,114,101,115,111,117,114,99,101,95,112,97,116,104,167, - 3,0,0,115,8,0,0,0,0,1,10,1,4,1,20,1, - 122,24,70,105,108,101,76,111,97,100,101,114,46,114,101,115, - 111,117,114,99,101,95,112,97,116,104,99,2,0,0,0,0, - 0,0,0,3,0,0,0,3,0,0,0,67,0,0,0,115, - 40,0,0,0,116,0,124,1,107,6,114,12,100,1,83,0, - 116,1,116,2,124,0,106,3,131,1,100,2,25,0,124,1, - 131,2,125,2,116,4,124,2,131,1,83,0,41,3,78,70, - 114,61,0,0,0,41,5,114,25,0,0,0,114,28,0,0, - 0,114,38,0,0,0,114,35,0,0,0,114,44,0,0,0, - 41,3,114,103,0,0,0,114,101,0,0,0,114,35,0,0, - 0,114,2,0,0,0,114,2,0,0,0,114,4,0,0,0, - 114,225,0,0,0,173,3,0,0,115,8,0,0,0,0,1, - 8,1,4,1,20,1,122,22,70,105,108,101,76,111,97,100, - 101,114,46,105,115,95,114,101,115,111,117,114,99,101,99,1, - 0,0,0,0,0,0,0,1,0,0,0,5,0,0,0,67, - 0,0,0,115,24,0,0,0,116,0,116,1,160,2,116,3, - 124,0,106,4,131,1,100,1,25,0,161,1,131,1,83,0, - 41,2,78,114,61,0,0,0,41,5,218,4,105,116,101,114, - 114,1,0,0,0,218,7,108,105,115,116,100,105,114,114,38, - 0,0,0,114,35,0,0,0,41,1,114,103,0,0,0,114, - 2,0,0,0,114,2,0,0,0,114,4,0,0,0,218,8, - 99,111,110,116,101,110,116,115,179,3,0,0,115,2,0,0, - 0,0,1,122,19,70,105,108,101,76,111,97,100,101,114,46, - 99,111,110,116,101,110,116,115,41,17,114,108,0,0,0,114, - 107,0,0,0,114,109,0,0,0,114,110,0,0,0,114,187, - 0,0,0,114,216,0,0,0,114,218,0,0,0,114,119,0, - 0,0,114,195,0,0,0,114,160,0,0,0,114,201,0,0, - 0,114,221,0,0,0,114,224,0,0,0,114,227,0,0,0, - 114,225,0,0,0,114,230,0,0,0,90,13,95,95,99,108, - 97,115,115,99,101,108,108,95,95,114,2,0,0,0,114,2, - 0,0,0,41,1,114,214,0,0,0,114,4,0,0,0,114, - 213,0,0,0,111,3,0,0,115,24,0,0,0,8,3,4, - 2,8,6,8,4,8,3,16,12,12,5,8,11,12,6,8, - 4,8,6,8,6,114,213,0,0,0,99,0,0,0,0,0, - 0,0,0,0,0,0,0,3,0,0,0,64,0,0,0,115, - 46,0,0,0,101,0,90,1,100,0,90,2,100,1,90,3, - 100,2,100,3,132,0,90,4,100,4,100,5,132,0,90,5, - 100,6,100,7,156,1,100,8,100,9,132,2,90,6,100,10, - 83,0,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,22,0,0,0, - 116,0,124,1,131,1,125,2,124,2,106,1,124,2,106,2, - 100,1,156,2,83,0,41,2,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,41,2,114,150,0, - 0,0,114,208,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,103,0,0,0,114,35,0,0,0,114,212,0, - 0,0,114,2,0,0,0,114,2,0,0,0,114,4,0,0, - 0,114,198,0,0,0,186,3,0,0,115,4,0,0,0,0, - 2,8,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,24,0,0,0,116,0,124,1,131,1, - 125,4,124,0,106,1,124,2,124,3,124,4,100,1,141,3, - 83,0,41,2,78,41,1,218,5,95,109,111,100,101,41,2, - 114,100,0,0,0,114,199,0,0,0,41,5,114,103,0,0, - 0,114,93,0,0,0,114,92,0,0,0,114,55,0,0,0, - 114,42,0,0,0,114,2,0,0,0,114,2,0,0,0,114, - 4,0,0,0,114,200,0,0,0,191,3,0,0,115,4,0, - 0,0,0,2,8,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,105,182,1,0,0,41,1,114, - 233,0,0,0,99,3,0,0,0,1,0,0,0,9,0,0, - 0,11,0,0,0,67,0,0,0,115,250,0,0,0,116,0, - 124,1,131,1,92,2,125,4,125,5,103,0,125,6,120,38, - 124,4,114,54,116,1,124,4,131,1,115,54,116,0,124,4, - 131,1,92,2,125,4,125,7,124,6,160,2,124,7,161,1, - 1,0,113,18,87,0,120,110,116,3,124,6,131,1,68,0, - 93,98,125,7,116,4,124,4,124,7,131,2,125,4,121,14, - 116,5,160,6,124,4,161,1,1,0,87,0,113,66,4,0, - 116,7,107,10,114,116,1,0,1,0,1,0,119,66,89,0, - 113,66,4,0,116,8,107,10,114,162,1,0,125,8,1,0, - 122,18,116,9,160,10,100,1,124,4,124,8,161,3,1,0, - 100,2,83,0,100,2,125,8,126,8,88,0,89,0,113,66, - 88,0,113,66,87,0,121,28,116,11,124,1,124,2,124,3, + 10,103,101,116,95,115,111,117,114,99,101,50,3,0,0,115, + 14,0,0,0,0,2,10,1,2,1,14,1,16,1,4,1, + 28,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,114,95,0,0,0, + 41,1,218,9,95,111,112,116,105,109,105,122,101,99,3,0, + 0,0,1,0,0,0,4,0,0,0,8,0,0,0,67,0, + 0,0,115,22,0,0,0,116,0,106,1,116,2,124,1,124, + 2,100,1,100,2,124,3,100,3,141,6,83,0,41,4,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,195,0,0,0,84,41,2,218,12,100,111,110, + 116,95,105,110,104,101,114,105,116,114,74,0,0,0,41,3, + 114,121,0,0,0,114,194,0,0,0,218,7,99,111,109,112, + 105,108,101,41,4,114,107,0,0,0,114,57,0,0,0,114, + 35,0,0,0,114,208,0,0,0,114,2,0,0,0,114,2, + 0,0,0,114,4,0,0,0,218,14,115,111,117,114,99,101, + 95,116,111,95,99,111,100,101,60,3,0,0,115,4,0,0, + 0,0,5,12,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,15,0,0,0,9, + 0,0,0,67,0,0,0,115,46,2,0,0,124,0,160,0, + 124,1,161,1,125,2,100,1,125,3,100,1,125,4,100,1, + 125,5,100,2,125,6,100,3,125,7,122,12,116,1,124,2, + 131,1,125,8,87,0,110,26,4,0,116,2,107,10,114,68, + 1,0,1,0,1,0,100,1,125,8,89,0,144,1,110,48, + 88,0,122,14,124,0,160,3,124,2,161,1,125,9,87,0, + 110,22,4,0,116,4,107,10,114,106,1,0,1,0,1,0, + 89,0,144,1,110,10,88,0,116,5,124,9,100,4,25,0, + 131,1,125,3,122,14,124,0,160,6,124,8,161,1,125,10, + 87,0,110,20,4,0,116,4,107,10,114,154,1,0,1,0, + 1,0,89,0,110,218,88,0,124,1,124,8,100,5,156,2, + 125,11,122,148,116,7,124,10,124,1,124,11,131,3,125,12, + 116,8,124,10,131,1,100,6,100,1,133,2,25,0,125,13, + 124,12,100,7,64,0,100,8,107,3,125,6,124,6,144,1, + 114,36,124,12,100,9,64,0,100,8,107,3,125,7,116,9, + 106,10,100,10,107,3,144,1,114,56,124,7,115,254,116,9, + 106,10,100,11,107,2,144,1,114,56,124,0,160,6,124,2, + 161,1,125,4,116,9,160,11,116,12,124,4,161,2,125,5, + 116,13,124,10,124,5,124,1,124,11,131,4,1,0,110,20, + 116,14,124,10,124,3,124,9,100,12,25,0,124,1,124,11, + 131,5,1,0,87,0,110,26,4,0,116,15,116,16,102,2, + 107,10,144,1,114,84,1,0,1,0,1,0,89,0,110,32, + 88,0,116,17,160,18,100,13,124,8,124,2,161,3,1,0, + 116,19,124,13,124,1,124,8,124,2,100,14,141,4,83,0, + 124,4,100,1,107,8,144,1,114,136,124,0,160,6,124,2, + 161,1,125,4,124,0,160,20,124,4,124,2,161,2,125,14, + 116,17,160,18,100,15,124,2,161,2,1,0,116,21,106,22, + 144,2,115,42,124,8,100,1,107,9,144,2,114,42,124,3, + 100,1,107,9,144,2,114,42,124,6,144,1,114,228,124,5, + 100,1,107,8,144,1,114,214,116,9,160,11,124,4,161,1, + 125,5,116,23,124,14,124,5,124,7,131,3,125,10,110,16, + 116,24,124,14,124,3,116,25,124,4,131,1,131,3,125,10, + 122,30,124,0,160,26,124,2,124,8,124,10,161,3,1,0, + 116,17,160,18,100,16,124,8,161,2,1,0,87,0,110,22, + 4,0,116,2,107,10,144,2,114,40,1,0,1,0,1,0, + 89,0,110,2,88,0,124,14,83,0,41,17,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,70,84,114, + 154,0,0,0,41,2,114,105,0,0,0,114,35,0,0,0, + 114,131,0,0,0,114,29,0,0,0,114,63,0,0,0,114, + 60,0,0,0,90,5,110,101,118,101,114,90,6,97,108,119, + 97,121,115,218,4,115,105,122,101,122,13,123,125,32,109,97, + 116,99,104,101,115,32,123,125,41,3,114,105,0,0,0,114, + 97,0,0,0,114,98,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,27,114,164,0,0, + 0,114,88,0,0,0,114,72,0,0,0,114,202,0,0,0, + 114,40,0,0,0,114,14,0,0,0,114,205,0,0,0,114, + 138,0,0,0,218,10,109,101,109,111,114,121,118,105,101,119, + 114,148,0,0,0,90,21,99,104,101,99,107,95,104,97,115, + 104,95,98,97,115,101,100,95,112,121,99,115,114,143,0,0, + 0,218,17,95,82,65,87,95,77,65,71,73,67,95,78,85, + 77,66,69,82,114,144,0,0,0,114,142,0,0,0,114,106, + 0,0,0,114,136,0,0,0,114,121,0,0,0,114,135,0, + 0,0,114,150,0,0,0,114,211,0,0,0,114,6,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,157,0,0,0,114,155,0,0,0, + 114,31,0,0,0,114,204,0,0,0,41,15,114,107,0,0, + 0,114,126,0,0,0,114,98,0,0,0,114,140,0,0,0, + 114,160,0,0,0,114,143,0,0,0,90,10,104,97,115,104, + 95,98,97,115,101,100,90,12,99,104,101,99,107,95,115,111, + 117,114,99,101,114,97,0,0,0,218,2,115,116,114,57,0, + 0,0,114,137,0,0,0,114,73,0,0,0,90,10,98,121, + 116,101,115,95,100,97,116,97,90,11,99,111,100,101,95,111, + 98,106,101,99,116,114,2,0,0,0,114,2,0,0,0,114, + 4,0,0,0,114,193,0,0,0,68,3,0,0,115,134,0, + 0,0,0,7,10,1,4,1,4,1,4,1,4,1,4,1, + 2,1,12,1,14,1,12,2,2,1,14,1,14,1,8,2, + 12,1,2,1,14,1,14,1,6,3,2,1,8,2,2,1, + 12,1,16,1,12,1,6,1,12,1,12,1,4,1,12,1, + 10,1,4,1,2,1,6,2,8,1,8,2,2,1,2,1, + 2,1,6,1,2,1,10,2,20,1,6,2,8,1,6,1, + 6,1,2,1,8,1,10,1,10,1,12,1,12,1,18,1, + 10,1,6,1,10,1,10,1,14,2,6,1,10,1,2,1, + 14,1,16,1,16,1,6,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, + 41,10,114,112,0,0,0,114,111,0,0,0,114,113,0,0, + 0,114,201,0,0,0,114,202,0,0,0,114,204,0,0,0, + 114,203,0,0,0,114,207,0,0,0,114,211,0,0,0,114, + 193,0,0,0,114,2,0,0,0,114,2,0,0,0,114,2, + 0,0,0,114,4,0,0,0,114,200,0,0,0,10,3,0, + 0,115,14,0,0,0,8,2,8,8,8,13,8,10,8,7, + 8,10,14,8,114,200,0,0,0,99,0,0,0,0,0,0, + 0,0,0,0,0,0,4,0,0,0,0,0,0,0,115,124, + 0,0,0,101,0,90,1,100,0,90,2,100,1,90,3,100, + 2,100,3,132,0,90,4,100,4,100,5,132,0,90,5,100, + 6,100,7,132,0,90,6,101,7,135,0,102,1,100,8,100, + 9,132,8,131,1,90,8,101,7,100,10,100,11,132,0,131, + 1,90,9,100,12,100,13,132,0,90,10,101,7,100,14,100, + 15,132,0,131,1,90,11,100,16,100,17,132,0,90,12,100, + 18,100,19,132,0,90,13,100,20,100,21,132,0,90,14,100, + 22,100,23,132,0,90,15,135,0,4,0,90,16,83,0,41, + 24,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,16,0,0,0, + 124,1,124,0,95,0,124,2,124,0,95,1,100,1,83,0, + 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,105,0,0,0,114,35,0,0,0,41,3,114,107, + 0,0,0,114,126,0,0,0,114,35,0,0,0,114,2,0, + 0,0,114,2,0,0,0,114,4,0,0,0,114,191,0,0, + 0,159,3,0,0,115,4,0,0,0,0,3,6,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,24,0,0,0,124,0,106, + 0,124,1,106,0,107,2,111,22,124,0,106,1,124,1,106, + 1,107,2,83,0,41,1,78,41,2,218,9,95,95,99,108, + 97,115,115,95,95,114,118,0,0,0,41,2,114,107,0,0, + 0,218,5,111,116,104,101,114,114,2,0,0,0,114,2,0, + 0,0,114,4,0,0,0,218,6,95,95,101,113,95,95,165, + 3,0,0,115,4,0,0,0,0,1,12,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,20,0,0,0,116,0,124,0,106,1,131, + 1,116,0,124,0,106,2,131,1,65,0,83,0,41,1,78, + 41,3,218,4,104,97,115,104,114,105,0,0,0,114,35,0, + 0,0,41,1,114,107,0,0,0,114,2,0,0,0,114,2, + 0,0,0,114,4,0,0,0,218,8,95,95,104,97,115,104, + 95,95,169,3,0,0,115,2,0,0,0,0,1,122,19,70, + 105,108,101,76,111,97,100,101,114,46,95,95,104,97,115,104, + 95,95,99,2,0,0,0,0,0,0,0,2,0,0,0,3, + 0,0,0,3,0,0,0,115,16,0,0,0,116,0,116,1, + 124,0,131,2,160,2,124,1,161,1,83,0,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,217,0, + 0,0,114,199,0,0,0,41,2,114,107,0,0,0,114,126, + 0,0,0,41,1,114,218,0,0,0,114,2,0,0,0,114, + 4,0,0,0,114,199,0,0,0,172,3,0,0,115,2,0, + 0,0,0,10,122,22,70,105,108,101,76,111,97,100,101,114, + 46,108,111,97,100,95,109,111,100,117,108,101,99,2,0,0, + 0,0,0,0,0,2,0,0,0,1,0,0,0,67,0,0, + 0,115,6,0,0,0,124,0,106,0,83,0,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,107,0,0,0,114,126,0,0,0,114,2,0, + 0,0,114,2,0,0,0,114,4,0,0,0,114,164,0,0, + 0,184,3,0,0,115,2,0,0,0,0,3,122,23,70,105, + 108,101,76,111,97,100,101,114,46,103,101,116,95,102,105,108, + 101,110,97,109,101,99,2,0,0,0,0,0,0,0,3,0, + 0,0,10,0,0,0,67,0,0,0,115,44,0,0,0,116, + 0,160,1,124,1,100,1,161,2,143,22,125,2,124,2,160, + 2,161,0,87,0,2,0,53,0,81,0,82,0,163,0,83, + 0,81,0,82,0,88,0,100,2,83,0,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,53,0,0, + 0,114,54,0,0,0,90,4,114,101,97,100,41,3,114,107, + 0,0,0,114,35,0,0,0,114,58,0,0,0,114,2,0, + 0,0,114,2,0,0,0,114,4,0,0,0,114,205,0,0, + 0,189,3,0,0,115,4,0,0,0,0,2,14,1,122,19, + 70,105,108,101,76,111,97,100,101,114,46,103,101,116,95,100, + 97,116,97,99,2,0,0,0,0,0,0,0,2,0,0,0, + 3,0,0,0,67,0,0,0,115,18,0,0,0,124,0,160, + 0,124,1,161,1,114,14,124,0,83,0,100,0,83,0,41, + 1,78,41,1,114,166,0,0,0,41,2,114,107,0,0,0, + 114,196,0,0,0,114,2,0,0,0,114,2,0,0,0,114, + 4,0,0,0,218,19,103,101,116,95,114,101,115,111,117,114, + 99,101,95,114,101,97,100,101,114,196,3,0,0,115,6,0, + 0,0,0,2,10,1,4,1,122,30,70,105,108,101,76,111, + 97,100,101,114,46,103,101,116,95,114,101,115,111,117,114,99, + 101,95,114,101,97,100,101,114,99,2,0,0,0,0,0,0, + 0,3,0,0,0,4,0,0,0,67,0,0,0,115,32,0, + 0,0,116,0,116,1,124,0,106,2,131,1,100,1,25,0, + 124,1,131,2,125,2,116,3,160,4,124,2,100,2,161,2, + 83,0,41,3,78,114,63,0,0,0,114,224,0,0,0,41, + 5,114,28,0,0,0,114,38,0,0,0,114,35,0,0,0, + 114,53,0,0,0,114,54,0,0,0,41,3,114,107,0,0, + 0,218,8,114,101,115,111,117,114,99,101,114,35,0,0,0, + 114,2,0,0,0,114,2,0,0,0,114,4,0,0,0,218, + 13,111,112,101,110,95,114,101,115,111,117,114,99,101,202,3, + 0,0,115,4,0,0,0,0,1,20,1,122,24,70,105,108, + 101,76,111,97,100,101,114,46,111,112,101,110,95,114,101,115, + 111,117,114,99,101,99,2,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,160,0,124,1,161,1,115,14,116,1,130,1,116,2,116, + 3,124,0,106,4,131,1,100,1,25,0,124,1,131,2,125, + 2,124,2,83,0,41,2,78,114,63,0,0,0,41,5,218, + 11,105,115,95,114,101,115,111,117,114,99,101,218,17,70,105, + 108,101,78,111,116,70,111,117,110,100,69,114,114,111,114,114, + 28,0,0,0,114,38,0,0,0,114,35,0,0,0,41,3, + 114,107,0,0,0,114,226,0,0,0,114,35,0,0,0,114, + 2,0,0,0,114,2,0,0,0,114,4,0,0,0,218,13, + 114,101,115,111,117,114,99,101,95,112,97,116,104,206,3,0, + 0,115,8,0,0,0,0,1,10,1,4,1,20,1,122,24, + 70,105,108,101,76,111,97,100,101,114,46,114,101,115,111,117, + 114,99,101,95,112,97,116,104,99,2,0,0,0,0,0,0, + 0,3,0,0,0,3,0,0,0,67,0,0,0,115,40,0, + 0,0,116,0,124,1,107,6,114,12,100,1,83,0,116,1, + 116,2,124,0,106,3,131,1,100,2,25,0,124,1,131,2, + 125,2,116,4,124,2,131,1,83,0,41,3,78,70,114,63, + 0,0,0,41,5,114,25,0,0,0,114,28,0,0,0,114, + 38,0,0,0,114,35,0,0,0,114,44,0,0,0,41,3, + 114,107,0,0,0,114,105,0,0,0,114,35,0,0,0,114, + 2,0,0,0,114,2,0,0,0,114,4,0,0,0,114,228, + 0,0,0,212,3,0,0,115,8,0,0,0,0,1,8,1, + 4,1,20,1,122,22,70,105,108,101,76,111,97,100,101,114, + 46,105,115,95,114,101,115,111,117,114,99,101,99,1,0,0, + 0,0,0,0,0,1,0,0,0,5,0,0,0,67,0,0, + 0,115,24,0,0,0,116,0,116,1,160,2,116,3,124,0, + 106,4,131,1,100,1,25,0,161,1,131,1,83,0,41,2, + 78,114,63,0,0,0,41,5,218,4,105,116,101,114,114,1, + 0,0,0,218,7,108,105,115,116,100,105,114,114,38,0,0, + 0,114,35,0,0,0,41,1,114,107,0,0,0,114,2,0, + 0,0,114,2,0,0,0,114,4,0,0,0,218,8,99,111, + 110,116,101,110,116,115,218,3,0,0,115,2,0,0,0,0, + 1,122,19,70,105,108,101,76,111,97,100,101,114,46,99,111, + 110,116,101,110,116,115,41,17,114,112,0,0,0,114,111,0, + 0,0,114,113,0,0,0,114,114,0,0,0,114,191,0,0, + 0,114,220,0,0,0,114,222,0,0,0,114,123,0,0,0, + 114,199,0,0,0,114,164,0,0,0,114,205,0,0,0,114, + 225,0,0,0,114,227,0,0,0,114,230,0,0,0,114,228, + 0,0,0,114,233,0,0,0,90,13,95,95,99,108,97,115, + 115,99,101,108,108,95,95,114,2,0,0,0,114,2,0,0, + 0,41,1,114,218,0,0,0,114,4,0,0,0,114,217,0, + 0,0,154,3,0,0,115,24,0,0,0,8,3,4,2,8, + 6,8,4,8,3,16,12,12,5,8,7,12,6,8,4,8, + 6,8,6,114,217,0,0,0,99,0,0,0,0,0,0,0, + 0,0,0,0,0,3,0,0,0,64,0,0,0,115,46,0, + 0,0,101,0,90,1,100,0,90,2,100,1,90,3,100,2, + 100,3,132,0,90,4,100,4,100,5,132,0,90,5,100,6, + 100,7,156,1,100,8,100,9,132,2,90,6,100,10,83,0, + 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,22,0,0,0,116,0, + 124,1,131,1,125,2,124,2,106,1,124,2,106,2,100,1, + 156,2,83,0,41,2,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,41,2,114,154,0,0,0, + 114,212,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,107,0,0,0,114,35,0,0,0,114,216,0,0,0, + 114,2,0,0,0,114,2,0,0,0,114,4,0,0,0,114, + 202,0,0,0,226,3,0,0,115,4,0,0,0,0,2,8, + 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,24,0,0,0,116,0,124,1,131,1,125,4, + 124,0,106,1,124,2,124,3,124,4,100,1,141,3,83,0, + 41,2,78,41,1,218,5,95,109,111,100,101,41,2,114,104, + 0,0,0,114,203,0,0,0,41,5,114,107,0,0,0,114, + 98,0,0,0,114,97,0,0,0,114,57,0,0,0,114,42, + 0,0,0,114,2,0,0,0,114,2,0,0,0,114,4,0, + 0,0,114,204,0,0,0,231,3,0,0,115,4,0,0,0, + 0,2,8,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,105,182,1,0,0,41,1,114,236,0, + 0,0,99,3,0,0,0,1,0,0,0,9,0,0,0,11, + 0,0,0,67,0,0,0,115,252,0,0,0,116,0,124,1, + 131,1,92,2,125,4,125,5,103,0,125,6,124,4,114,52, + 116,1,124,4,131,1,115,52,116,0,124,4,131,1,92,2, + 125,4,125,7,124,6,160,2,124,7,161,1,1,0,113,16, + 116,3,124,6,131,1,68,0,93,108,125,7,116,4,124,4, + 124,7,131,2,125,4,122,14,116,5,160,6,124,4,161,1, + 1,0,87,0,113,60,4,0,116,7,107,10,114,112,1,0, + 1,0,1,0,89,0,113,60,89,0,113,60,4,0,116,8, + 107,10,114,166,1,0,125,8,1,0,122,26,116,9,160,10, + 100,1,124,4,124,8,161,3,1,0,87,0,89,0,162,6, + 1,0,100,2,83,0,100,2,125,8,126,8,88,0,89,0, + 113,60,88,0,113,60,122,28,116,11,124,1,124,2,124,3, 131,3,1,0,116,9,160,10,100,3,124,1,161,2,1,0, - 87,0,110,48,4,0,116,8,107,10,114,244,1,0,125,8, + 87,0,110,48,4,0,116,8,107,10,114,246,1,0,125,8, 1,0,122,18,116,9,160,10,100,1,124,1,124,8,161,3, - 1,0,87,0,100,2,100,2,125,8,126,8,88,0,89,0, + 1,0,87,0,53,0,100,2,125,8,126,8,88,0,89,0, 110,2,88,0,100,2,83,0,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,12,114,38,0,0,0,114,46,0,0,0,114, - 166,0,0,0,114,33,0,0,0,114,28,0,0,0,114,1, + 170,0,0,0,114,33,0,0,0,114,28,0,0,0,114,1, 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,117,0,0,0,114,131,0,0,0,114,57,0,0,0,41, - 9,114,103,0,0,0,114,35,0,0,0,114,55,0,0,0, - 114,233,0,0,0,218,6,112,97,114,101,110,116,114,97,0, - 0,0,114,27,0,0,0,114,23,0,0,0,114,202,0,0, + 114,121,0,0,0,114,135,0,0,0,114,59,0,0,0,41, + 9,114,107,0,0,0,114,35,0,0,0,114,57,0,0,0, + 114,236,0,0,0,218,6,112,97,114,101,110,116,114,87,0, + 0,0,114,27,0,0,0,114,23,0,0,0,114,206,0,0, 0,114,2,0,0,0,114,2,0,0,0,114,4,0,0,0, - 114,199,0,0,0,196,3,0,0,115,42,0,0,0,0,2, - 12,1,4,2,14,1,12,1,14,2,14,1,10,1,2,1, - 14,1,14,2,6,1,16,3,6,1,8,1,22,1,2,1, + 114,203,0,0,0,236,3,0,0,115,42,0,0,0,0,2, + 12,1,4,2,12,1,12,1,12,2,12,1,10,1,2,1, + 14,1,14,2,8,1,16,3,6,1,8,1,28,1,2,1, 12,1,16,1,16,2,8,1,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,108,0,0,0,114,107,0,0,0, - 114,109,0,0,0,114,110,0,0,0,114,198,0,0,0,114, - 200,0,0,0,114,199,0,0,0,114,2,0,0,0,114,2, - 0,0,0,114,2,0,0,0,114,4,0,0,0,114,231,0, - 0,0,182,3,0,0,115,8,0,0,0,8,2,4,2,8, - 5,8,5,114,231,0,0,0,99,0,0,0,0,0,0,0, + 97,116,97,78,41,7,114,112,0,0,0,114,111,0,0,0, + 114,113,0,0,0,114,114,0,0,0,114,202,0,0,0,114, + 204,0,0,0,114,203,0,0,0,114,2,0,0,0,114,2, + 0,0,0,114,2,0,0,0,114,4,0,0,0,114,234,0, + 0,0,222,3,0,0,115,8,0,0,0,8,2,4,2,8, + 5,8,5,114,234,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,32,0, 0,0,101,0,90,1,100,0,90,2,100,1,90,3,100,2, 100,3,132,0,90,4,100,4,100,5,132,0,90,5,100,6, @@ -1571,14 +1603,14 @@ const unsigned char _Py_M__importlib_external[] = { 1,124,2,161,1,125,3,124,1,124,2,100,1,156,2,125, 4,116,2,124,3,124,1,124,4,131,3,1,0,116,3,116, 4,124,3,131,1,100,2,100,0,133,2,25,0,124,1,124, - 2,100,3,141,3,83,0,41,4,78,41,2,114,101,0,0, - 0,114,35,0,0,0,114,127,0,0,0,41,2,114,101,0, - 0,0,114,92,0,0,0,41,5,114,160,0,0,0,114,201, - 0,0,0,114,134,0,0,0,114,146,0,0,0,114,209,0, - 0,0,41,5,114,103,0,0,0,114,122,0,0,0,114,35, - 0,0,0,114,55,0,0,0,114,133,0,0,0,114,2,0, - 0,0,114,2,0,0,0,114,4,0,0,0,114,189,0,0, - 0,231,3,0,0,115,18,0,0,0,0,1,10,1,10,4, + 2,100,3,141,3,83,0,41,4,78,41,2,114,105,0,0, + 0,114,35,0,0,0,114,131,0,0,0,41,2,114,105,0, + 0,0,114,97,0,0,0,41,5,114,164,0,0,0,114,205, + 0,0,0,114,138,0,0,0,114,150,0,0,0,114,213,0, + 0,0,41,5,114,107,0,0,0,114,126,0,0,0,114,35, + 0,0,0,114,57,0,0,0,114,137,0,0,0,114,2,0, + 0,0,114,2,0,0,0,114,4,0,0,0,114,193,0,0, + 0,15,4,0,0,115,18,0,0,0,0,1,10,1,10,4, 2,1,8,2,12,1,2,1,14,1,2,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, @@ -1586,25 +1618,26 @@ const unsigned char _Py_M__importlib_external[] = { 115,4,0,0,0,100,1,83,0,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,2,0,0,0,41,2,114,103,0,0, - 0,114,122,0,0,0,114,2,0,0,0,114,2,0,0,0, - 114,4,0,0,0,114,203,0,0,0,247,3,0,0,115,2, + 111,100,101,46,78,114,2,0,0,0,41,2,114,107,0,0, + 0,114,126,0,0,0,114,2,0,0,0,114,2,0,0,0, + 114,4,0,0,0,114,207,0,0,0,31,4,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,108,0,0,0,114,107, - 0,0,0,114,109,0,0,0,114,110,0,0,0,114,189,0, - 0,0,114,203,0,0,0,114,2,0,0,0,114,2,0,0, - 0,114,2,0,0,0,114,4,0,0,0,114,236,0,0,0, - 227,3,0,0,115,6,0,0,0,8,2,4,2,8,16,114, - 236,0,0,0,99,0,0,0,0,0,0,0,0,0,0,0, + 115,111,117,114,99,101,78,41,6,114,112,0,0,0,114,111, + 0,0,0,114,113,0,0,0,114,114,0,0,0,114,193,0, + 0,0,114,207,0,0,0,114,2,0,0,0,114,2,0,0, + 0,114,2,0,0,0,114,4,0,0,0,114,239,0,0,0, + 11,4,0,0,115,6,0,0,0,8,2,4,2,8,16,114, + 239,0,0,0,99,0,0,0,0,0,0,0,0,0,0,0, 0,3,0,0,0,64,0,0,0,115,92,0,0,0,101,0, 90,1,100,0,90,2,100,1,90,3,100,2,100,3,132,0, 90,4,100,4,100,5,132,0,90,5,100,6,100,7,132,0, 90,6,100,8,100,9,132,0,90,7,100,10,100,11,132,0, 90,8,100,12,100,13,132,0,90,9,100,14,100,15,132,0, 90,10,100,16,100,17,132,0,90,11,101,12,100,18,100,19, - 132,0,131,1,90,13,100,20,83,0,41,21,114,220,0,0, - 0,122,93,76,111,97,100,101,114,32,102,111,114,32,101,120, + 132,0,131,1,90,13,100,20,83,0,41,21,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,32,84,104,101,32,99,111,110,115,116,114, 117,99,116,111,114,32,105,115,32,100,101,115,105,103,110,101, @@ -1613,27 +1646,27 @@ const unsigned char _Py_M__importlib_external[] = { 99,3,0,0,0,0,0,0,0,3,0,0,0,2,0,0, 0,67,0,0,0,115,16,0,0,0,124,1,124,0,95,0, 124,2,124,0,95,1,100,0,83,0,41,1,78,41,2,114, - 101,0,0,0,114,35,0,0,0,41,3,114,103,0,0,0, - 114,101,0,0,0,114,35,0,0,0,114,2,0,0,0,114, - 2,0,0,0,114,4,0,0,0,114,187,0,0,0,8,4, + 105,0,0,0,114,35,0,0,0,41,3,114,107,0,0,0, + 114,105,0,0,0,114,35,0,0,0,114,2,0,0,0,114, + 2,0,0,0,114,4,0,0,0,114,191,0,0,0,48,4, 0,0,115,4,0,0,0,0,1,6,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,24, 0,0,0,124,0,106,0,124,1,106,0,107,2,111,22,124, 0,106,1,124,1,106,1,107,2,83,0,41,1,78,41,2, - 114,214,0,0,0,114,114,0,0,0,41,2,114,103,0,0, - 0,114,215,0,0,0,114,2,0,0,0,114,2,0,0,0, - 114,4,0,0,0,114,216,0,0,0,12,4,0,0,115,4, + 114,218,0,0,0,114,118,0,0,0,41,2,114,107,0,0, + 0,114,219,0,0,0,114,2,0,0,0,114,2,0,0,0, + 114,4,0,0,0,114,220,0,0,0,52,4,0,0,115,4, 0,0,0,0,1,12,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,20,0,0,0,116,0,124, 0,106,1,131,1,116,0,124,0,106,2,131,1,65,0,83, - 0,41,1,78,41,3,114,217,0,0,0,114,101,0,0,0, - 114,35,0,0,0,41,1,114,103,0,0,0,114,2,0,0, - 0,114,2,0,0,0,114,4,0,0,0,114,218,0,0,0, - 16,4,0,0,115,2,0,0,0,0,1,122,28,69,120,116, + 0,41,1,78,41,3,114,221,0,0,0,114,105,0,0,0, + 114,35,0,0,0,41,1,114,107,0,0,0,114,2,0,0, + 0,114,2,0,0,0,114,4,0,0,0,114,222,0,0,0, + 56,4,0,0,115,2,0,0,0,0,1,122,28,69,120,116, 101,110,115,105,111,110,70,105,108,101,76,111,97,100,101,114, 46,95,95,104,97,115,104,95,95,99,2,0,0,0,0,0, 0,0,3,0,0,0,5,0,0,0,67,0,0,0,115,36, @@ -1644,12 +1677,12 @@ const unsigned char _Py_M__importlib_external[] = { 32,101,120,116,101,110,115,105,111,110,32,109,111,100,117,108, 101,122,38,101,120,116,101,110,115,105,111,110,32,109,111,100, 117,108,101,32,123,33,114,125,32,108,111,97,100,101,100,32, - 102,114,111,109,32,123,33,114,125,41,7,114,117,0,0,0, - 114,190,0,0,0,114,144,0,0,0,90,14,99,114,101,97, - 116,101,95,100,121,110,97,109,105,99,114,131,0,0,0,114, - 101,0,0,0,114,35,0,0,0,41,3,114,103,0,0,0, - 114,167,0,0,0,114,192,0,0,0,114,2,0,0,0,114, - 2,0,0,0,114,4,0,0,0,114,188,0,0,0,19,4, + 102,114,111,109,32,123,33,114,125,41,7,114,121,0,0,0, + 114,194,0,0,0,114,148,0,0,0,90,14,99,114,101,97, + 116,101,95,100,121,110,97,109,105,99,114,135,0,0,0,114, + 105,0,0,0,114,35,0,0,0,41,3,114,107,0,0,0, + 114,171,0,0,0,114,196,0,0,0,114,2,0,0,0,114, + 2,0,0,0,114,4,0,0,0,114,192,0,0,0,59,4, 0,0,115,10,0,0,0,0,2,4,1,10,1,6,1,12, 1,122,33,69,120,116,101,110,115,105,111,110,70,105,108,101, 76,111,97,100,101,114,46,99,114,101,97,116,101,95,109,111, @@ -1662,11 +1695,11 @@ const unsigned char _Py_M__importlib_external[] = { 100,117,108,101,122,40,101,120,116,101,110,115,105,111,110,32, 109,111,100,117,108,101,32,123,33,114,125,32,101,120,101,99, 117,116,101,100,32,102,114,111,109,32,123,33,114,125,78,41, - 7,114,117,0,0,0,114,190,0,0,0,114,144,0,0,0, - 90,12,101,120,101,99,95,100,121,110,97,109,105,99,114,131, - 0,0,0,114,101,0,0,0,114,35,0,0,0,41,2,114, - 103,0,0,0,114,192,0,0,0,114,2,0,0,0,114,2, - 0,0,0,114,4,0,0,0,114,193,0,0,0,27,4,0, + 7,114,121,0,0,0,114,194,0,0,0,114,148,0,0,0, + 90,12,101,120,101,99,95,100,121,110,97,109,105,99,114,135, + 0,0,0,114,105,0,0,0,114,35,0,0,0,41,2,114, + 107,0,0,0,114,196,0,0,0,114,2,0,0,0,114,2, + 0,0,0,114,4,0,0,0,114,197,0,0,0,67,4,0, 0,115,6,0,0,0,0,2,14,1,6,1,122,31,69,120, 116,101,110,115,105,111,110,70,105,108,101,76,111,97,100,101, 114,46,101,120,101,99,95,109,111,100,117,108,101,99,2,0, @@ -1680,19 +1713,19 @@ const unsigned char _Py_M__importlib_external[] = { 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,26,0,0,0,124, 0,93,18,125,1,136,0,100,0,124,1,23,0,107,2,86, - 0,1,0,113,2,100,1,83,0,41,2,114,187,0,0,0, + 0,1,0,113,2,100,1,83,0,41,2,114,191,0,0,0, 78,114,2,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,2,0,0,0,114,4,0,0,0,250,9,60,103, - 101,110,101,120,112,114,62,36,4,0,0,115,2,0,0,0, + 109,101,114,2,0,0,0,114,4,0,0,0,218,9,60,103, + 101,110,101,120,112,114,62,76,4,0,0,115,2,0,0,0, 4,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,218,3,97,110,121,218,18,69,88,84,69,78,83,73,79, - 78,95,83,85,70,70,73,88,69,83,41,2,114,103,0,0, - 0,114,122,0,0,0,114,2,0,0,0,41,1,114,238,0, - 0,0,114,4,0,0,0,114,162,0,0,0,33,4,0,0, + 78,95,83,85,70,70,73,88,69,83,41,2,114,107,0,0, + 0,114,126,0,0,0,114,2,0,0,0,41,1,114,242,0, + 0,0,114,4,0,0,0,114,166,0,0,0,73,4,0,0, 115,6,0,0,0,0,2,14,1,12,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, @@ -1702,9 +1735,9 @@ const unsigned char _Py_M__importlib_external[] = { 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,2,0, - 0,0,41,2,114,103,0,0,0,114,122,0,0,0,114,2, - 0,0,0,114,2,0,0,0,114,4,0,0,0,114,189,0, - 0,0,39,4,0,0,115,2,0,0,0,0,2,122,28,69, + 0,0,41,2,114,107,0,0,0,114,126,0,0,0,114,2, + 0,0,0,114,2,0,0,0,114,4,0,0,0,114,193,0, + 0,0,79,4,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, @@ -1712,9 +1745,9 @@ const unsigned char _Py_M__importlib_external[] = { 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,2,0,0,0,41,2,114,103,0,0,0,114, - 122,0,0,0,114,2,0,0,0,114,2,0,0,0,114,4, - 0,0,0,114,203,0,0,0,43,4,0,0,115,2,0,0, + 101,46,78,114,2,0,0,0,41,2,114,107,0,0,0,114, + 126,0,0,0,114,2,0,0,0,114,2,0,0,0,114,4, + 0,0,0,114,207,0,0,0,83,4,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, @@ -1723,20 +1756,20 @@ const unsigned char _Py_M__importlib_external[] = { 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,103,0,0,0,114, - 122,0,0,0,114,2,0,0,0,114,2,0,0,0,114,4, - 0,0,0,114,160,0,0,0,47,4,0,0,115,2,0,0, + 46,41,1,114,35,0,0,0,41,2,114,107,0,0,0,114, + 126,0,0,0,114,2,0,0,0,114,2,0,0,0,114,4, + 0,0,0,114,164,0,0,0,87,4,0,0,115,2,0,0, 0,0,3,122,32,69,120,116,101,110,115,105,111,110,70,105, 108,101,76,111,97,100,101,114,46,103,101,116,95,102,105,108, - 101,110,97,109,101,78,41,14,114,108,0,0,0,114,107,0, - 0,0,114,109,0,0,0,114,110,0,0,0,114,187,0,0, - 0,114,216,0,0,0,114,218,0,0,0,114,188,0,0,0, - 114,193,0,0,0,114,162,0,0,0,114,189,0,0,0,114, - 203,0,0,0,114,119,0,0,0,114,160,0,0,0,114,2, + 101,110,97,109,101,78,41,14,114,112,0,0,0,114,111,0, + 0,0,114,113,0,0,0,114,114,0,0,0,114,191,0,0, + 0,114,220,0,0,0,114,222,0,0,0,114,192,0,0,0, + 114,197,0,0,0,114,166,0,0,0,114,193,0,0,0,114, + 207,0,0,0,114,123,0,0,0,114,164,0,0,0,114,2, 0,0,0,114,2,0,0,0,114,2,0,0,0,114,4,0, - 0,0,114,220,0,0,0,0,4,0,0,115,20,0,0,0, + 0,0,114,240,0,0,0,40,4,0,0,115,20,0,0,0, 8,6,4,2,8,4,8,4,8,3,8,8,8,6,8,6, - 8,4,8,4,114,220,0,0,0,99,0,0,0,0,0,0, + 8,4,8,4,114,240,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,96, 0,0,0,101,0,90,1,100,0,90,2,100,1,90,3,100, 2,100,3,132,0,90,4,100,4,100,5,132,0,90,5,100, @@ -1769,13 +1802,13 @@ const unsigned char _Py_M__importlib_external[] = { 124,2,124,0,95,1,116,2,124,0,160,3,161,0,131,1, 124,0,95,4,124,3,124,0,95,5,100,0,83,0,41,1, 78,41,6,218,5,95,110,97,109,101,218,5,95,112,97,116, - 104,114,96,0,0,0,218,16,95,103,101,116,95,112,97,114, + 104,114,101,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,103,0,0,0, - 114,101,0,0,0,114,35,0,0,0,218,11,112,97,116,104, + 116,104,95,102,105,110,100,101,114,41,4,114,107,0,0,0, + 114,105,0,0,0,114,35,0,0,0,218,11,112,97,116,104, 95,102,105,110,100,101,114,114,2,0,0,0,114,2,0,0, - 0,114,4,0,0,0,114,187,0,0,0,60,4,0,0,115, + 0,114,4,0,0,0,114,191,0,0,0,100,4,0,0,115, 8,0,0,0,0,1,6,1,6,1,14,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, @@ -1786,26 +1819,26 @@ const unsigned char _Py_M__importlib_external[] = { 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,60,0,0,0,114,30,0,0, + 114,45,110,97,109,101,41,114,62,0,0,0,114,30,0,0, 0,41,2,114,6,0,0,0,114,35,0,0,0,90,8,95, - 95,112,97,116,104,95,95,41,2,114,243,0,0,0,114,32, - 0,0,0,41,4,114,103,0,0,0,114,235,0,0,0,218, + 95,112,97,116,104,95,95,41,2,114,247,0,0,0,114,32, + 0,0,0,41,4,114,107,0,0,0,114,238,0,0,0,218, 3,100,111,116,90,2,109,101,114,2,0,0,0,114,2,0, 0,0,114,4,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, - 66,4,0,0,115,8,0,0,0,0,2,18,1,8,2,4, + 106,4,0,0,115,8,0,0,0,0,2,18,1,8,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,28, 0,0,0,124,0,160,0,161,0,92,2,125,1,125,2,116, 1,116,2,106,3,124,1,25,0,124,2,131,2,83,0,41, - 1,78,41,4,114,250,0,0,0,114,113,0,0,0,114,6, - 0,0,0,218,7,109,111,100,117,108,101,115,41,3,114,103, + 1,78,41,4,114,254,0,0,0,114,117,0,0,0,114,6, + 0,0,0,218,7,109,111,100,117,108,101,115,41,3,114,107, 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,2,0,0,0,114,2,0,0, - 0,114,4,0,0,0,114,245,0,0,0,76,4,0,0,115, + 0,114,4,0,0,0,114,249,0,0,0,116,4,0,0,115, 4,0,0,0,0,1,12,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, @@ -1815,73 +1848,73 @@ const unsigned char _Py_M__importlib_external[] = { 4,124,1,161,2,125,2,124,2,100,0,107,9,114,68,124, 2,106,5,100,0,107,8,114,68,124,2,106,6,114,68,124, 2,106,6,124,0,95,7,124,1,124,0,95,2,124,0,106, - 7,83,0,41,1,78,41,8,114,96,0,0,0,114,245,0, - 0,0,114,246,0,0,0,114,247,0,0,0,114,243,0,0, - 0,114,123,0,0,0,114,159,0,0,0,114,244,0,0,0, - 41,3,114,103,0,0,0,90,11,112,97,114,101,110,116,95, - 112,97,116,104,114,167,0,0,0,114,2,0,0,0,114,2, + 7,83,0,41,1,78,41,8,114,101,0,0,0,114,249,0, + 0,0,114,250,0,0,0,114,251,0,0,0,114,247,0,0, + 0,114,127,0,0,0,114,163,0,0,0,114,248,0,0,0, + 41,3,114,107,0,0,0,90,11,112,97,114,101,110,116,95, + 112,97,116,104,114,171,0,0,0,114,2,0,0,0,114,2, 0,0,0,114,4,0,0,0,218,12,95,114,101,99,97,108, - 99,117,108,97,116,101,80,4,0,0,115,16,0,0,0,0, + 99,117,108,97,116,101,120,4,0,0,115,16,0,0,0,0, 2,12,1,10,1,14,3,18,1,6,1,8,1,6,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,3,0,0,0,67,0,0, 0,115,12,0,0,0,116,0,124,0,160,1,161,0,131,1, - 83,0,41,1,78,41,2,114,228,0,0,0,114,252,0,0, - 0,41,1,114,103,0,0,0,114,2,0,0,0,114,2,0, + 83,0,41,1,78,41,2,114,231,0,0,0,114,0,1,0, + 0,41,1,114,107,0,0,0,114,2,0,0,0,114,2,0, 0,0,114,4,0,0,0,218,8,95,95,105,116,101,114,95, - 95,93,4,0,0,115,2,0,0,0,0,1,122,23,95,78, + 95,133,4,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,3,0,0,0,0,0,0,0,3,0, 0,0,3,0,0,0,67,0,0,0,115,14,0,0,0,124, 2,124,0,106,0,124,1,60,0,100,0,83,0,41,1,78, - 41,1,114,244,0,0,0,41,3,114,103,0,0,0,218,5, + 41,1,114,248,0,0,0,41,3,114,107,0,0,0,218,5, 105,110,100,101,120,114,35,0,0,0,114,2,0,0,0,114, 2,0,0,0,114,4,0,0,0,218,11,95,95,115,101,116, - 105,116,101,109,95,95,96,4,0,0,115,2,0,0,0,0, + 105,116,101,109,95,95,136,4,0,0,115,2,0,0,0,0, 1,122,26,95,78,97,109,101,115,112,97,99,101,80,97,116, 104,46,95,95,115,101,116,105,116,101,109,95,95,99,1,0, 0,0,0,0,0,0,1,0,0,0,3,0,0,0,67,0, 0,0,115,12,0,0,0,116,0,124,0,160,1,161,0,131, - 1,83,0,41,1,78,41,2,114,31,0,0,0,114,252,0, - 0,0,41,1,114,103,0,0,0,114,2,0,0,0,114,2, + 1,83,0,41,1,78,41,2,114,31,0,0,0,114,0,1, + 0,0,41,1,114,107,0,0,0,114,2,0,0,0,114,2, 0,0,0,114,4,0,0,0,218,7,95,95,108,101,110,95, - 95,99,4,0,0,115,2,0,0,0,0,1,122,22,95,78, + 95,139,4,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,3,0,0,0,67,0,0,0,115,12,0,0,0,100,1, 160,0,124,0,106,1,161,1,83,0,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,48,0,0,0,114,244,0,0,0,41, - 1,114,103,0,0,0,114,2,0,0,0,114,2,0,0,0, - 114,4,0,0,0,218,8,95,95,114,101,112,114,95,95,102, + 114,125,41,41,2,114,51,0,0,0,114,248,0,0,0,41, + 1,114,107,0,0,0,114,2,0,0,0,114,2,0,0,0, + 114,4,0,0,0,218,8,95,95,114,101,112,114,95,95,142, 4,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, 3,0,0,0,67,0,0,0,115,12,0,0,0,124,1,124, - 0,160,0,161,0,107,6,83,0,41,1,78,41,1,114,252, - 0,0,0,41,2,114,103,0,0,0,218,4,105,116,101,109, + 0,160,0,161,0,107,6,83,0,41,1,78,41,1,114,0, + 1,0,0,41,2,114,107,0,0,0,218,4,105,116,101,109, 114,2,0,0,0,114,2,0,0,0,114,4,0,0,0,218, - 12,95,95,99,111,110,116,97,105,110,115,95,95,105,4,0, + 12,95,95,99,111,110,116,97,105,110,115,95,95,145,4,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,3,0,0,0,67,0,0,0,115,16,0,0,0,124, 0,106,0,160,1,124,1,161,1,1,0,100,0,83,0,41, - 1,78,41,2,114,244,0,0,0,114,166,0,0,0,41,2, - 114,103,0,0,0,114,2,1,0,0,114,2,0,0,0,114, - 2,0,0,0,114,4,0,0,0,114,166,0,0,0,108,4, + 1,78,41,2,114,248,0,0,0,114,170,0,0,0,41,2, + 114,107,0,0,0,114,6,1,0,0,114,2,0,0,0,114, + 2,0,0,0,114,4,0,0,0,114,170,0,0,0,148,4, 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,14,114,108,0,0,0,114,107,0,0,0,114,109,0, - 0,0,114,110,0,0,0,114,187,0,0,0,114,250,0,0, - 0,114,245,0,0,0,114,252,0,0,0,114,253,0,0,0, - 114,255,0,0,0,114,0,1,0,0,114,1,1,0,0,114, - 3,1,0,0,114,166,0,0,0,114,2,0,0,0,114,2, - 0,0,0,114,2,0,0,0,114,4,0,0,0,114,242,0, - 0,0,53,4,0,0,115,22,0,0,0,8,5,4,2,8, + 78,41,14,114,112,0,0,0,114,111,0,0,0,114,113,0, + 0,0,114,114,0,0,0,114,191,0,0,0,114,254,0,0, + 0,114,249,0,0,0,114,0,1,0,0,114,1,1,0,0, + 114,3,1,0,0,114,4,1,0,0,114,5,1,0,0,114, + 7,1,0,0,114,170,0,0,0,114,2,0,0,0,114,2, + 0,0,0,114,2,0,0,0,114,4,0,0,0,114,246,0, + 0,0,93,4,0,0,115,22,0,0,0,8,5,4,2,8, 6,8,10,8,4,8,13,8,3,8,3,8,3,8,3,8, - 3,114,242,0,0,0,99,0,0,0,0,0,0,0,0,0, + 3,114,246,0,0,0,99,0,0,0,0,0,0,0,0,0, 0,0,0,3,0,0,0,64,0,0,0,115,80,0,0,0, 101,0,90,1,100,0,90,2,100,1,100,2,132,0,90,3, 101,4,100,3,100,4,132,0,131,1,90,5,100,5,100,6, @@ -1892,10 +1925,10 @@ const unsigned char _Py_M__importlib_external[] = { 97,100,101,114,99,4,0,0,0,0,0,0,0,4,0,0, 0,4,0,0,0,67,0,0,0,115,18,0,0,0,116,0, 124,1,124,2,124,3,131,3,124,0,95,1,100,0,83,0, - 41,1,78,41,2,114,242,0,0,0,114,244,0,0,0,41, - 4,114,103,0,0,0,114,101,0,0,0,114,35,0,0,0, - 114,248,0,0,0,114,2,0,0,0,114,2,0,0,0,114, - 4,0,0,0,114,187,0,0,0,114,4,0,0,115,2,0, + 41,1,78,41,2,114,246,0,0,0,114,248,0,0,0,41, + 4,114,107,0,0,0,114,105,0,0,0,114,35,0,0,0, + 114,252,0,0,0,114,2,0,0,0,114,2,0,0,0,114, + 4,0,0,0,114,191,0,0,0,154,4,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,3,0,0,0, @@ -1909,34 +1942,34 @@ const unsigned char _Py_M__importlib_external[] = { 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,48,0,0,0,114,108, - 0,0,0,41,2,114,173,0,0,0,114,192,0,0,0,114, + 115,112,97,99,101,41,62,41,2,114,51,0,0,0,114,112, + 0,0,0,41,2,114,177,0,0,0,114,196,0,0,0,114, 2,0,0,0,114,2,0,0,0,114,4,0,0,0,218,11, - 109,111,100,117,108,101,95,114,101,112,114,117,4,0,0,115, + 109,111,100,117,108,101,95,114,101,112,114,157,4,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, - 83,0,41,2,78,84,114,2,0,0,0,41,2,114,103,0, - 0,0,114,122,0,0,0,114,2,0,0,0,114,2,0,0, - 0,114,4,0,0,0,114,162,0,0,0,126,4,0,0,115, + 83,0,41,2,78,84,114,2,0,0,0,41,2,114,107,0, + 0,0,114,126,0,0,0,114,2,0,0,0,114,2,0,0, + 0,114,4,0,0,0,114,166,0,0,0,166,4,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,83, 0,41,2,78,114,30,0,0,0,114,2,0,0,0,41,2, - 114,103,0,0,0,114,122,0,0,0,114,2,0,0,0,114, - 2,0,0,0,114,4,0,0,0,114,203,0,0,0,129,4, + 114,107,0,0,0,114,126,0,0,0,114,2,0,0,0,114, + 2,0,0,0,114,4,0,0,0,114,207,0,0,0,169,4, 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,16,0,0,0, 116,0,100,1,100,2,100,3,100,4,100,5,141,4,83,0, 41,6,78,114,30,0,0,0,122,8,60,115,116,114,105,110, - 103,62,114,191,0,0,0,84,41,1,114,205,0,0,0,41, - 1,114,206,0,0,0,41,2,114,103,0,0,0,114,122,0, + 103,62,114,195,0,0,0,84,41,1,114,209,0,0,0,41, + 1,114,210,0,0,0,41,2,114,107,0,0,0,114,126,0, 0,0,114,2,0,0,0,114,2,0,0,0,114,4,0,0, - 0,114,189,0,0,0,132,4,0,0,115,2,0,0,0,0, + 0,114,193,0,0,0,172,4,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, @@ -1944,15 +1977,15 @@ const unsigned char _Py_M__importlib_external[] = { 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,2,0,0,0,41,2, - 114,103,0,0,0,114,167,0,0,0,114,2,0,0,0,114, - 2,0,0,0,114,4,0,0,0,114,188,0,0,0,135,4, + 114,107,0,0,0,114,171,0,0,0,114,2,0,0,0,114, + 2,0,0,0,114,4,0,0,0,114,192,0,0,0,175,4, 0,0,115,2,0,0,0,0,1,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,83,0,41,1,78,114,2,0,0,0,41, - 2,114,103,0,0,0,114,192,0,0,0,114,2,0,0,0, - 114,2,0,0,0,114,4,0,0,0,114,193,0,0,0,138, + 2,114,107,0,0,0,114,196,0,0,0,114,2,0,0,0, + 114,2,0,0,0,114,4,0,0,0,114,197,0,0,0,178, 4,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, @@ -1967,20 +2000,20 @@ const unsigned char _Py_M__importlib_external[] = { 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,4,114,117,0,0, - 0,114,131,0,0,0,114,244,0,0,0,114,194,0,0,0, - 41,2,114,103,0,0,0,114,122,0,0,0,114,2,0,0, - 0,114,2,0,0,0,114,4,0,0,0,114,195,0,0,0, - 141,4,0,0,115,6,0,0,0,0,7,6,1,8,1,122, + 32,112,97,116,104,32,123,33,114,125,41,4,114,121,0,0, + 0,114,135,0,0,0,114,248,0,0,0,114,198,0,0,0, + 41,2,114,107,0,0,0,114,126,0,0,0,114,2,0,0, + 0,114,2,0,0,0,114,4,0,0,0,114,199,0,0,0, + 181,4,0,0,115,6,0,0,0,0,7,6,1,8,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,108,0,0,0,114,107,0,0,0,114,109,0,0,0,114, - 187,0,0,0,114,185,0,0,0,114,5,1,0,0,114,162, - 0,0,0,114,203,0,0,0,114,189,0,0,0,114,188,0, - 0,0,114,193,0,0,0,114,195,0,0,0,114,2,0,0, + 114,112,0,0,0,114,111,0,0,0,114,113,0,0,0,114, + 191,0,0,0,114,189,0,0,0,114,9,1,0,0,114,166, + 0,0,0,114,207,0,0,0,114,193,0,0,0,114,192,0, + 0,0,114,197,0,0,0,114,199,0,0,0,114,2,0,0, 0,114,2,0,0,0,114,2,0,0,0,114,4,0,0,0, - 114,4,1,0,0,113,4,0,0,115,16,0,0,0,8,1, - 8,3,12,9,8,3,8,3,8,3,8,3,8,3,114,4, + 114,8,1,0,0,153,4,0,0,115,16,0,0,0,8,1, + 8,3,12,9,8,3,8,3,8,3,8,3,8,3,114,8, 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,90, 1,100,0,90,2,100,1,90,3,101,4,100,2,100,3,132, @@ -1995,626 +2028,635 @@ const unsigned char _Py_M__importlib_external[] = { 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,3,0, - 0,0,4,0,0,0,67,0,0,0,115,68,0,0,0,120, - 62,116,0,116,1,106,2,160,3,161,0,131,1,68,0,93, - 44,92,2,125,1,125,2,124,2,100,1,107,8,114,42,116, - 1,106,2,124,1,61,0,113,16,116,4,124,2,100,2,131, - 2,114,16,124,2,160,5,161,0,1,0,113,16,87,0,100, - 1,83,0,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,78,218,17,105,110,118,97,108,105,100,97,116, - 101,95,99,97,99,104,101,115,41,6,218,4,108,105,115,116, - 114,6,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,5,105,116,101,109, - 115,114,111,0,0,0,114,7,1,0,0,41,3,114,173,0, - 0,0,114,101,0,0,0,218,6,102,105,110,100,101,114,114, - 2,0,0,0,114,2,0,0,0,114,4,0,0,0,114,7, - 1,0,0,159,4,0,0,115,10,0,0,0,0,4,24,1, - 8,1,10,1,10,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,9,0,0,0,67,0,0,0,115,84,0,0,0,116,0, - 106,1,100,1,107,9,114,28,116,0,106,1,115,28,116,2, - 160,3,100,2,116,4,161,2,1,0,120,50,116,0,106,1, - 68,0,93,36,125,2,121,8,124,2,124,1,131,1,83,0, - 4,0,116,5,107,10,114,70,1,0,1,0,1,0,119,36, - 89,0,113,36,88,0,113,36,87,0,100,1,83,0,100,1, - 83,0,41,3,122,46,83,101,97,114,99,104,32,115,121,115, - 46,112,97,116,104,95,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,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,6,0,0,0,218,10,112,97,116,104,95,104,111,111,107, - 115,114,62,0,0,0,114,63,0,0,0,114,121,0,0,0, - 114,102,0,0,0,41,3,114,173,0,0,0,114,35,0,0, - 0,90,4,104,111,111,107,114,2,0,0,0,114,2,0,0, - 0,114,4,0,0,0,218,11,95,112,97,116,104,95,104,111, - 111,107,115,169,4,0,0,115,16,0,0,0,0,3,16,1, - 12,1,12,1,2,1,8,1,14,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,8,0,0,0,67,0,0,0,115,102,0,0,0,124,1, - 100,1,107,2,114,42,121,12,116,0,160,1,161,0,125,1, - 87,0,110,20,4,0,116,2,107,10,114,40,1,0,1,0, - 1,0,100,2,83,0,88,0,121,14,116,3,106,4,124,1, - 25,0,125,2,87,0,110,40,4,0,116,5,107,10,114,96, - 1,0,1,0,1,0,124,0,160,6,124,1,161,1,125,2, - 124,2,116,3,106,4,124,1,60,0,89,0,110,2,88,0, - 124,2,83,0,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, + 0,0,4,0,0,0,67,0,0,0,115,64,0,0,0,116, + 0,116,1,106,2,160,3,161,0,131,1,68,0,93,44,92, + 2,125,1,125,2,124,2,100,1,107,8,114,40,116,1,106, + 2,124,1,61,0,113,14,116,4,124,2,100,2,131,2,114, + 14,124,2,160,5,161,0,1,0,113,14,100,1,83,0,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, + 78,218,17,105,110,118,97,108,105,100,97,116,101,95,99,97, + 99,104,101,115,41,6,218,4,108,105,115,116,114,6,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,5,105,116,101,109,115,114,115,0, + 0,0,114,11,1,0,0,41,3,114,177,0,0,0,114,105, + 0,0,0,218,6,102,105,110,100,101,114,114,2,0,0,0, + 114,2,0,0,0,114,4,0,0,0,114,11,1,0,0,199, + 4,0,0,115,10,0,0,0,0,4,22,1,8,1,10,1, + 10,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,9,0,0, + 0,67,0,0,0,115,84,0,0,0,116,0,106,1,100,1, + 107,9,114,28,116,0,106,1,115,28,116,2,160,3,100,2, + 116,4,161,2,1,0,116,0,106,1,68,0,93,44,125,2, + 122,14,124,2,124,1,131,1,87,0,2,0,1,0,83,0, + 4,0,116,5,107,10,114,76,1,0,1,0,1,0,89,0, + 113,34,89,0,113,34,88,0,113,34,100,1,83,0,41,3, + 122,46,83,101,97,114,99,104,32,115,121,115,46,112,97,116, + 104,95,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, + 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,6,0,0, + 0,218,10,112,97,116,104,95,104,111,111,107,115,114,65,0, + 0,0,114,66,0,0,0,114,125,0,0,0,114,106,0,0, + 0,41,3,114,177,0,0,0,114,35,0,0,0,90,4,104, + 111,111,107,114,2,0,0,0,114,2,0,0,0,114,4,0, + 0,0,218,11,95,112,97,116,104,95,104,111,111,107,115,209, + 4,0,0,115,16,0,0,0,0,3,16,1,12,1,10,1, + 2,1,14,1,14,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,8,0,0, + 0,67,0,0,0,115,104,0,0,0,124,1,100,1,107,2, + 114,44,122,12,116,0,160,1,161,0,125,1,87,0,110,22, + 4,0,116,2,107,10,114,42,1,0,1,0,1,0,89,0, + 100,2,83,0,88,0,122,14,116,3,106,4,124,1,25,0, + 125,2,87,0,110,40,4,0,116,5,107,10,114,98,1,0, + 1,0,1,0,124,0,160,6,124,1,161,1,125,2,124,2, + 116,3,106,4,124,1,60,0,89,0,110,2,88,0,124,2, + 83,0,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,1,0,0,0,114,45,0,0,0,114,229,0,0,0,114, + 6,0,0,0,114,13,1,0,0,218,8,75,101,121,69,114, + 114,111,114,114,17,1,0,0,41,3,114,177,0,0,0,114, + 35,0,0,0,114,15,1,0,0,114,2,0,0,0,114,2, + 0,0,0,114,4,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,222,4, + 0,0,115,22,0,0,0,0,8,8,1,2,1,12,1,14, + 3,8,1,2,1,14,1,14,1,10,1,16,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,4,0,0,0,67, + 0,0,0,115,82,0,0,0,116,0,124,2,100,1,131,2, + 114,26,124,2,160,1,124,1,161,1,92,2,125,3,125,4, + 110,14,124,2,160,2,124,1,161,1,125,3,103,0,125,4, + 124,3,100,0,107,9,114,60,116,3,160,4,124,1,124,3, + 161,2,83,0,116,3,160,5,124,1,100,0,161,2,125,5, + 124,4,124,5,95,6,124,5,83,0,41,2,78,114,124,0, + 0,0,41,7,114,115,0,0,0,114,124,0,0,0,114,188, + 0,0,0,114,121,0,0,0,114,185,0,0,0,114,167,0, + 0,0,114,163,0,0,0,41,6,114,177,0,0,0,114,126, + 0,0,0,114,15,1,0,0,114,127,0,0,0,114,128,0, + 0,0,114,171,0,0,0,114,2,0,0,0,114,2,0,0, + 0,114,4,0,0,0,218,16,95,108,101,103,97,99,121,95, + 103,101,116,95,115,112,101,99,244,4,0,0,115,18,0,0, + 0,0,4,10,1,16,2,10,1,4,1,8,1,12,1,12, + 1,6,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,166,0,0,0,103,0,125,4,124, + 2,68,0,93,134,125,5,116,0,124,5,116,1,116,2,102, + 2,131,2,115,28,113,8,124,0,160,3,124,5,161,1,125, + 6,124,6,100,1,107,9,114,8,116,4,124,6,100,2,131, + 2,114,70,124,6,160,5,124,1,124,3,161,2,125,7,110, + 12,124,0,160,6,124,1,124,6,161,2,125,7,124,7,100, + 1,107,8,114,92,113,8,124,7,106,7,100,1,107,9,114, + 110,124,7,2,0,1,0,83,0,124,7,106,8,125,8,124, + 8,100,1,107,8,114,132,116,9,100,3,131,1,130,1,124, + 4,160,10,124,8,161,1,1,0,113,8,116,11,160,12,124, + 1,100,1,161,2,125,7,124,4,124,7,95,8,124,7,83, + 0,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,187,0,0,0,122,19,115,112,101,99, + 32,109,105,115,115,105,110,103,32,108,111,97,100,101,114,41, + 13,114,146,0,0,0,114,75,0,0,0,218,5,98,121,116, + 101,115,114,19,1,0,0,114,115,0,0,0,114,187,0,0, + 0,114,20,1,0,0,114,127,0,0,0,114,163,0,0,0, + 114,106,0,0,0,114,152,0,0,0,114,121,0,0,0,114, + 167,0,0,0,41,9,114,177,0,0,0,114,126,0,0,0, + 114,35,0,0,0,114,186,0,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,15,1,0,0,114,171,0,0,0,114,128,0,0,0, + 114,2,0,0,0,114,2,0,0,0,114,4,0,0,0,218, + 9,95,103,101,116,95,115,112,101,99,3,5,0,0,115,40, + 0,0,0,0,5,4,1,8,1,14,1,2,1,10,1,8, + 1,10,1,14,2,12,1,8,1,2,1,10,1,8,1,6, + 1,8,1,8,5,12,2,12,1,6,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,5,0, + 0,0,67,0,0,0,115,100,0,0,0,124,2,100,1,107, + 8,114,14,116,0,106,1,125,2,124,0,160,2,124,1,124, + 2,124,3,161,3,125,4,124,4,100,1,107,8,114,40,100, + 1,83,0,124,4,106,3,100,1,107,8,114,92,124,4,106, + 4,125,5,124,5,114,86,100,1,124,4,95,5,116,6,124, + 1,124,5,124,0,106,2,131,3,124,4,95,4,124,4,83, + 0,100,1,83,0,110,4,124,4,83,0,100,1,83,0,41, + 2,122,141,84,114,121,32,116,111,32,102,105,110,100,32,97, + 32,115,112,101,99,32,102,111,114,32,39,102,117,108,108,110, + 97,109,101,39,32,111,110,32,115,121,115,46,112,97,116,104, + 32,111,114,32,39,112,97,116,104,39,46,10,10,32,32,32, + 32,32,32,32,32,84,104,101,32,115,101,97,114,99,104,32, + 105,115,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,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,1,0,0,0,114,45,0,0,0,114,226,0,0, - 0,114,6,0,0,0,114,9,1,0,0,218,8,75,101,121, - 69,114,114,111,114,114,13,1,0,0,41,3,114,173,0,0, - 0,114,35,0,0,0,114,11,1,0,0,114,2,0,0,0, - 114,2,0,0,0,114,4,0,0,0,218,20,95,112,97,116, + 95,99,97,99,104,101,46,10,32,32,32,32,32,32,32,32, + 78,41,7,114,6,0,0,0,114,35,0,0,0,114,23,1, + 0,0,114,127,0,0,0,114,163,0,0,0,114,165,0,0, + 0,114,246,0,0,0,41,6,114,177,0,0,0,114,126,0, + 0,0,114,35,0,0,0,114,186,0,0,0,114,171,0,0, + 0,114,22,1,0,0,114,2,0,0,0,114,2,0,0,0, + 114,4,0,0,0,114,187,0,0,0,35,5,0,0,115,26, + 0,0,0,0,6,8,1,6,1,14,1,8,1,4,1,10, + 1,6,1,4,3,6,1,16,1,4,2,6,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, + 4,0,0,0,67,0,0,0,115,30,0,0,0,124,0,160, + 0,124,1,124,2,161,2,125,3,124,3,100,1,107,8,114, + 24,100,1,83,0,124,3,106,1,83,0,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, - 182,4,0,0,115,22,0,0,0,0,8,8,1,2,1,12, - 1,14,3,6,1,2,1,14,1,14,1,10,1,16,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,4,0,0, - 0,67,0,0,0,115,82,0,0,0,116,0,124,2,100,1, - 131,2,114,26,124,2,160,1,124,1,161,1,92,2,125,3, - 125,4,110,14,124,2,160,2,124,1,161,1,125,3,103,0, - 125,4,124,3,100,0,107,9,114,60,116,3,160,4,124,1, - 124,3,161,2,83,0,116,3,160,5,124,1,100,0,161,2, - 125,5,124,4,124,5,95,6,124,5,83,0,41,2,78,114, - 120,0,0,0,41,7,114,111,0,0,0,114,120,0,0,0, - 114,184,0,0,0,114,117,0,0,0,114,181,0,0,0,114, - 163,0,0,0,114,159,0,0,0,41,6,114,173,0,0,0, - 114,122,0,0,0,114,11,1,0,0,114,123,0,0,0,114, - 124,0,0,0,114,167,0,0,0,114,2,0,0,0,114,2, - 0,0,0,114,4,0,0,0,218,16,95,108,101,103,97,99, - 121,95,103,101,116,95,115,112,101,99,204,4,0,0,115,18, - 0,0,0,0,4,10,1,16,2,10,1,4,1,8,1,12, - 1,12,1,6,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,170,0,0,0,103,0,125, - 4,120,160,124,2,68,0,93,130,125,5,116,0,124,5,116, - 1,116,2,102,2,131,2,115,30,113,10,124,0,160,3,124, - 5,161,1,125,6,124,6,100,1,107,9,114,10,116,4,124, - 6,100,2,131,2,114,72,124,6,160,5,124,1,124,3,161, - 2,125,7,110,12,124,0,160,6,124,1,124,6,161,2,125, - 7,124,7,100,1,107,8,114,94,113,10,124,7,106,7,100, - 1,107,9,114,108,124,7,83,0,124,7,106,8,125,8,124, - 8,100,1,107,8,114,130,116,9,100,3,131,1,130,1,124, - 4,160,10,124,8,161,1,1,0,113,10,87,0,116,11,160, - 12,124,1,100,1,161,2,125,7,124,4,124,7,95,8,124, - 7,83,0,100,1,83,0,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,183,0,0,0, - 122,19,115,112,101,99,32,109,105,115,115,105,110,103,32,108, - 111,97,100,101,114,41,13,114,142,0,0,0,114,72,0,0, - 0,218,5,98,121,116,101,115,114,15,1,0,0,114,111,0, - 0,0,114,183,0,0,0,114,16,1,0,0,114,123,0,0, - 0,114,159,0,0,0,114,102,0,0,0,114,148,0,0,0, - 114,117,0,0,0,114,163,0,0,0,41,9,114,173,0,0, - 0,114,122,0,0,0,114,35,0,0,0,114,182,0,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,11,1,0,0,114,167,0,0, - 0,114,124,0,0,0,114,2,0,0,0,114,2,0,0,0, - 114,4,0,0,0,218,9,95,103,101,116,95,115,112,101,99, - 219,4,0,0,115,40,0,0,0,0,5,4,1,10,1,14, - 1,2,1,10,1,8,1,10,1,14,2,12,1,8,1,2, - 1,10,1,4,1,6,1,8,1,8,5,14,2,12,1,6, - 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,5,0,0,0,67,0,0,0,115,100,0,0, - 0,124,2,100,1,107,8,114,14,116,0,106,1,125,2,124, - 0,160,2,124,1,124,2,124,3,161,3,125,4,124,4,100, - 1,107,8,114,40,100,1,83,0,124,4,106,3,100,1,107, - 8,114,92,124,4,106,4,125,5,124,5,114,86,100,1,124, - 4,95,5,116,6,124,1,124,5,124,0,106,2,131,3,124, - 4,95,4,124,4,83,0,100,1,83,0,110,4,124,4,83, - 0,100,1,83,0,41,2,122,141,84,114,121,32,116,111,32, - 102,105,110,100,32,97,32,115,112,101,99,32,102,111,114,32, - 39,102,117,108,108,110,97,109,101,39,32,111,110,32,115,121, - 115,46,112,97,116,104,32,111,114,32,39,112,97,116,104,39, - 46,10,10,32,32,32,32,32,32,32,32,84,104,101,32,115, - 101,97,114,99,104,32,105,115,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,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,32,32, - 32,32,32,32,32,32,78,41,7,114,6,0,0,0,114,35, - 0,0,0,114,19,1,0,0,114,123,0,0,0,114,159,0, - 0,0,114,161,0,0,0,114,242,0,0,0,41,6,114,173, - 0,0,0,114,122,0,0,0,114,35,0,0,0,114,182,0, - 0,0,114,167,0,0,0,114,18,1,0,0,114,2,0,0, - 0,114,2,0,0,0,114,4,0,0,0,114,183,0,0,0, - 251,4,0,0,115,26,0,0,0,0,6,8,1,6,1,14, - 1,8,1,4,1,10,1,6,1,4,3,6,1,16,1,4, - 2,6,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,4,0,0,0,67,0,0,0,115,30, - 0,0,0,124,0,160,0,124,1,124,2,161,2,125,3,124, - 3,100,1,107,8,114,24,100,1,83,0,124,3,106,1,83, - 0,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,183,0,0,0,114,123,0,0,0,41,4,114,173, - 0,0,0,114,122,0,0,0,114,35,0,0,0,114,167,0, - 0,0,114,2,0,0,0,114,2,0,0,0,114,4,0,0, - 0,114,184,0,0,0,19,5,0,0,115,8,0,0,0,0, - 8,12,1,8,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, - 1,78,41,2,78,78,41,1,78,41,12,114,108,0,0,0, - 114,107,0,0,0,114,109,0,0,0,114,110,0,0,0,114, - 185,0,0,0,114,7,1,0,0,114,13,1,0,0,114,15, - 1,0,0,114,16,1,0,0,114,19,1,0,0,114,183,0, - 0,0,114,184,0,0,0,114,2,0,0,0,114,2,0,0, - 0,114,2,0,0,0,114,4,0,0,0,114,6,1,0,0, - 155,4,0,0,115,22,0,0,0,8,2,4,2,12,10,12, - 13,12,22,12,15,2,1,12,31,2,1,12,23,2,1,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,90,0,0,0,101,0, - 90,1,100,0,90,2,100,1,90,3,100,2,100,3,132,0, - 90,4,100,4,100,5,132,0,90,5,101,6,90,7,100,6, - 100,7,132,0,90,8,100,8,100,9,132,0,90,9,100,19, - 100,11,100,12,132,1,90,10,100,13,100,14,132,0,90,11, - 101,12,100,15,100,16,132,0,131,1,90,13,100,17,100,18, - 132,0,90,14,100,10,83,0,41,20,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,6,0,0,0,7,0,0,0,115,88,0,0,0,103,0, - 125,3,120,40,124,2,68,0,93,32,92,2,137,0,125,4, - 124,3,160,0,135,0,102,1,100,1,100,2,132,8,124,4, - 68,0,131,1,161,1,1,0,113,10,87,0,124,3,124,0, - 95,1,124,1,112,58,100,3,124,0,95,2,100,4,124,0, - 95,3,116,4,131,0,124,0,95,5,116,4,131,0,124,0, - 95,6,100,5,83,0,41,6,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,22,0,0,0,124,0, - 93,14,125,1,124,1,136,0,102,2,86,0,1,0,113,2, - 100,0,83,0,41,1,78,114,2,0,0,0,41,2,114,22, - 0,0,0,114,237,0,0,0,41,1,114,123,0,0,0,114, - 2,0,0,0,114,4,0,0,0,114,239,0,0,0,48,5, - 0,0,115,2,0,0,0,4,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,60,0,0,0,114,90,0,0,0,78,41,7,114,148, - 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,103,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,169,0,0,0, - 114,2,0,0,0,41,1,114,123,0,0,0,114,4,0,0, - 0,114,187,0,0,0,42,5,0,0,115,16,0,0,0,0, - 4,4,1,14,1,28,1,6,2,10,1,6,1,8,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,10,0,0,0,100,1, - 124,0,95,0,100,2,83,0,41,3,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,90,0,0,0, - 78,41,1,114,22,1,0,0,41,1,114,103,0,0,0,114, - 2,0,0,0,114,2,0,0,0,114,4,0,0,0,114,7, - 1,0,0,56,5,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,42,0,0,0,124,0,160,0,124,1,161,1,125,2, - 124,2,100,1,107,8,114,26,100,1,103,0,102,2,83,0, - 124,2,106,1,124,2,106,2,112,38,103,0,102,2,83,0, - 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,183,0,0, - 0,114,123,0,0,0,114,159,0,0,0,41,3,114,103,0, - 0,0,114,122,0,0,0,114,167,0,0,0,114,2,0,0, - 0,114,2,0,0,0,114,4,0,0,0,114,120,0,0,0, - 62,5,0,0,115,8,0,0,0,0,7,10,1,8,1,8, - 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,6,0,0,0,67,0,0,0,115,26, - 0,0,0,124,1,124,2,124,3,131,2,125,6,116,0,124, - 2,124,3,124,6,124,4,100,1,141,4,83,0,41,2,78, - 41,2,114,123,0,0,0,114,159,0,0,0,41,1,114,170, - 0,0,0,41,7,114,103,0,0,0,114,168,0,0,0,114, - 122,0,0,0,114,35,0,0,0,90,4,115,109,115,108,114, - 182,0,0,0,114,123,0,0,0,114,2,0,0,0,114,2, - 0,0,0,114,4,0,0,0,114,19,1,0,0,74,5,0, - 0,115,6,0,0,0,0,1,10,1,8,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, - 8,0,0,0,67,0,0,0,115,98,1,0,0,100,1,125, - 3,124,1,160,0,100,2,161,1,100,3,25,0,125,4,121, - 24,116,1,124,0,106,2,112,34,116,3,160,4,161,0,131, - 1,106,5,125,5,87,0,110,24,4,0,116,6,107,10,114, - 66,1,0,1,0,1,0,100,4,125,5,89,0,110,2,88, - 0,124,5,124,0,106,7,107,3,114,92,124,0,160,8,161, - 0,1,0,124,5,124,0,95,7,116,9,131,0,114,114,124, - 0,106,10,125,6,124,4,160,11,161,0,125,7,110,10,124, - 0,106,12,125,6,124,4,125,7,124,7,124,6,107,6,114, - 218,116,13,124,0,106,2,124,4,131,2,125,8,120,72,124, - 0,106,14,68,0,93,54,92,2,125,9,125,10,100,5,124, - 9,23,0,125,11,116,13,124,8,124,11,131,2,125,12,116, - 15,124,12,131,1,114,152,124,0,160,16,124,10,124,1,124, - 12,124,8,103,1,124,2,161,5,83,0,113,152,87,0,116, - 17,124,8,131,1,125,3,120,88,124,0,106,14,68,0,93, - 78,92,2,125,9,125,10,116,13,124,0,106,2,124,4,124, - 9,23,0,131,2,125,12,116,18,106,19,100,6,124,12,100, - 3,100,7,141,3,1,0,124,7,124,9,23,0,124,6,107, - 6,114,226,116,15,124,12,131,1,114,226,124,0,160,16,124, - 10,124,1,124,12,100,8,124,2,161,5,83,0,113,226,87, - 0,124,3,144,1,114,94,116,18,160,19,100,9,124,8,161, - 2,1,0,116,18,160,20,124,1,100,8,161,2,125,13,124, - 8,103,1,124,13,95,21,124,13,83,0,100,8,83,0,41, - 10,122,111,84,114,121,32,116,111,32,102,105,110,100,32,97, - 32,115,112,101,99,32,102,111,114,32,116,104,101,32,115,112, - 101,99,105,102,105,101,100,32,109,111,100,117,108,101,46,10, - 10,32,32,32,32,32,32,32,32,82,101,116,117,114,110,115, - 32,116,104,101,32,109,97,116,99,104,105,110,103,32,115,112, - 101,99,44,32,111,114,32,78,111,110,101,32,105,102,32,110, - 111,116,32,102,111,117,110,100,46,10,32,32,32,32,32,32, - 32,32,70,114,60,0,0,0,114,58,0,0,0,114,90,0, - 0,0,114,187,0,0,0,122,9,116,114,121,105,110,103,32, - 123,125,41,1,90,9,118,101,114,98,111,115,105,116,121,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,41,22,114,32,0, - 0,0,114,39,0,0,0,114,35,0,0,0,114,1,0,0, - 0,114,45,0,0,0,114,232,0,0,0,114,40,0,0,0, - 114,22,1,0,0,218,11,95,102,105,108,108,95,99,97,99, - 104,101,114,5,0,0,0,114,25,1,0,0,114,91,0,0, - 0,114,24,1,0,0,114,28,0,0,0,114,21,1,0,0, - 114,44,0,0,0,114,19,1,0,0,114,46,0,0,0,114, - 117,0,0,0,114,131,0,0,0,114,163,0,0,0,114,159, - 0,0,0,41,14,114,103,0,0,0,114,122,0,0,0,114, - 182,0,0,0,90,12,105,115,95,110,97,109,101,115,112,97, - 99,101,90,11,116,97,105,108,95,109,111,100,117,108,101,114, - 150,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,237,0,0,0,114,168,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,167,0,0,0,114,2,0, - 0,0,114,2,0,0,0,114,4,0,0,0,114,183,0,0, - 0,79,5,0,0,115,70,0,0,0,0,5,4,1,14,1, - 2,1,24,1,14,1,10,1,10,1,8,1,6,2,6,1, - 6,1,10,2,6,1,4,2,8,1,12,1,16,1,8,1, - 10,1,8,1,24,4,8,2,16,1,16,1,16,1,12,1, - 8,1,10,1,12,1,6,1,12,1,12,1,8,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,10,0,0,0,67,0,0,0,115,194,0,0,0, - 124,0,106,0,125,1,121,22,116,1,160,2,124,1,112,22, - 116,1,160,3,161,0,161,1,125,2,87,0,110,30,4,0, - 116,4,116,5,116,6,102,3,107,10,114,58,1,0,1,0, - 1,0,103,0,125,2,89,0,110,2,88,0,116,7,106,8, - 160,9,100,1,161,1,115,84,116,10,124,2,131,1,124,0, - 95,11,110,78,116,10,131,0,125,3,120,64,124,2,68,0, - 93,56,125,4,124,4,160,12,100,2,161,1,92,3,125,5, - 125,6,125,7,124,6,114,138,100,3,160,13,124,5,124,7, - 160,14,161,0,161,2,125,8,110,4,124,5,125,8,124,3, - 160,15,124,8,161,1,1,0,113,96,87,0,124,3,124,0, - 95,11,116,7,106,8,160,9,116,16,161,1,114,190,100,4, - 100,5,132,0,124,2,68,0,131,1,124,0,95,17,100,6, - 83,0,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, - 60,0,0,0,122,5,123,125,46,123,125,99,1,0,0,0, - 0,0,0,0,2,0,0,0,4,0,0,0,83,0,0,0, - 115,20,0,0,0,104,0,124,0,93,12,125,1,124,1,160, - 0,161,0,146,2,113,4,83,0,114,2,0,0,0,41,1, - 114,91,0,0,0,41,2,114,22,0,0,0,90,2,102,110, - 114,2,0,0,0,114,2,0,0,0,114,4,0,0,0,250, - 9,60,115,101,116,99,111,109,112,62,156,5,0,0,115,2, - 0,0,0,6,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,1,0,0,0,114,229,0, - 0,0,114,45,0,0,0,114,226,0,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,6,0,0,0,114,7,0,0,0,114,8,0,0,0, - 114,23,1,0,0,114,24,1,0,0,114,86,0,0,0,114, - 48,0,0,0,114,91,0,0,0,218,3,97,100,100,114,9, - 0,0,0,114,25,1,0,0,41,9,114,103,0,0,0,114, - 35,0,0,0,114,230,0,0,0,90,21,108,111,119,101,114, - 95,115,117,102,102,105,120,95,99,111,110,116,101,110,116,115, - 114,2,1,0,0,114,101,0,0,0,114,249,0,0,0,114, - 237,0,0,0,90,8,110,101,119,95,110,97,109,101,114,2, - 0,0,0,114,2,0,0,0,114,4,0,0,0,114,27,1, - 0,0,127,5,0,0,115,34,0,0,0,0,2,6,1,2, - 1,22,1,20,3,10,3,12,1,12,7,6,1,10,1,16, - 1,4,1,18,2,4,1,14,1,6,1,12,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,18,0,0,0,135, - 0,135,1,102,2,100,1,100,2,132,8,125,2,124,2,83, - 0,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,34,0,0,0,116,0,124,0,131,1,115,20,116,1, - 100,1,124,0,100,2,141,2,130,1,136,0,124,0,102,1, - 136,1,158,2,142,0,83,0,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,41,1,114,35,0,0,0, - 41,2,114,46,0,0,0,114,102,0,0,0,41,1,114,35, - 0,0,0,41,2,114,173,0,0,0,114,26,1,0,0,114, - 2,0,0,0,114,4,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,168,5,0,0,115,6,0,0,0,0,2,8,1, - 12,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,2,0,0,0,41, - 3,114,173,0,0,0,114,26,1,0,0,114,32,1,0,0, - 114,2,0,0,0,41,2,114,173,0,0,0,114,26,1,0, - 0,114,4,0,0,0,218,9,112,97,116,104,95,104,111,111, - 107,158,5,0,0,115,4,0,0,0,0,10,14,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,3,0,0,0,67,0,0,0,115,12,0,0,0,100,1, - 160,0,124,0,106,1,161,1,83,0,41,2,78,122,16,70, - 105,108,101,70,105,110,100,101,114,40,123,33,114,125,41,41, - 2,114,48,0,0,0,114,35,0,0,0,41,1,114,103,0, + 10,32,32,32,32,32,32,32,32,78,41,2,114,187,0,0, + 0,114,127,0,0,0,41,4,114,177,0,0,0,114,126,0, + 0,0,114,35,0,0,0,114,171,0,0,0,114,2,0,0, + 0,114,2,0,0,0,114,4,0,0,0,114,188,0,0,0, + 59,5,0,0,115,8,0,0,0,0,8,12,1,8,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,1,78,41,2,78,78, + 41,1,78,41,12,114,112,0,0,0,114,111,0,0,0,114, + 113,0,0,0,114,114,0,0,0,114,189,0,0,0,114,11, + 1,0,0,114,17,1,0,0,114,19,1,0,0,114,20,1, + 0,0,114,23,1,0,0,114,187,0,0,0,114,188,0,0, + 0,114,2,0,0,0,114,2,0,0,0,114,2,0,0,0, + 114,4,0,0,0,114,10,1,0,0,195,4,0,0,115,22, + 0,0,0,8,2,4,2,12,10,12,13,12,22,12,15,2, + 1,12,31,2,1,12,23,2,1,114,10,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,90,0,0,0,101,0,90,1,100,0,90,2, + 100,1,90,3,100,2,100,3,132,0,90,4,100,4,100,5, + 132,0,90,5,101,6,90,7,100,6,100,7,132,0,90,8, + 100,8,100,9,132,0,90,9,100,19,100,11,100,12,132,1, + 90,10,100,13,100,14,132,0,90,11,101,12,100,15,100,16, + 132,0,131,1,90,13,100,17,100,18,132,0,90,14,100,10, + 83,0,41,20,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,6,0,0,0,7, + 0,0,0,115,84,0,0,0,103,0,125,3,124,2,68,0, + 93,32,92,2,137,0,125,4,124,3,160,0,135,0,102,1, + 100,1,100,2,132,8,124,4,68,0,131,1,161,1,1,0, + 113,8,124,3,124,0,95,1,124,1,112,54,100,3,124,0, + 95,2,100,4,124,0,95,3,116,4,131,0,124,0,95,5, + 116,4,131,0,124,0,95,6,100,5,83,0,41,6,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, + 22,0,0,0,124,0,93,14,125,1,124,1,136,0,102,2, + 86,0,1,0,113,2,100,0,83,0,41,1,78,114,2,0, + 0,0,41,2,114,22,0,0,0,114,241,0,0,0,41,1, + 114,127,0,0,0,114,2,0,0,0,114,4,0,0,0,114, + 243,0,0,0,88,5,0,0,115,2,0,0,0,4,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,62,0,0,0,114,95,0,0, + 0,78,41,7,114,152,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,107, + 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,173,0,0,0,114,2,0,0,0,41,1,114,127,0, + 0,0,114,4,0,0,0,114,191,0,0,0,82,5,0,0, + 115,16,0,0,0,0,4,4,1,12,1,26,1,6,2,10, + 1,6,1,8,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, + 10,0,0,0,100,1,124,0,95,0,100,2,83,0,41,3, + 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,95,0,0,0,78,41,1,114,26,1,0,0,41,1, + 114,107,0,0,0,114,2,0,0,0,114,2,0,0,0,114, + 4,0,0,0,114,11,1,0,0,96,5,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,42,0,0,0,124,0,160,0, + 124,1,161,1,125,2,124,2,100,1,107,8,114,26,100,1, + 103,0,102,2,83,0,124,2,106,1,124,2,106,2,112,38, + 103,0,102,2,83,0,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,187,0,0,0,114,127,0,0,0,114,163,0,0, + 0,41,3,114,107,0,0,0,114,126,0,0,0,114,171,0, 0,0,114,2,0,0,0,114,2,0,0,0,114,4,0,0, - 0,114,1,1,0,0,176,5,0,0,115,2,0,0,0,0, - 1,122,19,70,105,108,101,70,105,110,100,101,114,46,95,95, - 114,101,112,114,95,95,41,1,78,41,15,114,108,0,0,0, - 114,107,0,0,0,114,109,0,0,0,114,110,0,0,0,114, - 187,0,0,0,114,7,1,0,0,114,126,0,0,0,114,184, - 0,0,0,114,120,0,0,0,114,19,1,0,0,114,183,0, - 0,0,114,27,1,0,0,114,185,0,0,0,114,33,1,0, - 0,114,1,1,0,0,114,2,0,0,0,114,2,0,0,0, - 114,2,0,0,0,114,4,0,0,0,114,20,1,0,0,33, - 5,0,0,115,20,0,0,0,8,7,4,2,8,14,8,4, - 4,2,8,12,8,5,10,48,8,31,12,18,114,20,1,0, - 0,99,4,0,0,0,0,0,0,0,6,0,0,0,8,0, - 0,0,67,0,0,0,115,146,0,0,0,124,0,160,0,100, - 1,161,1,125,4,124,0,160,0,100,2,161,1,125,5,124, - 4,115,66,124,5,114,36,124,5,106,1,125,4,110,30,124, - 2,124,3,107,2,114,56,116,2,124,1,124,2,131,2,125, - 4,110,10,116,3,124,1,124,2,131,2,125,4,124,5,115, - 84,116,4,124,1,124,2,124,4,100,3,141,3,125,5,121, - 36,124,5,124,0,100,2,60,0,124,4,124,0,100,1,60, - 0,124,2,124,0,100,4,60,0,124,3,124,0,100,5,60, - 0,87,0,110,20,4,0,116,5,107,10,114,140,1,0,1, - 0,1,0,89,0,110,2,88,0,100,0,83,0,41,6,78, - 218,10,95,95,108,111,97,100,101,114,95,95,218,8,95,95, - 115,112,101,99,95,95,41,1,114,123,0,0,0,90,8,95, - 95,102,105,108,101,95,95,90,10,95,95,99,97,99,104,101, - 100,95,95,41,6,218,3,103,101,116,114,123,0,0,0,114, - 236,0,0,0,114,231,0,0,0,114,170,0,0,0,218,9, - 69,120,99,101,112,116,105,111,110,41,6,90,2,110,115,114, - 101,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,123,0,0,0,114,167, + 0,114,124,0,0,0,102,5,0,0,115,8,0,0,0,0, + 7,10,1,8,1,8,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,6,0,0,0, + 67,0,0,0,115,26,0,0,0,124,1,124,2,124,3,131, + 2,125,6,116,0,124,2,124,3,124,6,124,4,100,1,141, + 4,83,0,41,2,78,41,2,114,127,0,0,0,114,163,0, + 0,0,41,1,114,174,0,0,0,41,7,114,107,0,0,0, + 114,172,0,0,0,114,126,0,0,0,114,35,0,0,0,90, + 4,115,109,115,108,114,186,0,0,0,114,127,0,0,0,114, + 2,0,0,0,114,2,0,0,0,114,4,0,0,0,114,23, + 1,0,0,114,5,0,0,115,6,0,0,0,0,1,10,1, + 8,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,8,0,0,0,67,0,0,0,115,98, + 1,0,0,100,1,125,3,124,1,160,0,100,2,161,1,100, + 3,25,0,125,4,122,24,116,1,124,0,106,2,112,34,116, + 3,160,4,161,0,131,1,106,5,125,5,87,0,110,24,4, + 0,116,6,107,10,114,66,1,0,1,0,1,0,100,4,125, + 5,89,0,110,2,88,0,124,5,124,0,106,7,107,3,114, + 92,124,0,160,8,161,0,1,0,124,5,124,0,95,7,116, + 9,131,0,114,114,124,0,106,10,125,6,124,4,160,11,161, + 0,125,7,110,10,124,0,106,12,125,6,124,4,125,7,124, + 7,124,6,107,6,114,218,116,13,124,0,106,2,124,4,131, + 2,125,8,124,0,106,14,68,0,93,58,92,2,125,9,125, + 10,100,5,124,9,23,0,125,11,116,13,124,8,124,11,131, + 2,125,12,116,15,124,12,131,1,114,150,124,0,160,16,124, + 10,124,1,124,12,124,8,103,1,124,2,161,5,2,0,1, + 0,83,0,113,150,116,17,124,8,131,1,125,3,124,0,106, + 14,68,0,93,82,92,2,125,9,125,10,116,13,124,0,106, + 2,124,4,124,9,23,0,131,2,125,12,116,18,106,19,100, + 6,124,12,100,3,100,7,141,3,1,0,124,7,124,9,23, + 0,124,6,107,6,114,224,116,15,124,12,131,1,114,224,124, + 0,160,16,124,10,124,1,124,12,100,8,124,2,161,5,2, + 0,1,0,83,0,113,224,124,3,144,1,114,94,116,18,160, + 19,100,9,124,8,161,2,1,0,116,18,160,20,124,1,100, + 8,161,2,125,13,124,8,103,1,124,13,95,21,124,13,83, + 0,100,8,83,0,41,10,122,111,84,114,121,32,116,111,32, + 102,105,110,100,32,97,32,115,112,101,99,32,102,111,114,32, + 116,104,101,32,115,112,101,99,105,102,105,101,100,32,109,111, + 100,117,108,101,46,10,10,32,32,32,32,32,32,32,32,82, + 101,116,117,114,110,115,32,116,104,101,32,109,97,116,99,104, + 105,110,103,32,115,112,101,99,44,32,111,114,32,78,111,110, + 101,32,105,102,32,110,111,116,32,102,111,117,110,100,46,10, + 32,32,32,32,32,32,32,32,70,114,62,0,0,0,114,60, + 0,0,0,114,95,0,0,0,114,191,0,0,0,122,9,116, + 114,121,105,110,103,32,123,125,41,1,90,9,118,101,114,98, + 111,115,105,116,121,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,41,22,114,32,0,0,0,114,39,0,0,0,114,35,0, + 0,0,114,1,0,0,0,114,45,0,0,0,114,235,0,0, + 0,114,40,0,0,0,114,26,1,0,0,218,11,95,102,105, + 108,108,95,99,97,99,104,101,114,5,0,0,0,114,29,1, + 0,0,114,96,0,0,0,114,28,1,0,0,114,28,0,0, + 0,114,25,1,0,0,114,44,0,0,0,114,23,1,0,0, + 114,46,0,0,0,114,121,0,0,0,114,135,0,0,0,114, + 167,0,0,0,114,163,0,0,0,41,14,114,107,0,0,0, + 114,126,0,0,0,114,186,0,0,0,90,12,105,115,95,110, + 97,109,101,115,112,97,99,101,90,11,116,97,105,108,95,109, + 111,100,117,108,101,114,154,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,241,0,0,0,114, + 172,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,171, 0,0,0,114,2,0,0,0,114,2,0,0,0,114,4,0, - 0,0,218,14,95,102,105,120,95,117,112,95,109,111,100,117, - 108,101,182,5,0,0,115,34,0,0,0,0,2,10,1,10, - 1,4,1,4,1,8,1,8,1,12,2,10,1,4,1,14, - 1,2,1,8,1,8,1,8,1,12,1,14,2,114,38,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,38,0,0,0,116,0,116,1, - 160,2,161,0,102,2,125,0,116,3,116,4,102,2,125,1, - 116,5,116,6,102,2,125,2,124,0,124,1,124,2,103,3, - 83,0,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,220,0,0,0,114,144,0,0, - 0,218,18,101,120,116,101,110,115,105,111,110,95,115,117,102, - 102,105,120,101,115,114,231,0,0,0,114,87,0,0,0,114, - 236,0,0,0,114,77,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,2,0,0,0,114,2, - 0,0,0,114,4,0,0,0,114,164,0,0,0,205,5,0, - 0,115,8,0,0,0,0,5,12,1,8,1,8,1,114,164, - 0,0,0,99,1,0,0,0,0,0,0,0,12,0,0,0, - 9,0,0,0,67,0,0,0,115,156,1,0,0,124,0,97, - 0,116,0,106,1,97,1,116,0,106,2,97,2,116,1,106, - 3,116,4,25,0,125,1,120,56,100,1,68,0,93,48,125, - 2,124,2,116,1,106,3,107,7,114,58,116,0,160,5,124, + 0,0,114,187,0,0,0,119,5,0,0,115,70,0,0,0, + 0,5,4,1,14,1,2,1,24,1,14,1,10,1,10,1, + 8,1,6,2,6,1,6,1,10,2,6,1,4,2,8,1, + 12,1,14,1,8,1,10,1,8,1,26,4,8,2,14,1, + 16,1,16,1,12,1,8,1,10,1,14,1,6,1,12,1, + 12,1,8,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,10,0,0,0,67,0,0, + 0,115,190,0,0,0,124,0,106,0,125,1,122,22,116,1, + 160,2,124,1,112,22,116,1,160,3,161,0,161,1,125,2, + 87,0,110,30,4,0,116,4,116,5,116,6,102,3,107,10, + 114,58,1,0,1,0,1,0,103,0,125,2,89,0,110,2, + 88,0,116,7,106,8,160,9,100,1,161,1,115,84,116,10, + 124,2,131,1,124,0,95,11,110,74,116,10,131,0,125,3, + 124,2,68,0,93,56,125,4,124,4,160,12,100,2,161,1, + 92,3,125,5,125,6,125,7,124,6,114,136,100,3,160,13, + 124,5,124,7,160,14,161,0,161,2,125,8,110,4,124,5, + 125,8,124,3,160,15,124,8,161,1,1,0,113,94,124,3, + 124,0,95,11,116,7,106,8,160,9,116,16,161,1,114,186, + 100,4,100,5,132,0,124,2,68,0,131,1,124,0,95,17, + 100,6,83,0,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,62,0,0,0,122,5,123,125,46,123,125,99,1,0, + 0,0,0,0,0,0,2,0,0,0,4,0,0,0,83,0, + 0,0,115,20,0,0,0,104,0,124,0,93,12,125,1,124, + 1,160,0,161,0,146,2,113,4,83,0,114,2,0,0,0, + 41,1,114,96,0,0,0,41,2,114,22,0,0,0,90,2, + 102,110,114,2,0,0,0,114,2,0,0,0,114,4,0,0, + 0,218,9,60,115,101,116,99,111,109,112,62,196,5,0,0, + 115,2,0,0,0,6,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,1,0,0,0,114, + 232,0,0,0,114,45,0,0,0,114,229,0,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,6,0,0,0,114,7,0,0,0,114,8,0, + 0,0,114,27,1,0,0,114,28,1,0,0,114,91,0,0, + 0,114,51,0,0,0,114,96,0,0,0,218,3,97,100,100, + 114,9,0,0,0,114,29,1,0,0,41,9,114,107,0,0, + 0,114,35,0,0,0,114,233,0,0,0,90,21,108,111,119, + 101,114,95,115,117,102,102,105,120,95,99,111,110,116,101,110, + 116,115,114,6,1,0,0,114,105,0,0,0,114,253,0,0, + 0,114,241,0,0,0,90,8,110,101,119,95,110,97,109,101, + 114,2,0,0,0,114,2,0,0,0,114,4,0,0,0,114, + 31,1,0,0,167,5,0,0,115,34,0,0,0,0,2,6, + 1,2,1,22,1,20,3,10,3,12,1,12,7,6,1,8, + 1,16,1,4,1,18,2,4,1,12,1,6,1,12,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,18,0,0, + 0,135,0,135,1,102,2,100,1,100,2,132,8,125,2,124, + 2,83,0,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,34,0,0,0,116,0,124,0,131,1,115,20, + 116,1,100,1,124,0,100,2,141,2,130,1,136,0,124,0, + 102,1,136,1,158,2,142,0,83,0,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,41,1,114,35,0, + 0,0,41,2,114,46,0,0,0,114,106,0,0,0,41,1, + 114,35,0,0,0,41,2,114,177,0,0,0,114,30,1,0, + 0,114,2,0,0,0,114,4,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,208,5,0,0,115,6,0,0,0,0,2, + 8,1,12,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,2,0,0, + 0,41,3,114,177,0,0,0,114,30,1,0,0,114,36,1, + 0,0,114,2,0,0,0,41,2,114,177,0,0,0,114,30, + 1,0,0,114,4,0,0,0,218,9,112,97,116,104,95,104, + 111,111,107,198,5,0,0,115,4,0,0,0,0,10,14,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,3,0,0,0,67,0,0,0,115,12,0,0,0, + 100,1,160,0,124,0,106,1,161,1,83,0,41,2,78,122, + 16,70,105,108,101,70,105,110,100,101,114,40,123,33,114,125, + 41,41,2,114,51,0,0,0,114,35,0,0,0,41,1,114, + 107,0,0,0,114,2,0,0,0,114,2,0,0,0,114,4, + 0,0,0,114,5,1,0,0,216,5,0,0,115,2,0,0, + 0,0,1,122,19,70,105,108,101,70,105,110,100,101,114,46, + 95,95,114,101,112,114,95,95,41,1,78,41,15,114,112,0, + 0,0,114,111,0,0,0,114,113,0,0,0,114,114,0,0, + 0,114,191,0,0,0,114,11,1,0,0,114,130,0,0,0, + 114,188,0,0,0,114,124,0,0,0,114,23,1,0,0,114, + 187,0,0,0,114,31,1,0,0,114,189,0,0,0,114,37, + 1,0,0,114,5,1,0,0,114,2,0,0,0,114,2,0, + 0,0,114,2,0,0,0,114,4,0,0,0,114,24,1,0, + 0,73,5,0,0,115,20,0,0,0,8,7,4,2,8,14, + 8,4,4,2,8,12,8,5,10,48,8,31,12,18,114,24, + 1,0,0,99,4,0,0,0,0,0,0,0,6,0,0,0, + 8,0,0,0,67,0,0,0,115,146,0,0,0,124,0,160, + 0,100,1,161,1,125,4,124,0,160,0,100,2,161,1,125, + 5,124,4,115,66,124,5,114,36,124,5,106,1,125,4,110, + 30,124,2,124,3,107,2,114,56,116,2,124,1,124,2,131, + 2,125,4,110,10,116,3,124,1,124,2,131,2,125,4,124, + 5,115,84,116,4,124,1,124,2,124,4,100,3,141,3,125, + 5,122,36,124,5,124,0,100,2,60,0,124,4,124,0,100, + 1,60,0,124,2,124,0,100,4,60,0,124,3,124,0,100, + 5,60,0,87,0,110,20,4,0,116,5,107,10,114,140,1, + 0,1,0,1,0,89,0,110,2,88,0,100,0,83,0,41, + 6,78,218,10,95,95,108,111,97,100,101,114,95,95,218,8, + 95,95,115,112,101,99,95,95,41,1,114,127,0,0,0,90, + 8,95,95,102,105,108,101,95,95,90,10,95,95,99,97,99, + 104,101,100,95,95,41,6,218,3,103,101,116,114,127,0,0, + 0,114,239,0,0,0,114,234,0,0,0,114,174,0,0,0, + 218,9,69,120,99,101,112,116,105,111,110,41,6,90,2,110, + 115,114,105,0,0,0,90,8,112,97,116,104,110,97,109,101, + 90,9,99,112,97,116,104,110,97,109,101,114,127,0,0,0, + 114,171,0,0,0,114,2,0,0,0,114,2,0,0,0,114, + 4,0,0,0,218,14,95,102,105,120,95,117,112,95,109,111, + 100,117,108,101,222,5,0,0,115,34,0,0,0,0,2,10, + 1,10,1,4,1,4,1,8,1,8,1,12,2,10,1,4, + 1,14,1,2,1,8,1,8,1,8,1,12,1,14,2,114, + 42,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,38,0,0,0,116,0, + 116,1,160,2,161,0,102,2,125,0,116,3,116,4,102,2, + 125,1,116,5,116,6,102,2,125,2,124,0,124,1,124,2, + 103,3,83,0,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,240,0,0,0,114,148, + 0,0,0,218,18,101,120,116,101,110,115,105,111,110,95,115, + 117,102,102,105,120,101,115,114,234,0,0,0,114,92,0,0, + 0,114,239,0,0,0,114,79,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,2,0,0,0, + 114,2,0,0,0,114,4,0,0,0,114,168,0,0,0,245, + 5,0,0,115,8,0,0,0,0,5,12,1,8,1,8,1, + 114,168,0,0,0,99,1,0,0,0,0,0,0,0,12,0, + 0,0,9,0,0,0,67,0,0,0,115,178,1,0,0,124, + 0,97,0,116,0,106,1,97,1,116,0,106,2,97,2,116, + 1,106,3,116,4,25,0,125,1,100,1,68,0,93,48,125, + 2,124,2,116,1,106,3,107,7,114,56,116,0,160,5,124, 2,161,1,125,3,110,10,116,1,106,3,124,2,25,0,125, - 3,116,6,124,1,124,2,124,3,131,3,1,0,113,32,87, - 0,100,2,100,3,103,1,102,2,100,4,100,5,100,3,103, - 2,102,2,102,2,125,4,120,118,124,4,68,0,93,102,92, - 2,125,5,125,6,116,7,100,6,100,7,132,0,124,6,68, - 0,131,1,131,1,115,142,116,8,130,1,124,6,100,8,25, - 0,125,7,124,5,116,1,106,3,107,6,114,174,116,1,106, - 3,124,5,25,0,125,8,80,0,113,112,121,16,116,0,160, - 5,124,5,161,1,125,8,80,0,87,0,113,112,4,0,116, - 9,107,10,114,212,1,0,1,0,1,0,119,112,89,0,113, - 112,88,0,113,112,87,0,116,9,100,9,131,1,130,1,116, - 6,124,1,100,10,124,8,131,3,1,0,116,6,124,1,100, - 11,124,7,131,3,1,0,116,6,124,1,100,12,100,13,160, - 10,124,6,161,1,131,3,1,0,116,0,160,5,100,14,161, - 1,125,9,116,6,124,1,100,14,124,9,131,3,1,0,116, - 0,160,5,100,15,161,1,125,10,116,6,124,1,100,15,124, - 10,131,3,1,0,124,5,100,4,107,2,144,1,114,88,116, - 0,160,5,100,16,161,1,125,11,116,6,124,1,100,17,124, - 11,131,3,1,0,116,6,124,1,100,18,116,11,131,0,131, - 3,1,0,116,12,160,13,116,2,160,14,161,0,161,1,1, - 0,124,5,100,4,107,2,144,1,114,152,116,15,160,16,100, - 19,161,1,1,0,100,20,116,12,107,6,144,1,114,152,100, - 21,116,17,95,18,100,22,83,0,41,23,122,205,83,101,116, - 117,112,32,116,104,101,32,112,97,116,104,45,98,97,115,101, - 100,32,105,109,112,111,114,116,101,114,115,32,102,111,114,32, - 105,109,112,111,114,116,108,105,98,32,98,121,32,105,109,112, - 111,114,116,105,110,103,32,110,101,101,100,101,100,10,32,32, - 32,32,98,117,105,108,116,45,105,110,32,109,111,100,117,108, - 101,115,32,97,110,100,32,105,110,106,101,99,116,105,110,103, - 32,116,104,101,109,32,105,110,116,111,32,116,104,101,32,103, - 108,111,98,97,108,32,110,97,109,101,115,112,97,99,101,46, - 10,10,32,32,32,32,79,116,104,101,114,32,99,111,109,112, - 111,110,101,110,116,115,32,97,114,101,32,101,120,116,114,97, - 99,116,101,100,32,102,114,111,109,32,116,104,101,32,99,111, - 114,101,32,98,111,111,116,115,116,114,97,112,32,109,111,100, - 117,108,101,46,10,10,32,32,32,32,41,4,114,51,0,0, - 0,114,62,0,0,0,218,8,98,117,105,108,116,105,110,115, - 114,141,0,0,0,90,5,112,111,115,105,120,250,1,47,90, - 2,110,116,250,1,92,99,1,0,0,0,0,0,0,0,2, - 0,0,0,3,0,0,0,115,0,0,0,115,26,0,0,0, - 124,0,93,18,125,1,116,0,124,1,131,1,100,0,107,2, - 86,0,1,0,113,2,100,1,83,0,41,2,114,29,0,0, - 0,78,41,1,114,31,0,0,0,41,2,114,22,0,0,0, - 114,80,0,0,0,114,2,0,0,0,114,2,0,0,0,114, - 4,0,0,0,114,239,0,0,0,241,5,0,0,115,2,0, - 0,0,4,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, - 61,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,1,0,0,0,114,25,0,0,0,114,21, - 0,0,0,114,30,0,0,0,90,7,95,116,104,114,101,97, - 100,90,8,95,119,101,97,107,114,101,102,90,6,119,105,110, - 114,101,103,114,172,0,0,0,114,5,0,0,0,122,4,46, - 112,121,119,122,6,95,100,46,112,121,100,84,78,41,19,114, - 117,0,0,0,114,6,0,0,0,114,144,0,0,0,114,251, - 0,0,0,114,108,0,0,0,90,18,95,98,117,105,108,116, - 105,110,95,102,114,111,109,95,110,97,109,101,114,112,0,0, - 0,218,3,97,108,108,114,152,0,0,0,114,102,0,0,0, - 114,26,0,0,0,114,11,0,0,0,114,241,0,0,0,114, - 148,0,0,0,114,39,1,0,0,114,87,0,0,0,114,166, - 0,0,0,114,171,0,0,0,114,175,0,0,0,41,12,218, - 17,95,98,111,111,116,115,116,114,97,112,95,109,111,100,117, - 108,101,90,11,115,101,108,102,95,109,111,100,117,108,101,90, - 12,98,117,105,108,116,105,110,95,110,97,109,101,90,14,98, - 117,105,108,116,105,110,95,109,111,100,117,108,101,90,10,111, - 115,95,100,101,116,97,105,108,115,90,10,98,117,105,108,116, - 105,110,95,111,115,114,21,0,0,0,114,25,0,0,0,90, - 9,111,115,95,109,111,100,117,108,101,90,13,116,104,114,101, - 97,100,95,109,111,100,117,108,101,90,14,119,101,97,107,114, - 101,102,95,109,111,100,117,108,101,90,13,119,105,110,114,101, - 103,95,109,111,100,117,108,101,114,2,0,0,0,114,2,0, - 0,0,114,4,0,0,0,218,6,95,115,101,116,117,112,216, - 5,0,0,115,76,0,0,0,0,8,4,1,6,1,6,3, - 10,1,10,1,10,1,12,2,10,1,16,3,22,1,14,2, - 22,1,8,1,10,1,10,1,4,2,2,1,10,1,6,1, - 14,1,12,2,8,1,12,1,12,1,18,3,10,1,12,3, - 10,1,12,3,10,1,10,1,12,3,14,1,14,1,10,1, - 10,1,10,1,114,45,1,0,0,99,1,0,0,0,0,0, - 0,0,2,0,0,0,4,0,0,0,67,0,0,0,115,50, - 0,0,0,116,0,124,0,131,1,1,0,116,1,131,0,125, - 1,116,2,106,3,160,4,116,5,106,6,124,1,142,0,103, - 1,161,1,1,0,116,2,106,7,160,8,116,9,161,1,1, - 0,100,1,83,0,41,2,122,41,73,110,115,116,97,108,108, - 32,116,104,101,32,112,97,116,104,45,98,97,115,101,100,32, - 105,109,112,111,114,116,32,99,111,109,112,111,110,101,110,116, - 115,46,78,41,10,114,45,1,0,0,114,164,0,0,0,114, - 6,0,0,0,114,12,1,0,0,114,148,0,0,0,114,20, - 1,0,0,114,33,1,0,0,218,9,109,101,116,97,95,112, - 97,116,104,114,166,0,0,0,114,6,1,0,0,41,2,114, - 44,1,0,0,90,17,115,117,112,112,111,114,116,101,100,95, - 108,111,97,100,101,114,115,114,2,0,0,0,114,2,0,0, - 0,114,4,0,0,0,218,8,95,105,110,115,116,97,108,108, - 24,6,0,0,115,8,0,0,0,0,2,8,1,6,1,20, - 1,114,47,1,0,0,41,1,114,47,0,0,0,41,1,78, - 41,3,78,78,78,41,2,114,61,0,0,0,114,61,0,0, - 0,41,1,84,41,1,78,41,1,78,41,61,114,110,0,0, - 0,114,10,0,0,0,90,37,95,67,65,83,69,95,73,78, - 83,69,78,83,73,84,73,86,69,95,80,76,65,84,70,79, - 82,77,83,95,66,89,84,69,83,95,75,69,89,114,9,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, - 57,0,0,0,218,4,116,121,112,101,218,8,95,95,99,111, - 100,101,95,95,114,143,0,0,0,114,15,0,0,0,114,130, - 0,0,0,114,14,0,0,0,114,18,0,0,0,114,210,0, - 0,0,114,76,0,0,0,114,75,0,0,0,114,87,0,0, - 0,114,77,0,0,0,90,23,68,69,66,85,71,95,66,89, - 84,69,67,79,68,69,95,83,85,70,70,73,88,69,83,90, - 27,79,80,84,73,77,73,90,69,68,95,66,89,84,69,67, - 79,68,69,95,83,85,70,70,73,88,69,83,114,82,0,0, - 0,114,88,0,0,0,114,94,0,0,0,114,98,0,0,0, - 114,100,0,0,0,114,119,0,0,0,114,126,0,0,0,114, - 134,0,0,0,114,138,0,0,0,114,140,0,0,0,114,146, - 0,0,0,114,151,0,0,0,114,153,0,0,0,114,158,0, - 0,0,218,6,111,98,106,101,99,116,114,165,0,0,0,114, - 170,0,0,0,114,171,0,0,0,114,186,0,0,0,114,196, - 0,0,0,114,213,0,0,0,114,231,0,0,0,114,236,0, - 0,0,114,241,0,0,0,114,220,0,0,0,114,242,0,0, - 0,114,4,1,0,0,114,6,1,0,0,114,20,1,0,0, - 114,38,1,0,0,114,164,0,0,0,114,45,1,0,0,114, - 47,1,0,0,114,2,0,0,0,114,2,0,0,0,114,2, - 0,0,0,114,4,0,0,0,218,8,60,109,111,100,117,108, - 101,62,8,0,0,0,115,118,0,0,0,4,15,4,1,4, - 1,2,1,6,3,8,17,8,5,8,5,8,6,8,12,8, - 10,8,9,8,5,8,7,10,22,10,127,0,5,16,1,12, - 2,4,1,4,2,6,2,6,2,8,2,16,45,8,34,8, - 19,8,12,8,12,8,28,8,17,8,33,8,28,8,24,10, - 13,10,10,10,11,8,14,6,3,4,1,14,67,14,64,14, - 29,16,127,0,17,14,71,18,45,18,26,4,3,18,53,14, - 60,14,42,14,127,0,7,14,127,0,22,10,23,8,11,8, - 64, + 3,116,6,124,1,124,2,124,3,131,3,1,0,113,30,100, + 2,100,3,103,1,102,2,100,4,100,5,100,3,103,2,102, + 2,102,2,125,4,124,4,68,0,93,110,92,2,125,5,125, + 6,116,7,100,6,100,7,132,0,124,6,68,0,131,1,131, + 1,115,136,116,8,130,1,124,6,100,8,25,0,125,7,124, + 5,116,1,106,3,107,6,114,170,116,1,106,3,124,5,25, + 0,125,8,1,0,113,226,113,106,122,20,116,0,160,5,124, + 5,161,1,125,8,87,0,1,0,113,226,87,0,113,106,4, + 0,116,9,107,10,114,214,1,0,1,0,1,0,89,0,113, + 106,89,0,113,106,88,0,113,106,116,9,100,9,131,1,130, + 1,116,6,124,1,100,10,124,8,131,3,1,0,116,6,124, + 1,100,11,124,7,131,3,1,0,116,6,124,1,100,12,100, + 13,160,10,124,6,161,1,131,3,1,0,116,6,124,1,100, + 14,100,15,100,16,132,0,124,6,68,0,131,1,131,3,1, + 0,116,0,160,5,100,17,161,1,125,9,116,6,124,1,100, + 17,124,9,131,3,1,0,116,0,160,5,100,18,161,1,125, + 10,116,6,124,1,100,18,124,10,131,3,1,0,124,5,100, + 4,107,2,144,1,114,110,116,0,160,5,100,19,161,1,125, + 11,116,6,124,1,100,20,124,11,131,3,1,0,116,6,124, + 1,100,21,116,11,131,0,131,3,1,0,116,12,160,13,116, + 2,160,14,161,0,161,1,1,0,124,5,100,4,107,2,144, + 1,114,174,116,15,160,16,100,22,161,1,1,0,100,23,116, + 12,107,6,144,1,114,174,100,24,116,17,95,18,100,25,83, + 0,41,26,122,205,83,101,116,117,112,32,116,104,101,32,112, + 97,116,104,45,98,97,115,101,100,32,105,109,112,111,114,116, + 101,114,115,32,102,111,114,32,105,109,112,111,114,116,108,105, + 98,32,98,121,32,105,109,112,111,114,116,105,110,103,32,110, + 101,101,100,101,100,10,32,32,32,32,98,117,105,108,116,45, + 105,110,32,109,111,100,117,108,101,115,32,97,110,100,32,105, + 110,106,101,99,116,105,110,103,32,116,104,101,109,32,105,110, + 116,111,32,116,104,101,32,103,108,111,98,97,108,32,110,97, + 109,101,115,112,97,99,101,46,10,10,32,32,32,32,79,116, + 104,101,114,32,99,111,109,112,111,110,101,110,116,115,32,97, + 114,101,32,101,120,116,114,97,99,116,101,100,32,102,114,111, + 109,32,116,104,101,32,99,111,114,101,32,98,111,111,116,115, + 116,114,97,112,32,109,111,100,117,108,101,46,10,10,32,32, + 32,32,41,4,114,53,0,0,0,114,65,0,0,0,218,8, + 98,117,105,108,116,105,110,115,114,145,0,0,0,90,5,112, + 111,115,105,120,250,1,47,90,2,110,116,250,1,92,99,1, + 0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,115, + 0,0,0,115,26,0,0,0,124,0,93,18,125,1,116,0, + 124,1,131,1,100,0,107,2,86,0,1,0,113,2,100,1, + 83,0,41,2,114,29,0,0,0,78,41,1,114,31,0,0, + 0,41,2,114,22,0,0,0,114,85,0,0,0,114,2,0, + 0,0,114,2,0,0,0,114,4,0,0,0,114,243,0,0, + 0,25,6,0,0,115,2,0,0,0,4,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,63,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,1,0,0, + 0,114,25,0,0,0,114,21,0,0,0,114,30,0,0,0, + 114,48,0,0,0,99,1,0,0,0,0,0,0,0,2,0, + 0,0,4,0,0,0,83,0,0,0,115,22,0,0,0,104, + 0,124,0,93,14,125,1,100,0,124,1,155,0,157,2,146, + 2,113,4,83,0,41,1,114,64,0,0,0,114,2,0,0, + 0,41,2,114,22,0,0,0,218,1,115,114,2,0,0,0, + 114,2,0,0,0,114,4,0,0,0,114,32,1,0,0,41, + 6,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,115,101,116, + 99,111,109,112,62,90,7,95,116,104,114,101,97,100,90,8, + 95,119,101,97,107,114,101,102,90,6,119,105,110,114,101,103, + 114,176,0,0,0,114,5,0,0,0,122,4,46,112,121,119, + 122,6,95,100,46,112,121,100,84,78,41,19,114,121,0,0, + 0,114,6,0,0,0,114,148,0,0,0,114,255,0,0,0, + 114,112,0,0,0,90,18,95,98,117,105,108,116,105,110,95, + 102,114,111,109,95,110,97,109,101,114,116,0,0,0,218,3, + 97,108,108,114,156,0,0,0,114,106,0,0,0,114,26,0, + 0,0,114,11,0,0,0,114,245,0,0,0,114,152,0,0, + 0,114,43,1,0,0,114,92,0,0,0,114,170,0,0,0, + 114,175,0,0,0,114,179,0,0,0,41,12,218,17,95,98, + 111,111,116,115,116,114,97,112,95,109,111,100,117,108,101,90, + 11,115,101,108,102,95,109,111,100,117,108,101,90,12,98,117, + 105,108,116,105,110,95,110,97,109,101,90,14,98,117,105,108, + 116,105,110,95,109,111,100,117,108,101,90,10,111,115,95,100, + 101,116,97,105,108,115,90,10,98,117,105,108,116,105,110,95, + 111,115,114,21,0,0,0,114,25,0,0,0,90,9,111,115, + 95,109,111,100,117,108,101,90,13,116,104,114,101,97,100,95, + 109,111,100,117,108,101,90,14,119,101,97,107,114,101,102,95, + 109,111,100,117,108,101,90,13,119,105,110,114,101,103,95,109, + 111,100,117,108,101,114,2,0,0,0,114,2,0,0,0,114, + 4,0,0,0,218,6,95,115,101,116,117,112,0,6,0,0, + 115,78,0,0,0,0,8,4,1,6,1,6,3,10,1,8, + 1,10,1,12,2,10,1,14,3,22,1,12,2,22,1,8, + 1,10,1,10,1,6,2,2,1,10,1,10,1,14,1,12, + 2,8,1,12,1,12,1,18,1,22,3,10,1,12,3,10, + 1,12,3,10,1,10,1,12,3,14,1,14,1,10,1,10, + 1,10,1,114,50,1,0,0,99,1,0,0,0,0,0,0, + 0,2,0,0,0,4,0,0,0,67,0,0,0,115,50,0, + 0,0,116,0,124,0,131,1,1,0,116,1,131,0,125,1, + 116,2,106,3,160,4,116,5,106,6,124,1,142,0,103,1, + 161,1,1,0,116,2,106,7,160,8,116,9,161,1,1,0, + 100,1,83,0,41,2,122,41,73,110,115,116,97,108,108,32, + 116,104,101,32,112,97,116,104,45,98,97,115,101,100,32,105, + 109,112,111,114,116,32,99,111,109,112,111,110,101,110,116,115, + 46,78,41,10,114,50,1,0,0,114,168,0,0,0,114,6, + 0,0,0,114,16,1,0,0,114,152,0,0,0,114,24,1, + 0,0,114,37,1,0,0,218,9,109,101,116,97,95,112,97, + 116,104,114,170,0,0,0,114,10,1,0,0,41,2,114,49, + 1,0,0,90,17,115,117,112,112,111,114,116,101,100,95,108, + 111,97,100,101,114,115,114,2,0,0,0,114,2,0,0,0, + 114,4,0,0,0,218,8,95,105,110,115,116,97,108,108,65, + 6,0,0,115,8,0,0,0,0,2,8,1,6,1,20,1, + 114,52,1,0,0,41,1,114,50,0,0,0,41,1,78,41, + 3,78,78,78,41,2,114,63,0,0,0,114,63,0,0,0, + 41,1,84,41,1,78,41,1,78,41,62,114,114,0,0,0, + 114,10,0,0,0,90,37,95,67,65,83,69,95,73,78,83, + 69,78,83,73,84,73,86,69,95,80,76,65,84,70,79,82, + 77,83,95,66,89,84,69,83,95,75,69,89,114,9,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,49, + 0,0,0,114,59,0,0,0,218,4,116,121,112,101,218,8, + 95,95,99,111,100,101,95,95,114,147,0,0,0,114,15,0, + 0,0,114,134,0,0,0,114,14,0,0,0,114,18,0,0, + 0,114,214,0,0,0,114,82,0,0,0,114,78,0,0,0, + 114,92,0,0,0,114,79,0,0,0,90,23,68,69,66,85, + 71,95,66,89,84,69,67,79,68,69,95,83,85,70,70,73, + 88,69,83,90,27,79,80,84,73,77,73,90,69,68,95,66, + 89,84,69,67,79,68,69,95,83,85,70,70,73,88,69,83, + 114,88,0,0,0,114,93,0,0,0,114,99,0,0,0,114, + 102,0,0,0,114,104,0,0,0,114,123,0,0,0,114,130, + 0,0,0,114,138,0,0,0,114,142,0,0,0,114,144,0, + 0,0,114,150,0,0,0,114,155,0,0,0,114,157,0,0, + 0,114,162,0,0,0,218,6,111,98,106,101,99,116,114,169, + 0,0,0,114,174,0,0,0,114,175,0,0,0,114,190,0, + 0,0,114,200,0,0,0,114,217,0,0,0,114,234,0,0, + 0,114,239,0,0,0,114,245,0,0,0,114,240,0,0,0, + 114,246,0,0,0,114,8,1,0,0,114,10,1,0,0,114, + 24,1,0,0,114,42,1,0,0,114,168,0,0,0,114,50, + 1,0,0,114,52,1,0,0,114,2,0,0,0,114,2,0, + 0,0,114,2,0,0,0,114,4,0,0,0,218,8,60,109, + 111,100,117,108,101,62,8,0,0,0,115,120,0,0,0,4, + 15,4,1,4,1,2,1,6,3,8,17,8,5,8,5,8, + 6,8,12,8,10,8,9,8,5,8,7,8,9,10,22,10, + 127,0,7,16,1,12,2,4,1,4,2,6,2,6,2,8, + 2,16,71,8,40,8,19,8,12,8,12,8,28,8,17,8, + 33,8,28,8,24,10,13,10,10,10,11,8,14,6,3,4, + 1,14,67,14,64,14,29,16,127,0,17,14,68,18,45,18, + 26,4,3,18,53,14,60,14,42,14,127,0,7,14,127,0, + 22,10,23,8,11,8,65, }; diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index da6d032bce410f..e82959be086455 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -5,7 +5,7 @@ static void *opcode_targets[256] = { &&TARGET_ROT_THREE, &&TARGET_DUP_TOP, &&TARGET_DUP_TOP_TWO, - &&_unknown_opcode, + &&TARGET_ROT_FOUR, &&_unknown_opcode, &&_unknown_opcode, &&TARGET_NOP, @@ -52,8 +52,8 @@ static void *opcode_targets[256] = { &&TARGET_GET_AITER, &&TARGET_GET_ANEXT, &&TARGET_BEFORE_ASYNC_WITH, - &&_unknown_opcode, - &&_unknown_opcode, + &&TARGET_BEGIN_FINALLY, + &&TARGET_END_ASYNC_FOR, &&TARGET_INPLACE_ADD, &&TARGET_INPLACE_SUBTRACT, &&TARGET_INPLACE_MULTIPLY, @@ -79,7 +79,7 @@ static void *opcode_targets[256] = { &&TARGET_INPLACE_AND, &&TARGET_INPLACE_XOR, &&TARGET_INPLACE_OR, - &&TARGET_BREAK_LOOP, + &&_unknown_opcode, &&TARGET_WITH_CLEANUP_START, &&TARGET_WITH_CLEANUP_FINISH, &&TARGET_RETURN_VALUE, @@ -118,9 +118,9 @@ static void *opcode_targets[256] = { &&TARGET_LOAD_GLOBAL, &&_unknown_opcode, &&_unknown_opcode, - &&TARGET_CONTINUE_LOOP, - &&TARGET_SETUP_LOOP, - &&TARGET_SETUP_EXCEPT, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, &&TARGET_SETUP_FINALLY, &&_unknown_opcode, &&TARGET_LOAD_FAST, @@ -161,8 +161,8 @@ static void *opcode_targets[256] = { &&_unknown_opcode, &&TARGET_LOAD_METHOD, &&TARGET_CALL_METHOD, - &&_unknown_opcode, - &&_unknown_opcode, + &&TARGET_CALL_FINALLY, + &&TARGET_POP_FINALLY, &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, diff --git a/Python/peephole.c b/Python/peephole.c index 76a0edbcc2bcac..16fd5009bf1d8c 100644 --- a/Python/peephole.c +++ b/Python/peephole.c @@ -13,7 +13,7 @@ #define UNCONDITIONAL_JUMP(op) (op==JUMP_ABSOLUTE || op==JUMP_FORWARD) #define CONDITIONAL_JUMP(op) (op==POP_JUMP_IF_FALSE || op==POP_JUMP_IF_TRUE \ || op==JUMP_IF_FALSE_OR_POP || op==JUMP_IF_TRUE_OR_POP) -#define ABSOLUTE_JUMP(op) (op==JUMP_ABSOLUTE || op==CONTINUE_LOOP \ +#define ABSOLUTE_JUMP(op) (op==JUMP_ABSOLUTE \ || op==POP_JUMP_IF_FALSE || op==POP_JUMP_IF_TRUE \ || 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) @@ -185,12 +185,10 @@ markblocks(_Py_CODEUNIT *code, Py_ssize_t len) case POP_JUMP_IF_FALSE: case POP_JUMP_IF_TRUE: case JUMP_ABSOLUTE: - case CONTINUE_LOOP: - case SETUP_LOOP: - case SETUP_EXCEPT: case SETUP_FINALLY: case SETUP_WITH: case SETUP_ASYNC_WITH: + case CALL_FINALLY: j = GETJUMPTGT(code, i); assert(j < len); blocks[j] = 1; @@ -373,15 +371,8 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, /* Replace jumps to unconditional jumps */ case POP_JUMP_IF_FALSE: case POP_JUMP_IF_TRUE: - case FOR_ITER: case JUMP_FORWARD: case JUMP_ABSOLUTE: - case CONTINUE_LOOP: - case SETUP_LOOP: - case SETUP_EXCEPT: - case SETUP_FINALLY: - case SETUP_WITH: - case SETUP_ASYNC_WITH: h = GETJUMPTGT(codestr, i); tgt = find_op(codestr, h); /* Replace JUMP_* to a RETURN into just a RETURN */ @@ -407,7 +398,21 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, /* Remove unreachable ops after RETURN */ case RETURN_VALUE: h = i + 1; - while (h < codelen && ISBASICBLOCK(blocks, i, h)) { + /* END_FINALLY should be kept since it denotes the end of + the 'finally' block in frame_setlineno() in frameobject.c. + SETUP_FINALLY should be kept for balancing. + */ + while (h < codelen && ISBASICBLOCK(blocks, i, h) && + _Py_OPCODE(codestr[h]) != END_FINALLY) + { + if (_Py_OPCODE(codestr[h]) == SETUP_FINALLY) { + while (h > i + 1 && + _Py_OPCODE(codestr[h - 1]) == EXTENDED_ARG) + { + h--; + } + break; + } h++; } if (h > i + 1) { @@ -452,7 +457,6 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, case NOP:continue; case JUMP_ABSOLUTE: - case CONTINUE_LOOP: case POP_JUMP_IF_FALSE: case POP_JUMP_IF_TRUE: case JUMP_IF_FALSE_OR_POP: @@ -462,11 +466,10 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, case FOR_ITER: case JUMP_FORWARD: - case SETUP_LOOP: - case SETUP_EXCEPT: case SETUP_FINALLY: case SETUP_WITH: case SETUP_ASYNC_WITH: + case CALL_FINALLY: j = blocks[j / sizeof(_Py_CODEUNIT) + i + 1] - blocks[i] - 1; j *= sizeof(_Py_CODEUNIT); break; diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index f5699de4f18900..0eb4cc862a14a5 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -685,9 +685,6 @@ _Py_InitializeCore(const _PyCoreConfig *core_config) _Py_ReadyTypes(); - if (!_PyFrame_Init()) - return _Py_INIT_ERR("can't init frames"); - if (!_PyLong_Init()) return _Py_INIT_ERR("can't init longs"); diff --git a/Python/pystate.c b/Python/pystate.c index d9dc0cd37b5fff..161ea573d4e8af 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -1133,6 +1133,352 @@ PyGILState_Release(PyGILState_STATE oldstate) } +/**************************/ +/* cross-interpreter data */ +/**************************/ + +/* cross-interpreter data */ + +crossinterpdatafunc _PyCrossInterpreterData_Lookup(PyObject *); + +/* This is a separate func from _PyCrossInterpreterData_Lookup in order + to keep the registry code separate. */ +static crossinterpdatafunc +_lookup_getdata(PyObject *obj) +{ + crossinterpdatafunc getdata = _PyCrossInterpreterData_Lookup(obj); + if (getdata == NULL && PyErr_Occurred() == 0) + PyErr_Format(PyExc_ValueError, + "%S does not support cross-interpreter data", obj); + return getdata; +} + +int +_PyObject_CheckCrossInterpreterData(PyObject *obj) +{ + crossinterpdatafunc getdata = _lookup_getdata(obj); + if (getdata == NULL) { + return -1; + } + return 0; +} + +static int +_check_xidata(_PyCrossInterpreterData *data) +{ + // data->data can be anything, including NULL, so we don't check it. + + // data->obj may be NULL, so we don't check it. + + if (data->interp < 0) { + PyErr_SetString(PyExc_SystemError, "missing interp"); + return -1; + } + + if (data->new_object == NULL) { + PyErr_SetString(PyExc_SystemError, "missing new_object func"); + return -1; + } + + // data->free may be NULL, so we don't check it. + + return 0; +} + +int +_PyObject_GetCrossInterpreterData(PyObject *obj, _PyCrossInterpreterData *data) +{ + PyThreadState *tstate = PyThreadState_Get(); + // PyThreadState_Get() aborts if lookup fails, so we don't need + // to check the result for NULL. + PyInterpreterState *interp = tstate->interp; + + // Reset data before re-populating. + *data = (_PyCrossInterpreterData){0}; + data->free = PyMem_RawFree; // Set a default that may be overridden. + + // Call the "getdata" func for the object. + Py_INCREF(obj); + crossinterpdatafunc getdata = _lookup_getdata(obj); + if (getdata == NULL) { + Py_DECREF(obj); + return -1; + } + int res = getdata(obj, data); + Py_DECREF(obj); + if (res != 0) { + return -1; + } + + // Fill in the blanks and validate the result. + data->interp = interp->id; + if (_check_xidata(data) != 0) { + _PyCrossInterpreterData_Release(data); + return -1; + } + + return 0; +} + +static void +_release_xidata(void *arg) +{ + _PyCrossInterpreterData *data = (_PyCrossInterpreterData *)arg; + if (data->free != NULL) { + data->free(data->data); + } + Py_XDECREF(data->obj); +} + +static void +_call_in_interpreter(PyInterpreterState *interp, + void (*func)(void *), void *arg) +{ + /* We would use Py_AddPendingCall() if it weren't specific to the + * main interpreter (see bpo-33608). In the meantime we take a + * naive approach. + */ + PyThreadState *save_tstate = NULL; + if (interp != PyThreadState_Get()->interp) { + // XXX Using the "head" thread isn't strictly correct. + PyThreadState *tstate = PyInterpreterState_ThreadHead(interp); + // XXX Possible GILState issues? + save_tstate = PyThreadState_Swap(tstate); + } + + func(arg); + + // Switch back. + if (save_tstate != NULL) { + PyThreadState_Swap(save_tstate); + } +} + +void +_PyCrossInterpreterData_Release(_PyCrossInterpreterData *data) +{ + if (data->data == NULL && data->obj == NULL) { + // Nothing to release! + return; + } + + // Switch to the original interpreter. + PyInterpreterState *interp = _PyInterpreterState_LookUpID(data->interp); + if (interp == NULL) { + // The intepreter was already destroyed. + if (data->free != NULL) { + // XXX Someone leaked some memory... + } + return; + } + + // "Release" the data and/or the object. + _call_in_interpreter(interp, _release_xidata, data); +} + +PyObject * +_PyCrossInterpreterData_NewObject(_PyCrossInterpreterData *data) +{ + return data->new_object(data); +} + +/* registry of {type -> crossinterpdatafunc} */ + +/* For now we use a global registry of shareable classes. An + alternative would be to add a tp_* slot for a class's + crossinterpdatafunc. It would be simpler and more efficient. */ + +static int +_register_xidata(PyTypeObject *cls, crossinterpdatafunc getdata) +{ + // Note that we effectively replace already registered classes + // rather than failing. + struct _xidregitem *newhead = PyMem_RawMalloc(sizeof(struct _xidregitem)); + if (newhead == NULL) + return -1; + newhead->cls = cls; + newhead->getdata = getdata; + newhead->next = _PyRuntime.xidregistry.head; + _PyRuntime.xidregistry.head = newhead; + return 0; +} + +static void _register_builtins_for_crossinterpreter_data(void); + +int +_PyCrossInterpreterData_Register_Class(PyTypeObject *cls, + crossinterpdatafunc getdata) +{ + if (!PyType_Check(cls)) { + PyErr_Format(PyExc_ValueError, "only classes may be registered"); + return -1; + } + if (getdata == NULL) { + PyErr_Format(PyExc_ValueError, "missing 'getdata' func"); + return -1; + } + + // Make sure the class isn't ever deallocated. + Py_INCREF((PyObject *)cls); + + PyThread_acquire_lock(_PyRuntime.xidregistry.mutex, WAIT_LOCK); + if (_PyRuntime.xidregistry.head == NULL) { + _register_builtins_for_crossinterpreter_data(); + } + int res = _register_xidata(cls, getdata); + PyThread_release_lock(_PyRuntime.xidregistry.mutex); + return res; +} + +/* Cross-interpreter objects are looked up by exact match on the class. + We can reassess this policy when we move from a global registry to a + tp_* slot. */ + +crossinterpdatafunc +_PyCrossInterpreterData_Lookup(PyObject *obj) +{ + PyObject *cls = PyObject_Type(obj); + crossinterpdatafunc getdata = NULL; + PyThread_acquire_lock(_PyRuntime.xidregistry.mutex, WAIT_LOCK); + struct _xidregitem *cur = _PyRuntime.xidregistry.head; + if (cur == NULL) { + _register_builtins_for_crossinterpreter_data(); + cur = _PyRuntime.xidregistry.head; + } + for(; cur != NULL; cur = cur->next) { + if (cur->cls == (PyTypeObject *)cls) { + getdata = cur->getdata; + break; + } + } + Py_DECREF(cls); + PyThread_release_lock(_PyRuntime.xidregistry.mutex); + return getdata; +} + +/* cross-interpreter data for builtin types */ + +struct _shared_bytes_data { + char *bytes; + Py_ssize_t len; +}; + +static PyObject * +_new_bytes_object(_PyCrossInterpreterData *data) +{ + struct _shared_bytes_data *shared = (struct _shared_bytes_data *)(data->data); + return PyBytes_FromStringAndSize(shared->bytes, shared->len); +} + +static int +_bytes_shared(PyObject *obj, _PyCrossInterpreterData *data) +{ + struct _shared_bytes_data *shared = PyMem_NEW(struct _shared_bytes_data, 1); + if (PyBytes_AsStringAndSize(obj, &shared->bytes, &shared->len) < 0) { + return -1; + } + data->data = (void *)shared; + Py_INCREF(obj); + data->obj = obj; // Will be "released" (decref'ed) when data released. + data->new_object = _new_bytes_object; + data->free = PyMem_Free; + return 0; +} + +struct _shared_str_data { + int kind; + const void *buffer; + Py_ssize_t len; +}; + +static PyObject * +_new_str_object(_PyCrossInterpreterData *data) +{ + struct _shared_str_data *shared = (struct _shared_str_data *)(data->data); + return PyUnicode_FromKindAndData(shared->kind, shared->buffer, shared->len); +} + +static int +_str_shared(PyObject *obj, _PyCrossInterpreterData *data) +{ + struct _shared_str_data *shared = PyMem_NEW(struct _shared_str_data, 1); + shared->kind = PyUnicode_KIND(obj); + shared->buffer = PyUnicode_DATA(obj); + shared->len = PyUnicode_GET_LENGTH(obj) - 1; + data->data = (void *)shared; + Py_INCREF(obj); + data->obj = obj; // Will be "released" (decref'ed) when data released. + data->new_object = _new_str_object; + data->free = PyMem_Free; + return 0; +} + +static PyObject * +_new_long_object(_PyCrossInterpreterData *data) +{ + return PyLong_FromLongLong((int64_t)(data->data)); +} + +static int +_long_shared(PyObject *obj, _PyCrossInterpreterData *data) +{ + int64_t value = PyLong_AsLongLong(obj); + if (value == -1 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + PyErr_SetString(PyExc_OverflowError, "try sending as bytes"); + } + return -1; + } + data->data = (void *)value; + data->obj = NULL; + data->new_object = _new_long_object; + data->free = NULL; + return 0; +} + +static PyObject * +_new_none_object(_PyCrossInterpreterData *data) +{ + // XXX Singleton refcounts are problematic across interpreters... + Py_INCREF(Py_None); + return Py_None; +} + +static int +_none_shared(PyObject *obj, _PyCrossInterpreterData *data) +{ + data->data = NULL; + // data->obj remains NULL + data->new_object = _new_none_object; + data->free = NULL; // There is nothing to free. + return 0; +} + +static void +_register_builtins_for_crossinterpreter_data(void) +{ + // None + if (_register_xidata((PyTypeObject *)PyObject_Type(Py_None), _none_shared) != 0) { + Py_FatalError("could not register None for cross-interpreter sharing"); + } + + // int + if (_register_xidata(&PyLong_Type, _long_shared) != 0) { + Py_FatalError("could not register int for cross-interpreter sharing"); + } + + // bytes + if (_register_xidata(&PyBytes_Type, _bytes_shared) != 0) { + Py_FatalError("could not register bytes for cross-interpreter sharing"); + } + + // str + if (_register_xidata(&PyUnicode_Type, _str_shared) != 0) { + Py_FatalError("could not register str for cross-interpreter sharing"); + } +} + + #ifdef __cplusplus } #endif diff --git a/Python/pystrtod.c b/Python/pystrtod.c index 9bf93638621038..3546d44c84248b 100644 --- a/Python/pystrtod.c +++ b/Python/pystrtod.c @@ -1060,8 +1060,6 @@ format_float_short(double d, char format_code, else { /* shouldn't get here: Gay's code should always return something starting with a digit, an 'I', or 'N' */ - strncpy(p, "ERR", 3); - /* p += 3; */ Py_UNREACHABLE(); } goto exit; diff --git a/Python/pythonrun.c b/Python/pythonrun.c index e22b20051f4c95..d857d4fe463c18 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -418,7 +418,6 @@ PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit, goto done; } v = run_pyc_file(pyc_fp, filename, d, d, flags); - fclose(pyc_fp); } else { /* When running from stdin, leave __main__.__loader__ alone */ if (strcmp(filename, "<stdin>") != 0 && @@ -432,6 +431,7 @@ PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit, } flush_io(); if (v == NULL) { + Py_CLEAR(m); PyErr_Print(); goto done; } @@ -440,7 +440,7 @@ PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit, done: if (set_file_name && PyDict_DelItemString(d, "__file__")) PyErr_Clear(); - Py_DECREF(m); + Py_XDECREF(m); return ret; } @@ -774,12 +774,12 @@ print_exception(PyObject *f, PyObject *value) } else { PyObject* moduleName; - char* className; + const char *className; _Py_IDENTIFIER(__module__); assert(PyExceptionClass_Check(type)); className = PyExceptionClass_Name(type); if (className != NULL) { - char *dot = strrchr(className, '.'); + const char *dot = strrchr(className, '.'); if (dot != NULL) className = dot+1; } @@ -1059,28 +1059,32 @@ run_pyc_file(FILE *fp, const char *filename, PyObject *globals, if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError, "Bad magic number in .pyc file"); - return NULL; + goto error; } /* Skip the rest of the header. */ (void) PyMarshal_ReadLongFromFile(fp); (void) PyMarshal_ReadLongFromFile(fp); (void) PyMarshal_ReadLongFromFile(fp); - if (PyErr_Occurred()) - return NULL; - + if (PyErr_Occurred()) { + goto error; + } v = PyMarshal_ReadLastObjectFromFile(fp); if (v == NULL || !PyCode_Check(v)) { Py_XDECREF(v); PyErr_SetString(PyExc_RuntimeError, "Bad code object in .pyc file"); - return NULL; + goto error; } + fclose(fp); co = (PyCodeObject *)v; v = PyEval_EvalCode((PyObject*)co, globals, locals); if (v && flags) flags->cf_flags |= (co->co_flags & PyCF_MASK); Py_DECREF(co); return v; +error: + fclose(fp); + return NULL; } PyObject * diff --git a/Python/symtable.c b/Python/symtable.c index 1c328a99614032..3e8c6f5dae30c9 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -1729,35 +1729,18 @@ symtable_handle_comprehension(struct symtable *st, expr_ty e, VISIT(st, expr, value); VISIT(st, expr, elt); if (st->st_cur->ste_generator) { - PyObject *msg = PyUnicode_FromString( + PyErr_SetString(PyExc_SyntaxError, (e->kind == ListComp_kind) ? "'yield' inside list comprehension" : (e->kind == SetComp_kind) ? "'yield' inside set comprehension" : (e->kind == DictComp_kind) ? "'yield' inside dict comprehension" : "'yield' inside generator expression"); - if (msg == NULL) { - symtable_exit_block(st, (void *)e); - return 0; - } - if (PyErr_WarnExplicitObject(PyExc_DeprecationWarning, - msg, st->st_filename, st->st_cur->ste_lineno, - NULL, NULL) == -1) - { - if (PyErr_ExceptionMatches(PyExc_DeprecationWarning)) { - /* Replace the DeprecationWarning exception with a SyntaxError - to get a more accurate error report */ - PyErr_Clear(); - PyErr_SetObject(PyExc_SyntaxError, msg); - PyErr_SyntaxLocationObject(st->st_filename, - st->st_cur->ste_lineno, - st->st_cur->ste_col_offset); - } - Py_DECREF(msg); - symtable_exit_block(st, (void *)e); - return 0; - } - Py_DECREF(msg); + PyErr_SyntaxLocationObject(st->st_filename, + st->st_cur->ste_lineno, + st->st_cur->ste_col_offset); + symtable_exit_block(st, (void *)e); + return 0; } - st->st_cur->ste_generator |= is_generator; + st->st_cur->ste_generator = is_generator; return symtable_exit_block(st, (void *)e); } diff --git a/Python/sysmodule.c b/Python/sysmodule.c index dc5a0801995fa3..105e122028b933 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -511,7 +511,7 @@ exit status will be one (i.e., failure)." static PyObject * -sys_getdefaultencoding(PyObject *self) +sys_getdefaultencoding(PyObject *self, PyObject *Py_UNUSED(ignored)) { return PyUnicode_FromString(PyUnicode_GetDefaultEncoding()); } @@ -519,12 +519,12 @@ sys_getdefaultencoding(PyObject *self) PyDoc_STRVAR(getdefaultencoding_doc, "getdefaultencoding() -> string\n\ \n\ -Return the current default string encoding used by the Unicode \n\ +Return the current default string encoding used by the Unicode\n\ implementation." ); static PyObject * -sys_getfilesystemencoding(PyObject *self) +sys_getfilesystemencoding(PyObject *self, PyObject *Py_UNUSED(ignored)) { if (Py_FileSystemDefaultEncoding) return PyUnicode_FromString(Py_FileSystemDefaultEncoding); @@ -541,7 +541,7 @@ operating system filenames." ); static PyObject * -sys_getfilesystemencodeerrors(PyObject *self) +sys_getfilesystemencodeerrors(PyObject *self, PyObject *Py_UNUSED(ignored)) { if (Py_FileSystemDefaultEncodeErrors) return PyUnicode_FromString(Py_FileSystemDefaultEncodeErrors); @@ -1142,7 +1142,7 @@ dependent." ); static PyObject * -sys_getrecursionlimit(PyObject *self) +sys_getrecursionlimit(PyObject *self, PyObject *Py_UNUSED(ignored)) { return PyLong_FromLong(Py_GetRecursionLimit()); } @@ -1276,7 +1276,7 @@ PyDoc_STRVAR(enablelegacywindowsfsencoding_doc, Changes the default filesystem encoding to mbcs:replace for consistency\n\ with earlier versions of Python. See PEP 529 for more information.\n\ \n\ -This is equivalent to defining the PYTHONLEGACYWINDOWSFSENCODING \n\ +This is equivalent to defining the PYTHONLEGACYWINDOWSFSENCODING\n\ environment variable before launching Python." ); @@ -1428,7 +1428,7 @@ sys_getrefcount(PyObject *self, PyObject *arg) #ifdef Py_REF_DEBUG static PyObject * -sys_gettotalrefcount(PyObject *self) +sys_gettotalrefcount(PyObject *self, PyObject *Py_UNUSED(ignored)) { return PyLong_FromSsize_t(_Py_GetRefTotal()); } @@ -1443,7 +1443,7 @@ reference as an argument to getrefcount()." ); static PyObject * -sys_getallocatedblocks(PyObject *self) +sys_getallocatedblocks(PyObject *self, PyObject *Py_UNUSED(ignored)) { return PyLong_FromSsize_t(_Py_GetAllocatedBlocks()); } @@ -1560,7 +1560,7 @@ a 11-tuple where the entries in the tuple are counts of:\n\ ); static PyObject * -sys_callstats(PyObject *self) +sys_callstats(PyObject *self, PyObject *Py_UNUSED(ignored)) { if (PyErr_WarnEx(PyExc_DeprecationWarning, "sys.callstats() has been deprecated in Python 3.7 " @@ -1725,7 +1725,7 @@ static PyMethodDef sys_methods[] = { {"audit", sys_audit, METH_VARARGS, audit_doc }, {"breakpointhook", (PyCFunction)sys_breakpointhook, METH_FASTCALL | METH_KEYWORDS, breakpointhook_doc}, - {"callstats", (PyCFunction)sys_callstats, METH_NOARGS, + {"callstats", sys_callstats, METH_NOARGS, callstats_doc}, {"_clear_type_cache", sys_clear_type_cache, METH_NOARGS, sys_clear_type_cache__doc__}, @@ -1735,13 +1735,13 @@ static PyMethodDef sys_methods[] = { {"exc_info", sys_exc_info, METH_NOARGS, exc_info_doc}, {"excepthook", sys_excepthook, METH_VARARGS, excepthook_doc}, {"exit", sys_exit, METH_VARARGS, exit_doc}, - {"getdefaultencoding", (PyCFunction)sys_getdefaultencoding, + {"getdefaultencoding", sys_getdefaultencoding, METH_NOARGS, getdefaultencoding_doc}, #ifdef HAVE_DLOPEN {"getdlopenflags", (PyCFunction)sys_getdlopenflags, METH_NOARGS, getdlopenflags_doc}, #endif - {"getallocatedblocks", (PyCFunction)sys_getallocatedblocks, METH_NOARGS, + {"getallocatedblocks", sys_getallocatedblocks, METH_NOARGS, getallocatedblocks_doc}, #ifdef COUNT_ALLOCS {"getcounts", (PyCFunction)sys_getcounts, METH_NOARGS}, @@ -1749,18 +1749,18 @@ static PyMethodDef sys_methods[] = { #ifdef DYNAMIC_EXECUTION_PROFILE {"getdxp", _Py_GetDXProfile, METH_VARARGS}, #endif - {"getfilesystemencoding", (PyCFunction)sys_getfilesystemencoding, + {"getfilesystemencoding", sys_getfilesystemencoding, METH_NOARGS, getfilesystemencoding_doc}, - { "getfilesystemencodeerrors", (PyCFunction)sys_getfilesystemencodeerrors, + { "getfilesystemencodeerrors", sys_getfilesystemencodeerrors, METH_NOARGS, getfilesystemencodeerrors_doc }, #ifdef Py_TRACE_REFS {"getobjects", _Py_GetObjects, METH_VARARGS}, #endif #ifdef Py_REF_DEBUG - {"gettotalrefcount", (PyCFunction)sys_gettotalrefcount, METH_NOARGS}, + {"gettotalrefcount", sys_gettotalrefcount, METH_NOARGS}, #endif {"getrefcount", (PyCFunction)sys_getrefcount, METH_O, getrefcount_doc}, - {"getrecursionlimit", (PyCFunction)sys_getrecursionlimit, METH_NOARGS, + {"getrecursionlimit", sys_getrecursionlimit, METH_NOARGS, getrecursionlimit_doc}, {"getsizeof", (PyCFunction)sys_getsizeof, METH_VARARGS | METH_KEYWORDS, getsizeof_doc}, @@ -2200,7 +2200,7 @@ winver -- [Windows only] version number of the Python DLL\n\ #ifdef MS_WINDOWS /* concatenating string here */ PyDoc_STR( -"_enablelegacywindowsfsencoding -- [Windows only] \n\ +"_enablelegacywindowsfsencoding -- [Windows only]\n\ " ) #endif @@ -2690,6 +2690,12 @@ _PySys_EndInit(PyObject *sysdict, _PyMainInterpreterConfig *config) SET_SYS_FROM_STRING_BORROW("exec_prefix", config->exec_prefix); SET_SYS_FROM_STRING_BORROW("base_exec_prefix", config->base_exec_prefix); + if (config->pycache_prefix != NULL) { + SET_SYS_FROM_STRING_BORROW("pycache_prefix", config->pycache_prefix); + } else { + PyDict_SetItemString(sysdict, "pycache_prefix", Py_None); + } + if (config->argv != NULL) { SET_SYS_FROM_STRING_BORROW("argv", config->argv); } diff --git a/Python/traceback.c b/Python/traceback.c index b00864b06e43cd..21fb034160022b 100644 --- a/Python/traceback.c +++ b/Python/traceback.c @@ -87,7 +87,7 @@ tb_new_impl(PyTypeObject *type, PyObject *tb_next, PyFrameObject *tb_frame, } static PyObject * -tb_dir(PyTracebackObject *self) +tb_dir(PyTracebackObject *self, PyObject *Py_UNUSED(ignored)) { return Py_BuildValue("[ssss]", "tb_frame", "tb_next", "tb_lasti", "tb_lineno"); diff --git a/README.rst b/README.rst index b3af33b1fc5fe3..9f86b630fdd191 100644 --- a/README.rst +++ b/README.rst @@ -1,5 +1,5 @@ -This is Python version 3.7.0 -============================ +This is Python version 3.8.0 alpha 0 +==================================== .. image:: https://travis-ci.org/python/cpython.svg?branch=master :alt: CPython build status on Travis CI @@ -13,6 +13,11 @@ This is Python version 3.7.0 :alt: CPython code coverage on Codecov :target: https://codecov.io/gh/python/cpython +.. image:: https://img.shields.io/badge/zulip-join_chat-brightgreen.svg + :alt: Python Zulip chat + :target: https://python.zulipchat.com + + Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 Python Software Foundation. All rights reserved. @@ -133,7 +138,7 @@ What's New ---------- We have a comprehensive overview of the changes in the `What's New in Python -3.7 <https://docs.python.org/3.7/whatsnew/3.7.html>`_ document. For a more +3.8 <https://docs.python.org/3.8/whatsnew/3.8.html>`_ document. For a more detailed change log, read `Misc/NEWS <https://github.com/python/cpython/blob/master/Misc/NEWS.d>`_, but a full accounting of changes can only be gleaned from the `commit history @@ -146,7 +151,7 @@ entitled "Installing multiple versions". Documentation ------------- -`Documentation for Python 3.7 <https://docs.python.org/3.7/>`_ is online, +`Documentation for Python 3.8 <https://docs.python.org/3.8/>`_ is online, updated daily. It can also be downloaded in many formats for faster access. The documentation @@ -203,8 +208,8 @@ intend to install multiple versions using the same prefix you must decide which version (if any) is your "primary" version. Install that version using ``make install``. Install all other versions using ``make altinstall``. -For example, if you want to install Python 2.7, 3.6, and 3.7 with 3.7 being the -primary version, you would execute ``make install`` in your 3.7 build directory +For example, if you want to install Python 2.7, 3.6, and 3.8 with 3.8 being the +primary version, you would execute ``make install`` in your 3.8 build directory and ``make altinstall`` in the others. @@ -234,7 +239,7 @@ All current PEPs, as well as guidelines for submitting a new PEP, are listed at Release Schedule ---------------- -See :pep:`537` for Python 3.7 release details. +See :pep:`569` for Python 3.8 release details. Copyright and License Information diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index b704b5a669fbd2..e7c7eb47e818ee 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -2556,9 +2556,29 @@ class char_converter(CConverter): format_unit = 'c' c_ignored_default = "'\0'" + # characters which need to be escaped in C code + _escapes = {x: r'\%d' % x for x in range(7)} + _escapes.update({ + 0x07: r'\a', + 0x08: r'\b', + 0x09: r'\t', + 0x0A: r'\n', + 0x0B: r'\v', + 0x0C: r'\f', + 0x0D: r'\r', + 0x22: r'\"', + 0x27: r'\'', + 0x3F: r'\?', + 0x5C: r'\\', + }) + def converter_init(self): - if isinstance(self.default, self.default_type) and (len(self.default) != 1): - fail("char_converter: illegal default value " + repr(self.default)) + if isinstance(self.default, self.default_type): + if len(self.default) != 1: + fail("char_converter: illegal default value " + repr(self.default)) + + c_ord = self.default[0] + self.c_default = "'%s'" % self._escapes.get(c_ord, chr(c_ord)) @add_legacy_c_converter('B', bitwise=True) diff --git a/Tools/demo/redemo.py b/Tools/demo/redemo.py index 256a63e0a00d4e..f801dfce5fe1a3 100755 --- a/Tools/demo/redemo.py +++ b/Tools/demo/redemo.py @@ -96,7 +96,6 @@ def getflags(self): flags = 0 for var in self.vars: flags = flags | var.get() - flags = flags return flags def recompile(self, event=None): diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py index 7df7c9bd541672..27eabcb0d3d091 100755 --- a/Tools/gdb/libpython.py +++ b/Tools/gdb/libpython.py @@ -270,12 +270,13 @@ def is_optimized_out(self): def safe_tp_name(self): try: - return self.type().field('tp_name').string() - except NullPyObjectPtr: - # NULL tp_name? - return 'unknown' - except RuntimeError: - # Can't even read the object at all? + ob_type = self.type() + tp_name = ob_type.field('tp_name') + return tp_name.string() + # NullPyObjectPtr: NULL tp_name? + # RuntimeError: Can't even read the object at all? + # UnicodeDecodeError: Failed to decode tp_name bytestring + except (NullPyObjectPtr, RuntimeError, UnicodeDecodeError): return 'unknown' def proxyval(self, visited): @@ -349,7 +350,9 @@ def subclass_from_type(cls, t): try: tp_name = t.field('tp_name').string() tp_flags = int(t.field('tp_flags')) - except RuntimeError: + # RuntimeError: NULL pointers + # UnicodeDecodeError: string() fails to decode the bytestring + except (RuntimeError, UnicodeDecodeError): # Handle any kind of error e.g. NULL ptrs by simply using the base # class return cls @@ -617,7 +620,10 @@ class PyCFunctionObjectPtr(PyObjectPtr): def proxyval(self, visited): m_ml = self.field('m_ml') # m_ml is a (PyMethodDef*) - ml_name = m_ml['ml_name'].string() + try: + ml_name = m_ml['ml_name'].string() + except UnicodeDecodeError: + ml_name = '<ml_name:UnicodeDecodeError>' pyop_m_self = self.pyop_field('m_self') if pyop_m_self.is_null(): @@ -1340,13 +1346,13 @@ def safe_name(self): try: name = self.field('descr')['d_base']['name'].string() return repr(name) - except (NullPyObjectPtr, RuntimeError): + except (NullPyObjectPtr, RuntimeError, UnicodeDecodeError): return '<unknown name>' def safe_tp_name(self): try: return self.field('self')['ob_type']['tp_name'].string() - except (NullPyObjectPtr, RuntimeError): + except (NullPyObjectPtr, RuntimeError, UnicodeDecodeError): return '<unknown tp_name>' def safe_self_addresss(self): @@ -1552,15 +1558,22 @@ def is_other_python_frame(self): # Use the prettyprinter for the func: func = frame.read_var(arg_name) return str(func) + except ValueError: + return ('PyCFunction invocation (unable to read %s: ' + 'missing debuginfos?)' % arg_name) except RuntimeError: return 'PyCFunction invocation (unable to read %s)' % arg_name if caller == 'wrapper_call': + arg_name = 'wp' try: - func = frame.read_var('wp') + func = frame.read_var(arg_name) return str(func) + except ValueError: + return ('<wrapper_call invocation (unable to read %s: ' + 'missing debuginfos?)>' % arg_name) except RuntimeError: - return '<wrapper_call invocation>' + return '<wrapper_call invocation (unable to read %s)>' % arg_name # This frame isn't worth reporting: return False diff --git a/Tools/i18n/makelocalealias.py b/Tools/i18n/makelocalealias.py index c7ecacec387788..b407a8a643be7c 100755 --- a/Tools/i18n/makelocalealias.py +++ b/Tools/i18n/makelocalealias.py @@ -19,6 +19,9 @@ def parse(filename): with open(filename, encoding='latin1') as f: lines = list(f) + # Remove mojibake in /usr/share/X11/locale/locale.alias. + # b'\xef\xbf\xbd' == '\ufffd'.encode('utf-8') + lines = [line for line in lines if '\xef\xbf\xbd' not in line] data = {} for line in lines: line = line.strip() diff --git a/Tools/msi/tools/tools_files.wxs b/Tools/msi/tools/tools_files.wxs index 9c76b1b44460ab..3de6c9291cf676 100644 --- a/Tools/msi/tools/tools_files.wxs +++ b/Tools/msi/tools/tools_files.wxs @@ -8,9 +8,6 @@ <Component Id="Tools_scripts_pydoc3.py" Directory="Tools_scripts" Guid="*"> <File Id="Tools_scripts_pydoc3.py" Name="pydoc3.py" Source="!(bindpath.src)Tools\scripts\pydoc3" /> </Component> - <Component Id="Tools_scripts_pyvenv.py" Directory="Tools_scripts" Guid="*"> - <File Id="Tools_scripts_pyvenv.py" Name="pyvenv.py" Source="!(bindpath.src)Tools\scripts\pyvenv" /> - </Component> </ComponentGroup> </Fragment> <Fragment> diff --git a/Tools/msi/uploadrelease.ps1 b/Tools/msi/uploadrelease.ps1 new file mode 100644 index 00000000000000..3e01d1e45312f6 --- /dev/null +++ b/Tools/msi/uploadrelease.ps1 @@ -0,0 +1,133 @@ +<# +.Synopsis + Uploads from a VSTS release build layout to python.org +.Description + Given the downloaded/extracted build artifact from a release + build run on python.visualstudio.com, this script uploads + the files to the correct locations. +.Parameter build + The location on disk of the extracted build artifact. +.Parameter user + The username to use when logging into the host. +.Parameter server + The host or PuTTY session name. +.Parameter target + The subdirectory on the host to copy files to. +.Parameter tests + The path to run download tests in. +.Parameter skipupload + Skip uploading +.Parameter skippurge + Skip purging the CDN +.Parameter skiptest + Skip the download tests +.Parameter skiphash + Skip displaying hashes +#> +param( + [Parameter(Mandatory=$true)][string]$build, + [Parameter(Mandatory=$true)][string]$user, + [string]$server="python-downloads", + [string]$target="/srv/www.python.org/ftp/python", + [string]$tests=${env:TEMP}, + [switch]$skipupload, + [switch]$skippurge, + [switch]$skiptest, + [switch]$skiphash +) + +if (-not $build) { throw "-build option is required" } +if (-not $user) { throw "-user option is required" } + +if (-not ((Test-Path "$build\win32\python-*.exe") -or (Test-Path "$build\amd64\python-*.exe"))) { + throw "-build argument does not look like a 'build' directory" +} + +function find-putty-tool { + param ([string]$n) + $t = gcm $n -EA 0 + if (-not $t) { $t = gcm ".\$n" -EA 0 } + if (-not $t) { $t = gcm "${env:ProgramFiles}\PuTTY\$n" -EA 0 } + if (-not $t) { $t = gcm "${env:ProgramFiles(x86)}\PuTTY\$n" -EA 0 } + if (-not $t) { throw "Unable to locate $n.exe. Please put it on $PATH" } + return gi $t.Path +} + +$p = gci -r "$build\python-*.exe" | ` + ?{ $_.Name -match '^python-(\d+\.\d+\.\d+)((a|b|rc)\d+)?-.+' } | ` + select -first 1 | ` + %{ $Matches[1], $Matches[2] } + +"Uploading version $($p[0]) $($p[1])" +" from: $build" +" to: $($server):$target/$($p[0])" +"" + +if (-not $skipupload) { + # Upload files to the server + $pscp = find-putty-tool "pscp" + $plink = find-putty-tool "plink" + + "Upload using $pscp and $plink" + "" + + pushd $build + $doc = gci python*.chm, python*.chm.asc + popd + + $d = "$target/$($p[0])/" + & $plink -batch $user@$server mkdir $d + & $plink -batch $user@$server chgrp downloads $d + & $plink -batch $user@$server chmod g-x,o+rx $d + & $pscp -batch $doc.FullName "$user@${server}:$d" + + foreach ($a in gci "$build" -Directory) { + "Uploading files from $($a.FullName)" + pushd "$($a.FullName)" + $exe = gci *.exe, *.exe.asc, *.zip, *.zip.asc + $msi = gci *.msi, *.msi.asc, *.msu, *.msu.asc + popd + + & $pscp -batch $exe.FullName "$user@${server}:$d" + + $sd = "$d$($a.Name)$($p[1])/" + & $plink -batch $user@$server mkdir $sd + & $plink -batch $user@$server chgrp downloads $sd + & $plink -batch $user@$server chmod g-x,o+rx $sd + & $pscp -batch $msi.FullName "$user@${server}:$sd" + & $plink -batch $user@$server chgrp downloads $sd* + & $plink -batch $user@$server chmod g-x,o+r $sd* + } + + & $plink -batch $user@$server chgrp downloads $d* + & $plink -batch $user@$server chmod g-x,o+r $d* +} + +if (-not $skippurge) { + # Run a CDN purge + py purge.py "$($p[0])$($p[1])" +} + +if (-not $skiptest) { + # Use each web installer to produce a layout. This will download + # each referenced file and validate their signatures/hashes. + gci "$build\*-webinstall.exe" -r -File | %{ + $d = mkdir "$tests\$($_.BaseName)" -Force + gci $d -r -File | del + $ic = copy $_ $d -PassThru + "Checking layout for $($ic.Name)" + Start-Process -wait $ic "/passive", "/layout", "$d\layout", "/log", "$d\log\install.log" + if (-not $?) { + Write-Error "Failed to validate layout of $($inst.Name)" + } + } +} + +if (-not $skiphash) { + # Display MD5 hash and size of each downloadable file + pushd $build + gci python*.chm, *\*.exe, *\*.zip | ` + Sort-Object Name | ` + Format-Table Name, @{Label="MD5"; Expression={(Get-FileHash $_ -Algorithm MD5).Hash}}, Length + popd +} diff --git a/Tools/scripts/pep384_macrocheck.py b/Tools/scripts/pep384_macrocheck.py new file mode 100644 index 00000000000000..142d248dd2fa9b --- /dev/null +++ b/Tools/scripts/pep384_macrocheck.py @@ -0,0 +1,148 @@ +""" +pep384_macrocheck.py + +This programm tries to locate errors in the relevant Python header +files where macros access type fields when they are reachable from +the limided API. + +The idea is to search macros with the string "->tp_" in it. +When the macro name does not begin with an underscore, +then we have found a dormant error. + +Christian Tismer +2018-06-02 +""" + +import sys +import os +import re + + +DEBUG = False + +def dprint(*args, **kw): + if DEBUG: + print(*args, **kw) + +def parse_headerfiles(startpath): + """ + Scan all header files which are reachable fronm Python.h + """ + search = "Python.h" + name = os.path.join(startpath, search) + if not os.path.exists(name): + raise ValueError("file {} was not found in {}\n" + "Please give the path to Python's include directory." + .format(search, startpath)) + errors = 0 + with open(name) as python_h: + while True: + line = python_h.readline() + if not line: + break + found = re.match(r'^\s*#\s*include\s*"(\w+\.h)"', line) + if not found: + continue + include = found.group(1) + dprint("Scanning", include) + name = os.path.join(startpath, include) + if not os.path.exists(name): + name = os.path.join(startpath, "../PC", include) + errors += parse_file(name) + return errors + +def ifdef_level_gen(): + """ + Scan lines for #ifdef and track the level. + """ + level = 0 + ifdef_pattern = r"^\s*#\s*if" # covers ifdef and ifndef as well + endif_pattern = r"^\s*#\s*endif" + while True: + line = yield level + if re.match(ifdef_pattern, line): + level += 1 + elif re.match(endif_pattern, line): + level -= 1 + +def limited_gen(): + """ + Scan lines for Py_LIMITED_API yes(1) no(-1) or nothing (0) + """ + limited = [0] # nothing + unlimited_pattern = r"^\s*#\s*ifndef\s+Py_LIMITED_API" + limited_pattern = "|".join([ + r"^\s*#\s*ifdef\s+Py_LIMITED_API", + r"^\s*#\s*(el)?if\s+!\s*defined\s*\(\s*Py_LIMITED_API\s*\)\s*\|\|", + r"^\s*#\s*(el)?if\s+defined\s*\(\s*Py_LIMITED_API" + ]) + else_pattern = r"^\s*#\s*else" + ifdef_level = ifdef_level_gen() + status = next(ifdef_level) + wait_for = -1 + while True: + line = yield limited[-1] + new_status = ifdef_level.send(line) + dir = new_status - status + status = new_status + if dir == 1: + if re.match(unlimited_pattern, line): + limited.append(-1) + wait_for = status - 1 + elif re.match(limited_pattern, line): + limited.append(1) + wait_for = status - 1 + elif dir == -1: + # this must have been an endif + if status == wait_for: + limited.pop() + wait_for = -1 + else: + # it could be that we have an elif + if re.match(limited_pattern, line): + limited.append(1) + wait_for = status - 1 + elif re.match(else_pattern, line): + limited.append(-limited.pop()) # negate top + +def parse_file(fname): + errors = 0 + with open(fname) as f: + lines = f.readlines() + type_pattern = r"^.*?->\s*tp_" + define_pattern = r"^\s*#\s*define\s+(\w+)" + limited = limited_gen() + status = next(limited) + for nr, line in enumerate(lines): + status = limited.send(line) + line = line.rstrip() + dprint(fname, nr, status, line) + if status != -1: + if re.match(define_pattern, line): + name = re.match(define_pattern, line).group(1) + if not name.startswith("_"): + # found a candidate, check it! + macro = line + "\n" + idx = nr + while line.endswith("\\"): + idx += 1 + line = lines[idx].rstrip() + macro += line + "\n" + if re.match(type_pattern, macro, re.DOTALL): + # this type field can reach the limited API + report(fname, nr + 1, macro) + errors += 1 + return errors + +def report(fname, nr, macro): + f = sys.stderr + print(fname + ":" + str(nr), file=f) + print(macro, file=f) + +if __name__ == "__main__": + p = sys.argv[1] if sys.argv[1:] else "../../Include" + errors = parse_headerfiles(p) + if errors: + # somehow it makes sense to raise a TypeError :-) + raise TypeError("These {} locations contradict the limited API." + .format(errors)) diff --git a/Tools/scripts/pyvenv b/Tools/scripts/pyvenv deleted file mode 100755 index 1fb42c639132a8..00000000000000 --- a/Tools/scripts/pyvenv +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env python3 -if __name__ == '__main__': - import sys - import pathlib - - executable = pathlib.Path(sys.executable or 'python3').name - print('WARNING: the pyenv script is deprecated in favour of ' - f'`{executable} -m venv`', file=sys.stderr) - - rc = 1 - try: - import venv - venv.main() - rc = 0 - except Exception as e: - print('Error: %s' % e, file=sys.stderr) - sys.exit(rc) diff --git a/Tools/scripts/smelly.py b/Tools/scripts/smelly.py index 212eedb30bc384..43d091654d2dc8 100755 --- a/Tools/scripts/smelly.py +++ b/Tools/scripts/smelly.py @@ -27,6 +27,11 @@ def get_exported_symbols(): def get_smelly_symbols(stdout): symbols = [] ignored_symtypes = set() + + allowed_prefixes = ('Py', '_Py') + if sys.platform == 'darwin': + allowed_prefixes += ('__Py',) + for line in stdout.splitlines(): # Split line '0000000000001b80 D PyTextIOWrapper_Type' if not line: @@ -47,7 +52,7 @@ def get_smelly_symbols(stdout): continue symbol = parts[-1] - if symbol.startswith(('Py', '_Py')): + if symbol.startswith(allowed_prefixes): continue symbol = '%s (type: %s)' % (symbol, symtype) symbols.append(symbol) diff --git a/configure b/configure index e0389649ae0655..0fa15945c52dca 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.7. +# Generated by GNU Autoconf 2.69 for python 3.8. # # Report bugs to <https://bugs.python.org/>. # @@ -580,8 +580,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='python' PACKAGE_TARNAME='python' -PACKAGE_VERSION='3.7' -PACKAGE_STRING='python 3.7' +PACKAGE_VERSION='3.8' +PACKAGE_STRING='python 3.8' PACKAGE_BUGREPORT='https://bugs.python.org/' PACKAGE_URL='' @@ -807,8 +807,6 @@ enable_universalsdk with_universal_archs with_framework_name enable_framework -with_gcc -with_icc with_cxx_main with_suffix enable_shared @@ -1395,7 +1393,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.7 to adapt to many kinds of systems. +\`configure' configures python 3.8 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1461,7 +1459,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of python 3.7:";; + short | recursive ) echo "Configuration of python 3.8:";; esac cat <<\_ACEOF @@ -1494,8 +1492,6 @@ Optional Packages: --with-framework-name=FRAMEWORK specify an alternate name of the framework built with --enable-framework - --without-gcc never use gcc - --with-icc build with icc --with-cxx-main=<compiler> compile main() and link python executable with C++ compiler @@ -1628,7 +1624,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -python configure 3.7 +python configure 3.8 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2337,7 +2333,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.7, which was +It was created by python $as_me 3.8, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2957,7 +2953,7 @@ rm confdefs.h mv confdefs.h.new confdefs.h -VERSION=3.7 +VERSION=3.8 # Version number of Python's own shared library file. @@ -3442,57 +3438,6 @@ EXPORT_MACOSX_DEPLOYMENT_TARGET='#' # when running configure or make. The build should not break if they do. # BASECFLAGS should generally not be messed with, however. -# XXX shouldn't some/most/all of this code be merged with the stuff later -# on that fiddles with OPT and BASECFLAGS? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --without-gcc" >&5 -$as_echo_n "checking for --without-gcc... " >&6; } - -# Check whether --with-gcc was given. -if test "${with_gcc+set}" = set; then : - withval=$with_gcc; - case $withval in - no) CC=${CC:-cc} - without_gcc=yes;; - yes) CC=gcc - without_gcc=no;; - *) CC=$withval - without_gcc=$withval;; - esac -else - - case $ac_sys_system in - AIX*) CC=${CC:-xlc_r} - without_gcc=;; - *) without_gcc=no;; - esac -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $without_gcc" >&5 -$as_echo "$without_gcc" >&6; } - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-icc" >&5 -$as_echo_n "checking for --with-icc... " >&6; } - -# Check whether --with-icc was given. -if test "${with_icc+set}" = set; then : - withval=$with_icc; - case $withval in - no) CC=${CC:-cc} - with_icc=no;; - yes) CC=icc - CXX=icpc - with_icc=yes;; - *) CC=$withval - with_icc=$withval;; - esac -else - - with_icc=no -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_icc" >&5 -$as_echo "$with_icc" >&6; } - # If the user switches compilers, we can't believe the cache if test ! -z "$ac_cv_prog_CC" -a ! -z "$CC" -a "$CC" != "$ac_cv_prog_CC" then @@ -6482,6 +6427,14 @@ if test "$Py_LTO" = 'true' ; then esac ;; esac + + if test "$ac_cv_prog_cc_g" = "yes" + then + # bpo-30345: Add -g to LDFLAGS when compiling with LTO + # to get debug symbols. + LTOFLAGS="$LTOFLAGS -g" + fi + CFLAGS="$CFLAGS $LTOFLAGS" LDFLAGS="$LDFLAGS $LTOFLAGS" fi @@ -7281,7 +7234,6 @@ $as_echo "$ac_cv_enable_implicit_function_declaration_error" >&6; } BASECFLAGS="$BASECFLAGS -m486 -DSCO5" ;; - # is there any other compiler on Darwin besides gcc? Darwin*) # -Wno-long-double, -no-cpp-precomp, and -mno-fused-madd # used to be here, but non-Apple gcc doesn't accept them. @@ -8734,32 +8686,48 @@ _ACEOF -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for long double support" >&5 -$as_echo_n "checking for long double support... " >&6; } -have_long_double=no -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for long double" >&5 +$as_echo_n "checking for long double... " >&6; } +if ${ac_cv_type_long_double+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$GCC" = yes; then + ac_cv_type_long_double=yes + else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* The Stardent Vistra knows sizeof (long double), but does + not support it. */ + long double foo = 0.0L; int main () { -long double x; x = (long double)0; +static int test_array [1 - 2 * !(/* On Ultrix 4.3 cc, long double is 4 and double is 8. */ + sizeof (double) <= sizeof (long double))]; +test_array [0] = 0; +return test_array [0]; + ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : - + ac_cv_type_long_double=yes +else + ac_cv_type_long_double=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_long_double" >&5 +$as_echo "$ac_cv_type_long_double" >&6; } + if test $ac_cv_type_long_double = yes; then $as_echo "#define HAVE_LONG_DOUBLE 1" >>confdefs.h - have_long_double=yes + fi -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_long_double" >&5 -$as_echo "$have_long_double" >&6; } -if test "$have_long_double" = yes ; then # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. @@ -8793,7 +8761,6 @@ cat >>confdefs.h <<_ACEOF _ACEOF -fi # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects @@ -11356,7 +11323,7 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \ setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setpriority setuid setvbuf \ sched_get_priority_max sched_setaffinity sched_setscheduler sched_setparam \ sched_rr_get_interval \ - sigaction sigaltstack siginterrupt sigpending sigrelse \ + sigaction sigaltstack sigfillset siginterrupt sigpending sigrelse \ sigtimedwait sigwait sigwaitinfo snprintf strftime strlcpy symlinkat sync \ sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ truncate uname unlinkat unsetenv utimensat utimes waitid waitpid wait3 wait4 \ @@ -17637,7 +17604,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.7, which was +This file was extended by python $as_me 3.8, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -17699,7 +17666,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.7 +python config.status 3.8 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index b5beb0857475bd..a0f4230642e70c 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.7) +m4_define(PYTHON_VERSION, 3.8) AC_PREREQ(2.65) @@ -555,43 +555,6 @@ EXPORT_MACOSX_DEPLOYMENT_TARGET='#' # when running configure or make. The build should not break if they do. # BASECFLAGS should generally not be messed with, however. -# XXX shouldn't some/most/all of this code be merged with the stuff later -# on that fiddles with OPT and BASECFLAGS? -AC_MSG_CHECKING(for --without-gcc) -AC_ARG_WITH(gcc, - AS_HELP_STRING([--without-gcc], [never use gcc]), -[ - case $withval in - no) CC=${CC:-cc} - without_gcc=yes;; - yes) CC=gcc - without_gcc=no;; - *) CC=$withval - without_gcc=$withval;; - esac], [ - case $ac_sys_system in - AIX*) CC=${CC:-xlc_r} - without_gcc=;; - *) without_gcc=no;; - esac]) -AC_MSG_RESULT($without_gcc) - -AC_MSG_CHECKING(for --with-icc) -AC_ARG_WITH(icc, - AS_HELP_STRING([--with-icc], [build with icc]), -[ - case $withval in - no) CC=${CC:-cc} - with_icc=no;; - yes) CC=icc - CXX=icpc - with_icc=yes;; - *) CC=$withval - with_icc=$withval;; - esac], [ - with_icc=no]) -AC_MSG_RESULT($with_icc) - # If the user switches compilers, we can't believe the cache if test ! -z "$ac_cv_prog_CC" -a ! -z "$CC" -a "$CC" != "$ac_cv_prog_CC" then @@ -1339,6 +1302,14 @@ if test "$Py_LTO" = 'true' ; then esac ;; esac + + if test "$ac_cv_prog_cc_g" = "yes" + then + # bpo-30345: Add -g to LDFLAGS when compiling with LTO + # to get debug symbols. + LTOFLAGS="$LTOFLAGS -g" + fi + CFLAGS="$CFLAGS $LTOFLAGS" LDFLAGS="$LDFLAGS $LTOFLAGS" fi @@ -1784,7 +1755,6 @@ yes) BASECFLAGS="$BASECFLAGS -m486 -DSCO5" ;; - # is there any other compiler on Darwin besides gcc? Darwin*) # -Wno-long-double, -no-cpp-precomp, and -mno-fused-madd # used to be here, but non-Apple gcc doesn't accept them. @@ -2271,16 +2241,8 @@ AC_CHECK_SIZEOF(size_t, 4) AC_CHECK_SIZEOF(pid_t, 4) AC_CHECK_SIZEOF(uintptr_t) -AC_MSG_CHECKING(for long double support) -have_long_double=no -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[long double x; x = (long double)0;]])],[ - AC_DEFINE(HAVE_LONG_DOUBLE, 1, [Define this if you have the type long double.]) - have_long_double=yes -],[]) -AC_MSG_RESULT($have_long_double) -if test "$have_long_double" = yes ; then +AC_TYPE_LONG_DOUBLE AC_CHECK_SIZEOF(long double, 16) -fi AC_CHECK_SIZEOF(_Bool, 1) @@ -3522,7 +3484,7 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \ setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setpriority setuid setvbuf \ sched_get_priority_max sched_setaffinity sched_setscheduler sched_setparam \ sched_rr_get_interval \ - sigaction sigaltstack siginterrupt sigpending sigrelse \ + sigaction sigaltstack sigfillset siginterrupt sigpending sigrelse \ sigtimedwait sigwait sigwaitinfo snprintf strftime strlcpy symlinkat sync \ sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ truncate uname unlinkat unsetenv utimensat utimes waitid waitpid wait3 wait4 \ diff --git a/pyconfig.h.in b/pyconfig.h.in index e561a7c07cca78..91483190362399 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -617,7 +617,7 @@ /* Define to 1 if you have the `log2' function. */ #undef HAVE_LOG2 -/* Define this if you have the type long double. */ +/* Define to 1 if the system has the type `long double'. */ #undef HAVE_LONG_DOUBLE /* Define to 1 if you have the `lstat' function. */ @@ -896,6 +896,9 @@ /* Define to 1 if you have the `sigaltstack' function. */ #undef HAVE_SIGALTSTACK +/* Define to 1 if you have the `sigfillset' function. */ +#undef HAVE_SIGFILLSET + /* Define to 1 if `si_band' is a member of `siginfo_t'. */ #undef HAVE_SIGINFO_T_SI_BAND diff --git a/setup.py b/setup.py index a97a7559cae768..ba9d47be7a98f2 100644 --- a/setup.py +++ b/setup.py @@ -2287,7 +2287,7 @@ def copy_scripts(self): newoutfiles = [] newupdated_files = [] for filename in outfiles: - if filename.endswith(('2to3', 'pyvenv')): + if filename.endswith('2to3'): newfilename = filename + fullversion else: newfilename = filename + minoronly @@ -2355,7 +2355,7 @@ def main(): # check the PyBuildScripts command above, and change the links # created by the bininstall target in Makefile.pre.in scripts = ["Tools/scripts/pydoc3", "Tools/scripts/idle3", - "Tools/scripts/2to3", "Tools/scripts/pyvenv"] + "Tools/scripts/2to3"] ) # --install-platlib