Imported Upstream version 3.7.3 upstream/3.7.3
authorHyunjee Kim <hj0426.kim@samsung.com>
Thu, 23 May 2019 06:39:18 +0000 (15:39 +0900)
committerHyunjee Kim <hj0426.kim@samsung.com>
Thu, 23 May 2019 06:39:18 +0000 (15:39 +0900)
363 files changed:
.azure-pipelines/ci.yml
.azure-pipelines/docker-steps.yml [deleted file]
.azure-pipelines/posix-deps-apt.sh [new file with mode: 0755]
.azure-pipelines/posix-deps.sh [deleted file]
.azure-pipelines/posix-steps.yml
.azure-pipelines/pr.yml
.azure-pipelines/windows-appx-test.yml [deleted file]
.azure-pipelines/windows-layout-steps.yml [new file with mode: 0644]
.azure-pipelines/windows-steps.yml
Doc/bugs.rst
Doc/c-api/buffer.rst
Doc/c-api/codec.rst
Doc/c-api/dict.rst
Doc/c-api/exceptions.rst
Doc/c-api/mapping.rst
Doc/c-api/number.rst
Doc/c-api/objbuffer.rst
Doc/c-api/object.rst
Doc/c-api/tuple.rst
Doc/c-api/unicode.rst
Doc/copyright.rst
Doc/data/refcounts.dat
Doc/distutils/setupscript.rst
Doc/faq/general.rst
Doc/faq/programming.rst
Doc/glossary.rst
Doc/howto/functional.rst
Doc/howto/logging-cookbook.rst
Doc/howto/logging.rst
Doc/howto/regex.rst
Doc/howto/unicode.rst
Doc/library/aifc.rst
Doc/library/asyncio-eventloop.rst
Doc/library/asyncio-exceptions.rst
Doc/library/asyncio-policy.rst
Doc/library/asyncio-queue.rst
Doc/library/asyncio-task.rst
Doc/library/binascii.rst
Doc/library/collections.rst
Doc/library/compileall.rst
Doc/library/configparser.rst
Doc/library/contextlib.rst
Doc/library/dataclasses.rst
Doc/library/datetime.rst
Doc/library/decimal.rst
Doc/library/enum.rst
Doc/library/fileinput.rst
Doc/library/functions.rst
Doc/library/http.client.rst
Doc/library/http.rst
Doc/library/idle.rst
Doc/library/imaplib.rst
Doc/library/imp.rst
Doc/library/importlib.rst
Doc/library/inspect.rst
Doc/library/io.rst
Doc/library/logging.config.rst
Doc/library/multiprocessing.rst
Doc/library/nntplib.rst
Doc/library/os.path.rst
Doc/library/parser.rst
Doc/library/pathlib-inheritance.png
Doc/library/pathlib-inheritance.svg
Doc/library/pathlib.rst
Doc/library/pdb.rst
Doc/library/pickle.rst
Doc/library/random.rst
Doc/library/re.rst
Doc/library/select.rst
Doc/library/smtplib.rst
Doc/library/socketserver.rst
Doc/library/ssl.rst
Doc/library/stdtypes.rst
Doc/library/subprocess.rst
Doc/library/sys.rst
Doc/library/telnetlib.rst
Doc/library/tempfile.rst
Doc/library/test.rst
Doc/library/threading.rst
Doc/library/time.rst
Doc/library/timeit.rst
Doc/library/tkinter.tix.rst
Doc/library/types.rst
Doc/library/typing.rst
Doc/library/unittest.mock.rst
Doc/library/unittest.rst
Doc/library/urllib.parse.rst
Doc/library/venv.rst
Doc/library/wave.rst
Doc/library/xml.dom.minidom.rst
Doc/library/xml.etree.elementtree.rst
Doc/library/zipfile.rst
Doc/license.rst
Doc/make.bat
Doc/reference/compound_stmts.rst
Doc/reference/datamodel.rst
Doc/reference/executionmodel.rst
Doc/reference/expressions.rst
Doc/reference/import.rst
Doc/reference/simple_stmts.rst
Doc/tools/extensions/c_annotations.py
Doc/tools/templates/indexsidebar.html
Doc/tutorial/classes.rst
Doc/tutorial/controlflow.rst
Doc/tutorial/datastructures.rst
Doc/tutorial/errors.rst
Doc/tutorial/inputoutput.rst
Doc/tutorial/modules.rst
Doc/using/venv-create.inc
Doc/whatsnew/2.0.rst
Doc/whatsnew/2.1.rst
Doc/whatsnew/2.2.rst
Doc/whatsnew/2.3.rst
Doc/whatsnew/2.5.rst
Doc/whatsnew/2.6.rst
Doc/whatsnew/2.7.rst
Doc/whatsnew/3.0.rst
Doc/whatsnew/3.4.rst
Doc/whatsnew/3.6.rst
Doc/whatsnew/3.7.rst
Include/Python.h
Include/patchlevel.h
LICENSE
Lib/asyncio/proactor_events.py
Lib/asyncio/windows_events.py
Lib/ctypes/test/test_strings.py
Lib/dataclasses.py
Lib/distutils/_msvccompiler.py
Lib/distutils/command/build_ext.py
Lib/distutils/sysconfig.py
Lib/distutils/tests/test_build_ext.py
Lib/distutils/tests/test_util.py
Lib/distutils/unixccompiler.py
Lib/distutils/util.py
Lib/doctest.py
Lib/ensurepip/__init__.py
Lib/ensurepip/_bundled/pip-18.1-py2.py3-none-any.whl [deleted file]
Lib/ensurepip/_bundled/pip-19.0.3-py2.py3-none-any.whl [new file with mode: 0644]
Lib/ensurepip/_bundled/setuptools-40.6.2-py2.py3-none-any.whl [deleted file]
Lib/ensurepip/_bundled/setuptools-40.8.0-py2.py3-none-any.whl [new file with mode: 0644]
Lib/enum.py
Lib/functools.py
Lib/http/cookiejar.py
Lib/idlelib/NEWS.txt
Lib/idlelib/autocomplete_w.py
Lib/idlelib/calltip.py
Lib/idlelib/calltip_w.py
Lib/idlelib/codecontext.py
Lib/idlelib/colorizer.py
Lib/idlelib/config_key.py
Lib/idlelib/configdialog.py
Lib/idlelib/debugger.py
Lib/idlelib/editor.py
Lib/idlelib/grep.py
Lib/idlelib/help.html
Lib/idlelib/idle_test/htest.py
Lib/idlelib/idle_test/test_calltip.py
Lib/idlelib/idle_test/test_codecontext.py
Lib/idlelib/idle_test/test_colorizer.py
Lib/idlelib/idle_test/test_config_key.py
Lib/idlelib/idle_test/test_help_about.py
Lib/idlelib/idle_test/test_searchbase.py
Lib/idlelib/idle_test/test_squeezer.py
Lib/idlelib/macosx.py
Lib/idlelib/mainmenu.py
Lib/idlelib/outwin.py
Lib/idlelib/pyshell.py
Lib/idlelib/query.py
Lib/idlelib/replace.py
Lib/idlelib/scrolledlist.py
Lib/idlelib/search.py
Lib/idlelib/searchbase.py
Lib/idlelib/squeezer.py
Lib/idlelib/tree.py
Lib/idlelib/window.py
Lib/idlelib/zoomheight.py
Lib/multiprocessing/managers.py
Lib/multiprocessing/popen_spawn_win32.py
Lib/multiprocessing/spawn.py
Lib/pathlib.py
Lib/pdb.py
Lib/pprint.py
Lib/pydoc.py
Lib/pydoc_data/topics.py
Lib/random.py
Lib/site.py
Lib/socketserver.py
Lib/sqlite3/test/regression.py
Lib/sysconfig.py
Lib/test/_test_multiprocessing.py
Lib/test/bisect.py [deleted file]
Lib/test/bisect_cmd.py [new file with mode: 0755]
Lib/test/clinic.test [new file with mode: 0644]
Lib/test/datetimetester.py
Lib/test/eintrdata/eintr_tester.py
Lib/test/libregrtest/cmdline.py
Lib/test/libregrtest/main.py
Lib/test/libregrtest/runtest.py
Lib/test/list_tests.py
Lib/test/lock_tests.py
Lib/test/multibytecodec_support.py
Lib/test/pickletester.py
Lib/test/pythoninfo.py
Lib/test/support/__init__.py
Lib/test/talos-2019-0758.pem [new file with mode: 0644]
Lib/test/test_asyncio/test_events.py
Lib/test/test_asyncio/test_futures.py
Lib/test/test_asyncio/test_tasks.py
Lib/test/test_asyncio/test_unix_events.py
Lib/test/test_asyncio/utils.py
Lib/test/test_asyncore.py
Lib/test/test_bigmem.py
Lib/test/test_builtin.py
Lib/test/test_bytes.py
Lib/test/test_class.py
Lib/test/test_clinic.py
Lib/test/test_collections.py
Lib/test/test_dataclasses.py
Lib/test/test_doctest.py
Lib/test/test_dummy_thread.py
Lib/test/test_enum.py
Lib/test/test_faulthandler.py
Lib/test/test_float.py
Lib/test/test_frame.py
Lib/test/test_functools.py
Lib/test/test_future4.py
Lib/test/test_genericclass.py
Lib/test/test_http_cookiejar.py
Lib/test/test_imaplib.py
Lib/test/test_io.py
Lib/test/test_msilib.py
Lib/test/test_multiprocessing_main_handling.py
Lib/test/test_os.py
Lib/test/test_ossaudiodev.py
Lib/test/test_pdb.py
Lib/test/test_pydoc.py
Lib/test/test_re.py
Lib/test/test_regrtest.py
Lib/test/test_signal.py
Lib/test/test_site.py
Lib/test/test_socket.py
Lib/test/test_ssl.py
Lib/test/test_symbol.py
Lib/test/test_tarfile.py
Lib/test/test_threading.py
Lib/test/test_threading_local.py
Lib/test/test_threadsignals.py
Lib/test/test_timeout.py
Lib/test/test_unicode.py
Lib/test/test_urllib.py
Lib/test/test_urllib2net.py
Lib/test/test_urllibnet.py
Lib/test/test_urlparse.py
Lib/test/test_uu.py
Lib/test/test_venv.py
Lib/test/test_warnings/__init__.py
Lib/test/test_weakref.py
Lib/test/test_xml_etree_c.py
Lib/test/test_xmlrpc.py
Lib/test/test_zipfile64.py
Lib/test/time_hashlib.py
Lib/threading.py
Lib/tkinter/test/test_ttk/test_widgets.py
Lib/types.py
Lib/unittest/loader.py
Lib/unittest/mock.py
Lib/unittest/runner.py
Lib/unittest/test/test_loader.py
Lib/unittest/test/testmock/support.py
Lib/unittest/test/testmock/testhelpers.py
Lib/unittest/test/testmock/testmock.py
Lib/unittest/test/testmock/testpatch.py
Lib/unittest/test/testmock/testwith.py
Lib/urllib/parse.py
Lib/uu.py
Lib/venv/__init__.py
Lib/warnings.py
Lib/weakref.py
Mac/BuildScript/build-installer.py
Mac/BuildScript/tk868_on_10_8_10_9.patch [new file with mode: 0644]
Mac/IDLE/IDLE.app/Contents/Info.plist
Mac/PythonLauncher/Info.plist.in
Mac/Resources/app/Info.plist.in
Mac/Resources/framework/Info.plist.in
Misc/ACKS
Misc/NEWS
Misc/python.man
Modules/_abc.c
Modules/_asynciomodule.c
Modules/_cryptmodule.c
Modules/_ctypes/_ctypes.c
Modules/_ctypes/callproc.c
Modules/_datetimemodule.c
Modules/_elementtree.c
Modules/_functoolsmodule.c
Modules/_hashopenssl.c
Modules/_io/textio.c
Modules/_pickle.c
Modules/_posixsubprocess.c
Modules/_randommodule.c
Modules/_sha3/cleanup.py
Modules/_sqlite/connection.c
Modules/_sre.c
Modules/_ssl.c
Modules/_winapi.c
Modules/arraymodule.c
Modules/cjkcodecs/multibytecodec.c
Modules/clinic/_winapi.c.h
Modules/clinic/arraymodule.c.h
Modules/clinic/posixmodule.c.h
Modules/getpath.c
Modules/main.c
Modules/mathmodule.c
Modules/overlapped.c
Modules/posixmodule.c
Modules/socketmodule.c
Modules/sre_lib.h
Modules/timemodule.c
Objects/abstract.c
Objects/bytesobject.c
Objects/fileobject.c
Objects/frameobject.c
Objects/listobject.c
Objects/sliceobject.c
Objects/typeobject.c
Objects/unicodeobject.c
PC/_msi.c
PC/clinic/winreg.c.h
PC/config.c
PC/launcher.c
PC/layout/main.py
PC/pyconfig.h
PC/winreg.c
PCbuild/_contextvars.vcxproj [deleted file]
PCbuild/_contextvars.vcxproj.filters [deleted file]
PCbuild/find_python.bat
PCbuild/get_externals.bat
PCbuild/openssl.props
PCbuild/pcbuild.proj
PCbuild/pyproject.props
PCbuild/python.props
PCbuild/pythoncore.vcxproj
PCbuild/pythoncore.vcxproj.filters
PCbuild/tcltk.props
Python/bootstrap_hash.c
Python/getcopyright.c
Python/import.c
Python/sysmodule.c
Python/thread_nt.h
README.rst
Tools/clinic/clinic.py
Tools/gdb/libpython.py
Tools/msi/dev/dev.wixproj
Tools/msi/lib/lib_files.wxs
Tools/msi/sdktools.psm1
Tools/nuget/python.nuspec
Tools/nuget/pythondaily.nuspec
Tools/nuget/pythondaily.symbols.nuspec
Tools/nuget/pythonx86.nuspec
aclocal.m4
configure
configure.ac
pyconfig.h.in

index 49a7bb6232aa26df0fe2119c1a47d2e38a759020..15a83dd0370e1936386b5fb954dd8ee65cec4cae 100644 (file)
@@ -2,6 +2,11 @@ variables:
   manylinux: false
   coverage: false
 
+resources:
+  containers:
+  - container: manylinux1
+    image: pyca/cryptography-manylinux1:x86_64
+
 jobs:
 - job: Prebuild
   displayName: Pre-build checks
@@ -54,10 +59,12 @@ jobs:
   variables:
     testRunTitle: '$(build.sourceBranchName)-linux'
     testRunPlatform: linux
-    openssl_version: 1.1.0g
+    openssl_version: 1.1.0j
 
   steps:
   - template: ./posix-steps.yml
+    parameters:
+      dependencies: apt
 
 
 - job: ManyLinux1_CI_Tests
@@ -75,13 +82,20 @@ jobs:
   pool:
     vmImage: ubuntu-16.04
 
+  container: manylinux1
+
   variables:
     testRunTitle: '$(build.sourceBranchName)-manylinux1'
     testRunPlatform: manylinux1
-    imageName: 'dockcross/manylinux-x64'
+    openssl_version: ''
 
   steps:
-  - template: ./docker-steps.yml
+  - template: ./posix-steps.yml
+    parameters:
+      dependencies: yum
+      sudo_dependencies: ''
+      xvfb: false
+      patchcheck: false
 
 
 - job: Ubuntu_Coverage_CI_Tests
@@ -102,11 +116,12 @@ jobs:
   variables:
     testRunTitle: '$(Build.SourceBranchName)-linux-coverage'
     testRunPlatform: linux-coverage
-    openssl_version: 1.1.0g
+    openssl_version: 1.1.0j
 
   steps:
   - template: ./posix-steps.yml
     parameters:
+      dependencies: apt
       coverage: true
 
 
@@ -134,3 +149,14 @@ jobs:
 
   steps:
   - template: ./windows-steps.yml
+
+  - template: ./windows-layout-steps.yml
+    parameters:
+      kind: nuget
+  - template: ./windows-layout-steps.yml
+    parameters:
+      kind: embed
+  - template: ./windows-layout-steps.yml
+    parameters:
+      kind: appx
+      fulltest: true
diff --git a/.azure-pipelines/docker-steps.yml b/.azure-pipelines/docker-steps.yml
deleted file mode 100644 (file)
index ba4dfd7..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-steps:
-- checkout: self
-  clean: true
-  fetchDepth: 5
-
-- ${{ if ne(parameters.targetBranch, '') }}:
-  - script: |
-     git fetch -q origin ${{ parameters.targetbranch }}
-     if ! git diff --name-only HEAD $(git merge-base HEAD FETCH_HEAD) | grep -qvE '(\.rst$|^Doc|^Misc)'
-     then
-       echo "Only docs were updated, stopping build process."
-       echo "##vso[task.setvariable variable=DocOnly]true"
-       exit
-     fi
-    displayName: Detect doc-only changes
-
-- task: docker@0
-  displayName: 'Configure CPython (debug)'
-  inputs:
-    action: 'Run an image'
-    imageName: $(imageName)
-    volumes: |
-      $(build.sourcesDirectory):/src
-      $(build.binariesDirectory):/build
-    workDir: '/src'
-    containerCommand: './configure --with-pydebug'
-    detached: false
-  condition: and(succeeded(), ne(variables['DocOnly'], 'true'))
-
-- task: docker@0
-  displayName: 'Build CPython'
-  inputs:
-    action: 'Run an image'
-    imageName: $(imageName)
-    volumes: |
-      $(build.sourcesDirectory):/src
-      $(build.binariesDirectory):/build
-    workDir: '/src'
-    containerCommand: 'make -s -j4'
-    detached: false
-  condition: and(succeeded(), ne(variables['DocOnly'], 'true'))
-
-- task: docker@0
-  displayName: 'Display build info'
-  inputs:
-    action: 'Run an image'
-    imageName: $(imageName)
-    volumes: |
-      $(build.sourcesDirectory):/src
-      $(build.binariesDirectory):/build
-    workDir: '/src'
-    containerCommand: 'make pythoninfo'
-    detached: false
-  condition: and(succeeded(), ne(variables['DocOnly'], 'true'))
-
-- task: docker@0
-  displayName: 'Tests'
-  inputs:
-    action: 'Run an image'
-    imageName: $(imageName)
-    volumes: |
-      $(build.sourcesDirectory):/src
-      $(build.binariesDirectory):/build
-    workDir: '/src'
-    containerCommand: 'make buildbottest TESTOPTS="-j4 -uall,-cpu --junit-xml=/build/test-results.xml"'
-    detached: false
-  condition: and(succeeded(), ne(variables['DocOnly'], 'true'))
-
-- task: PublishTestResults@2
-  displayName: 'Publish Test Results'
-  inputs:
-    testResultsFiles: '$(build.binariesDirectory)/test-results.xml'
-    mergeTestResults: true
-    testRunTitle: $(testRunTitle)
-    platform: $(testRunPlatform)
-  condition: and(succeededOrFailed(), ne(variables['DocOnly'], 'true'))
diff --git a/.azure-pipelines/posix-deps-apt.sh b/.azure-pipelines/posix-deps-apt.sh
new file mode 100755 (executable)
index 0000000..4f48990
--- /dev/null
@@ -0,0 +1,26 @@
+apt-get update
+
+apt-get -yq install \
+    build-essential \
+    zlib1g-dev \
+    libbz2-dev \
+    liblzma-dev \
+    libncurses5-dev \
+    libreadline6-dev \
+    libsqlite3-dev \
+    libssl-dev \
+    libgdbm-dev \
+    tk-dev \
+    lzma \
+    lzma-dev \
+    liblzma-dev \
+    libffi-dev \
+    uuid-dev \
+    xvfb
+
+if [ ! -z "$1" ]
+then
+  echo ##vso[task.prependpath]$PWD/multissl/openssl/$1
+  echo ##vso[task.setvariable variable=OPENSSL_DIR]$PWD/multissl/openssl/$1
+  python3 Tools/ssl/multissltests.py --steps=library --base-directory $PWD/multissl --openssl $1 --system Linux
+fi
diff --git a/.azure-pipelines/posix-deps.sh b/.azure-pipelines/posix-deps.sh
deleted file mode 100755 (executable)
index a572107..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-sudo apt-get update
-
-sudo apt-get -yq install \
-    build-essential \
-    zlib1g-dev \
-    libbz2-dev \
-    liblzma-dev \
-    libncurses5-dev \
-    libreadline6-dev \
-    libsqlite3-dev \
-    libssl-dev \
-    libgdbm-dev \
-    tk-dev \
-    lzma \
-    lzma-dev \
-    liblzma-dev \
-    libffi-dev \
-    uuid-dev \
-    xvfb
-
-if [ ! -z "$1" ]
-then
-  echo ##vso[task.prependpath]$PWD/multissl/openssl/$1
-  echo ##vso[task.setvariable variable=OPENSSL_DIR]$PWD/multissl/openssl/$1
-  python3 Tools/ssl/multissltests.py --steps=library --base-directory $PWD/multissl --openssl $1 --system Linux
-fi
index 9fec9be8014ffd6cda5fa8e15e333c7ccad8a472..a4160e5a1bf51fa32fa7159e55b01e8125f0353a 100644 (file)
@@ -1,12 +1,16 @@
 parameters:
   coverage: false
+  sudo_dependencies: sudo
+  dependencies: apt
+  patchcheck: true
+  xvfb: true
 
 steps:
 - checkout: self
   clean: true
   fetchDepth: 5
 
-- script: ./.azure-pipelines/posix-deps.sh $(openssl_version)
+- script: ${{ parameters.sudo_dependencies }} ./.azure-pipelines/posix-deps-${{ parameters.dependencies }}.sh $(openssl_version)
   displayName: 'Install dependencies'
 
 - script: ./configure --with-pydebug
@@ -23,7 +27,7 @@ steps:
     displayName: 'Display build info'
 
   - script: |
-      xvfb-run ./venv/bin/python -m coverage run --pylib -m test \
+      $COMMAND -m coverage run --pylib -m test \
                 --fail-env-changed \
                 -uall,-cpu \
                 --junit-xml=$(build.binariesDirectory)/test-results.xml" \
@@ -32,6 +36,11 @@ steps:
                 -x test_multiprocessing_spawn \
                 -x test_concurrent_futures
     displayName: 'Tests with coverage'
+    env:
+      ${{ if eq(parameters.xvfb, 'true') }}:
+        COMMAND: xvfb-run ./venv/bin/python
+      ${{ if ne(parameters.xvfb, 'true') }}:
+        COMMAND: ./venv/bin/python
 
   - script: ./venv/bin/python -m coverage xml
     displayName: 'Generate coverage.xml'
@@ -44,13 +53,18 @@ steps:
   - script: make pythoninfo
     displayName: 'Display build info'
 
-  - script: xvfb-run make buildbottest TESTOPTS="-j4 -uall,-cpu --junit-xml=$(build.binariesDirectory)/test-results.xml"
+  - script: $COMMAND buildbottest TESTOPTS="-j4 -uall,-cpu --junit-xml=$(build.binariesDirectory)/test-results.xml"
     displayName: 'Tests'
-
-
-- script: ./python Tools/scripts/patchcheck.py --travis true
-  displayName: 'Run patchcheck.py'
-  condition: and(succeeded(), eq(variables['Build.Reason'], 'PullRequest'))
+    env:
+      ${{ if eq(parameters.xvfb, 'true') }}:
+        COMMAND: xvfb-run make
+      ${{ if ne(parameters.xvfb, 'true') }}:
+        COMMAND: make
+
+- ${{ if eq(parameters.patchcheck, 'true') }}:
+  - script: ./python Tools/scripts/patchcheck.py --travis true
+    displayName: 'Run patchcheck.py'
+    condition: and(succeeded(), eq(variables['Build.Reason'], 'PullRequest'))
 
 
 - task: PublishTestResults@2
index 2d7fba9cf3283ed8988342bd97dcc0dbc5eb8d57..0bd7921bcbefcc558e7edb1a64b8806b9474c60a 100644 (file)
@@ -1,3 +1,12 @@
+variables:
+  manylinux: false
+  coverage: false
+
+resources:
+  containers:
+  - container: manylinux1
+    image: pyca/cryptography-manylinux1:x86_64
+
 jobs:
 - job: Prebuild
   displayName: Pre-build checks
@@ -50,12 +59,70 @@ jobs:
   variables:
     testRunTitle: '$(system.pullRequest.TargetBranch)-linux'
     testRunPlatform: linux
-    openssl_version: 1.1.0g
+    openssl_version: 1.1.0j
 
   steps:
   - template: ./posix-steps.yml
     parameters:
-      targetBranch: $(System.PullRequest.TargetBranch)
+      dependencies: apt
+
+
+- job: ManyLinux1_PR_Tests
+  displayName: ManyLinux1 PR Tests
+  dependsOn: Prebuild
+  condition: |
+    and(
+        and(
+            succeeded(),
+            eq(variables['manylinux'], 'true')
+        ),
+        eq(dependencies.Prebuild.outputs['tests.run'], 'true')
+    )
+
+  pool:
+    vmImage: ubuntu-16.04
+
+  container: manylinux1
+
+  variables:
+    testRunTitle: '$(system.pullRequest.TargetBranch)-manylinux1'
+    testRunPlatform: manylinux1
+    openssl_version: ''
+
+  steps:
+  - template: ./posix-steps.yml
+    parameters:
+      dependencies: yum
+      sudo_dependencies: ''
+      xvfb: false
+      patchcheck: false
+
+
+- job: Ubuntu_Coverage_PR_Tests
+  displayName: Ubuntu PR Tests (coverage)
+  dependsOn: Prebuild
+  condition: |
+    and(
+        and(
+            succeeded(),
+            eq(variables['coverage'], 'true')
+        ),
+        eq(dependencies.Prebuild.outputs['tests.run'], 'true')
+    )
+
+  pool:
+    vmImage: ubuntu-16.04
+
+  variables:
+    testRunTitle: '$(Build.SourceBranchName)-linux-coverage'
+    testRunPlatform: linux-coverage
+    openssl_version: 1.1.0j
+
+  steps:
+  - template: ./posix-steps.yml
+    parameters:
+      dependencies: apt
+      coverage: true
 
 
 - job: Windows_PR_Tests
diff --git a/.azure-pipelines/windows-appx-test.yml b/.azure-pipelines/windows-appx-test.yml
deleted file mode 100644 (file)
index 5f3fe6c..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-jobs:
-- job: Prebuild
-  displayName: Pre-build checks
-
-  pool:
-    vmImage: ubuntu-16.04
-
-  steps:
-  - template: ./prebuild-checks.yml
-
-
-- job: Windows_Appx_Tests
-  displayName: Windows Appx Tests
-  dependsOn: Prebuild
-  condition: and(succeeded(), eq(dependencies.Prebuild.outputs['tests.run'], 'true'))
-
-  pool:
-    vmImage: vs2017-win2016
-
-  strategy:
-    matrix:
-      win64:
-        arch: amd64
-        buildOpt: '-p x64'
-        testRunTitle: '$(Build.SourceBranchName)-win64-appx'
-        testRunPlatform: win64
-    maxParallel: 2
-
-  steps:
-  - checkout: self
-    clean: true
-    fetchDepth: 5
-
-  - powershell: |
-      # Relocate build outputs outside of source directory to make cleaning faster
-      Write-Host '##vso[task.setvariable variable=Py_IntDir]$(Build.BinariesDirectory)\obj'
-      # UNDONE: Do not build to a different directory because of broken tests
-      Write-Host '##vso[task.setvariable variable=Py_OutDir]$(Build.SourcesDirectory)\PCbuild'
-      Write-Host '##vso[task.setvariable variable=EXTERNAL_DIR]$(Build.BinariesDirectory)\externals'
-    displayName: Update build locations
-
-  - script: PCbuild\build.bat -e $(buildOpt)
-    displayName: 'Build CPython'
-    env:
-      IncludeUwp: true
-
-  - script: python.bat PC\layout -vv -s "$(Build.SourcesDirectory)" -b "$(Py_OutDir)\$(arch)" -t "$(Py_IntDir)\layout-tmp-$(arch)" --copy "$(Py_IntDir)\layout-$(arch)" --precompile --preset-appx --include-tests
-    displayName: 'Create APPX layout'
-
-  - script: .\python.exe -m test.pythoninfo
-    workingDirectory: $(Py_IntDir)\layout-$(arch)
-    displayName: 'Display build info'
-
-  - script: .\python.exe -m test -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0 --junit-xml="$(Build.BinariesDirectory)\test-results.xml" --tempdir "$(Py_IntDir)\tmp-$(arch)"
-    workingDirectory: $(Py_IntDir)\layout-$(arch)
-    displayName: 'Tests'
-    env:
-      PREFIX: $(Py_IntDir)\layout-$(arch)
-
-  - task: PublishTestResults@2
-    displayName: 'Publish Test Results'
-    inputs:
-      testResultsFiles: '$(Build.BinariesDirectory)\test-results.xml'
-      mergeTestResults: true
-      testRunTitle: $(testRunTitle)
-      platform: $(testRunPlatform)
-    condition: succeededOrFailed()
diff --git a/.azure-pipelines/windows-layout-steps.yml b/.azure-pipelines/windows-layout-steps.yml
new file mode 100644 (file)
index 0000000..e15729f
--- /dev/null
@@ -0,0 +1,28 @@
+parameters:
+  kind: nuget
+  extraOpts: --precompile
+  fulltest: false
+
+steps:
+- script: .\python.bat PC\layout -vv -s "$(Build.SourcesDirectory)" -b "$(Py_OutDir)\$(arch)" -t "$(Build.BinariesDirectory)\layout-tmp-${{ parameters.kind }}-$(arch)" --copy "$(Build.BinariesDirectory)\layout-${{ parameters.kind }}-$(arch)" ${{ parameters.extraOpts }} --preset-${{ parameters.kind }} --include-tests
+  displayName: Create ${{ parameters.kind }} layout
+
+- script: .\python.exe -m test.pythoninfo
+  workingDirectory: $(Build.BinariesDirectory)\layout-${{ parameters.kind }}-$(arch)
+  displayName: Show layout info (${{ parameters.kind }})
+
+- ${{ if eq(parameters.fulltest, 'true') }}:
+  - script: .\python.exe -m test -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0 --junit-xml="$(Build.BinariesDirectory)\test-results-${{ parameters.kind }}.xml" --tempdir "$(Build.BinariesDirectory)\tmp-${{ parameters.kind }}-$(arch)"
+    workingDirectory: $(Build.BinariesDirectory)\layout-${{ parameters.kind }}-$(arch)
+    displayName: ${{ parameters.kind }} Tests
+    env:
+      PREFIX: $(Build.BinariesDirectory)\layout-${{ parameters.kind }}-$(arch)
+
+  - task: PublishTestResults@2
+    displayName: Publish ${{ parameters.kind }} Test Results
+    inputs:
+      testResultsFiles: $(Build.BinariesDirectory)\test-results-${{ parameters.kind }}.xml
+      mergeTestResults: true
+      testRunTitle: ${{ parameters.kind }}-$(testRunTitle)
+      platform: $(testRunPlatform)
+    condition: succeededOrFailed()
index cba00158ad131dd020b288ac4dbb81129fee7cf7..794a23a5d77e86597345a6793c7b1ef43d55a564 100644 (file)
@@ -1,6 +1,6 @@
 steps:
 - checkout: self
-  clean: true
+  clean: false
   fetchDepth: 5
 
 - powershell: |
@@ -8,7 +8,8 @@ steps:
     Write-Host '##vso[task.setvariable variable=Py_IntDir]$(Build.BinariesDirectory)\obj'
     # UNDONE: Do not build to a different directory because of broken tests
     Write-Host '##vso[task.setvariable variable=Py_OutDir]$(Build.SourcesDirectory)\PCbuild'
-    Write-Host '##vso[task.setvariable variable=EXTERNAL_DIR]$(Build.BinariesDirectory)\externals'
+    #Write-Host '##vso[task.setvariable variable=Py_OutDir]$(Build.BinariesDirectory)\bin'
+    Write-Host '##vso[task.setvariable variable=EXTERNALS_DIR]$(Build.BinariesDirectory)\externals'
   displayName: Update build locations
 
 - script: PCbuild\build.bat -e $(buildOpt)
index 109e9eb202d8ea9abad9132237a24fbfe58d08eb..c449ba2e719203e77948f7f24535cb7bc7afb8db 100644 (file)
@@ -17,7 +17,7 @@ Documentation bugs
 
 If you find a bug in this documentation or would like to propose an improvement,
 please submit a bug report on the :ref:`tracker <using-the-tracker>`.  If you
-have a suggestion how to fix it, include that as well.
+have a suggestion on how to fix it, include that as well.
 
 If you're short on time, you can also email documentation bug reports to
 docs@python.org (behavioral bugs can be sent to python-list@python.org).
@@ -89,4 +89,4 @@ any and all questions pertaining to the process of fixing issues in Python.
 
 .. _Documentation bugs: https://bugs.python.org/issue?@filter=status&@filter=components&components=4&status=1&@columns=id,activity,title,status&@sort=-activity
 .. _Python Developer's Guide: https://devguide.python.org/
-.. _core-mentorship mailing list: https://mail.python.org/mailman/listinfo/core-mentorship/
+.. _core-mentorship mailing list: https://mail.python.org/mailman3/lists/core-mentorship.python.org/
index 33abb5bb94d9de29fc8c811ae23dc023a91f2535..c7c1e3cc745ac40555b71ee3e8ae464981243f3d 100644 (file)
@@ -429,7 +429,7 @@ Buffer-related functions
 
    Return ``1`` if *obj* supports the buffer interface otherwise ``0``.  When ``1`` is
    returned, it doesn't guarantee that :c:func:`PyObject_GetBuffer` will
-   succeed.
+   succeed.  This function always succeeds.
 
 
 .. c:function:: int PyObject_GetBuffer(PyObject *exporter, Py_buffer *view, int flags)
@@ -470,7 +470,7 @@ Buffer-related functions
 
    Return ``1`` if the memory defined by the *view* is C-style (*order* is
    ``'C'``) or Fortran-style (*order* is ``'F'``) :term:`contiguous` or either one
-   (*order* is ``'A'``).  Return ``0`` otherwise.
+   (*order* is ``'A'``).  Return ``0`` otherwise.  This function always succeeds.
 
 
 .. c:function:: int PyBuffer_ToContiguous(void *buf, Py_buffer *src, Py_ssize_t len, char order)
index dfe3d436e5f4b7cf60a899338eb714e33b8c4d33..c55f19970e125dccdcddaf06047d0450a6f55424 100644 (file)
@@ -13,7 +13,7 @@ Codec registry and support functions
 .. c:function:: int PyCodec_KnownEncoding(const char *encoding)
 
    Return ``1`` or ``0`` depending on whether there is a registered codec for
-   the given *encoding*.
+   the given *encoding*.  This function always succeeds.
 
 .. c:function:: PyObject* PyCodec_Encode(PyObject *object, const char *encoding, const char *errors)
 
index b7225faf408ca0abed07d4f5445c7b916944b0d1..0ced5a5fd0017028bfd78d580bba616966f739ff 100644 (file)
@@ -95,6 +95,10 @@ Dictionary Objects
    Return the object from dictionary *p* which has a key *key*.  Return *NULL*
    if the key *key* is not present, but *without* setting an exception.
 
+   Note that exceptions which occur while calling :meth:`__hash__` and
+   :meth:`__eq__` methods will get suppressed.
+   To get error reporting use :c:func:`PyDict_GetItemWithError()` instead.
+
 
 .. c:function:: PyObject* PyDict_GetItemWithError(PyObject *p, PyObject *key)
 
@@ -109,8 +113,13 @@ Dictionary Objects
    This is the same as :c:func:`PyDict_GetItem`, but *key* is specified as a
    :c:type:`const char\*`, rather than a :c:type:`PyObject\*`.
 
+   Note that exceptions which occur while calling :meth:`__hash__` and
+   :meth:`__eq__` methods and creating a temporary string object
+   will get suppressed.
+   To get error reporting use :c:func:`PyDict_GetItemWithError()` instead.
+
 
-.. c:function:: PyObject* PyDict_SetDefault(PyObject *p, PyObject *key, PyObject *default)
+.. c:function:: PyObject* PyDict_SetDefault(PyObject *p, PyObject *key, PyObject *defaultobj)
 
    This is the same as the Python-level :meth:`dict.setdefault`.  If present, it
    returns the value corresponding to *key* from the dictionary *p*.  If the key
index dd1e026cb0716aa4af976577eb16abd84ce68aca..cd06096ef7bbfb1e7bc429140de77a07411bbed9 100644 (file)
@@ -53,8 +53,12 @@ Printing and clearing
 .. c:function:: void PyErr_PrintEx(int set_sys_last_vars)
 
    Print a standard traceback to ``sys.stderr`` and clear the error indicator.
-   Call this function only when the error indicator is set.  (Otherwise it will
-   cause a fatal error!)
+   **Unless** the error is a ``SystemExit``.  In that case the no traceback
+   is printed and Python process will exit with the error code specified by
+   the ``SystemExit`` instance.
+
+   Call this function **only** when the error indicator is set.  Otherwise it
+   will cause a fatal error!
 
    If *set_sys_last_vars* is nonzero, the variables :data:`sys.last_type`,
    :data:`sys.last_value` and :data:`sys.last_traceback` will be set to the
index b8eaadbd702c106e2413d9d6ff282774a169ad3c..e37dec9949ab6892c651abf715da4669eef48394 100644 (file)
@@ -60,6 +60,10 @@ See also :c:func:`PyObject_GetItem`, :c:func:`PyObject_SetItem` and
    This is equivalent to the Python expression ``key in o``.
    This function always succeeds.
 
+   Note that exceptions which occur while calling the :meth:`__getitem__`
+   method will get suppressed.
+   To get error reporting use :c:func:`PyObject_GetItem()` instead.
+
 
 .. c:function:: int PyMapping_HasKeyString(PyObject *o, const char *key)
 
@@ -67,6 +71,10 @@ See also :c:func:`PyObject_GetItem`, :c:func:`PyObject_SetItem` and
    This is equivalent to the Python expression ``key in o``.
    This function always succeeds.
 
+   Note that exceptions which occur while calling the :meth:`__getitem__`
+   method and creating a temporary string object will get suppressed.
+   To get error reporting use :c:func:`PyMapping_GetItemString()` instead.
+
 
 .. c:function:: PyObject* PyMapping_Keys(PyObject *o)
 
index 3c7605a67fa226027594b0c6f1e57eb4ef21ad49..296b21c132b79a48f1ca8b37d4bd412653d091cc 100644 (file)
@@ -280,3 +280,4 @@ Number Protocol
 
    Returns ``1`` if *o* is an index integer (has the nb_index slot of  the
    tp_as_number structure filled in), and ``0`` otherwise.
+   This function always succeeds.
index e7f4fde00256db7bb993a406927d00a0f0f49a2a..3572564b13e9b324704b2dd1885a7b315349fa99 100644 (file)
@@ -39,7 +39,11 @@ an object, and :c:func:`PyBuffer_Release` when the buffer view can be released.
 .. c:function:: int PyObject_CheckReadBuffer(PyObject *o)
 
    Returns ``1`` if *o* supports the single-segment readable buffer interface.
-   Otherwise returns ``0``.
+   Otherwise returns ``0``.  This function always succeeds.
+
+   Note that this function tries to get and release a buffer, and exceptions
+   which occur while calling corresponding functions will get suppressed.
+   To get error reporting use :c:func:`PyObject_GetBuffer()` instead.
 
 
 .. c:function:: int PyObject_AsWriteBuffer(PyObject *obj, void **buffer, Py_ssize_t *buffer_len)
index f0b2005f2d12cc940848f4edf3162c5c88fdb5dd..a64ff2e6b58b4cc69d6bfe3ffaebe6a5be3fe8ae 100644 (file)
@@ -33,6 +33,10 @@ Object Protocol
    is equivalent to the Python expression ``hasattr(o, attr_name)``.  This function
    always succeeds.
 
+   Note that exceptions which occur while calling :meth:`__getattr__` and
+   :meth:`__getattribute__` methods will get suppressed.
+   To get error reporting use :c:func:`PyObject_GetAttr()` instead.
+
 
 .. c:function:: int PyObject_HasAttrString(PyObject *o, const char *attr_name)
 
@@ -40,6 +44,11 @@ Object Protocol
    is equivalent to the Python expression ``hasattr(o, attr_name)``.  This function
    always succeeds.
 
+   Note that exceptions which occur while calling :meth:`__getattr__` and
+   :meth:`__getattribute__` methods and creating a temporary string object
+   will get suppressed.
+   To get error reporting use :c:func:`PyObject_GetAttrString()` instead.
+
 
 .. c:function:: PyObject* PyObject_GetAttr(PyObject *o, PyObject *attr_name)
 
index a66832cfa4349280dd8a633978858d5b90243906..20bf9f0b0804cdd4ca96723c726d2f9f2cc2e7f9 100644 (file)
@@ -209,7 +209,7 @@ type.
       This function "steals" a reference to *o*.
 
 
-.. c:function:: PyObject* PyStructSequence_SET_ITEM(PyObject *p, Py_ssize_t *pos, PyObject *o)
+.. c:function:: void PyStructSequence_SET_ITEM(PyObject *p, Py_ssize_t *pos, PyObject *o)
 
    Macro equivalent of :c:func:`PyStructSequence_SetItem`.
 
index 92e22b16a4ef2992db976ae06a006574b35c01d3..39c067d439cc6446ccf0f004c6de3de1e2ffa376 100644 (file)
@@ -935,7 +935,7 @@ wchar_t Support
    Return *NULL* on failure.
 
 
-.. c:function:: Py_ssize_t PyUnicode_AsWideChar(PyUnicodeObject *unicode, wchar_t *w, Py_ssize_t size)
+.. c:function:: Py_ssize_t PyUnicode_AsWideChar(PyObject *unicode, wchar_t *w, Py_ssize_t size)
 
    Copy the Unicode object contents into the :c:type:`wchar_t` buffer *w*.  At most
    *size* :c:type:`wchar_t` characters are copied (excluding a possibly trailing
@@ -1346,7 +1346,7 @@ These are the "Raw Unicode Escape" codec APIs:
 
 
 .. c:function:: PyObject* PyUnicode_EncodeRawUnicodeEscape(const Py_UNICODE *s, \
-                              Py_ssize_t size, const char *errors)
+                              Py_ssize_t size)
 
    Encode the :c:type:`Py_UNICODE` buffer of the given *size* using Raw-Unicode-Escape
    and return a bytes object.  Return *NULL* if an exception was raised by the codec.
@@ -1515,8 +1515,8 @@ the user settings on the machine running the codec.
    Return *NULL* if an exception was raised by the codec.
 
 
-.. c:function:: PyObject* PyUnicode_DecodeMBCSStateful(const char *s, int size, \
-                              const char *errors, int *consumed)
+.. c:function:: PyObject* PyUnicode_DecodeMBCSStateful(const char *s, Py_ssize_t size, \
+                              const char *errors, Py_ssize_t *consumed)
 
    If *consumed* is *NULL*, behave like :c:func:`PyUnicode_DecodeMBCS`. If
    *consumed* is not *NULL*, :c:func:`PyUnicode_DecodeMBCSStateful` will not decode
index 540ff5ef0593af71039f7b9fc384e4d3174620c1..393a1f03751f823fdc370686ebaf3aa6fb848099 100644 (file)
@@ -4,7 +4,7 @@ Copyright
 
 Python and this documentation is:
 
-Copyright © 2001-2018 Python Software Foundation. All rights reserved.
+Copyright © 2001-2019 Python Software Foundation. All rights reserved.
 
 Copyright © 2000 BeOpen.com. All rights reserved.
 
index 62cc93832783b7ef770f0f3c9f39c64d71063ecf..35527c179f3481566d7faeccaa1aa8e79f380518 100644 (file)
 # The parameter names are as they appear in the API manual, not the source
 # code.
 
+PyAnySet_Check:int:::
+PyAnySet_Check:PyObject*:p:0:
+
+PyAnySet_CheckExact:int:::
+PyAnySet_CheckExact:PyObject*:p:0:
+
+PyBool_Check:int:::
+PyBool_Check:PyObject*:o:0:
+
 PyBool_FromLong:PyObject*::+1:
-PyBool_FromLong:long:v:0:
+PyBool_FromLong:long:v::
+
+PyBuffer_FillContiguousStrides:void:::
+PyBuffer_FillContiguousStrides:int:ndims::
+PyBuffer_FillContiguousStrides:Py_ssize_t*:shape::
+PyBuffer_FillContiguousStrides:Py_ssize_t*:strides::
+PyBuffer_FillContiguousStrides:int:itemsize::
+PyBuffer_FillContiguousStrides:char:order::
+
+PyBuffer_FillInfo:int:::
+PyBuffer_FillInfo:Py_buffer*:view::
+PyBuffer_FillInfo:PyObject*:exporter:0:
+PyBuffer_FillInfo:void*:buf::
+PyBuffer_FillInfo:Py_ssize_t:len::
+PyBuffer_FillInfo:int:readonly::
+PyBuffer_FillInfo:int:flags::
+
+PyBuffer_IsContiguous:int:::
+PyBuffer_IsContiguous:Py_buffer*:view::
+PyBuffer_IsContiguous:char:order::
+
+PyBuffer_Release:void:::
+PyBuffer_Release:Py_buffer*:view::
+
+PyBuffer_ToContiguous:int:::
+PyBuffer_ToContiguous:void*:buf::
+PyBuffer_ToContiguous:Py_buffer*:src::
+PyBuffer_ToContiguous:Py_ssize_t:len::
+PyBuffer_ToContiguous:char:order::
+
+PyByteArray_AS_STRING:char*:::
+PyByteArray_AS_STRING:PyObject*:bytearray:0:
+
+PyByteArray_AsString:char*:::
+PyByteArray_AsString:PyObject*:bytearray:0:
+
+PyByteArray_Check:int:::
+PyByteArray_Check:PyObject*:o:0:
+
+PyByteArray_CheckExact:int:::
+PyByteArray_CheckExact:PyObject*:o:0:
+
+PyByteArray_Concat:PyObject*::+1:
+PyByteArray_Concat:PyObject*:a:0:
+PyByteArray_Concat:PyObject*:b:0:
+
+PyByteArray_FromObject:PyObject*::+1:
+PyByteArray_FromObject:PyObject*:o:0:
+
+PyByteArray_FromStringAndSize:PyObject*::+1:
+PyByteArray_FromStringAndSize:const char*:string::
+PyByteArray_FromStringAndSize:Py_ssize_t:len::
+
+PyByteArray_GET_SIZE:Py_ssize_t:::
+PyByteArray_GET_SIZE:PyObject*:bytearray:0:
+
+PyByteArray_Resize:int:::
+PyByteArray_Resize:PyObject*:bytearray:0:
+PyByteArray_Resize:Py_ssize_t:len::
+
+PyByteArray_Size:Py_ssize_t:::
+PyByteArray_Size:PyObject*:bytearray:0:
+
+PyBytes_AS_STRING:char*:::
+PyBytes_AS_STRING:PyObject*:string:0:
 
-PyBuffer_FromObject:PyObject*::+1:
-PyBuffer_FromObject:PyObject*:base:+1:
-PyBuffer_FromObject:int:offset::
-PyBuffer_FromObject:int:size::
+PyBytes_AsString:char*:::
+PyBytes_AsString:PyObject*:o:0:
 
-PyBuffer_FromReadWriteObject:PyObject*::+1:
-PyBuffer_FromReadWriteObject:PyObject*:base:+1:
-PyBuffer_FromReadWriteObject:int:offset::
-PyBuffer_FromReadWriteObject:int:size::
+PyBytes_AsStringAndSize:int:::
+PyBytes_AsStringAndSize:PyObject*:obj:0:
+PyBytes_AsStringAndSize:char**:buffer::
+PyBytes_AsStringAndSize:Py_ssize_t*:length::
 
-PyBuffer_FromMemory:PyObject*::+1:
-PyBuffer_FromMemory:void*:ptr::
-PyBuffer_FromMemory:int:size::
+PyBytes_Check:int:::
+PyBytes_Check:PyObject*:o:0:
 
-PyBuffer_FromReadWriteMemory:PyObject*::+1:
-PyBuffer_FromReadWriteMemory:void*:ptr::
-PyBuffer_FromReadWriteMemory:int:size::
+PyBytes_CheckExact:int:::
+PyBytes_CheckExact:PyObject*:o:0:
 
-PyBuffer_New:PyObject*::+1:
-PyBuffer_New:int:size::
+PyBytes_Concat:void:::
+PyBytes_Concat:PyObject**:bytes:0:
+PyBytes_Concat:PyObject*:newpart:0:
+
+PyBytes_ConcatAndDel:void:::
+PyBytes_ConcatAndDel:PyObject**:bytes:0:
+PyBytes_ConcatAndDel:PyObject*:newpart:-1:
+
+PyBytes_FromString:PyObject*::+1:
+PyBytes_FromString:const char*:v::
+
+PyBytes_FromStringAndSize:PyObject*::+1:
+PyBytes_FromStringAndSize:const char*:v::
+PyBytes_FromStringAndSize:Py_ssize_t:len::
+
+PyBytes_FromFormat:PyObject*::+1:
+PyBytes_FromFormat:const char*:format::
+PyBytes_FromFormat::...::
+
+PyBytes_FromFormatV:PyObject*::+1:
+PyBytes_FromFormatV:const char*:format::
+PyBytes_FromFormatV:va_list:vargs::
+
+PyBytes_FromObject:PyObject*::+1:
+PyBytes_FromObject:PyObject*:o:0:
+
+PyBytes_GET_SIZE:Py_ssize_t:::
+PyBytes_GET_SIZE:PyObject*:o:0:
+
+PyBytes_Size:Py_ssize_t:::
+PyBytes_Size:PyObject*:o:0:
+
+PyCapsule_CheckExact:int:::
+PyCapsule_CheckExact:PyObject*:p:0:
 
 PyCapsule_GetContext:void *:::
 PyCapsule_GetContext:PyObject*:self:0:
@@ -72,6 +173,10 @@ PyCapsule_Import:void *:::
 PyCapsule_Import:const char *:name::
 PyCapsule_Import:int:no_block::
 
+PyCapsule_IsValid:int:::
+PyCapsule_IsValid:PyObject*:capsule:0:
+PyCapsule_IsValid:const char*:name::
+
 PyCapsule_New:PyObject*::+1:
 PyCapsule_New:void*:pointer::
 PyCapsule_New:const char *:name::
@@ -93,21 +198,8 @@ PyCapsule_SetPointer:int:::
 PyCapsule_SetPointer:PyObject*:self:0:
 PyCapsule_SetPointer:void*:pointer::
 
-
-PyCObject_AsVoidPtr:void*:::
-PyCObject_AsVoidPtr:PyObject*:self:0:
-
-PyCObject_FromVoidPtr:PyObject*::+1:
-PyCObject_FromVoidPtr:void*:cobj::
-PyCObject_FromVoidPtr::void (* destr)(void* )::
-
-PyCObject_FromVoidPtrAndDesc:PyObject*::+1:
-PyCObject_FromVoidPtrAndDesc:void*:cobj::
-PyCObject_FromVoidPtrAndDesc:void*:desc::
-PyCObject_FromVoidPtrAndDesc:void(*)(void*,void*):destr::
-
-PyCObject_GetDesc:void*:::
-PyCObject_GetDesc:PyObject*:self:0:
+PyCell_Check:int:::
+PyCell_Check::ob::
 
 PyCell_New:PyObject*::+1:
 PyCell_New:PyObject*:ob:0:
@@ -126,19 +218,118 @@ PyCell_Set:int:::
 PyCell_Set:PyObject*:cell:0:
 PyCell_Set:PyObject*:value:0:
 
+PyCallIter_Check:int:::
+PyCallIter_Check::op::
+
 PyCallIter_New:PyObject*::+1:
-PyCallIter_New:PyObject*:callable::
-PyCallIter_New:PyObject*:sentinel::
+PyCallIter_New:PyObject*:callable:+1:
+PyCallIter_New:PyObject*:sentinel:+1:
 
 PyCallable_Check:int:::
 PyCallable_Check:PyObject*:o:0:
 
+PyCode_Check:int:::
+PyCode_Check:PyObject*:co:0:
+
+PyCode_GetNumFree:int:::
+PyCode_GetNumFree:PyCodeObject*:co:0:
+
+PyCode_New:PyCodeObject*::+1:
+PyCode_New:int:argcount::
+PyCode_New:int:kwonlyargcount::
+PyCode_New:int:nlocals::
+PyCode_New:int:stacksize::
+PyCode_New:int:flags::
+PyCode_New:PyObject*:code:0:
+PyCode_New:PyObject*:consts:0:
+PyCode_New:PyObject*:names:0:
+PyCode_New:PyObject*:varnames:0:
+PyCode_New:PyObject*:freevars:0:
+PyCode_New:PyObject*:cellvars:0:
+PyCode_New:PyObject*:filename:0:
+PyCode_New:PyObject*:name:0:
+PyCode_New:int:firstlineno::
+PyCode_New:PyObject*:lnotab:0:
+
+PyCode_NewEmpty:PyCodeObject*::+1:
+PyCode_NewEmpty:const char*:filename::
+PyCode_NewEmpty:const char*:funcname::
+PyCode_NewEmpty:int:firstlineno::
+
+PyCodec_Register:int:::
+PyCodec_Register:PyObject*:search_function:+1:
+
+PyCodec_KnownEncoding:int:::
+PyCodec_KnownEncoding:const char*:encoding::
+
+PyCodec_Encode:PyObject*::+1:
+PyCodec_Encode:PyObject*:object:0:
+PyCodec_Encode:const char*:encoding::
+PyCodec_Encode:const char*:errors::
+
+PyCodec_Decode:PyObject*::+1:
+PyCodec_Decode:PyObject*:object:0:
+PyCodec_Decode:const char*:encoding::
+PyCodec_Decode:const char*:errors::
+
+PyCodec_Encoder:PyObject*::+1:
+PyCodec_Encoder:const char*:encoding::
+
+PyCodec_Decoder:PyObject*::+1:
+PyCodec_Decoder:const char*:encoding::
+
+PyCodec_IncrementalEncoder:PyObject*::+1:
+PyCodec_IncrementalEncoder:const char*:encoding::
+PyCodec_IncrementalEncoder:const char*:errors::
+
+PyCodec_IncrementalDecoder:PyObject*::+1:
+PyCodec_IncrementalDecoder:const char*:encoding::
+PyCodec_IncrementalDecoder:const char*:errors::
+
+PyCodec_StreamReader:PyObject*::+1:
+PyCodec_StreamReader:const char*:encoding::
+PyCodec_StreamReader:PyObject*:stream:0:
+PyCodec_StreamReader:const char*:errors::
+
+PyCodec_StreamWriter:PyObject*::+1:
+PyCodec_StreamWriter:const char*:encoding::
+PyCodec_StreamWriter:PyObject*:stream:0:
+PyCodec_StreamWriter:const char*:errors::
+
+PyCodec_RegisterError:int:::
+PyCodec_RegisterError:const char*:name::
+PyCodec_RegisterError:PyObject*:error:+1:
+
+PyCodec_LookupError:PyObject*::+1:
+PyCodec_LookupError:const char*:name::
+
+PyCodec_StrictErrors:PyObject*::null:
+PyCodec_StrictErrors:PyObject*:exc:0:
+
+PyCodec_IgnoreErrors:PyObject*::+1:
+PyCodec_IgnoreErrors:PyObject*:exc:0:
+
+PyCodec_ReplaceErrors:PyObject*::+1:
+PyCodec_ReplaceErrors:PyObject*:exc:0:
+
+PyCodec_XMLCharRefReplaceErrors:PyObject*::+1:
+PyCodec_XMLCharRefReplaceErrors:PyObject*:exc:0:
+
+PyCodec_BackslashReplaceErrors:PyObject*::+1:
+PyCodec_BackslashReplaceErrors:PyObject*:exc:0:
+
+PyCodec_NameReplaceErrors:PyObject*::+1:
+PyCodec_NameReplaceErrors:PyObject*:exc:0:
+
 PyComplex_AsCComplex:Py_complex:::
 PyComplex_AsCComplex:PyObject*:op:0:
 
 PyComplex_Check:int:::
 PyComplex_Check:PyObject*:p:0:
 
+PyComplex_CheckExact:int:::
+PyComplex_CheckExact:PyObject*:p:0:
+
 PyComplex_FromCComplex:PyObject*::+1:
 PyComplex_FromCComplex::Py_complex v::
 
@@ -193,6 +384,12 @@ PyContextVar_Reset:int:::
 PyContextVar_Reset:PyObject*:var:0:
 PyContextVar_Reset:PyObject*:token:-1:
 
+PyDate_Check:int:::
+PyDate_Check:PyObject*:ob:0:
+
+PyDate_CheckExact:int:::
+PyDate_CheckExact:PyObject*:ob:0:
+
 PyDate_FromDate:PyObject*::+1:
 PyDate_FromDate:int:year::
 PyDate_FromDate:int:month::
@@ -201,6 +398,12 @@ PyDate_FromDate:int:day::
 PyDate_FromTimestamp:PyObject*::+1:
 PyDate_FromTimestamp:PyObject*:args:0:
 
+PyDateTime_Check:int:::
+PyDateTime_Check:PyObject*:ob:0:
+
+PyDateTime_CheckExact:int:::
+PyDateTime_CheckExact:PyObject*:ob:0:
+
 PyDateTime_FromDateAndTime:PyObject*::+1:
 PyDateTime_FromDateAndTime:int:year::
 PyDateTime_FromDateAndTime:int:month::
@@ -213,46 +416,62 @@ PyDateTime_FromDateAndTime:int:usecond::
 PyDateTime_FromTimestamp:PyObject*::+1:
 PyDateTime_FromTimestamp:PyObject*:args:0:
 
+PyDelta_Check:int:::
+PyDelta_Check:PyObject*:ob:0:
+
+PyDelta_CheckExact:int:::
+PyDelta_CheckExact:PyObject*:ob:0:
+
 PyDelta_FromDSU:PyObject*::+1:
 PyDelta_FromDSU:int:days::
 PyDelta_FromDSU:int:seconds::
 PyDelta_FromDSU:int:useconds::
 
 PyTimeZone_FromOffset:PyObject*::+1:
-PyTimeZone_FromOffset:PyDateTime_DeltaType*:offset:+1:Reference count not increased if offset is +00:00
+PyTimeZone_FromOffset:PyObject*:offset:+1:Reference count not increased if offset is +00:00
 
 PyTimeZone_FromOffsetAndName:PyObject*::+1:
-PyTimeZone_FromOffsetAndName:PyDateTime_DeltaType*:offset:+1:Reference count not increased if offset is +00:00 and name == NULL
-PyTimeZone_FromOffsetAndName:PyUnicode*:name:+1:
+PyTimeZone_FromOffsetAndName:PyObject*:offset:+1:Reference count not increased if offset is +00:00 and name == NULL
+PyTimeZone_FromOffsetAndName:PyObject*:name:+1:
 
 
+PyDescr_IsData:int:::
+PyDescr_IsData:PyObject*:descr:0:
+
 PyDescr_NewClassMethod:PyObject*::+1:
-PyDescr_NewClassMethod:PyTypeObject*:type::
+PyDescr_NewClassMethod:PyTypeObject*:type:+1:
 PyDescr_NewClassMethod:PyMethodDef*:method::
 
 PyDescr_NewGetSet:PyObject*::+1:
-PyDescr_NewGetSet:PyTypeObject*:type::
+PyDescr_NewGetSet:PyTypeObject*:type:+1:
 PyDescr_NewGetSet:PyGetSetDef*:getset::
 
 PyDescr_NewMember:PyObject*::+1:
-PyDescr_NewMember:PyTypeObject*:type::
+PyDescr_NewMember:PyTypeObject*:type:+1:
 PyDescr_NewMember:PyMemberDef*:member::
 
 PyDescr_NewMethod:PyObject*::+1:
-PyDescr_NewMethod:PyTypeObject*:type::
+PyDescr_NewMethod:PyTypeObject*:type:+1:
 PyDescr_NewMethod:PyMethodDef*:meth::
 
 PyDescr_NewWrapper:PyObject*::+1:
-PyDescr_NewWrapper:PyTypeObject*:type::
+PyDescr_NewWrapper:PyTypeObject*:type:+1:
 PyDescr_NewWrapper:struct wrapperbase*:base::
 PyDescr_NewWrapper:void*:wrapped::
 
 PyDict_Check:int:::
 PyDict_Check:PyObject*:p:0:
 
+PyDict_CheckExact:int:::
+PyDict_CheckExact:PyObject*:p:0:
+
 PyDict_Clear:void:::
 PyDict_Clear:PyObject*:p:0:
 
+PyDict_Contains:int:::
+PyDict_Contains:PyObject*:p:0:
+PyDict_Contains:PyObject*:key:0:
+
 PyDict_DelItem:int:::
 PyDict_DelItem:PyObject*:p:0:
 PyDict_DelItem:PyObject*:key:0:
@@ -261,7 +480,7 @@ PyDict_DelItemString:int:::
 PyDict_DelItemString:PyObject*:p:0:
 PyDict_DelItemString:const char*:key::
 
-PyDict_GetItem:PyObject*::0:0
+PyDict_GetItem:PyObject*::0:
 PyDict_GetItem:PyObject*:p:0:
 PyDict_GetItem:PyObject*:key:0:
 
@@ -289,9 +508,19 @@ PyDict_New:PyObject*::+1:
 PyDict_Copy:PyObject*::+1:
 PyDict_Copy:PyObject*:p:0:
 
+PyDict_Merge:int:::
+PyDict_Merge:PyObject*:a:0:
+PyDict_Merge:PyObject*:b:0:
+PyDict_Merge:int:override::
+
+PyDict_MergeFromSeq2:int:::
+PyDict_MergeFromSeq2:PyObject*:a:0:
+PyDict_MergeFromSeq2:PyObject*:seq2:0:
+PyDict_MergeFromSeq2:int:override::
+
 PyDict_Next:int:::
 PyDict_Next:PyObject*:p:0:
-PyDict_Next:int:ppos::
+PyDict_Next:Py_ssize_t:ppos::
 PyDict_Next:PyObject**:pkey:0:
 PyDict_Next:PyObject**:pvalue:0:
 
@@ -305,8 +534,12 @@ PyDict_SetItemString:PyObject*:p:0:
 PyDict_SetItemString:const char*:key::
 PyDict_SetItemString:PyObject*:val:+1:
 
-PyDict_Size:int:::
-PyDict_Size:PyObject*:p::
+PyDict_Size:Py_ssize_t:::
+PyDict_Size:PyObject*:p:0:
+
+PyDict_Update:int:::
+PyDict_Update:PyObject*:a:0:
+PyDict_Update:PyObject*:b:0:
 
 PyDict_Values:PyObject*::+1:
 PyDict_Values:PyObject*:p:0:
@@ -330,6 +563,21 @@ PyErr_Fetch:PyObject**:ptype:0:
 PyErr_Fetch:PyObject**:pvalue:0:
 PyErr_Fetch:PyObject**:ptraceback:0:
 
+PyErr_Format:PyObject*::null:
+PyErr_Format:PyObject*:exception:+1:
+PyErr_Format:const char*:format::
+PyErr_Format::...::
+
+PyErr_FormatV:PyObject*::null:
+PyErr_FormatV:PyObject*:exception:+1:
+PyErr_FormatV:const char*:format::
+PyErr_FormatV:va_list:vargs::
+
+PyErr_GetExcInfo:void:::
+PyErr_GetExcInfo:PyObject**:ptype:+1:
+PyErr_GetExcInfo:PyObject**:pvalue:+1:
+PyErr_GetExcInfo:PyObject**:ptraceback:+1:
+
 PyErr_GivenExceptionMatches:int:::
 PyErr_GivenExceptionMatches:PyObject*:given:0:
 PyErr_GivenExceptionMatches:PyObject*:exc:0:
@@ -356,27 +604,61 @@ PyErr_Occurred:PyObject*::0:
 
 PyErr_Print:void:::
 
+PyErr_PrintEx:void:::
+PyErr_PrintEx:int:set_sys_last_vars::
+
+PyErr_ResourceWarning:int:::
+PyErr_ResourceWarning:PyObject*:source:0:
+PyErr_ResourceWarning:Py_ssize_t:stack_level::
+PyErr_ResourceWarning:const char*:format::
+PyErr_ResourceWarning::...::
+
 PyErr_Restore:void:::
 PyErr_Restore:PyObject*:type:-1:
 PyErr_Restore:PyObject*:value:-1:
 PyErr_Restore:PyObject*:traceback:-1:
 
 PyErr_SetExcFromWindowsErr:PyObject*::null:
-PyErr_SetExcFromWindowsErr:PyObject*:type:0:
+PyErr_SetExcFromWindowsErr:PyObject*:type:+1:
 PyErr_SetExcFromWindowsErr:int:ierr::
 
 PyErr_SetExcFromWindowsErrWithFilename:PyObject*::null:
-PyErr_SetExcFromWindowsErrWithFilename:PyObject*:type:0:
+PyErr_SetExcFromWindowsErrWithFilename:PyObject*:type:+1:
 PyErr_SetExcFromWindowsErrWithFilename:int:ierr::
 PyErr_SetExcFromWindowsErrWithFilename:const char*:filename::
 
+PyErr_SetExcFromWindowsErrWithFilenameObject:PyObject*::null:
+PyErr_SetExcFromWindowsErrWithFilenameObject:PyObject*:type:+1:
+PyErr_SetExcFromWindowsErrWithFilenameObject:int:ierr::
+PyErr_SetExcFromWindowsErrWithFilenameObject:PyObject*:filename:+1:
+
+PyErr_SetExcFromWindowsErrWithFilenameObjects:PyObject*::null:
+PyErr_SetExcFromWindowsErrWithFilenameObjects:PyObject*:type:+1:
+PyErr_SetExcFromWindowsErrWithFilenameObjects:int:ierr::
+PyErr_SetExcFromWindowsErrWithFilenameObjects:PyObject*:filename:+1:
+PyErr_SetExcFromWindowsErrWithFilenameObjects:PyObject*:filename2:+1:
+
+PyErr_SetExcInfo:void:::
+PyErr_SetExcInfo:PyObject*:type:0:
+PyErr_SetExcInfo:PyObject*:value:0:
+PyErr_SetExcInfo:PyObject*:traceback:0:
+
 PyErr_SetFromErrno:PyObject*::null:
-PyErr_SetFromErrno:PyObject*:type:0:
+PyErr_SetFromErrno:PyObject*:type:+1:
 
 PyErr_SetFromErrnoWithFilename:PyObject*::null:
-PyErr_SetFromErrnoWithFilename:PyObject*:type:0:
+PyErr_SetFromErrnoWithFilename:PyObject*:type:+1:
 PyErr_SetFromErrnoWithFilename:const char*:filename::
 
+PyErr_SetFromErrnoWithFilenameObject:PyObject*::null:
+PyErr_SetFromErrnoWithFilenameObject:PyObject*:type:+1:
+PyErr_SetFromErrnoWithFilenameObject:PyObject*:filenameObject:+1:
+
+PyErr_SetFromErrnoWithFilenameObjects:PyObject*::null:
+PyErr_SetFromErrnoWithFilenameObjects:PyObject*:type:+1:
+PyErr_SetFromErrnoWithFilenameObjects:PyObject*:filenameObject:+1:
+PyErr_SetFromErrnoWithFilenameObjects:PyObject*:filenameObject2:+1:
+
 PyErr_SetFromWindowsErr:PyObject*::null:
 PyErr_SetFromWindowsErr:int:ierr::
 
@@ -384,6 +666,16 @@ PyErr_SetFromWindowsErrWithFilename:PyObject*::null:
 PyErr_SetFromWindowsErrWithFilename:int:ierr::
 PyErr_SetFromWindowsErrWithFilename:const char*:filename::
 
+PyErr_SetImportError:PyObject*::null:
+PyErr_SetImportError:PyObject*:msg:+1:
+PyErr_SetImportError:PyObject*:name:+1:
+PyErr_SetImportError:PyObject*:path:+1:
+
+PyErr_SetImportErrorSubclass:PyObject*::null:
+PyErr_SetImportErrorSubclass:PyObject*:msg:+1:
+PyErr_SetImportErrorSubclass:PyObject*:name:+1:
+PyErr_SetImportErrorSubclass:PyObject*:path:+1:
+
 PyErr_SetInterrupt:void:::
 
 PyErr_SetNone:void:::
@@ -397,31 +689,69 @@ PyErr_SetString:void:::
 PyErr_SetString:PyObject*:type:+1:
 PyErr_SetString:const char*:message::
 
-PyErr_Format:PyObject*::null:
-PyErr_Format:PyObject*:exception:+1:
-PyErr_Format:const char*:format::
-PyErr_Format::...::
+PyErr_SyntaxLocation:void:::
+PyErr_SyntaxLocation:const char*:filename::
+PyErr_SyntaxLocation:int:lineno::
 
-PyErr_FormatV:PyObject*::null:
-PyErr_FormatV:PyObject*:exception:+1:
-PyErr_FormatV:const char*:format::
-PyErr_FormatV:va_list:vargs::
+PyErr_SyntaxLocationEx:void:::
+PyErr_SyntaxLocationEx:const char*:filename::
+PyErr_SyntaxLocationEx:int:lineno::
+PyErr_SyntaxLocationEx:int:col_offset::
+
+PyErr_SyntaxLocationObject:void:::
+PyErr_SyntaxLocationObject:PyObject*:filename:+1:
+PyErr_SyntaxLocationObject:int:lineno::
+PyErr_SyntaxLocationObject:int:col_offset::
 
 PyErr_WarnEx:int:::
 PyErr_WarnEx:PyObject*:category:0:
 PyErr_WarnEx:const char*:message::
 PyErr_WarnEx:Py_ssize_t:stack_level::
 
+PyErr_WarnExplicit:int:::
+PyErr_WarnExplicit:PyObject*:category:0:
+PyErr_WarnExplicit:const char*:message::
+PyErr_WarnExplicit:const char*:filename::
+PyErr_WarnExplicit:int:lineno::
+PyErr_WarnExplicit:const char*:module::
+PyErr_WarnExplicit:PyObject*:registry:0:
+
+PyErr_WarnExplicitObject:int:::
+PyErr_WarnExplicitObject:PyObject*:category:0:
+PyErr_WarnExplicitObject:PyObject*:message:0:
+PyErr_WarnExplicitObject:PyObject*:filename:0:
+PyErr_WarnExplicitObject:int:lineno::
+PyErr_WarnExplicitObject:PyObject*:module:0:
+PyErr_WarnExplicitObject:PyObject*:registry:0:
+
+PyErr_WarnFormat:int:::
+PyErr_WarnFormat:PyObject*:category:0:
+PyErr_WarnFormat:Py_ssize_t:stack_level::
+PyErr_WarnFormat:const char*:format::
+PyErr_WarnFormat::...::
+
+PyErr_WriteUnraisable:void:::
+PyErr_WriteUnraisable:PyObject*:obj:0:
+
 PyEval_AcquireLock:void:::
 
 PyEval_AcquireThread:void:::
 PyEval_AcquireThread:PyThreadState*:tstate::
 
 PyEval_GetBuiltins:PyObject*::0:
+
 PyEval_GetLocals:PyObject*::0:
+
 PyEval_GetGlobals:PyObject*::0:
+
 PyEval_GetFrame:PyObject*::0:
 
+PyEval_GetFuncDesc:const char*:::
+PyEval_GetFuncDesc:PyObject*:func:0:
+
+PyEval_GetFuncName:const char*:::
+PyEval_GetFuncName:PyObject*:func:0:
+
 PyEval_InitThreads:void:::
 
 PyEval_ReleaseLock:void:::
@@ -434,61 +764,85 @@ PyEval_RestoreThread:PyThreadState*:tstate::
 
 PyEval_SaveThread:PyThreadState*:::
 
+PyEval_SetProfile:void:::
+PyEval_SetProfile:Py_tracefunc:func::
+PyEval_SetProfile:PyObject*:obj:+1:
+
+PyEval_SetTrace:void:::
+PyEval_SetTrace:Py_tracefunc:func::
+PyEval_SetTrace:PyObject*:obj:+1:
+
 PyEval_EvalCode:PyObject*::+1:
-PyEval_EvalCode:PyCodeObject*:co:0:
+PyEval_EvalCode:PyObject*:co:0:
 PyEval_EvalCode:PyObject*:globals:0:
 PyEval_EvalCode:PyObject*:locals:0:
 
-PyException_GetTraceback:PyObject*::+1:
+PyEval_EvalCodeEx:PyObject*::+1:
+PyEval_EvalCodeEx:PyObject*:co:0:
+PyEval_EvalCodeEx:PyObject*:globals:0:
+PyEval_EvalCodeEx:PyObject*:locals:0:
+PyEval_EvalCodeEx:PyObject*const*:args::
+PyEval_EvalCodeEx:int:argcount::
+PyEval_EvalCodeEx:PyObject*const*:kws::
+PyEval_EvalCodeEx:int:kwcount::
+PyEval_EvalCodeEx:PyObject*const*:defs::
+PyEval_EvalCodeEx:int:defcount::
+PyEval_EvalCodeEx:PyObject*:kwdefs:0:
+PyEval_EvalCodeEx:PyObject*:closure:0:
 
-PyFile_AsFile:FILE*:::
-PyFile_AsFile:PyFileObject*:p:0:
+PyEval_EvalFrame:PyObject*::+1:
+PyEval_EvalFrame:PyFrameObject*:f:0:
 
-PyFile_Check:int:::
-PyFile_Check:PyObject*:p:0:
+PyEval_EvalFrameEx:PyObject*::+1:
+PyEval_EvalFrameEx:PyFrameObject*:f:0:
+PyEval_EvalFrameEx:int:throwflag::
 
-PyFile_FromFile:PyObject*::+1:
-PyFile_FromFile:FILE*:fp::
-PyFile_FromFile:const char*:name::
-PyFile_FromFile:const char*:mode::
-PyFile_FromFile:int(*:close)::
+PyEval_MergeCompilerFlags:int:::
+PyEval_MergeCompilerFlags:PyCompilerFlags*:cf::
 
-PyFile_FromFileEx:PyObject*::+1:
-PyFile_FromFileEx:FILE*:fp::
-PyFile_FromFileEx:const char*:name::
-PyFile_FromFileEx:const char*:mode::
-PyFile_FromFileEx:int(*:close)::
-PyFile_FromFileEx:int:buffering::
-PyFile_FromFileEx:const char*:encoding::
-PyFile_FromFileEx:const char*:newline::
+PyException_GetCause:PyObject*::+1:
+PyException_GetCause:PyObject*:ex:0:
 
-PyFile_FromString:PyObject*::+1:
-PyFile_FromString:const char*:name::
-PyFile_FromString:const char*:mode::
+PyException_GetContext:PyObject*::+1:
+PyException_GetContext:PyObject*:ex:0:
+
+PyException_GetTraceback:PyObject*::+1:
+PyException_GetTraceback:PyObject*:ex:0:
+
+PyException_SetCause:void:::
+PyException_SetCause:PyObject*:ex:0:
+PyException_SetCause:PyObject*:cause:+1:
+
+PyException_SetContext:void:::
+PyException_SetContext:PyObject*:ex:0:
+PyException_SetContext:PyObject*:ctx:+1:
+
+PyException_SetTraceback:int:::
+PyException_SetTraceback:PyObject*:ex:0:
+PyException_SetTraceback:PyObject*:tb:+1:
+
+PyFile_FromFd:PyObject*::+1:
+PyFile_FromFd:int:fd::
+PyFile_FromFd:const char*:name::
+PyFile_FromFd:const char*:mode::
+PyFile_FromFd:int:buffering::
+PyFile_FromFd:const char*:encoding::
+PyFile_FromFd:const char*:errors::
+PyFile_FromFd:const char*:newline::
+PyFile_FromFd:int:closefd::
 
 PyFile_GetLine:PyObject*::+1:
-PyFile_GetLine:PyObject*:p::
+PyFile_GetLine:PyObject*:p:0:
 PyFile_GetLine:int:n::
 
-PyFile_Name:PyObject*::0:
-PyFile_Name:PyObject*:p:0:
-
-PyFile_SetBufSize:void:::
-PyFile_SetBufSize:PyFileObject*:p:0:
-PyFile_SetBufSize:int:n::
-
-PyFile_SoftSpace:int:::
-PyFile_SoftSpace:PyFileObject*:p:0:
-PyFile_SoftSpace:int:newflag::
-
 PyFile_WriteObject:int:::
 PyFile_WriteObject:PyObject*:obj:0:
-PyFile_WriteObject:PyFileObject*:p:0:
+PyFile_WriteObject:PyObject*:p:0:
 PyFile_WriteObject:int:flags::
 
 PyFile_WriteString:int:::
 PyFile_WriteString:const char*:s::
-PyFile_WriteString:PyFileObject*:p:0:
+PyFile_WriteString:PyObject*:p:0:
 PyFile_WriteString:int:flags::
 
 PyFloat_AS_DOUBLE:double:::
@@ -500,15 +854,33 @@ PyFloat_AsDouble:PyObject*:pyfloat:0:
 PyFloat_Check:int:::
 PyFloat_Check:PyObject*:p:0:
 
+PyFloat_CheckExact:int:::
+PyFloat_CheckExact:PyObject*:p:0:
+
 PyFloat_FromDouble:PyObject*::+1:
 PyFloat_FromDouble:double:v::
 
 PyFloat_FromString:PyObject*::+1:
 PyFloat_FromString:PyObject*:str:0:
 
+PyFloat_GetInfo:PyObject*::+1:
+PyFloat_GetInfo::void::
+
+PyFrozenSet_Check:int:::
+PyFrozenSet_Check:PyObject*:p:0:
+
+PyFrozenSet_CheckExact:int:::
+PyFrozenSet_CheckExact:PyObject*:p:0:
+
 PyFrozenSet_New:PyObject*::+1:
 PyFrozenSet_New:PyObject*:iterable:0:
 
+PyFunction_Check:int:::
+PyFunction_Check:PyObject*:o:0:
+
+PyFunction_GetAnnotations:PyObject*::0:
+PyFunction_GetAnnotations:PyObject*:op:0:
+
 PyFunction_GetClosure:PyObject*::0:
 PyFunction_GetClosure:PyObject*:op:0:
 
@@ -533,6 +905,10 @@ PyFunction_NewWithQualName:PyObject*:code:+1:
 PyFunction_NewWithQualName:PyObject*:globals:+1:
 PyFunction_NewWithQualName:PyObject*:qualname:+1:
 
+PyFunction_SetAnnotations:int:::
+PyFunction_SetAnnotations:PyObject*:op:0:
+PyFunction_SetAnnotations:PyObject*:annotations:+1:
+
 PyFunction_SetClosure:int:::
 PyFunction_SetClosure:PyObject*:op:0:
 PyFunction_SetClosure:PyObject*:closure:+1:
@@ -541,34 +917,34 @@ PyFunction_SetDefaults:int:::
 PyFunction_SetDefaults:PyObject*:op:0:
 PyFunction_SetDefaults:PyObject*:defaults:+1:
 
+PyGen_Check:int:::
+PyGen_Check:PyObject*:ob:0:
+
+PyGen_CheckExact:int:::
+PyGen_CheckExact:PyObject*:ob:0:
+
 PyGen_New:PyObject*::+1:
 PyGen_New:PyFrameObject*:frame:0:
 
 PyGen_NewWithQualName:PyObject*::+1:
 PyGen_NewWithQualName:PyFrameObject*:frame:0:
+PyGen_NewWithQualName:PyObject*:name:0:
+PyGen_NewWithQualName:PyObject*:qualname:0:
+
+PyCoro_CheckExact:int:::
+PyCoro_CheckExact:PyObject*:ob:0:
 
 PyCoro_New:PyObject*::+1:
 PyCoro_New:PyFrameObject*:frame:0:
-
-Py_InitModule:PyObject*::0:
-Py_InitModule:const char*:name::
-Py_InitModule:PyMethodDef[]:methods::
-
-Py_InitModule3:PyObject*::0:
-Py_InitModule3:const char*:name::
-Py_InitModule3:PyMethodDef[]:methods::
-Py_InitModule3:const char*:doc::
-
-Py_InitModule4:PyObject*::0:
-Py_InitModule4:const char*:name::
-Py_InitModule4:PyMethodDef[]:methods::
-Py_InitModule4:const char*:doc::
-Py_InitModule4:PyObject*:self::
-Py_InitModule4:int:apiver::usually provided by Py_InitModule or Py_InitModule3
+PyCoro_New:PyObject*:name:0:
+PyCoro_New:PyObject*:qualname:0:
 
 PyImport_AddModule:PyObject*::0:reference borrowed from sys.modules
 PyImport_AddModule:const char*:name::
 
+PyImport_AddModuleObject:PyObject*::0:reference borrowed from sys.modules
+PyImport_AddModuleObject:PyObject*:name:0:
+
 PyImport_Cleanup:void:::
 
 PyImport_ExecCodeModule:PyObject*::+1:
@@ -580,6 +956,21 @@ PyImport_ExecCodeModuleEx:const char*:name::
 PyImport_ExecCodeModuleEx:PyObject*:co:0:
 PyImport_ExecCodeModuleEx:const char*:pathname::
 
+PyImport_ExecCodeModuleObject:PyObject*::+1:
+PyImport_ExecCodeModuleObject:const char*:name::
+PyImport_ExecCodeModuleObject:PyObject*:co:0:
+PyImport_ExecCodeModuleObject:PyObject*:pathname:0:
+PyImport_ExecCodeModuleObject:PyObject*:cpathname:0:
+
+PyImport_ExecCodeModuleWithPathnames:PyObject*::+1:
+PyImport_ExecCodeModuleWithPathnames:const char*:name::
+PyImport_ExecCodeModuleWithPathnames:PyObject*:co:0:
+PyImport_ExecCodeModuleWithPathnames:const char*:pathname::
+PyImport_ExecCodeModuleWithPathnames:const char*:cpathname::
+
+PyImport_GetImporter:PyObject*::+1:
+PyImport_GetImporter:PyObject*:path:0:
+
 PyImport_GetMagicNumber:long:::
 
 PyImport_GetModule:PyObject*::+1:
@@ -593,6 +984,9 @@ PyImport_Import:PyObject*:name:0:
 PyImport_ImportFrozenModule:int:::
 PyImport_ImportFrozenModule:const char*:::
 
+PyImport_ImportFrozenModuleObject:int:::
+PyImport_ImportFrozenModuleObject:PyObject*::+1:
+
 PyImport_ImportModule:PyObject*::+1:
 PyImport_ImportModule:const char*:name::
 
@@ -609,39 +1003,33 @@ PyImport_ImportModuleLevel:PyObject*:locals:0:???
 PyImport_ImportModuleLevel:PyObject*:fromlist:0:???
 PyImport_ImportModuleLevel:int:level::
 
-PyImport_ReloadModule:PyObject*::+1:
-PyImport_ReloadModule:PyObject*:m:0:
-
-PyInstance_New:PyObject*::+1:
-PyInstance_New:PyObject*:klass:+1:
-PyInstance_New:PyObject*:arg:0:
-PyInstance_New:PyObject*:kw:0:
-
-PyInstance_NewRaw:PyObject*::+1:
-PyInstance_NewRaw:PyObject*:klass:+1:
-PyInstance_NewRaw:PyObject*:dict:+1:
+PyImport_ImportModuleLevelObject:PyObject*::+1:
+PyImport_ImportModuleLevelObject:PyObject*:name:0:
+PyImport_ImportModuleLevelObject:PyObject*:globals:0:???
+PyImport_ImportModuleLevelObject:PyObject*:locals:0:???
+PyImport_ImportModuleLevelObject:PyObject*:fromlist:0:???
+PyImport_ImportModuleLevelObject:int:level::
 
-PyInt_AS_LONG:long:::
-PyInt_AS_LONG:PyIntObject*:io:0:
+PyImport_ImportModuleNoBlock:PyObject*::+1:
+PyImport_ImportModuleNoBlock:const char*:name::
 
-PyInt_AsLong:long:::
-PyInt_AsLong:PyObject*:io:0:
+PyImport_ReloadModule:PyObject*::+1:
+PyImport_ReloadModule:PyObject*:m:0:
 
-PyInt_Check:int:::
-PyInt_Check:PyObject*:op:0:
+PyIndex_Check:int:::
+PyIndex_Check:PyObject*:o:0:
 
-PyInt_FromLong:PyObject*::+1:
-PyInt_FromLong:long:ival::
+PyInstanceMethod_Check:int:::
+PyInstanceMethod_Check:PyObject*:o:0:
 
-PyInt_FromString:PyObject*::+1:
-PyInt_FromString:char*:str:0:
-PyInt_FromString:char**:pend:0:
-PyInt_FromString:int:base:0:
+PyInstanceMethod_Function:PyObject*::0:
+PyInstanceMethod_Function:PyObject*:im:0:
 
-PyInt_FromSsize_t:PyObject*::+1:
-PyInt_FromSsize_t:Py_ssize_t:ival::
+PyInstanceMethod_GET_FUNCTION:PyObject*::0:
+PyInstanceMethod_GET_FUNCTION:PyObject*:im:0:
 
-PyInt_GetMax:long:::
+PyInstanceMethod_New:PyObject*::+1:
+PyInstanceMethod_New:PyObject*:func:0:
 
 PyInterpreterState_Clear:void:::
 PyInterpreterState_Clear:PyInterpreterState*:interp::
@@ -654,7 +1042,8 @@ PyInterpreterState_GetID:PyInterpreterState*:interp::
 
 PyInterpreterState_New:PyInterpreterState*:::
 
-PyIter_Check:int:o:0:
+PyIter_Check:int:::
+PyIter_Check:PyObject*:o:0:
 
 PyIter_Next:PyObject*::+1:
 PyIter_Next:PyObject*:o:0:
@@ -669,50 +1058,53 @@ PyList_AsTuple:PyObject*:list:0:
 PyList_Check:int:::
 PyList_Check:PyObject*:p:0:
 
+PyList_CheckExact:int:::
+PyList_CheckExact:PyObject*:p:0:
+
 PyList_GET_ITEM:PyObject*::0:
 PyList_GET_ITEM:PyObject*:list:0:
-PyList_GET_ITEM:int:i:0:
+PyList_GET_ITEM:Py_ssize_t:i::
 
-PyList_GET_SIZE:int:::
+PyList_GET_SIZE:Py_ssize_t:::
 PyList_GET_SIZE:PyObject*:list:0:
 
 PyList_GetItem:PyObject*::0:
 PyList_GetItem:PyObject*:list:0:
-PyList_GetItem:int:index::
+PyList_GetItem:Py_ssize_t:index::
 
 PyList_GetSlice:PyObject*::+1:
 PyList_GetSlice:PyObject*:list:0:
-PyList_GetSlice:int:low::
-PyList_GetSlice:int:high::
+PyList_GetSlice:Py_ssize_t:low::
+PyList_GetSlice:Py_ssize_t:high::
 
 PyList_Insert:int:::
 PyList_Insert:PyObject*:list:0:
-PyList_Insert:int:index::
+PyList_Insert:Py_ssize_t:index::
 PyList_Insert:PyObject*:item:+1:
 
 PyList_New:PyObject*::+1:
-PyList_New:int:len::
+PyList_New:Py_ssize_t:len::
 
 PyList_Reverse:int:::
 PyList_Reverse:PyObject*:list:0:
 
 PyList_SET_ITEM:void:::
 PyList_SET_ITEM:PyObject*:list:0:
-PyList_SET_ITEM:int:i::
+PyList_SET_ITEM:Py_ssize_t:i::
 PyList_SET_ITEM:PyObject*:o:0:
 
 PyList_SetItem:int:::
 PyList_SetItem:PyObject*:list:0:
-PyList_SetItem:int:index::
+PyList_SetItem:Py_ssize_t:index::
 PyList_SetItem:PyObject*:item:0:
 
 PyList_SetSlice:int:::
 PyList_SetSlice:PyObject*:list:0:
-PyList_SetSlice:int:low::
-PyList_SetSlice:int:high::
+PyList_SetSlice:Py_ssize_t:low::
+PyList_SetSlice:Py_ssize_t:high::
 PyList_SetSlice:PyObject*:itemlist:0:but increfs its elements?
 
-PyList_Size:int:::
+PyList_Size:Py_ssize_t:::
 PyList_Size:PyObject*:list:0:
 
 PyList_Sort:int:::
@@ -724,12 +1116,44 @@ PyLong_AsDouble:PyObject*:pylong:0:
 PyLong_AsLong:long:::
 PyLong_AsLong:PyObject*:pylong:0:
 
+PyLong_AsLongAndOverflow:long:::
+PyLong_AsLongAndOverflow:PyObject*:obj:0:
+PyLong_AsLongAndOverflow:int*:overflow::
+
+PyLong_AsLongLong:long long:::
+PyLong_AsLongLong:PyObject*:obj:0:
+
+PyLong_AsLongLongAndOverflow:long long:::
+PyLong_AsLongLongAndOverflow:PyObject*:obj:0:
+PyLong_AsLongLongAndOverflow:int*:overflow::
+
+PyLong_AsSize_t:size_t:::
+PyLong_AsSize_t:PyObject*:pylong:0:
+
+PyLong_AsSsize_t:Py_ssize_t:::
+PyLong_AsSsize_t:PyObject*:pylong:0:
+
 PyLong_AsUnsignedLong:unsigned long:::
 PyLong_AsUnsignedLong:PyObject*:pylong:0:
 
+PyLong_AsUnsignedLongLong:unsigned long long:::
+PyLong_AsUnsignedLongLong:PyObject*:pylong:0:
+
+PyLong_AsUnsignedLongMask:unsigned long:::
+PyLong_AsUnsignedLongMask:PyObject*:obj:0:
+
+PyLong_AsUnsignedLongLongMask:unsigned long long:::
+PyLong_AsUnsignedLongLongMask:PyObject*:obj:0:
+
+PyLong_AsVoidPtr:void*:::
+PyLong_AsVoidPtr:PyObject*:pylong:0:
+
 PyLong_Check:int:::
 PyLong_Check:PyObject*:p:0:
 
+PyLong_CheckExact:int:::
+PyLong_CheckExact:PyObject*:p:0:
+
 PyLong_FromDouble:PyObject*::+1:
 PyLong_FromDouble:double:v::
 
@@ -742,16 +1166,26 @@ PyLong_FromLongLong:long long:v::
 PyLong_FromUnsignedLongLong:PyObject*::+1:
 PyLong_FromUnsignedLongLong:unsigned long long:v::
 
+PyLong_FromSize_t:PyObject*::+1:
+PyLong_FromSize_t:size_t:v::
+
+PyLong_FromSsize_t:PyObject*::+1:
+PyLong_FromSsize_t:Py_ssize_t:v::
+
 PyLong_FromString:PyObject*::+1:
 PyLong_FromString:const char*:str::
 PyLong_FromString:char**:pend::
 PyLong_FromString:int:base::
 
 PyLong_FromUnicode:PyObject*::+1:
-PyLong_FromUnicode:Py_UNICODE:u::
-PyLong_FromUnicode:int:length::
+PyLong_FromUnicode:Py_UNICODE*:u::
+PyLong_FromUnicode:Py_ssize_t:length::
 PyLong_FromUnicode:int:base::
 
+PyLong_FromUnicodeObject:PyObject*::+1:
+PyLong_FromUnicodeObject:PyObject*:u:0:
+PyLong_FromUnicodeObject:int:base::
+
 PyLong_FromUnsignedLong:PyObject*::+1:
 PyLong_FromUnsignedLong:unsignedlong:v::
 
@@ -787,7 +1221,7 @@ PyMapping_Items:PyObject*:o:0:
 PyMapping_Keys:PyObject*::+1:
 PyMapping_Keys:PyObject*:o:0:
 
-PyMapping_Length:int:::
+PyMapping_Length:Py_ssize_t:::
 PyMapping_Length:PyObject*:o:0:
 
 PyMapping_SetItemString:int:::
@@ -795,6 +1229,9 @@ PyMapping_SetItemString:PyObject*:o:0:
 PyMapping_SetItemString:const char*:key::
 PyMapping_SetItemString:PyObject*:v:+1:
 
+PyMapping_Size:Py_ssize_t:::
+PyMapping_Size:PyObject*:o:0:
+
 PyMapping_Values:PyObject*::+1:
 PyMapping_Values:PyObject*:o:0:
 
@@ -806,20 +1243,43 @@ PyMarshal_ReadObjectFromFile:FILE*:file::
 
 PyMarshal_ReadObjectFromString:PyObject*::+1:
 PyMarshal_ReadObjectFromString:const char*:string::
-PyMarshal_ReadObjectFromString:int:len::
+PyMarshal_ReadObjectFromString:Py_ssize_t:len::
 
 PyMarshal_WriteObjectToString:PyObject*::+1:
 PyMarshal_WriteObjectToString:PyObject*:value:0:
+PyMarshal_WriteObjectToString:int:version::
+
+PyMemoryView_Check:int:::
+PyMemoryView_Check:PyObject*:obj:0:
+
+PyMemoryView_FromBuffer:PyObject*::+1:
+PyMemoryView_FromBuffer:Py_buffer*:view::
+
+PyMemoryView_FromMemory:PyObject*::+1:
+PyMemoryView_FromMemory:char*:mem::
+PyMemoryView_FromMemory:Py_ssize_t:size::
+PyMemoryView_FromMemory:int:flags::
+
+PyMemoryView_FromObject:PyObject*::+1:
+PyMemoryView_FromObject:PyObject*:obj:0:
+
+PyMemoryView_GET_BASE:Py_buffer*:::
+PyMemoryView_GET_BASE:PyObject*:mview:0:
+
+PyMemoryView_GET_BUFFER:Py_buffer*:::
+PyMemoryView_GET_BUFFER:PyObject*:mview:0:
 
-PyMethod_Class:PyObject*::0:
-PyMethod_Class:PyObject*:im:0:
+PyMemoryView_GetContiguous:PyObject*::+1:
+PyMemoryView_GetContiguous:PyObject*:obj:0:
+PyMemoryView_GetContiguous:int:buffertype::
+PyMemoryView_GetContiguous:char:order::
+
+PyMethod_Check:int:::
+PyMethod_Check:PyObject*:o:0:
 
 PyMethod_Function:PyObject*::0:
 PyMethod_Function:PyObject*:im:0:
 
-PyMethod_GET_CLASS:PyObject*::0:
-PyMethod_GET_CLASS:PyObject*:im:0:
-
 PyMethod_GET_FUNCTION:PyObject*::0:
 PyMethod_GET_FUNCTION:PyObject*:im:0:
 
@@ -834,18 +1294,93 @@ PyMethod_New:PyObject*:class:0:
 PyMethod_Self:PyObject*::0:
 PyMethod_Self:PyObject*:im:0:
 
+PyModule_AddFunctions:int:::
+PyModule_AddFunctions:PyObject*:module:0:
+PyModule_AddFunctions:PyMethodDef*:functions::
+
+PyModule_AddIntConstant:int:::
+PyModule_AddIntConstant:PyObject*:module:0:
+PyModule_AddIntConstant:const char*:name::
+PyModule_AddIntConstant:long:value::
+
+PyModule_AddIntMacro:int:::
+PyModule_AddIntMacro:PyObject*:module:0:
+PyModule_AddIntMacro::macro::
+
+PyModule_AddObject:int:::
+PyModule_AddObject:PyObject*:module:0:
+PyModule_AddObject:const char*:name::
+PyModule_AddObject:PyObject*:value:+1:
+
+PyModule_AddStringConstant:int:::
+PyModule_AddStringConstant:PyObject*:module:0:
+PyModule_AddStringConstant:const char*:name::
+PyModule_AddStringConstant:const char*:value::
+
+PyModule_AddStringMacro:int:::
+PyModule_AddStringMacro:PyObject*:module:0:
+PyModule_AddStringMacro::macro::
+
+PyModule_Check:int:::
+PyModule_Check:PyObject*:p:0:
+
+PyModule_CheckExact:int:::
+PyModule_CheckExact:PyObject*:p:0:
+
+PyModule_Create:PyObject*::+1:
+PyModule_Create:PyModuleDef*:def::
+
+PyModule_Create2:PyObject*::+1:
+PyModule_Create2:PyModuleDef*:def::
+PyModule_Create2:int:module_api_version::
+
+PyModule_ExecDef:int:::
+PyModule_ExecDef:PyObject*:module:0:
+PyModule_ExecDef:PyModuleDef*:def::
+
+PyModule_FromDefAndSpec:PyObject*::+1:
+PyModule_FromDefAndSpec:PyModuleDef*:def::
+PyModule_FromDefAndSpec:PyObject*:spec:0:
+
+PyModule_FromDefAndSpec2:PyObject*::+1:
+PyModule_FromDefAndSpec2:PyModuleDef*:def::
+PyModule_FromDefAndSpec2:PyObject*:spec:0:
+PyModule_FromDefAndSpec2:int:module_api_version::
+
+PyModule_GetDef:PyModuleDef*::0:
+PyModule_GetDef:PyObject*:module:0:
+
 PyModule_GetDict:PyObject*::0:
-PyModule_GetDict::PyObject* module:0:
+PyModule_GetDict:PyObject*:module:0:
 
 PyModule_GetFilename:const char*:::
 PyModule_GetFilename:PyObject*:module:0:
 
+PyModule_GetFilenameObject:PyObject*::+1:
+PyModule_GetFilenameObject:PyObject*:module:0:
+
 PyModule_GetName:const char*:::
 PyModule_GetName:PyObject*:module:0:
 
+PyModule_GetNameObject:PyObject*::+1:
+PyModule_GetNameObject:PyObject*:module:0:
+
+PyModule_GetState:void*:::
+PyModule_GetState:PyObject*:module:0:
+
 PyModule_New:PyObject*::+1:
 PyModule_New::char* name::
 
+PyModule_NewObject:PyObject*::+1:
+PyModule_NewObject:PyObject*:name:+1:
+
+PyModule_SetDocString:int:::
+PyModule_SetDocString:PyObject*:module:0:
+PyModule_SetDocString:const char*:docstring::
+
+PyModuleDef_Init:PyObject*::0:
+PyModuleDef_Init:PyModuleDef*:def:0:
+
 PyNumber_Absolute:PyObject*::+1:
 PyNumber_Absolute:PyObject*:o:0:
 
@@ -857,12 +1392,12 @@ PyNumber_And:PyObject*::+1:
 PyNumber_And:PyObject*:o1:0:
 PyNumber_And:PyObject*:o2:0:
 
-PyNumber_Check:PyObject*:o:0:
-PyNumber_Check:int:::
+PyNumber_AsSsize_t:Py_ssize_t:::
+PyNumber_AsSsize_t:PyObject*:o:0:
+PyNumber_AsSsize_t:PyObject*:exc:0:
 
-PyNumber_Divide:PyObject*::+1:
-PyNumber_Divide:PyObject*:o1:0:
-PyNumber_Divide:PyObject*:o2:0:
+PyNumber_Check:int:::
+PyNumber_Check:PyObject*:o:0:
 
 PyNumber_Divmod:PyObject*::+1:
 PyNumber_Divmod:PyObject*:o1:0:
@@ -875,6 +1410,9 @@ PyNumber_FloorDivide:PyObject*::+1:
 PyNumber_FloorDivide:PyObject*:v:0:
 PyNumber_FloorDivide:PyObject*:w:0:
 
+PyNumber_Index:PyObject*::+1:
+PyNumber_Index:PyObject*:o:0:
+
 PyNumber_InPlaceAdd:PyObject*::+1:
 PyNumber_InPlaceAdd:PyObject*:v:0:
 PyNumber_InPlaceAdd:PyObject*:w:0:
@@ -883,10 +1421,6 @@ PyNumber_InPlaceAnd:PyObject*::+1:
 PyNumber_InPlaceAnd:PyObject*:v:0:
 PyNumber_InPlaceAnd:PyObject*:w:0:
 
-PyNumber_InPlaceDivide:PyObject*::+1:
-PyNumber_InPlaceDivide:PyObject*:v:0:
-PyNumber_InPlaceDivide:PyObject*:w:0:
-
 PyNumber_InPlaceFloorDivide:PyObject*::+1:
 PyNumber_InPlaceFloorDivide:PyObject*:v:0:
 PyNumber_InPlaceFloorDivide:PyObject*:w:0:
@@ -895,6 +1429,10 @@ PyNumber_InPlaceLshift:PyObject*::+1:
 PyNumber_InPlaceLshift:PyObject*:v:0:
 PyNumber_InPlaceLshift:PyObject*:w:0:
 
+PyNumber_InPlaceMatrixMultiply:PyObject*::+1:
+PyNumber_InPlaceMatrixMultiply:PyObject*:o1:0:
+PyNumber_InPlaceMatrixMultiply:PyObject*:o2:0:
+
 PyNumber_InPlaceMultiply:PyObject*::+1:
 PyNumber_InPlaceMultiply:PyObject*:v:0:
 PyNumber_InPlaceMultiply:PyObject*:w:0:
@@ -938,6 +1476,10 @@ PyNumber_Lshift:PyObject*::+1:
 PyNumber_Lshift:PyObject*:o1:0:
 PyNumber_Lshift:PyObject*:o2:0:
 
+PyNumber_MatrixMultiply:PyObject*::+1:
+PyNumber_MatrixMultiply:PyObject*:o1:0:
+PyNumber_MatrixMultiply:PyObject*:o2:0:
+
 PyNumber_Multiply:PyObject*::+1:
 PyNumber_Multiply:PyObject*:o1:0:
 PyNumber_Multiply:PyObject*:o2:0:
@@ -969,6 +1511,10 @@ PyNumber_Subtract:PyObject*::+1:
 PyNumber_Subtract:PyObject*:o1:0:
 PyNumber_Subtract:PyObject*:o2:0:
 
+PyNumber_ToBase:PyObject*::+1:
+PyNumber_ToBase:PyObject*:n:0:
+PyNumber_ToBase:int:base::
+
 PyNumber_TrueDivide:PyObject*::+1:
 PyNumber_TrueDivide:PyObject*:v:0:
 PyNumber_TrueDivide:PyObject*:w:0:
@@ -991,6 +1537,27 @@ PyOS_BeforeFork:void:::
 PyOS_FSPath:PyObject*::+1:
 PyOS_FSPath:PyObject*:path:0:
 
+PyObject_ASCII:PyObject*::+1:
+PyObject_ASCII:PyObject*:o:0:
+
+PyObject_AsCharBuffer:int:::
+PyObject_AsCharBuffer:PyObject*:obj:0:
+PyObject_AsCharBuffer:const char**:buffer::
+PyObject_AsCharBuffer:Py_ssize_t*:buffer_len::
+
+PyObject_AsReadBuffer:int:::
+PyObject_AsReadBuffer:PyObject*:obj:0:
+PyObject_AsReadBuffer:const void**:buffer::
+PyObject_AsReadBuffer:Py_ssize_t*:buffer_len::
+
+PyObject_AsWriteBuffer:int:::
+PyObject_AsWriteBuffer:PyObject*:obj:0:
+PyObject_AsWriteBuffer:void**:buffer::
+PyObject_AsWriteBuffer:Py_ssize_t*:buffer_len::
+
+PyObject_Bytes:PyObject*::+1:
+PyObject_Bytes:PyObject*:o:0:
+
 PyObject_Call:PyObject*::+1:
 PyObject_Call:PyObject*:callable_object:0:
 PyObject_Call:PyObject*:args:0:
@@ -1020,14 +1587,11 @@ PyObject_CallObject:PyObject*::+1:
 PyObject_CallObject:PyObject*:callable_object:0:
 PyObject_CallObject:PyObject*:args:0:
 
-PyObject_Cmp:int:::
-PyObject_Cmp:PyObject*:o1:0:
-PyObject_Cmp:PyObject*:o2:0:
-PyObject_Cmp:int*:result::
+PyObject_CheckBuffer:int:::
+PyObject_CheckBuffer:PyObject*:obj:0:
 
-PyObject_Compare:int:::
-PyObject_Compare:PyObject*:o1:0:
-PyObject_Compare:PyObject*:o2:0:
+PyObject_CheckReadBuffer:int:::
+PyObject_CheckReadBuffer:PyObject*:o:0:
 
 PyObject_DelAttr:int:::
 PyObject_DelAttr:PyObject*:o:0:
@@ -1044,6 +1608,46 @@ PyObject_DelItem:PyObject*:key:0:
 PyObject_Dir:PyObject*::+1:
 PyObject_Dir:PyObject*:o:0:
 
+PyObject_GC_Del:void:::
+PyObject_GC_Del:void*:op::
+
+PyObject_GC_New:TYPE*::+1:
+PyObject_GC_New::TYPE::
+PyObject_GC_New:PyTypeObject*:type:0:
+
+PyObject_GC_NewVar:TYPE*::+1:
+PyObject_GC_NewVar::TYPE::
+PyObject_GC_NewVar:PyTypeObject*:type:0:
+PyObject_GC_NewVar:Py_ssize_t:size::
+
+PyObject_GC_Resize:TYPE*::0:
+PyObject_GC_Resize::TYPE::
+PyObject_GC_Resize:PyVarObject*:op:0:
+PyObject_GC_Resize:Py_ssize_t:newsize::
+
+PyObject_GC_Track:void:::
+PyObject_GC_Track:PyObject*:op:0:
+
+PyObject_GC_UnTrack:void:::
+PyObject_GC_UnTrack:void*:op::
+
+PyObject_GenericGetAttr:PyObject*::+1:
+PyObject_GenericGetAttr:PyObject*:o:0:
+PyObject_GenericGetAttr:PyObject*:name:0:
+
+PyObject_GenericGetDict:PyObject*::+1:
+PyObject_GenericGetDict:PyObject*:o:0:
+PyObject_GenericGetDict:void*:context::
+
+PyObject_GenericSetAttr:int:::
+PyObject_GenericSetAttr:PyObject*:o:0:
+PyObject_GenericSetAttr:PyObject*:name:0:
+PyObject_GenericSetAttr:PyObject*:value:+1:
+
+PyObject_GenericSetDict:int:::
+PyObject_GenericSetDict:PyObject*:o:+1:
+PyObject_GenericSetDict:void*:context::
+
 PyObject_GetAttr:PyObject*::+1:
 PyObject_GetAttr:PyObject*:o:0:
 PyObject_GetAttr:PyObject*:attr_name:0:
@@ -1052,6 +1656,11 @@ PyObject_GetAttrString:PyObject*::+1:
 PyObject_GetAttrString:PyObject*:o:0:
 PyObject_GetAttrString:const char*:attr_name::
 
+PyObject_GetBuffer:int:::
+PyObject_GetBuffer:PyObject*:exporter:0:
+PyObject_GetBuffer:Py_buffer*:view::
+PyObject_GetBuffer:int:flags::
+
 PyObject_GetItem:PyObject*::+1:
 PyObject_GetItem:PyObject*:o:0:
 PyObject_GetItem:PyObject*:key:0:
@@ -1065,30 +1674,59 @@ PyObject_HasAttr:PyObject*:attr_name:0:
 
 PyObject_HasAttrString:int:::
 PyObject_HasAttrString:PyObject*:o:0:
-PyObject_HasAttrString:const char*:attr_name:0:
+PyObject_HasAttrString:const char*:attr_name::
 
 PyObject_Hash:int:::
 PyObject_Hash:PyObject*:o:0:
 
+PyObject_HashNotImplemented:Py_hash_t:::
+PyObject_HashNotImplemented:PyObject*:o:0:
+
+PyObject_IsInstance:int:::
+PyObject_IsInstance:PyObject*:inst:0:
+PyObject_IsInstance:PyObject*:cls:0:
+
+PyObject_IsSubclass:int:::
+PyObject_IsSubclass:PyObject*:derived:0:
+PyObject_IsSubclass:PyObject*:cls:0:
+
 PyObject_IsTrue:int:::
 PyObject_IsTrue:PyObject*:o:0:
 
 PyObject_Init:PyObject*::0:
 PyObject_Init:PyObject*:op:0:
+PyObject_Init:PyTypeObject*:type:0:
 
 PyObject_InitVar:PyVarObject*::0:
 PyObject_InitVar:PyVarObject*:op:0:
 
-PyObject_Length:int:::
+PyObject_Length:Py_ssize_t:::
 PyObject_Length:PyObject*:o:0:
 
+PyObject_LengthHint:Py_ssize_t:::
+PyObject_LengthHint:PyObject*:o:0:
+PyObject_LengthHint:Py_ssize_t:default::
+
 PyObject_NEW:PyObject*::+1:
+PyObject_NEW::TYPE::
+PyObject_NEW:PyTypeObject*:type:0:
 
 PyObject_New:PyObject*::+1:
+PyObject_New::TYPE::
+PyObject_New:PyTypeObject*:type:0:
 
 PyObject_NEW_VAR:PyObject*::+1:
+PyObject_NEW_VAR::TYPE::
+PyObject_NEW_VAR:PyTypeObject*:type:0:
+PyObject_NEW_VAR:Py_ssize_t:size::
 
 PyObject_NewVar:PyObject*::+1:
+PyObject_NewVar::TYPE::
+PyObject_NewVar:PyTypeObject*:type:0:
+PyObject_NewVar:Py_ssize_t:size::
+
+PyObject_Not:int:::
+PyObject_Not:PyObject*:o:0:
 
 PyObject_Print:int:::
 PyObject_Print:PyObject*:o:0:
@@ -1123,28 +1761,65 @@ PyObject_SetItem:PyObject*:o:0:
 PyObject_SetItem:PyObject*:key:0:
 PyObject_SetItem:PyObject*:v:+1:
 
+PyObject_Size:Py_ssize_t:::
+PyObject_Size:PyObject*:o:0:
+
 PyObject_Str:PyObject*::+1:
 PyObject_Str:PyObject*:o:0:
 
 PyObject_Type:PyObject*::+1:
 PyObject_Type:PyObject*:o:0:
 
-PyObject_Unicode:PyObject*::+1:
-PyObject_Unicode:PyObject*:o:0:
+PyObject_TypeCheck:int:::
+PyObject_TypeCheck:PyObject*:o:0:
+PyObject_TypeCheck:PyTypeObject*:type:0:
 
 PyParser_SimpleParseFile:struct _node*:::
 PyParser_SimpleParseFile:FILE*:fp::
 PyParser_SimpleParseFile:const char*:filename::
 PyParser_SimpleParseFile:int:start::
 
+PyParser_SimpleParseFileFlags:struct _node*:::
+PyParser_SimpleParseFileFlags:FILE*:fp::
+PyParser_SimpleParseFileFlags:const char*:filename::
+PyParser_SimpleParseFileFlags:int:start::
+PyParser_SimpleParseFileFlags:int:flags::
+
 PyParser_SimpleParseString:struct _node*:::
 PyParser_SimpleParseString:const char*:str::
 PyParser_SimpleParseString:int:start::
 
+PyParser_SimpleParseStringFlags:struct _node*:::
+PyParser_SimpleParseStringFlags:const char*:str::
+PyParser_SimpleParseStringFlags:int:start::
+PyParser_SimpleParseStringFlags:int:flags::
+
+PyParser_SimpleParseStringFlagsFilename:struct _node*:::
+PyParser_SimpleParseStringFlagsFilename:const char*:str::
+PyParser_SimpleParseStringFlagsFilename:const char*:filename::
+PyParser_SimpleParseStringFlagsFilename:int:start::
+PyParser_SimpleParseStringFlagsFilename:int:flags::
+
 PyRun_AnyFile:int:::
 PyRun_AnyFile:FILE*:fp::
 PyRun_AnyFile:const char*:filename::
 
+PyRun_AnyFileFlags:int:::
+PyRun_AnyFileFlags:FILE*:fp::
+PyRun_AnyFileFlags:const char*:filename::
+PyRun_AnyFileFlags:PyCompilerFlags*:flags::
+
+PyRun_AnyFileEx:int:::
+PyRun_AnyFileEx:FILE*:fp::
+PyRun_AnyFileEx:const char*:filename::
+PyRun_AnyFileEx:int:closeit::
+
+PyRun_AnyFileExFlags:int:::
+PyRun_AnyFileExFlags:FILE*:fp::
+PyRun_AnyFileExFlags:const char*:filename::
+PyRun_AnyFileExFlags:int:closeit::
+PyRun_AnyFileExFlags:PyCompilerFlags*:flags::
+
 PyRun_File:PyObject*::+1:??? -- same as eval_code2()
 PyRun_File:FILE*:fp::
 PyRun_File:const char*:filename::
@@ -1181,17 +1856,42 @@ PyRun_InteractiveLoop:int:::
 PyRun_InteractiveLoop:FILE*:fp::
 PyRun_InteractiveLoop:const char*:filename::
 
+PyRun_InteractiveLoopFlags:int:::
+PyRun_InteractiveLoopFlags:FILE*:fp::
+PyRun_InteractiveLoopFlags:const char*:filename::
+PyRun_InteractiveLoopFlags:PyCompilerFlags*:flags::
+
 PyRun_InteractiveOne:int:::
 PyRun_InteractiveOne:FILE*:fp::
 PyRun_InteractiveOne:const char*:filename::
 
+PyRun_InteractiveOneFlags:int:::
+PyRun_InteractiveOneFlags:FILE*:fp::
+PyRun_InteractiveOneFlags:const char*:filename::
+PyRun_InteractiveOneFlags:PyCompilerFlags*:flags::
+
 PyRun_SimpleFile:int:::
 PyRun_SimpleFile:FILE*:fp::
 PyRun_SimpleFile:const char*:filename::
 
+PyRun_SimpleFileEx:int:::
+PyRun_SimpleFileEx:FILE*:fp::
+PyRun_SimpleFileEx:const char*:filename::
+PyRun_SimpleFileEx:int:closeit::
+
+PyRun_SimpleFileExFlags:int:::
+PyRun_SimpleFileExFlags:FILE*:fp::
+PyRun_SimpleFileExFlags:const char*:filename::
+PyRun_SimpleFileExFlags:int:closeit::
+PyRun_SimpleFileExFlags:PyCompilerFlags*:flags::
+
 PyRun_SimpleString:int:::
 PyRun_SimpleString:const char*:command::
 
+PyRun_SimpleStringFlags:int:::
+PyRun_SimpleStringFlags:const char*:command::
+PyRun_SimpleStringFlags:PyCompilerFlags*:flags::
+
 PyRun_String:PyObject*::+1:??? -- same as eval_code2()
 PyRun_String:const char*:str::
 PyRun_String:int:start::
@@ -1205,6 +1905,9 @@ PyRun_StringFlags:PyObject*:globals:0:
 PyRun_StringFlags:PyObject*:locals:0:
 PyRun_StringFlags:PyCompilerFlags*:flags::
 
+PySeqIter_Check:int:::
+PySeqIter_Check::op::
+
 PySeqIter_New:PyObject*::+1:
 PySeqIter_New:PyObject*:seq::
 
@@ -1215,18 +1918,22 @@ PySequence_Concat:PyObject*::+1:
 PySequence_Concat:PyObject*:o1:0:
 PySequence_Concat:PyObject*:o2:0:
 
-PySequence_Count:int:::
+PySequence_Contains:int:::
+PySequence_Contains:PyObject*:o:0:
+PySequence_Contains:PyObject*:value:0:
+
+PySequence_Count:Py_ssize_t:::
 PySequence_Count:PyObject*:o:0:
 PySequence_Count:PyObject*:value:0:
 
 PySequence_DelItem:int:::
 PySequence_DelItem:PyObject*:o:0:
-PySequence_DelItem:int:i::
+PySequence_DelItem:Py_ssize_t:i::
 
 PySequence_DelSlice:int:::
 PySequence_DelSlice:PyObject*:o:0:
-PySequence_DelSlice:int:i1::
-PySequence_DelSlice:int:i2::
+PySequence_DelSlice:Py_ssize_t:i1::
+PySequence_DelSlice:Py_ssize_t:i2::
 
 PySequence_Fast:PyObject*::+1:
 PySequence_Fast:PyObject*:v:0:
@@ -1234,22 +1941,28 @@ PySequence_Fast:const char*:m::
 
 PySequence_Fast_GET_ITEM:PyObject*::0:
 PySequence_Fast_GET_ITEM:PyObject*:o:0:
-PySequence_Fast_GET_ITEM:int:i::
+PySequence_Fast_GET_ITEM:Py_ssize_t:i::
+
+PySequence_Fast_GET_SIZE:Py_ssize_t:::
+PySequence_Fast_GET_SIZE:PyObject*:o:0:
+
+PySequence_Fast_ITEMS:PyObject**:::
+PySequence_Fast_ITEMS:PyObject*:o:0:
 
 PySequence_GetItem:PyObject*::+1:
 PySequence_GetItem:PyObject*:o:0:
-PySequence_GetItem:int:i::
+PySequence_GetItem:Py_ssize_t:i::
 
 PySequence_GetSlice:PyObject*::+1:
 PySequence_GetSlice:PyObject*:o:0:
-PySequence_GetSlice:int:i1::
-PySequence_GetSlice:int:i2::
+PySequence_GetSlice:Py_ssize_t:i1::
+PySequence_GetSlice:Py_ssize_t:i2::
 
 PySequence_In:int:::
 PySequence_In:PyObject*:o:0:
 PySequence_In:PyObject*:value:0:
 
-PySequence_Index:int:::
+PySequence_Index:Py_ssize_t:::
 PySequence_Index:PyObject*:o:0:
 PySequence_Index:PyObject*:value:0:
 
@@ -1263,22 +1976,25 @@ PySequence_InPlaceRepeat:PyObject*:o:0:
 
 PySequence_ITEM:PyObject*::+1:
 PySequence_ITEM:PyObject*:o:0:
-PySequence_ITEM:int:i::
+PySequence_ITEM:Py_ssize_t:i::
 
 PySequence_Repeat:PyObject*::+1:
 PySequence_Repeat:PyObject*:o:0:
-PySequence_Repeat:int:count::
+PySequence_Repeat:Py_ssize_t:count::
 
 PySequence_SetItem:int:::
 PySequence_SetItem:PyObject*:o:0:
-PySequence_SetItem:int:i::
+PySequence_SetItem:Py_ssize_t:i::
 PySequence_SetItem:PyObject*:v:+1:
 
 PySequence_SetSlice:int:::
 PySequence_SetSlice:PyObject*:o:0:
-PySequence_SetSlice:int:i1::
-PySequence_SetSlice:int:i2::
-PySequence_SetSlice:PyObject*:v:+1:
+PySequence_SetSlice:Py_ssize_t:i1::
+PySequence_SetSlice:Py_ssize_t:i2::
+PySequence_SetSlice:PyObject*:v:0:
+
+PySequence_Size:Py_ssize_t:::
+PySequence_Size:PyObject*:o:0:
 
 PySequence_List:PyObject*::+1:
 PySequence_List:PyObject*:o:0:
@@ -1286,9 +2002,15 @@ PySequence_List:PyObject*:o:0:
 PySequence_Tuple:PyObject*::+1:
 PySequence_Tuple:PyObject*:o:0:
 
-PySet_Append:int:::
-PySet_Append:PyObject*:set:0:
-PySet_Append:PyObject*:key:+1:
+PySet_Add:int:::
+PySet_Add:PyObject*:set:0:
+PySet_Add:PyObject*:key:+1:
+
+PySet_Check:int:::
+PySet_Check:PyObject*:p:0:
+
+PySet_Clear:int:::
+PySet_Clear:PyObject*:set:0:
 
 PySet_Contains:int:::
 PySet_Contains:PyObject*:anyset:0:
@@ -1298,15 +2020,21 @@ PySet_Discard:int:::
 PySet_Discard:PyObject*:set:0:
 PySet_Discard:PyObject*:key:-1:no effect if key not found
 
+PySet_GET_SIZE:Py_ssize_t:::
+PySet_GET_SIZE:PyObject*:anyset:0:
+
 PySet_New:PyObject*::+1:
 PySet_New:PyObject*:iterable:0:
 
 PySet_Pop:PyObject*::+1:or returns NULL and raises KeyError if set is empty
 PySet_Pop:PyObject*:set:0:
 
-PySet_Size:int:::
+PySet_Size:Py_ssize_t:::
 PySet_Size:PyObject*:anyset:0:
 
+PySignal_SetWakeupFd:int:::
+PySignal_SetWakeupFd:int:fd::
+
 PySlice_AdjustIndices:Py_ssize_t:::
 PySlice_AdjustIndices:Py_ssize_t:length::
 PySlice_AdjustIndices:Py_ssize_t*:start::
@@ -1316,6 +2044,21 @@ PySlice_AdjustIndices:Py_ssize_t*:step::
 PySlice_Check:int:::
 PySlice_Check:PyObject*:ob:0:
 
+PySlice_GetIndices:int:::
+PySlice_GetIndices:PyObject*:slice:0:
+PySlice_GetIndices:Py_ssize_t:length::
+PySlice_GetIndices:Py_ssize_t*:start::
+PySlice_GetIndices:Py_ssize_t*:stop::
+PySlice_GetIndices:Py_ssize_t*:step::
+
+PySlice_GetIndicesEx:int:::
+PySlice_GetIndicesEx:PyObject*:slice:0:
+PySlice_GetIndicesEx:Py_ssize_t:length::
+PySlice_GetIndicesEx:Py_ssize_t*:start::
+PySlice_GetIndicesEx:Py_ssize_t*:stop::
+PySlice_GetIndicesEx:Py_ssize_t*:step::
+PySlice_GetIndicesEx:Py_ssize_t*:slicelength::
+
 PySlice_New:PyObject*::+1:
 PySlice_New:PyObject*:start:0:
 PySlice_New:PyObject*:stop:0:
@@ -1327,100 +2070,78 @@ PySlice_Unpack:Py_ssize_t*:start::
 PySlice_Unpack:Py_ssize_t*:stop::
 PySlice_Unpack:Py_ssize_t*:step::
 
-PyString_AS_STRING:const char*:::
-PyString_AS_STRING:PyObject*:string:0:
-
-PyString_AsDecodedObject:PyObject*::+1:
-PyString_AsDecodedObject:PyObject*:str:0:
-PyString_AsDecodedObject:const char*:encoding::
-PyString_AsDecodedObject:const char*:errors::
-
-PyString_AsEncodedObject:PyObject*::+1:
-PyString_AsEncodedObject:PyObject*:str:0:
-PyString_AsEncodedObject:const char*:encoding::
-PyString_AsEncodedObject:const char*:errors::
-
-PyString_AsString:const char*:::
-PyString_AsString:PyObject*:string:0:
-
-PyString_AsStringAndSize:int:::
-PyString_AsStringAndSize:PyObject*:obj:0:
-PyString_AsStringAndSize:char**:buffer::
-PyString_AsStringAndSize:int*:length::
-
-PyString_Check:int:::
-PyString_Check:PyObject*:o:0:
-
-PyString_Concat:void:::
-PyString_Concat:PyObject**:string:0:??? -- replaces w/ new string or NULL
-PyString_Concat:PyObject*:newpart:0:
-
-PyString_ConcatAndDel:void:::
-PyString_ConcatAndDel:PyObject**:string:0:??? -- replaces w/ new string or NULL
-PyString_ConcatAndDel:PyObject*:newpart:-1:
-
-PyString_Format:PyObject*::+1:
-PyString_Format:PyObject*:format:0:
-PyString_Format:PyObject*:args:0:
-
-PyString_FromString:PyObject*::+1:
-PyString_FromString:const char*:v::
+PyState_AddModule:int:::
+PyState_AddModule:PyObject*:module:+1:
+PyState_AddModule:PyModuleDef*:def::
 
-PyString_FromStringAndSize:PyObject*::+1:
-PyString_FromStringAndSize:const char*:v::
-PyString_FromStringAndSize:int:len::
+PyState_FindModule:PyObject*::0:
+PyState_FindModule:PyModuleDef*:def::
 
-PyString_FromFormat:PyObject*::+1:
-PyString_FromFormat:const char*:format::
-PyString_FromFormat::...::
+PyState_RemoveModule:int:::
+PyState_RemoveModule:PyModuleDef*:def::
 
-PyString_FromFormatV:PyObject*::+1:
-PyString_FromFormatV:const char*:format::
-PyString_FromFormatV:va_list:vargs::
+PyStructSequence_GET_ITEM:PyObject*::0:
+PyStructSequence_GET_ITEM:PyObject*:p:0:
+PyStructSequence_GET_ITEM:Py_ssize_t:pos::
 
-PyString_GET_SIZE:int:::
-PyString_GET_SIZE:PyObject*:string:0:
+PyStructSequence_GetItem:PyObject*::0:
+PyStructSequence_GetItem:PyObject*:p:0:
+PyStructSequence_GetItem:Py_ssize_t:pos::
 
-PyString_InternFromString:PyObject*::+1:
-PyString_InternFromString:const char*:v::
+PyStructSequence_InitType:void:::
+PyStructSequence_InitType:PyTypeObject*:type:+1:
+PyStructSequence_InitType:PyStructSequence_Desc*:desc::
 
-PyString_InternInPlace:void:::
-PyString_InternInPlace:PyObject**:string:+1:???
+PyStructSequence_InitType2:int:::
+PyStructSequence_InitType2:PyTypeObject*:type:+1:
+PyStructSequence_InitType2:PyStructSequence_Desc*:desc::
 
-PyString_Size:int:::
-PyString_Size:PyObject*:string:0:
+PyStructSequence_New:PyObject*::+1:
+PyStructSequence_New:PyTypeObject*:type:0:
 
-PyString_Decode:PyObject*::+1:
-PyString_Decode:const char*:s::
-PyString_Decode:int:size::
-PyString_Decode:const char*:encoding::
-PyString_Decode:const char*:errors::
+PyStructSequence_NewType:PyTypeObject*::+1:
+PyStructSequence_NewType:PyStructSequence_Desc*:desc::
 
-PyString_Encode:PyObject*::+1:
-PyString_Encode:const char*:s::
-PyString_Encode:int:size::
-PyString_Encode:const char*:encoding::
-PyString_Encode:const char*:errors::
+PyStructSequence_SET_ITEM:void:::
+PyStructSequence_SET_ITEM:PyObject*:p:0:
+PyStructSequence_SET_ITEM:Py_ssize_t*:pos::
+PyStructSequence_SET_ITEM:PyObject*:o:0:
 
-PyString_AsEncodedString:PyObject*::+1:
-PyString_AsEncodedString:PyObject*:str::
-PyString_AsEncodedString:const char*:encoding::
-PyString_AsEncodedString:const char*:errors::
+PyStructSequence_SetItem:void:::
+PyStructSequence_SetItem:PyObject*:p:0:
+PyStructSequence_SetItem:Py_ssize_t:pos::
+PyStructSequence_SetItem:PyObject*:o:0:
 
 PySys_AddWarnOption:void:::
-PySys_AddWarnOption:const char*:s::
+PySys_AddWarnOption:const wchar_t*:s::
+
+PySys_AddWarnOptionUnicode:void:::
+PySys_AddWarnOptionUnicode:PyObject*:unicode:0:
 
 PySys_AddXOption:void:::
 PySys_AddXOption:const wchar_t*:s::
 
+PySys_FormatStderr:void:::
+PySys_FormatStderr:const char*:format::
+PySys_FormatStderr::...::
+
+PySys_FormatStdout:void:::
+PySys_FormatStdout:const char*:format::
+PySys_FormatStdout::...::
+
 PySys_GetObject:PyObject*::0:
 PySys_GetObject:const char*:name::
 
 PySys_GetXOptions:PyObject*::0:
 
-PySys_SetArgv:int:::
+PySys_SetArgv:void:::
 PySys_SetArgv:int:argc::
-PySys_SetArgv:char**:argv::
+PySys_SetArgv:wchar_t**:argv::
+
+PySys_SetArgvEx:void:::
+PySys_SetArgvEx:int:argc::
+PySys_SetArgvEx:wchar_t**:argv::
+PySys_SetArgvEx:int:updatepath::
 
 PySys_SetObject:int:::
 PySys_SetObject:const char*:name::
@@ -1430,9 +2151,11 @@ PySys_ResetWarnOptions:void:::
 
 PySys_WriteStdout:void:::
 PySys_WriteStdout:const char*:format::
+PySys_WriteStdout::...::
 
 PySys_WriteStderr:void:::
 PySys_WriteStderr:const char*:format::
+PySys_WriteStderr::...::
 
 PyThreadState_Clear:void:::
 PyThreadState_Clear:PyThreadState*:tstate::
@@ -1447,6 +2170,10 @@ PyThreadState_GetDict:PyObject*::0:
 PyThreadState_New:PyThreadState*:::
 PyThreadState_New:PyInterpreterState*:interp::
 
+PyThreadState_SetAsyncExc:int:::
+PyThreadState_SetAsyncExc:unsigned long:id::
+PyThreadState_SetAsyncExc:PyObject*:exc:+1:
+
 PyThreadState_Swap:PyThreadState*:::
 PyThreadState_Swap:PyThreadState*:tstate::
 
@@ -1471,6 +2198,12 @@ PyThread_tss_set:int:::
 PyThread_tss_set:Py_tss_t*:key::
 PyThread_tss_set:void*:value::
 
+PyTime_Check:int:::
+PyTime_Check:PyObject*:ob:0:
+
+PyTime_CheckExact:int:::
+PyTime_CheckExact:PyObject*:ob:0:
+
 PyTime_FromTime:PyObject*::+1:
 PyTime_FromTime:int:hour::
 PyTime_FromTime:int:minute::
@@ -1489,63 +2222,130 @@ PyTraceMalloc_Untrack:uintptr_t:ptr::
 PyTuple_Check:int:::
 PyTuple_Check:PyObject*:p:0:
 
+PyTuple_CheckExact:int:::
+PyTuple_CheckExact:PyObject*:p:0:
+
 PyTuple_GET_ITEM:PyObject*::0:
-PyTuple_GET_ITEM:PyTupleObject*:p:0:
-PyTuple_GET_ITEM:int:pos::
+PyTuple_GET_ITEM:PyObject*:p:0:
+PyTuple_GET_ITEM:Py_ssize_t:pos::
 
 PyTuple_GetItem:PyObject*::0:
-PyTuple_GetItem:PyTupleObject*:p:0:
-PyTuple_GetItem:int:pos::
+PyTuple_GetItem:PyObject*:p:0:
+PyTuple_GetItem:Py_ssize_t:pos::
+
+PyTuple_GET_SIZE:Py_ssize_t:::
+PyTuple_GET_SIZE:PyObject*:p:0:
 
 PyTuple_GetSlice:PyObject*::+1:
-PyTuple_GetSlice:PyTupleObject*:p:0:
-PyTuple_GetSlice:int:low::
-PyTuple_GetSlice:int:high::
+PyTuple_GetSlice:PyObject*:p:0:
+PyTuple_GetSlice:Py_ssize_t:low::
+PyTuple_GetSlice:Py_ssize_t:high::
 
 PyTuple_New:PyObject*::+1:
-PyTuple_New:int:len::
+PyTuple_New:Py_ssize_t:len::
 
 PyTuple_Pack:PyObject*::+1:
-PyTuple_Pack:int:len::
+PyTuple_Pack:Py_ssize_t:len::
 PyTuple_Pack:PyObject*:...:0:
 
 PyTuple_SET_ITEM:void:::
-PyTuple_SET_ITEM:PyTupleObject*:p:0:
-PyTuple_SET_ITEM:int:pos::
+PyTuple_SET_ITEM:PyObject*:p:0:
+PyTuple_SET_ITEM:Py_ssize_t:pos::
 PyTuple_SET_ITEM:PyObject*:o:0:
 
 PyTuple_SetItem:int:::
-PyTuple_SetItem:PyTupleObject*:p:0:
-PyTuple_SetItem:int:pos::
+PyTuple_SetItem:PyObject*:p:0:
+PyTuple_SetItem:Py_ssize_t:pos::
 PyTuple_SetItem:PyObject*:o:0:
 
-PyTuple_Size:int:::
-PyTuple_Size:PyTupleObject*:p:0:
+PyTuple_Size:Py_ssize_t:::
+PyTuple_Size:PyObject*:p:0:
+
+PyType_Check:int:::
+PyType_Check:PyObject*:o:0:
+
+PyType_CheckExact:int:::
+PyType_CheckExact:PyObject*:o:0:
+
+PyType_FromSpec:PyObject*::+1:
+PyType_FromSpec:PyType_Spec*:spec::
+
+PyType_FromSpecWithBases:PyObject*::+1:
+PyType_FromSpecWithBases:PyType_Spec*:spec::
+PyType_FromSpecWithBases:PyObject*:bases:0:
 
 PyType_GenericAlloc:PyObject*::+1:
 PyType_GenericAlloc:PyObject*:type:0:
-PyType_GenericAlloc:int:nitems:0:
+PyType_GenericAlloc:Py_ssize_t:nitems::
 
 PyType_GenericNew:PyObject*::+1:
 PyType_GenericNew:PyObject*:type:0:
 PyType_GenericNew:PyObject*:args:0:
 PyType_GenericNew:PyObject*:kwds:0:
 
+PyType_GetFlags:unsigned long:::
+PyType_GetFlags:PyTypeObject*:type:0:
+
+PyType_GetSlot:void*:::
+PyType_GetSlot:PyTypeObject*:type:0:
+PyType_GetSlot:int:slot::
+
+PyType_HasFeature:int:::
+PyType_HasFeature:PyTypeObject*:o:0:
+PyType_HasFeature:int:feature::
+
+PyType_IS_GC:int:::
+PyType_IS_GC:PyTypeObject*:o:0:
+
+PyType_IsSubtype:int:::
+PyType_IsSubtype:PyTypeObject*:a:0:
+PyType_IsSubtype:PyTypeObject*:b:0:
+
+PyType_Modified:void:::
+PyType_Modified:PyTypeObject*:type:0:
+
+PyType_Ready:int:::
+PyType_Ready:PyTypeObject*:type:0:
+
+PyUnicode_1BYTE_DATA:Py_UCS1*:::
+PyUnicode_1BYTE_DATA:PyObject*:o:0:
+
 PyUnicode_Check:int:::
 PyUnicode_Check:PyObject*:o:0:
 
-PyUnicode_GET_SIZE:int:::
+PyUnicode_CheckExact:int:::
+PyUnicode_CheckExact:PyObject*:o:0:
+
+PyUnicode_DATA:void*:::
+PyUnicode_DATA:PyObject*:o:0:
+
+PyUnicode_GET_LENGTH:Py_ssize_t:::
+PyUnicode_GET_LENGTH:PyObject*:o:0:
+
+PyUnicode_GET_SIZE:Py_ssize_t:::
 PyUnicode_GET_SIZE:PyObject*:o:0:
 
-PyUnicode_GET_DATA_SIZE:int:::
+PyUnicode_GET_DATA_SIZE:Py_ssize_t:::
 PyUnicode_GET_DATA_SIZE:PyObject*:o:0:
 
+PyUnicode_KIND:int:::
+PyUnicode_KIND:PyObject*:o:0:
+
+PyUnicode_MAX_CHAR_VALUE::::
+PyUnicode_MAX_CHAR_VALUE:PyObject*:o:0:
+
 PyUnicode_AS_UNICODE:Py_UNICODE*:::
 PyUnicode_AS_UNICODE:PyObject*:o:0:
 
 PyUnicode_AS_DATA:const char*:::
 PyUnicode_AS_DATA:PyObject*:o:0:
 
+Py_UNICODE_ISALNUM:int:::
+Py_UNICODE_ISALNUM:Py_UNICODE:ch::
+
+Py_UNICODE_ISALPHA:int:::
+Py_UNICODE_ISALPHA:Py_UNICODE:ch::
+
 Py_UNICODE_ISSPACE:int:::
 Py_UNICODE_ISSPACE:Py_UNICODE:ch::
 
@@ -1570,6 +2370,9 @@ Py_UNICODE_ISDIGIT:Py_UNICODE:ch::
 Py_UNICODE_ISNUMERIC:int:::
 Py_UNICODE_ISNUMERIC:Py_UNICODE:ch::
 
+Py_UNICODE_ISPRINTABLE:int:::
+Py_UNICODE_ISPRINTABLE:Py_UNICODE:ch::
+
 Py_UNICODE_TOLOWER:Py_UNICODE:::
 Py_UNICODE_TOLOWER:Py_UNICODE:ch::
 
@@ -1590,150 +2393,210 @@ Py_UNICODE_TONUMERIC:Py_UNICODE:ch::
 
 PyUnicode_FromUnicode:PyObject*::+1:
 PyUnicode_FromUnicode:const Py_UNICODE*:u::
-PyUnicode_FromUnicode:int:size::
+PyUnicode_FromUnicode:Py_ssize_t:size::
 
 PyUnicode_AsUnicode:Py_UNICODE*:::
-PyUnicode_AsUnicode:PyObject :*unicode:0:
+PyUnicode_AsUnicode:PyObject*:unicode:0:
+
+PyUnicode_TransformDecimalToASCII:PyObject*::+1:
+PyUnicode_TransformDecimalToASCII:Py_UNICODE*:s::
+PyUnicode_TransformDecimalToASCII:Py_ssize_t:size::
+
+PyUnicode_AsUnicodeAndSize:Py_UNICODE*:::
+PyUnicode_AsUnicodeAndSize:PyObject*:unicode:0:
+PyUnicode_AsUnicodeAndSize:Py_ssize_t*:size::
+
+PyUnicode_AsUnicodeCopy:Py_UNICODE*:::
+PyUnicode_AsUnicodeCopy:PyObject*:unicode:0:
 
-PyUnicode_GetSize:int:::
-PyUnicode_GetSize:PyObject :*unicode:0:
+PyUnicode_GetSize:Py_ssize_t:::
+PyUnicode_GetSize:PyObject*:unicode:0:
 
 PyUnicode_FromObject:PyObject*::+1:
-PyUnicode_FromObject:PyObject*:*obj:0:
+PyUnicode_FromObject:PyObject*:obj:0:
 
 PyUnicode_FromEncodedObject:PyObject*::+1:
-PyUnicode_FromEncodedObject:PyObject*:*obj:0:
+PyUnicode_FromEncodedObject:PyObject*:obj:0:
 PyUnicode_FromEncodedObject:const char*:encoding::
 PyUnicode_FromEncodedObject:const char*:errors::
 
 PyUnicode_FromWideChar:PyObject*::+1:
 PyUnicode_FromWideChar:const wchar_t*:w::
-PyUnicode_FromWideChar:int:size::
+PyUnicode_FromWideChar:Py_ssize_t:size::
 
-PyUnicode_AsWideChar:int:::
+PyUnicode_AsWideChar:Py_ssize_t:::
 PyUnicode_AsWideChar:PyObject*:*unicode:0:
 PyUnicode_AsWideChar:wchar_t*:w::
-PyUnicode_AsWideChar:int:size::
+PyUnicode_AsWideChar:Pyssize_t:size::
+
+PyUnicode_AsWideCharString:wchar_t*:::
+PyUnicode_AsWideCharString:PyObject*:unicode:0:
+PyUnicode_AsWideCharString:Py_ssize_t*:size::
 
 PyUnicode_Decode:PyObject*::+1:
 PyUnicode_Decode:const char*:s::
-PyUnicode_Decode:int:size::
+PyUnicode_Decode:Py_ssize_t:size::
 PyUnicode_Decode:const char*:encoding::
 PyUnicode_Decode:const char*:errors::
 
 PyUnicode_DecodeUTF16Stateful:PyObject*::+1:
 PyUnicode_DecodeUTF16Stateful:const char*:s::
-PyUnicode_DecodeUTF16Stateful:int:size::
+PyUnicode_DecodeUTF16Stateful:Py_ssize_t:size::
 PyUnicode_DecodeUTF16Stateful:const char*:errors::
 PyUnicode_DecodeUTF16Stateful:int*:byteorder::
-PyUnicode_DecodeUTF16Stateful:int*:consumed::
+PyUnicode_DecodeUTF16Stateful:Py_ssize_t*:consumed::
 
 PyUnicode_DecodeUTF8Stateful:PyObject*::+1:
 PyUnicode_DecodeUTF8Stateful:const char*:s::
-PyUnicode_DecodeUTF8Stateful:int:size::
+PyUnicode_DecodeUTF8Stateful:Py_ssize_t:size::
 PyUnicode_DecodeUTF8Stateful:const char*:errors::
-PyUnicode_DecodeUTF8Stateful:int*:consumed::
+PyUnicode_DecodeUTF8Stateful:Py_ssize_t*:consumed::
 
 PyUnicode_Encode:PyObject*::+1:
 PyUnicode_Encode:const Py_UNICODE*:s::
-PyUnicode_Encode:int:size::
+PyUnicode_Encode:Py_ssize_t:size::
 PyUnicode_Encode:const char*:encoding::
 PyUnicode_Encode:const char*:errors::
 
 PyUnicode_AsEncodedString:PyObject*::+1:
-PyUnicode_AsEncodedString:PyObject*:unicode::
+PyUnicode_AsEncodedString:PyObject*:unicode:0:
 PyUnicode_AsEncodedString:const char*:encoding::
 PyUnicode_AsEncodedString:const char*:errors::
 
+PyUnicode_DecodeUTF7:PyObject*::+1:
+PyUnicode_DecodeUTF7:const char*:s::
+PyUnicode_DecodeUTF7:Py_ssize_t:size::
+PyUnicode_DecodeUTF7:const char*:errors::
+
+PyUnicode_DecodeUTF7Stateful:PyObject*::+1:
+PyUnicode_DecodeUTF7Stateful:const char*:s::
+PyUnicode_DecodeUTF7Stateful:Py_ssize_t:size::
+PyUnicode_DecodeUTF7Stateful:const char*:errors::
+PyUnicode_DecodeUTF7Stateful:Py_ssize_t*:consumed::
+
+PyUnicode_EncodeUTF7:PyObject*::+1:
+PyUnicode_EncodeUTF7:const Py_UNICODE*:s::
+PyUnicode_EncodeUTF7:Py_ssize_t:size::
+PyUnicode_EncodeUTF7:int:base64SetO::
+PyUnicode_EncodeUTF7:int:base64WhiteSpace::
+PyUnicode_EncodeUTF7:const char*:errors::
+
 PyUnicode_DecodeUTF8:PyObject*::+1:
 PyUnicode_DecodeUTF8:const char*:s::
-PyUnicode_DecodeUTF8:int:size::
+PyUnicode_DecodeUTF8:Py_ssize_t:size::
 PyUnicode_DecodeUTF8:const char*:errors::
 
 PyUnicode_EncodeUTF8:PyObject*::+1:
 PyUnicode_EncodeUTF8:const Py_UNICODE*:s::
-PyUnicode_EncodeUTF8:int:size::
+PyUnicode_EncodeUTF8:Py_ssize_t:size::
 PyUnicode_EncodeUTF8:const char*:errors::
 
 PyUnicode_AsUTF8String:PyObject*::+1:
-PyUnicode_AsUTF8String:PyObject*:unicode::
+PyUnicode_AsUTF8String:PyObject*:unicode:0:
+
+PyUnicode_AsUTF8AndSize:const char*:::
+PyUnicode_AsUTF8AndSize:PyObject*:unicode:0:
+PyUnicode_AsUTF8AndSize:Py_ssize_t*:size:0:
+
+PyUnicode_AsUTF8:const char*:::
+PyUnicode_AsUTF8:PyObject*:unicode:0:
 
 PyUnicode_DecodeUTF16:PyObject*::+1:
 PyUnicode_DecodeUTF16:const char*:s::
-PyUnicode_DecodeUTF16:int:size::
+PyUnicode_DecodeUTF16:Py_ssize_t:size::
 PyUnicode_DecodeUTF16:const char*:errors::
 PyUnicode_DecodeUTF16:int*:byteorder::
 
 PyUnicode_EncodeUTF16:PyObject*::+1:
 PyUnicode_EncodeUTF16:const Py_UNICODE*:s::
-PyUnicode_EncodeUTF16:int:size::
+PyUnicode_EncodeUTF16:Py_ssize_t:size::
 PyUnicode_EncodeUTF16:const char*:errors::
 PyUnicode_EncodeUTF16:int:byteorder::
 
 PyUnicode_AsUTF16String:PyObject*::+1:
-PyUnicode_AsUTF16String:PyObject*:unicode::
+PyUnicode_AsUTF16String:PyObject*:unicode:0:
+
+PyUnicode_DecodeUTF32:PyObject*::+1:
+PyUnicode_DecodeUTF32:const char*:s::
+PyUnicode_DecodeUTF32:Py_ssize_t:size::
+PyUnicode_DecodeUTF32:const char*:errors::
+PyUnicode_DecodeUTF32:int*:byteorder::
+
+PyUnicode_DecodeUTF32Stateful:PyObject*::+1:
+PyUnicode_DecodeUTF32Stateful:const char*:s::
+PyUnicode_DecodeUTF32Stateful:Py_ssize_t:size::
+PyUnicode_DecodeUTF32Stateful:const char*:errors::
+PyUnicode_DecodeUTF32Stateful:int*:byteorder::
+PyUnicode_DecodeUTF32Stateful:Py_ssize_t*:consumed::
+
+PyUnicode_AsUTF32String:PyObject*::+1:
+PyUnicode_AsUTF32String:PyObject*:unicode:0:
+
+PyUnicode_EncodeUTF32:PyObject*::+1:
+PyUnicode_EncodeUTF32:const Py_UNICODE*:s::
+PyUnicode_EncodeUTF32:Py_ssize_t:size::
+PyUnicode_EncodeUTF32:const char*:errors::
+PyUnicode_EncodeUTF32:int:byteorder::
 
 PyUnicode_DecodeUnicodeEscape:PyObject*::+1:
 PyUnicode_DecodeUnicodeEscape:const char*:s::
-PyUnicode_DecodeUnicodeEscape:int:size::
+PyUnicode_DecodeUnicodeEscape:Py_ssize_t:size::
 PyUnicode_DecodeUnicodeEscape:const char*:errors::
 
 PyUnicode_EncodeUnicodeEscape:PyObject*::+1:
 PyUnicode_EncodeUnicodeEscape:const Py_UNICODE*:s::
-PyUnicode_EncodeUnicodeEscape:int:size::
-PyUnicode_EncodeUnicodeEscape:const char*:errors::
+PyUnicode_EncodeUnicodeEscape:Py_ssize_t:size::
 
 PyUnicode_AsUnicodeEscapeString:PyObject*::+1:
-PyUnicode_AsUnicodeEscapeString:PyObject*:unicode::
+PyUnicode_AsUnicodeEscapeString:PyObject*:unicode:0:
 
 PyUnicode_DecodeRawUnicodeEscape:PyObject*::+1:
 PyUnicode_DecodeRawUnicodeEscape:const char*:s::
-PyUnicode_DecodeRawUnicodeEscape:int:size::
+PyUnicode_DecodeRawUnicodeEscape:Py_ssize_t:size::
 PyUnicode_DecodeRawUnicodeEscape:const char*:errors::
 
 PyUnicode_EncodeRawUnicodeEscape:PyObject*::+1:
 PyUnicode_EncodeRawUnicodeEscape:const Py_UNICODE*:s::
-PyUnicode_EncodeRawUnicodeEscape:int:size::
-PyUnicode_EncodeRawUnicodeEscape:const char*:errors::
+PyUnicode_EncodeRawUnicodeEscape:Py_ssize_t:size::
 
 PyUnicode_AsRawUnicodeEscapeString:PyObject*::+1:
-PyUnicode_AsRawUnicodeEscapeString:PyObject*:unicode::
+PyUnicode_AsRawUnicodeEscapeString:PyObject*:unicode:0:
 
 PyUnicode_DecodeLatin1:PyObject*::+1:
 PyUnicode_DecodeLatin1:const char*:s::
-PyUnicode_DecodeLatin1:int:size::
+PyUnicode_DecodeLatin1:Py_ssize_t:size::
 PyUnicode_DecodeLatin1:const char*:errors::
 
 PyUnicode_EncodeLatin1:PyObject*::+1:
 PyUnicode_EncodeLatin1:const Py_UNICODE*:s::
-PyUnicode_EncodeLatin1:int:size::
+PyUnicode_EncodeLatin1:Py_ssize_t:size::
 PyUnicode_EncodeLatin1:const char*:errors::
 
 PyUnicode_AsLatin1String:PyObject*::+1:
-PyUnicode_AsLatin1String:PyObject*:unicode::
+PyUnicode_AsLatin1String:PyObject*:unicode:0:
 
 PyUnicode_DecodeASCII:PyObject*::+1:
 PyUnicode_DecodeASCII:const char*:s::
-PyUnicode_DecodeASCII:int:size::
+PyUnicode_DecodeASCII:Py_ssize_t:size::
 PyUnicode_DecodeASCII:const char*:errors::
 
 PyUnicode_EncodeASCII:PyObject*::+1:
 PyUnicode_EncodeASCII:const Py_UNICODE*:s::
-PyUnicode_EncodeASCII:int:size::
+PyUnicode_EncodeASCII:Py_ssize_t:size::
 PyUnicode_EncodeASCII:const char*:errors::
 
 PyUnicode_AsASCIIString:PyObject*::+1:
-PyUnicode_AsASCIIString:PyObject*:unicode::
+PyUnicode_AsASCIIString:PyObject*:unicode:0:
 
 PyUnicode_DecodeCharmap:PyObject*::+1:
 PyUnicode_DecodeCharmap:const char*:s::
-PyUnicode_DecodeCharmap:int:size::
+PyUnicode_DecodeCharmap:Py_ssize_t:size::
 PyUnicode_DecodeCharmap:PyObject*:mapping:0:
 PyUnicode_DecodeCharmap:const char*:errors::
 
 PyUnicode_EncodeCharmap:PyObject*::+1:
 PyUnicode_EncodeCharmap:const Py_UNICODE*:s::
-PyUnicode_EncodeCharmap:int:size::
+PyUnicode_EncodeCharmap:Py_ssize_t:size::
 PyUnicode_EncodeCharmap:PyObject*:mapping:0:
 PyUnicode_EncodeCharmap:const char*:errors::
 
@@ -1743,22 +2606,33 @@ PyUnicode_AsCharmapString:PyObject*:mapping:0:
 
 PyUnicode_TranslateCharmap:PyObject*::+1:
 PyUnicode_TranslateCharmap:const Py_UNICODE*:s::
-PyUnicode_TranslateCharmap:int:size::
-PyUnicode_TranslateCharmap:PyObject*:table:0:
+PyUnicode_TranslateCharmap:Py_ssize_t:size::
+PyUnicode_TranslateCharmap:PyObject*:mapping:0:
 PyUnicode_TranslateCharmap:const char*:errors::
 
 PyUnicode_DecodeMBCS:PyObject*::+1:
 PyUnicode_DecodeMBCS:const char*:s::
-PyUnicode_DecodeMBCS:int:size::
+PyUnicode_DecodeMBCS:Py_ssize_t:size::
 PyUnicode_DecodeMBCS:const char*:errors::
 
+PyUnicode_DecodeMBCSStateful:PyObject*::+1:
+PyUnicode_DecodeMBCSStateful:const char*:s::
+PyUnicode_DecodeMBCSStateful:Py_ssize_t:size::
+PyUnicode_DecodeMBCSStateful:const char*:errors::
+PyUnicode_DecodeMBCSStateful:Py_ssize_t*:consumed::
+
+PyUnicode_EncodeCodePage:PyObject*::+1:
+PyUnicode_EncodeCodePage:int:code_page::
+PyUnicode_EncodeCodePage:PyObject*:unicode:0:
+PyUnicode_EncodeCodePage:const char*:errors::
+
 PyUnicode_EncodeMBCS:PyObject*::+1:
 PyUnicode_EncodeMBCS:const Py_UNICODE*:s::
-PyUnicode_EncodeMBCS:int:size::
+PyUnicode_EncodeMBCS:Py_ssize_t:size::
 PyUnicode_EncodeMBCS:const char*:errors::
 
 PyUnicode_AsMBCSString:PyObject*::+1:
-PyUnicode_AsMBCSString:PyObject*:unicode::
+PyUnicode_AsMBCSString:PyObject*:unicode:0:
 
 PyUnicode_Concat:PyObject*::+1:
 PyUnicode_Concat:PyObject*:left:0:
@@ -1767,11 +2641,11 @@ PyUnicode_Concat:PyObject*:right:0:
 PyUnicode_Split:PyObject*::+1:
 PyUnicode_Split:PyObject*:left:0:
 PyUnicode_Split:PyObject*:right:0:
-PyUnicode_Split:int:maxsplit::
+PyUnicode_Split:Py_ssize_t:maxsplit::
 
 PyUnicode_Splitlines:PyObject*::+1:
 PyUnicode_Splitlines:PyObject*:s:0:
-PyUnicode_Splitlines:int:maxsplit::
+PyUnicode_Splitlines:int:keepend::
 
 PyUnicode_Translate:PyObject*::+1:
 PyUnicode_Translate:PyObject*:str:0:
@@ -1782,36 +2656,52 @@ PyUnicode_Join:PyObject*::+1:
 PyUnicode_Join:PyObject*:separator:0:
 PyUnicode_Join:PyObject*:seq:0:
 
-PyUnicode_Tailmatch:int:::
+PyUnicode_Tailmatch:Py_ssize_t:::
 PyUnicode_Tailmatch:PyObject*:str:0:
 PyUnicode_Tailmatch:PyObject*:substr:0:
-PyUnicode_Tailmatch:int:start::
-PyUnicode_Tailmatch:int:end::
+PyUnicode_Tailmatch:Py_ssize_t:start::
+PyUnicode_Tailmatch:Py_ssize_t:end::
 PyUnicode_Tailmatch:int:direction::
 
-PyUnicode_Find:int:::
+PyUnicode_Find:Py_ssize_t:::
 PyUnicode_Find:PyObject*:str:0:
 PyUnicode_Find:PyObject*:substr:0:
-PyUnicode_Find:int:start::
-PyUnicode_Find:int:end::
+PyUnicode_Find:Py_ssize_t:start::
+PyUnicode_Find:Py_ssize_t:end::
 PyUnicode_Find:int:direction::
 
-PyUnicode_Count:int:::
+PyUnicode_FindChar:Py_ssize_t:::
+PyUnicode_FindChar:PyObject*:str:0:
+PyUnicode_FindChar:Py_UCS4:ch::
+PyUnicode_FindChar:Py_ssize_t:start::
+PyUnicode_FindChar:Py_ssize_t:end::
+PyUnicode_FindChar:int:direction::
+
+PyUnicode_Count:Py_ssize_t:::
 PyUnicode_Count:PyObject*:str:0:
 PyUnicode_Count:PyObject*:substr:0:
-PyUnicode_Count:int:start::
-PyUnicode_Count:int:end::
+PyUnicode_Count:Py_ssize_t:start::
+PyUnicode_Count:Py_ssize_t:end::
 
 PyUnicode_Replace:PyObject*::+1:
 PyUnicode_Replace:PyObject*:str:0:
 PyUnicode_Replace:PyObject*:substr:0:
 PyUnicode_Replace:PyObject*:replstr:0:
-PyUnicode_Replace:int:maxcount::
+PyUnicode_Replace:Py_ssize_t:maxcount::
 
 PyUnicode_Compare:int:::
 PyUnicode_Compare:PyObject*:left:0:
 PyUnicode_Compare:PyObject*:right:0:
 
+PyUnicode_CompareWithASCIIString:int:::
+PyUnicode_CompareWithASCIIString:PyObject*:uni:0:
+PyUnicode_CompareWithASCIIString:const char*:string::
+
+PyUnicode_RichCompare:PyObject*::+1:
+PyUnicode_RichCompare:PyObject*:left:0:
+PyUnicode_RichCompare:PyObject*:right:0:
+PyUnicode_RichCompare:int:op::
+
 PyUnicode_Format:PyObject*::+1:
 PyUnicode_Format:PyObject*:format:0:
 PyUnicode_Format:PyObject*:args:0:
@@ -1820,6 +2710,185 @@ PyUnicode_Contains:int:::
 PyUnicode_Contains:PyObject*:container:0:
 PyUnicode_Contains:PyObject*:element:0:
 
+PyUnicode_InternInPlace:void:::
+PyUnicode_InternInPlace:PyObject**:string:+1:
+
+PyUnicode_InternFromString:PyObject*::+1:
+PyUnicode_InternFromString:const char*:v::
+
+PyUnicode_New:PyObject*::+1:
+PyUnicode_New:Py_ssize_t:size::
+PyUnicode_New:Py_UCS4:maxchar::
+
+PyUnicode_FromKindAndData:PyObject*::+1:
+PyUnicode_FromKindAndData:int:kind::
+PyUnicode_FromKindAndData:const void*:buffer::
+PyUnicode_FromKindAndData:Py_ssize_t:size::
+
+PyUnicode_FromStringAndSize:PyObject*::+1:
+PyUnicode_FromStringAndSize:const char*:u::
+PyUnicode_FromStringAndSize:Py_ssize_t:size::
+
+PyUnicode_FromString:PyObject*::+1:
+PyUnicode_FromString:const char*:u::
+
+PyUnicode_FromFormat:PyObject*::+1:
+PyUnicode_FromFormat:const char*:format::
+PyUnicode_FromFormat::...::
+
+PyUnicode_FromFormatV:PyObject*::+1:
+PyUnicode_FromFormatV:const char*:format::
+PyUnicode_FromFormatV:va_list:args::
+
+PyUnicode_GetLength:Py_ssize_t:::
+PyUnicode_GetLength:PyObject*:unicode:0:
+
+PyUnicode_CopyCharacters:Py_ssize_t:::
+PyUnicode_CopyCharacters:PyObject*:to:0:
+PyUnicode_CopyCharacters:Py_ssize_t:to_start::
+PyUnicode_CopyCharacters:PyObject*:from:0:
+PyUnicode_CopyCharacters:Py_ssize_t:from_start::
+PyUnicode_CopyCharacters:Py_ssize_t:how_many::
+
+PyUnicode_Fill:Py_ssize_t:::
+PyUnicode_Fill:PyObject*:unicode:0:
+PyUnicode_Fill:Py_ssize_t:start::
+PyUnicode_Fill:Py_ssize_t:length::
+PyUnicode_Fill:Py_UCS4:fill_char::
+
+PyUnicode_READ:Py_UCS4:::
+PyUnicode_READ:int:kind::
+PyUnicode_READ:void*:data::
+PyUnicode_READ:Py_ssize_t:index::
+
+PyUnicode_READ_CHAR:Py_UCS4:::
+PyUnicode_READ_CHAR:PyObject*:o:0:
+PyUnicode_READ_CHAR:Py_ssize_t:index::
+
+PyUnicode_ReadChar:Py_UCS4:::
+PyUnicode_ReadChar:PyObject*:unicode:0:
+PyUnicode_ReadChar:Py_ssize_t:index::
+
+PyUnicode_WRITE:void:::
+PyUnicode_WRITE:int:kind::
+PyUnicode_WRITE:void*:data::
+PyUnicode_WRITE:Py_ssize_t:index::
+PyUnicode_WRITE:Py_UCS4:value::
+
+PyUnicode_WriteChar:int:::
+PyUnicode_WriteChar:PyObject*:unicode:0:
+PyUnicode_WriteChar:Py_ssize_t:index::
+PyUnicode_WriteChar:Py_UCS4:character::
+
+PyUnicode_READY:int:::
+PyUnicode_READY:PyObject*:o:0:
+
+PyUnicode_Substring:PyObject*::+1:
+PyUnicode_Substring:PyObject*:str:0:
+PyUnicode_Substring:Py_ssize_t:start::
+PyUnicode_Substring:Py_ssize_t:end::
+
+PyUnicode_AsUCS4:Py_UCS4*:::
+PyUnicode_AsUCS4:PyObject*:u:0:
+PyUnicode_AsUCS4:Py_UCS4*:buffer::
+PyUnicode_AsUCS4:Py_ssize_t:buflen::
+PyUnicode_AsUCS4:int:copy_null::
+
+PyUnicode_AsUCS4Copy:Py_UCS4*:::
+PyUnicode_AsUCS4Copy:PyObject*:u:0:
+
+PyUnicode_DecodeLocaleAndSize:PyObject*::+1:
+PyUnicode_DecodeLocaleAndSize:const char*:str::
+PyUnicode_DecodeLocaleAndSize:Py_ssize_t:len::
+PyUnicode_DecodeLocaleAndSize:const char*:errors::
+
+PyUnicode_DecodeLocale:PyObject*::+1:
+PyUnicode_DecodeLocale:const char*:str::
+PyUnicode_DecodeLocale:const char*:errors::
+
+PyUnicode_EncodeLocale:PyObject*::+1:
+PyUnicode_EncodeLocale:PyObject*:unicode:0:
+PyUnicode_EncodeLocale:const char*:errors::
+
+PyUnicode_FSConverter:int:::
+PyUnicode_FSConverter:PyObject*:obj:0:
+PyUnicode_FSConverter:void*:result::
+
+PyUnicode_FSDecoder:int:::
+PyUnicode_FSDecoder:PyObject*:obj:0:
+PyUnicode_FSDecoder:void*:result::
+
+PyUnicode_DecodeFSDefaultAndSize:PyObject*::+1:
+PyUnicode_DecodeFSDefaultAndSize:const char*:s::
+PyUnicode_DecodeFSDefaultAndSize:Py_ssize_t:size::
+
+PyUnicode_DecodeFSDefault:PyObject*::+1:
+PyUnicode_DecodeFSDefault:const char*:s::
+
+PyUnicode_EncodeFSDefault:PyObject*::+1:
+PyUnicode_EncodeFSDefault:PyObject*:unicode:0:
+
+PyUnicodeDecodeError_Create:PyObject*::+1:
+PyUnicodeDecodeError_Create:const char*:encoding::
+PyUnicodeDecodeError_Create:const char*:object::
+PyUnicodeDecodeError_Create:Py_ssize_t:length::
+PyUnicodeDecodeError_Create:Py_ssize_t:start::
+PyUnicodeDecodeError_Create:Py_ssize_t:end::
+PyUnicodeDecodeError_Create:const char*:reason::
+
+PyUnicodeDecodeError_GetEncoding:PyObject*::+1:
+PyUnicodeDecodeError_GetEncoding:PyObject*:exc:0:
+
+PyUnicodeDecodeError_GetEnd:Py_ssize_t:::
+PyUnicodeDecodeError_GetEnd:PyObject*:exc:0:
+PyUnicodeDecodeError_GetEnd:Py_ssize_t*:end::
+
+PyUnicodeDecodeError_GetObject:PyObject*::+1:
+PyUnicodeDecodeError_GetObject:PyObject*:exc:0:
+
+PyUnicodeDecodeError_GetReason:PyObject*::+1:
+PyUnicodeDecodeError_GetReason:PyObject*:exc:0:
+
+PyUnicodeDecodeError_GetStart:Py_ssize_t:::
+PyUnicodeDecodeError_GetStart:PyObject*:exc:0:
+PyUnicodeDecodeError_GetStart:Py_ssize_t*:start::
+
+PyUnicodeDecodeError_SetEnd:int:::
+PyUnicodeDecodeError_SetEnd:PyObject*:exc:0:
+PyUnicodeDecodeError_SetEnd:Py_ssize_t:end::
+
+PyUnicodeDecodeError_SetReason:int:::
+PyUnicodeDecodeError_SetReason:PyObject*:exc:0:
+PyUnicodeDecodeError_SetReason:const char*:reason::
+
+PyUnicodeDecodeError_SetStart:int:::
+PyUnicodeDecodeError_SetStart:PyObject*:exc:0:
+PyUnicodeDecodeError_SetStart:Py_ssize_t:start::
+
+PyUnicodeEncodeError_Create:PyObject*::+1:
+PyUnicodeEncodeError_Create:const char*:encoding::
+PyUnicodeEncodeError_Create:const Py_UNICODE*:object::
+PyUnicodeEncodeError_Create:Py_ssize_t:length::
+PyUnicodeEncodeError_Create:Py_ssize_t:start::
+PyUnicodeEncodeError_Create:Py_ssize_t:end::
+PyUnicodeEncodeError_Create:const char*:reason::
+
+PyUnicodeTranslateError_Create:PyObject*::+1:
+PyUnicodeTranslateError_Create:const Py_UNICODE*:object::
+PyUnicodeTranslateError_Create:Py_ssize_t:length::
+PyUnicodeTranslateError_Create:Py_ssize_t:start::
+PyUnicodeTranslateError_Create:Py_ssize_t:end::
+PyUnicodeTranslateError_Create:const char*:reason::
+
+PyWeakref_Check:int:::
+PyWeakref_Check:PyObject*:ob::
+
+PyWeakref_CheckProxy:int:::
+PyWeakref_CheckProxy:PyObject*:ob::
+
+PyWeakref_CheckRef:int:::
+PyWeakref_CheckRef:PyObject*:ob::
+
 PyWeakref_GET_OBJECT:PyObject*::0:
 PyWeakref_GET_OBJECT:PyObject*:ref:0:
 
@@ -1843,18 +2912,40 @@ Py_AtExit:void (*)():func::
 
 Py_BuildValue:PyObject*::+1:
 Py_BuildValue:const char*:format::
+Py_BuildValue::...::
+
+Py_VaBuildValue:PyObject*::+1:
+Py_VaBuildValue:const char*:format::
+Py_VaBuildValue:va_list:vargs::
+
+Py_CLEAR:void:::
+Py_CLEAR:PyObject*:o:-1:
 
 Py_CompileString:PyObject*::+1:
 Py_CompileString:const char*:str::
 Py_CompileString:const char*:filename::
 Py_CompileString:int:start::
 
+Py_CompileStringExFlags:PyObject*::+1:
+Py_CompileStringExFlags:const char*:str::
+Py_CompileStringExFlags:const char*:filename::
+Py_CompileStringExFlags:int:start::
+Py_CompileStringExFlags:PyCompilerFlags*:flags::
+Py_CompileStringExFlags:int:optimize::
+
 Py_CompileStringFlags:PyObject*::+1:
 Py_CompileStringFlags:const char*:str::
 Py_CompileStringFlags:const char*:filename::
 Py_CompileStringFlags:int:start::
 Py_CompileStringFlags:PyCompilerFlags*:flags::
 
+Py_CompileStringObject:PyObject*::+1:
+Py_CompileStringObject:const char*:str::
+Py_CompileStringObject:PyObject*:filename:0:
+Py_CompileStringObject:int:start::
+Py_CompileStringObject:PyCompilerFlags*:flags::
+Py_CompileStringObject:int:optimize::
+
 Py_DECREF:void:::
 Py_DECREF:PyObject*:o:-1:
 
@@ -1873,25 +2964,25 @@ Py_FdIsInteractive:const char*:filename::
 
 Py_Finalize:void:::
 
-Py_GetBuildInfoconst:const char*:::
+Py_GetBuildInfo:const char*:::
 
-Py_GetCompilerconst:const char*:::
+Py_GetCompiler:const char*:::
 
-Py_GetCopyrightconst:const char*:::
+Py_GetCopyright:const char*:::
 
-Py_GetExecPrefix:const char*:::
+Py_GetExecPrefix:wchar_t*:::
 
-Py_GetPath:const char*:::
+Py_GetPath:wchar_t*:::
 
-Py_GetPlatformconst:const char*:::
+Py_GetPlatform:const char*:::
 
-Py_GetPrefix:const char*:::
+Py_GetPrefix:wchar_t*:::
 
-Py_GetProgramFullPath:const char*:::
+Py_GetProgramFullPath:wchar_t*:::
 
-Py_GetProgramName:const char*:::
+Py_GetProgramName:wchar_t*:::
 
-Py_GetVersionconst:const char*:::
+Py_GetVersion:const char*:::
 
 Py_INCREF:void:::
 Py_INCREF:PyObject*:o:+1:
@@ -1902,8 +2993,14 @@ Py_IsInitialized:int:::
 
 Py_NewInterpreter:PyThreadState*:::
 
+Py_ReprEnter:int:::
+Py_ReprEnter:PyObject*:object:+1:
+
+Py_ReprLeave:void:::
+Py_ReprLeave:PyObject*:object:-1:
+
 Py_SetProgramName:void:::
-Py_SetProgramName:const char*:name::
+Py_SetProgramName:const wchar_t*:name::
 
 Py_XDECREF:void:::
 Py_XDECREF:PyObject*:o:-1:if o is not NULL
@@ -1911,32 +3008,24 @@ Py_XDECREF:PyObject*:o:-1:if o is not NULL
 Py_XINCREF:void:::
 Py_XINCREF:PyObject*:o:+1:if o is not NULL
 
-_PyImport_FindExtension:PyObject*::0:??? see PyImport_AddModule
-_PyImport_FindExtension:const char*:::
-_PyImport_FindExtension:const char*:::
-
 _PyImport_Fini:void:::
 
-_PyImport_FixupExtension:PyObject*:::???
-_PyImport_FixupExtension:const char*:::
-_PyImport_FixupExtension:const char*:::
-
 _PyImport_Init:void:::
 
 _PyObject_New:PyObject*::+1:
 _PyObject_New:PyTypeObject*:type:0:
 
-_PyObject_NewVar:PyObject*::+1:
+_PyObject_NewVar:PyVarObject*::+1:
 _PyObject_NewVar:PyTypeObject*:type:0:
-_PyObject_NewVar:int:size::
+_PyObject_NewVar:Py_ssize_t:size::
 
-_PyString_Resize:int:::
-_PyString_Resize:PyObject**:string:+1:
-_PyString_Resize:int:newsize::
+_PyBytes_Resize:int:::
+_PyBytes_Resize:PyObject**:bytes:0:
+_PyBytes_Resize:Py_ssize_t:newsize::
 
 _PyTuple_Resize:int:::
-_PyTuple_Resize:PyTupleObject**:p:+1:
-_PyTuple_Resize:int:new::
+_PyTuple_Resize:PyObject**:p:0:
+_PyTuple_Resize:Py_ssize_t:new::
 
 _Py_c_diff:Py_complex:::
 _Py_c_diff:Py_complex:left::
index c1051d2e807e7946d928248ff659b26de5be2621..54ed1aebc242d8ea1887ee5bc3a608566b3a7c94 100644 (file)
@@ -524,20 +524,23 @@ following way::
     setup(...,
           data_files=[('bitmaps', ['bm/b1.gif', 'bm/b2.gif']),
                       ('config', ['cfg/data.cfg']),
-                      ('/etc/init.d', ['init-script'])]
          )
 
-Note that you can specify the directory names where the data files will be
-installed, but you cannot rename the data files themselves.
-
 Each (*directory*, *files*) pair in the sequence specifies the installation
-directory and the files to install there.  If *directory* is a relative path, it
-is interpreted relative to the installation prefix (Python's ``sys.prefix`` for
-pure-Python packages, ``sys.exec_prefix`` for packages that contain extension
-modules).  Each file name in *files* is interpreted relative to the
-:file:`setup.py` script at the top of the package source distribution.  No
-directory information from *files* is used to determine the final location of
-the installed file; only the name of the file is used.
+directory and the files to install there.
+
+Each file name in *files* is interpreted relative to the :file:`setup.py`
+script at the top of the package source distribution. Note that you can
+specify the directory where the data files will be installed, but you cannot
+rename the data files themselves.
+
+The *directory* should be a relative path. It is interpreted relative to the
+installation prefix (Python's ``sys.prefix`` for system installations;
+``site.USER_BASE`` for user installations). Distutils allows *directory* to be
+an absolute installation path, but this is discouraged since it is
+incompatible with the wheel packaging format. No directory information from
+*files* is used to determine the final location of the installed file; only
+the name of the file is used.
 
 You can specify the ``data_files`` options as a simple sequence of files
 without specifying a target directory, but this is not recommended, and the
index 90fd69e72960c0b876f50dd649c11ce8af3d8fe4..7ee340d7957c9808f12a604ba026ed7a6904c0a0 100644 (file)
@@ -268,14 +268,8 @@ Python references; or perhaps search for "Python" and "language".
 Where in the world is www.python.org located?
 ---------------------------------------------
 
-The Python project's infrastructure is located all over the world.
-`www.python.org <https://www.python.org>`_ is graciously hosted by `Rackspace
-<https://www.rackspace.com>`_, with CDN caching provided by `Fastly
-<https://www.fastly.com>`_.  `Upfront Systems
-<http://www.upfrontsoftware.co.za>`_ hosts `bugs.python.org
-<https://bugs.python.org>`_.  Many other Python services like `the Wiki
-<https://wiki.python.org>`_ are hosted by `Oregon State
-University Open Source Lab <https://osuosl.org>`_.
+The Python project's infrastructure is located all over the world and is managed
+by the Python Infrastructure Team. Details `here <http://infra.psf.io>`__.
 
 
 Why is it called Python?
index fd720c1a304b0f3f5e003a8b561c6d757aeb1bd4..31614189a62d2ceb723e445045c776d948259695 100644 (file)
@@ -738,7 +738,7 @@ Is it possible to write obfuscated one-liners in Python?
 --------------------------------------------------------
 
 Yes.  Usually this is done by nesting :keyword:`lambda` within
-:keyword:`lambda`.  See the following three examples, due to Ulf Bartelt::
+:keyword:`!lambda`.  See the following three examples, due to Ulf Bartelt::
 
    from functools import reduce
 
@@ -767,6 +767,41 @@ Yes.  Usually this is done by nesting :keyword:`lambda` within
 Don't try this at home, kids!
 
 
+.. _faq-positional-only-arguments:
+
+What does the slash(/) in the parameter list of a function mean?
+----------------------------------------------------------------
+
+A slash in the argument list of a function denotes that the parameters prior to
+it are positional-only.  Positional-only parameters are the ones without an
+externally-usable name.  Upon calling a function that accepts positional-only
+parameters, arguments are mapped to parameters based solely on their position.
+For example, :func:`pow` is a function that accepts positional-only parameters.
+Its documentation looks like this::
+
+   >>> help(pow)
+   Help on built-in function pow in module builtins:
+
+   pow(x, y, z=None, /)
+      Equivalent to x**y (with two arguments) or x**y % z (with three arguments)
+
+      Some types, such as ints, are able to use a more efficient algorithm when
+      invoked using the three argument form.
+
+The slash at the end of the parameter list means that all three parameters are
+positional-only. Thus, calling :func:`pow` with keyword aguments would lead to
+an error::
+
+   >>> pow(x=3, y=4)
+   Traceback (most recent call last):
+     File "<stdin>", line 1, in <module>
+   TypeError: pow() takes no keyword arguments
+
+Note that as of this writing this is only documentational and no valid syntax
+in Python, although there is :pep:`570`, which proposes a syntax for
+position-only parameters in Python.
+
+
 Numbers and strings
 ===================
 
@@ -1317,9 +1352,6 @@ The ``__iadd__`` succeeds, and thus the list is extended, but even though
 that final assignment still results in an error, because tuples are immutable.
 
 
-Dictionaries
-============
-
 I want to do a complicated sort: can you do a Schwartzian Transform in Python?
 ------------------------------------------------------------------------------
 
index b8d98dd34c13091ad4d6ffaa19b5dc23031018cc..fb8ff2a7c6561235bec5f4c44c486bfda8a8d8fc 100644 (file)
@@ -332,7 +332,7 @@ Glossary
       names, attribute access, operators or function calls which all return a
       value.  In contrast to many other languages, not all language constructs
       are expressions.  There are also :term:`statement`\s which cannot be used
-      as expressions, such as :keyword:`if`.  Assignments are also statements,
+      as expressions, such as :keyword:`while`.  Assignments are also statements,
       not expressions.
 
    extension module
@@ -444,8 +444,8 @@ Glossary
 
    generator expression
       An expression that returns an iterator.  It looks like a normal expression
-      followed by a :keyword:`for` expression defining a loop variable, range,
-      and an optional :keyword:`if` expression.  The combined expression
+      followed by a :keyword:`!for` clause defining a loop variable, range,
+      and an optional :keyword:`!if` clause.  The combined expression
       generates values for an enclosing function::
 
          >>> sum(i*i for i in range(10))         # sum of squares 0, 1, 4, ... 81
index 2efe4537e288d674a976c8021a50d1c7d1e151e2..f8f2aac70f9b063aad79ebc3f35d31dd09c1184a 100644 (file)
@@ -1108,7 +1108,7 @@ need to define a new function at all::
     existing_files = filter(os.path.exists, file_list)
 
 If the function you need doesn't exist, you need to write it.  One way to write
-small functions is to use the :keyword:`lambda` statement.  ``lambda`` takes a
+small functions is to use the :keyword:`lambda` expression.  ``lambda`` takes a
 number of parameters and an expression combining these parameters, and creates
 an anonymous function that returns the value of the expression::
 
index b1930a791fca5b51cc0cc070a4c0ec156609a6fe..e391506ce2e49c946b19a0e44ddd6ce90282d99b 100644 (file)
@@ -186,7 +186,7 @@ previous simple module-based configuration example::
     # 'application' code
     logger.debug('debug message')
     logger.info('info message')
-    logger.warn('warn message')
+    logger.warning('warn message')
     logger.error('error message')
     logger.critical('critical message')
 
@@ -295,7 +295,7 @@ Here is an example of a module using the logging configuration server::
         while True:
             logger.debug('debug message')
             logger.info('info message')
-            logger.warn('warn message')
+            logger.warning('warn message')
             logger.error('error message')
             logger.critical('critical message')
             time.sleep(5)
index 2a2282e9ecf068ef495fd8a2744b7ccfeea70e2b..7a68ca89199c777a8d8cc270f232f0935f2cebe5 100644 (file)
@@ -610,7 +610,7 @@ logger, a console handler, and a simple formatter using Python code::
     # 'application' code
     logger.debug('debug message')
     logger.info('info message')
-    logger.warn('warn message')
+    logger.warning('warn message')
     logger.error('error message')
     logger.critical('critical message')
 
@@ -640,7 +640,7 @@ the names of the objects::
     # 'application' code
     logger.debug('debug message')
     logger.info('info message')
-    logger.warn('warn message')
+    logger.warning('warn message')
     logger.error('error message')
     logger.critical('critical message')
 
@@ -695,15 +695,15 @@ noncoders to easily modify the logging properties.
 .. warning:: The :func:`fileConfig` function takes a default parameter,
    ``disable_existing_loggers``, which defaults to ``True`` for reasons of
    backward compatibility. This may or may not be what you want, since it
-   will cause any loggers existing before the :func:`fileConfig` call to
-   be disabled unless they (or an ancestor) are explicitly named in the
-   configuration.  Please refer to the reference documentation for more
+   will cause any non-root loggers existing before the :func:`fileConfig`
+   call to be disabled unless they (or an ancestor) are explicitly named in
+   the configuration. Please refer to the reference documentation for more
    information, and specify ``False`` for this parameter if you wish.
 
    The dictionary passed to :func:`dictConfig` can also specify a Boolean
    value with key ``disable_existing_loggers``, which if not specified
    explicitly in the dictionary also defaults to being interpreted as
-   ``True``.  This leads to the logger-disabling behaviour described above,
+   ``True``. This leads to the logger-disabling behaviour described above,
    which may not be what you want - in which case, provide the key
    explicitly with a value of ``False``.
 
@@ -802,7 +802,7 @@ the best default behaviour.
 If for some reason you *don't* want these messages printed in the absence of
 any logging configuration, you can attach a do-nothing handler to the top-level
 logger for your library. This avoids the message being printed, since a handler
-will be always be found for the library's events: it just doesn't produce any
+will always be found for the library's events: it just doesn't produce any
 output. If the library user configures logging for application use, presumably
 that configuration will add some handlers, and if levels are suitably
 configured then logging calls made in library code will send output to those
index b09f748a9227330fd89551f90c278654cc4574b3..d385d991344b2898340ef5ffa9bf7662d7365357 100644 (file)
@@ -96,8 +96,9 @@ special nature.
 
 You can match the characters not listed within the class by :dfn:`complementing`
 the set.  This is indicated by including a ``'^'`` as the first character of the
-class; ``'^'`` outside a character class will simply match the ``'^'``
-character.  For example, ``[^5]`` will match any character except ``'5'``.
+class. For example, ``[^5]`` will match any character except ``'5'``.  If the
+caret appears elsewhere in a character class, it does not have special meaning.
+For example: ``[5^]`` will match either a ``'5'`` or a ``'^'``.
 
 Perhaps the most important metacharacter is the backslash, ``\``.   As in Python
 string literals, the backslash can be followed by various characters to signal
index be1fefb35a71f0970d5e84aadb93f011d79f73f9..5339bf45bf0e804d8ebcda1638c54ea711f15e9c 100644 (file)
@@ -6,95 +6,48 @@
 
 :Release: 1.12
 
-This HOWTO discusses Python support for Unicode, and explains
-various problems that people commonly encounter when trying to work
-with Unicode.
+This HOWTO discusses Python's support for the Unicode specification
+for representing textual data, and explains various problems that
+people commonly encounter when trying to work with Unicode.
+
 
 Introduction to Unicode
 =======================
 
-History of Character Codes
---------------------------
-
-In 1968, the American Standard Code for Information Interchange, better known by
-its acronym ASCII, was standardized.  ASCII defined numeric codes for various
-characters, with the numeric values running from 0 to 127.  For example, the
-lowercase letter 'a' is assigned 97 as its code value.
-
-ASCII was an American-developed standard, so it only defined unaccented
-characters.  There was an 'e', but no 'é' or 'Í'.  This meant that languages
-which required accented characters couldn't be faithfully represented in ASCII.
-(Actually the missing accents matter for English, too, which contains words such
-as 'naïve' and 'café', and some publications have house styles which require
-spellings such as 'coöperate'.)
-
-For a while people just wrote programs that didn't display accents.
-In the mid-1980s an Apple II BASIC program written by a French speaker
-might have lines like these:
-
-.. code-block:: basic
-
-   PRINT "MISE A JOUR TERMINEE"
-   PRINT "PARAMETRES ENREGISTRES"
-
-Those messages should contain accents (terminée, paramètre, enregistrés) and
-they just look wrong to someone who can read French.
-
-In the 1980s, almost all personal computers were 8-bit, meaning that bytes could
-hold values ranging from 0 to 255.  ASCII codes only went up to 127, so some
-machines assigned values between 128 and 255 to accented characters.  Different
-machines had different codes, however, which led to problems exchanging files.
-Eventually various commonly used sets of values for the 128--255 range emerged.
-Some were true standards, defined by the International Organization for
-Standardization, and some were *de facto* conventions that were invented by one
-company or another and managed to catch on.
-
-255 characters aren't very many.  For example, you can't fit both the accented
-characters used in Western Europe and the Cyrillic alphabet used for Russian
-into the 128--255 range because there are more than 128 such characters.
-
-You could write files using different codes (all your Russian files in a coding
-system called KOI8, all your French files in a different coding system called
-Latin1), but what if you wanted to write a French document that quotes some
-Russian text?  In the 1980s people began to want to solve this problem, and the
-Unicode standardization effort began.
-
-Unicode started out using 16-bit characters instead of 8-bit characters.  16
-bits means you have 2^16 = 65,536 distinct values available, making it possible
-to represent many different characters from many different alphabets; an initial
-goal was to have Unicode contain the alphabets for every single human language.
-It turns out that even 16 bits isn't enough to meet that goal, and the modern
-Unicode specification uses a wider range of codes, 0 through 1,114,111 (
-``0x10FFFF`` in base 16).
-
-There's a related ISO standard, ISO 10646.  Unicode and ISO 10646 were
-originally separate efforts, but the specifications were merged with the 1.1
-revision of Unicode.
-
-(This discussion of Unicode's history is highly simplified.  The
-precise historical details aren't necessary for understanding how to
-use Unicode effectively, but if you're curious, consult the Unicode
-consortium site listed in the References or
-the `Wikipedia entry for Unicode <https://en.wikipedia.org/wiki/Unicode#History>`_
-for more information.)
-
-
 Definitions
 -----------
 
+Today's programs need to be able to handle a wide variety of
+characters.  Applications are often internationalized to display
+messages and output in a variety of user-selectable languages; the
+same program might need to output an error message in English, French,
+Japanese, Hebrew, or Russian.  Web content can be written in any of
+these languages and can also include a variety of emoji symbols.
+Python's string type uses the Unicode Standard for representing
+characters, which lets Python programs work with all these different
+possible characters.
+
+Unicode (https://www.unicode.org/) is a specification that aims to
+list every character used by human languages and give each character
+its own unique code.  The Unicode specifications are continually
+revised and updated to add new languages and symbols.
+
 A **character** is the smallest possible component of a text.  'A', 'B', 'C',
-etc., are all different characters.  So are 'È' and 'Í'.  Characters are
-abstractions, and vary depending on the language or context you're talking
-about.  For example, the symbol for ohms (Ω) is usually drawn much like the
-capital letter omega (Ω) in the Greek alphabet (they may even be the same in
-some fonts), but these are two different characters that have different
-meanings.
-
-The Unicode standard describes how characters are represented by **code
-points**.  A code point is an integer value, usually denoted in base 16.  In the
-standard, a code point is written using the notation ``U+12CA`` to mean the
-character with value ``0x12ca`` (4,810 decimal).  The Unicode standard contains
-a lot of tables listing characters and their corresponding code points:
+etc., are all different characters.  So are 'È' and 'Í'.  Characters vary
+depending on the language or context you're talking
+about.  For example, there's a character for "Roman Numeral One", 'Ⅰ', that's
+separate from the uppercase letter 'I'.  They'll usually look the same,
+but these are two different characters that have different meanings.
+
+The Unicode standard describes how characters are represented by
+**code points**.  A code point value is an integer in the range 0 to
+0x10FFFF (about 1.1 million values, with some 110 thousand assigned so
+far).  In the standard and in this document, a code point is written
+using the notation ``U+265E`` to mean the character with value
+``0x265e`` (9,822 in decimal).
+
+The Unicode standard contains a lot of tables listing characters and
+their corresponding code points:
 
 .. code-block:: none
 
@@ -103,10 +56,21 @@ a lot of tables listing characters and their corresponding code points:
    0063    'c'; LATIN SMALL LETTER C
    ...
    007B    '{'; LEFT CURLY BRACKET
+   ...
+   2167    'Ⅶ': ROMAN NUMERAL EIGHT
+   2168    'Ⅸ': ROMAN NUMERAL NINE
+   ...
+   265E    '♞': BLACK CHESS KNIGHT
+   265F    '♟': BLACK CHESS PAWN
+   ...
+   1F600   '😀': GRINNING FACE
+   1F609   '😉': WINKING FACE
+   ...
 
 Strictly, these definitions imply that it's meaningless to say 'this is
-character ``U+12CA``'.  ``U+12CA`` is a code point, which represents some particular
-character; in this case, it represents the character 'ETHIOPIC SYLLABLE WI'.  In
+character ``U+265E``'.  ``U+265E`` is a code point, which represents some particular
+character; in this case, it represents the character 'BLACK CHESS KNIGHT',
+'♞'.  In
 informal contexts, this distinction between code points and characters will
 sometimes be forgotten.
 
@@ -121,14 +85,17 @@ toolkit or a terminal's font renderer.
 Encodings
 ---------
 
-To summarize the previous section: a Unicode string is a sequence of code
-points, which are numbers from 0 through ``0x10FFFF`` (1,114,111 decimal).  This
-sequence needs to be represented as a set of bytes (meaning, values
-from 0 through 255) in memory.  The rules for translating a Unicode string
-into a sequence of bytes are called an **encoding**.
+To summarize the previous section: a Unicode string is a sequence of
+code points, which are numbers from 0 through ``0x10FFFF`` (1,114,111
+decimal).  This sequence of code points needs to be represented in
+memory as a set of **code units**, and **code units** are then mapped
+to 8-bit bytes.  The rules for translating a Unicode string into a
+sequence of bytes are called a **character encoding**, or just
+an **encoding**.
 
-The first encoding you might think of is an array of 32-bit integers.  In this
-representation, the string "Python" would look like this:
+The first encoding you might think of is using 32-bit integers as the
+code unit, and then using the CPU's representation of 32-bit integers.
+In this representation, the string "Python" might look like this:
 
 .. code-block:: none
 
@@ -152,40 +119,14 @@ problems.
 3. It's not compatible with existing C functions such as ``strlen()``, so a new
    family of wide string functions would need to be used.
 
-4. Many Internet standards are defined in terms of textual data, and can't
-   handle content with embedded zero bytes.
-
-Generally people don't use this encoding, instead choosing other
-encodings that are more efficient and convenient.  UTF-8 is probably
-the most commonly supported encoding; it will be discussed below.
-
-Encodings don't have to handle every possible Unicode character, and most
-encodings don't.  The rules for converting a Unicode string into the ASCII
-encoding, for example, are simple; for each code point:
-
-1. If the code point is < 128, each byte is the same as the value of the code
-   point.
+Therefore this encoding isn't used very much, and people instead choose other
+encodings that are more efficient and convenient, such as UTF-8.
 
-2. If the code point is 128 or greater, the Unicode string can't be represented
-   in this encoding.  (Python raises a :exc:`UnicodeEncodeError` exception in this
-   case.)
-
-Latin-1, also known as ISO-8859-1, is a similar encoding.  Unicode code points
-0--255 are identical to the Latin-1 values, so converting to this encoding simply
-requires converting code points to byte values; if a code point larger than 255
-is encountered, the string can't be encoded into Latin-1.
-
-Encodings don't have to be simple one-to-one mappings like Latin-1.  Consider
-IBM's EBCDIC, which was used on IBM mainframes.  Letter values weren't in one
-block: 'a' through 'i' had values from 129 to 137, but 'j' through 'r' were 145
-through 153.  If you wanted to use EBCDIC as an encoding, you'd probably use
-some sort of lookup table to perform the conversion, but this is largely an
-internal detail.
-
-UTF-8 is one of the most commonly used encodings.  UTF stands for "Unicode
-Transformation Format", and the '8' means that 8-bit numbers are used in the
-encoding.  (There are also a UTF-16 and UTF-32 encodings, but they are less
-frequently used than UTF-8.)  UTF-8 uses the following rules:
+UTF-8 is one of the most commonly used encodings, and Python often
+defaults to using it.  UTF stands for "Unicode Transformation Format",
+and the '8' means that 8-bit values are used in the encoding.  (There
+are also UTF-16 and UTF-32 encodings, but they are less frequently
+used than UTF-8.)  UTF-8 uses the following rules:
 
 1. If the code point is < 128, it's represented by the corresponding byte value.
 2. If the code point is >= 128, it's turned into a sequence of two, three, or
@@ -215,6 +156,10 @@ glossary, and PDF versions of the Unicode specification.  Be prepared for some
 difficult reading.  `A chronology <http://www.unicode.org/history/>`_ of the
 origin and development of Unicode is also available on the site.
 
+On the Computerphile Youtube channel, Tom Scott briefly
+`discusses the history of Unicode and UTF-8 <https://www.youtube.com/watch?v=MijmeoH9LT4>`
+(9 minutes 36 seconds).
+
 To help understand the standard, Jukka Korpela has written `an introductory
 guide <http://jkorpela.fi/unicode/guide.html>`_ to reading the
 Unicode character tables.
@@ -238,7 +183,7 @@ Unicode features.
 The String Type
 ---------------
 
-Since Python 3.0, the language features a :class:`str` type that contain Unicode
+Since Python 3.0, the language's :class:`str` type contains Unicode
 characters, meaning any string created using ``"unicode rocks!"``, ``'unicode
 rocks!'``, or the triple-quoted string syntax is stored as Unicode.
 
@@ -252,11 +197,6 @@ include a Unicode character in a string literal::
        # 'File not found' error message.
        print("Fichier non trouvé")
 
-You can use a different encoding from UTF-8 by putting a specially-formatted
-comment as the first or second line of the source code::
-
-   # -*- coding: <encoding name> -*-
-
 Side note: Python 3 also supports using Unicode characters in identifiers::
 
    répertoire = "/tmp/records.log"
@@ -299,7 +239,7 @@ The following examples show the differences::
     >>> b'\x80abc'.decode("utf-8", "ignore")
     'abc'
 
-Encodings are specified as strings containing the encoding's name.  Python 3.2
+Encodings are specified as strings containing the encoding's name.  Python
 comes with roughly 100 different encodings; see the Python Library Reference at
 :ref:`standard-encodings` for a list.  Some encodings have multiple names; for
 example, ``'latin-1'``, ``'iso_8859_1'`` and ``'8859``' are all synonyms for
@@ -409,12 +349,13 @@ already mentioned.  See also :pep:`263` for more information.
 Unicode Properties
 ------------------
 
-The Unicode specification includes a database of information about code points.
-For each defined code point, the information includes the character's
-name, its category, the numeric value if applicable (Unicode has characters
-representing the Roman numerals and fractions such as one-third and
-four-fifths).  There are also properties related to the code point's use in
-bidirectional text and other display-related properties.
+The Unicode specification includes a database of information about
+code points.  For each defined code point, the information includes
+the character's name, its category, the numeric value if applicable
+(for characters representing numeric concepts such as the Roman
+numerals, fractions such as one-third and four-fifths, etc.).  There
+are also display-related properties, such as how to use the code point
+in bidirectional text.
 
 The following program displays some information about several characters, and
 prints the numeric value of one particular character::
@@ -451,6 +392,88 @@ other".  See
 list of category codes.
 
 
+Comparing Strings
+-----------------
+
+Unicode adds some complication to comparing strings, because the same
+set of characters can be represented by different sequences of code
+points.  For example, a letter like 'ê' can be represented as a single
+code point U+00EA, or as U+0065 U+0302, which is the code point for
+'e' followed by a code point for 'COMBINING CIRCUMFLEX ACCENT'.  These
+will produce the same output when printed, but one is a string of
+length 1 and the other is of length 2.
+
+One tool for a case-insensitive comparison is the
+:meth:`~str.casefold` string method that converts a string to a
+case-insensitive form following an algorithm described by the Unicode
+Standard.  This algorithm has special handling for characters such as
+the German letter 'ß' (code point U+00DF), which becomes the pair of
+lowercase letters 'ss'.
+
+::
+
+    >>> street = 'Gürzenichstraße'
+    >>> street.casefold()
+    'gürzenichstrasse'
+
+A second tool is the :mod:`unicodedata` module's
+:func:`~unicodedata.normalize` function that converts strings to one
+of several normal forms, where letters followed by a combining
+character are replaced with single characters.  :func:`normalize` can
+be used to perform string comparisons that won't falsely report
+inequality if two strings use combining characters differently:
+
+::
+
+    import unicodedata
+
+    def compare_strs(s1, s2):
+        def NFD(s):
+            return unicodedata.normalize('NFD', s)
+
+        return NFD(s1) == NFD(s2)
+
+    single_char = 'ê'
+    multiple_chars = '\N{LATIN SMALL LETTER E}\N{COMBINING CIRCUMFLEX ACCENT}'
+    print('length of first string=', len(single_char))
+    print('length of second string=', len(multiple_chars))
+    print(compare_strs(single_char, multiple_chars))
+
+When run, this outputs:
+
+.. code-block:: shell-session
+
+    $ python3 compare-strs.py
+    length of first string= 1
+    length of second string= 2
+    True
+
+The first argument to the :func:`~unicodedata.normalize` function is a
+string giving the desired normalization form, which can be one of
+'NFC', 'NFKC', 'NFD', and 'NFKD'.
+
+The Unicode Standard also specifies how to do caseless comparisons::
+
+    import unicodedata
+
+    def compare_caseless(s1, s2):
+        def NFD(s):
+            return unicodedata.normalize('NFD', s)
+
+        return NFD(NFD(s1).casefold()) == NFD(NFD(s2).casefold())
+
+    # Example usage
+    single_char = 'ê'
+    multiple_chars = '\N{LATIN CAPITAL LETTER E}\N{COMBINING CIRCUMFLEX ACCENT}'
+
+    print(compare_caseless(single_char, multiple_chars))
+
+This will print ``True``.  (Why is :func:`NFD` invoked twice?  Because
+there are a few characters that make :meth:`casefold` return a
+non-normalized string, so the result needs to be normalized again. See
+section 3.13 of the Unicode Standard for a discussion and an example.)
+
+
 Unicode Regular Expressions
 ---------------------------
 
@@ -567,22 +590,22 @@ particular byte ordering and don't skip the BOM.
 
 In some areas, it is also convention to use a "BOM" at the start of UTF-8
 encoded files; the name is misleading since UTF-8 is not byte-order dependent.
-The mark simply announces that the file is encoded in UTF-8.  Use the
-'utf-8-sig' codec to automatically skip the mark if present for reading such
-files.
+The mark simply announces that the file is encoded in UTF-8.  For reading such
+files, use the 'utf-8-sig' codec to automatically skip the mark if present.
 
 
 Unicode filenames
 -----------------
 
-Most of the operating systems in common use today support filenames that contain
-arbitrary Unicode characters.  Usually this is implemented by converting the
-Unicode string into some encoding that varies depending on the system.  For
-example, Mac OS X uses UTF-8 while Windows uses a configurable encoding; on
-Windows, Python uses the name "mbcs" to refer to whatever the currently
-configured encoding is.  On Unix systems, there will only be a filesystem
-encoding if you've set the ``LANG`` or ``LC_CTYPE`` environment variables; if
-you haven't, the default encoding is UTF-8.
+Most of the operating systems in common use today support filenames
+that contain arbitrary Unicode characters.  Usually this is
+implemented by converting the Unicode string into some encoding that
+varies depending on the system.  Today Python is converging on using
+UTF-8: Python on MacOS has used UTF-8 for several versions, and Python
+3.6 switched to using UTF-8 on Windows as well.  On Unix systems,
+there will only be a filesystem encoding if you've set the ``LANG`` or
+``LC_CTYPE`` environment variables; if you haven't, the default
+encoding is again UTF-8.
 
 The :func:`sys.getfilesystemencoding` function returns the encoding to use on
 your current system, in case you want to do the encoding manually, but there's
@@ -597,9 +620,9 @@ automatically converted to the right encoding for you::
 Functions in the :mod:`os` module such as :func:`os.stat` will also accept Unicode
 filenames.
 
-The :func:`os.listdir` function returns filenames and raises an issue: should it return
+The :func:`os.listdir` function returns filenames, which raises an issue: should it return
 the Unicode version of filenames, or should it return bytes containing
-the encoded versions?  :func:`os.listdir` will do both, depending on whether you
+the encoded versions?  :func:`os.listdir` can do both, depending on whether you
 provided the directory path as bytes or a Unicode string.  If you pass a
 Unicode string as the path, filenames will be decoded using the filesystem's
 encoding and a list of Unicode strings will be returned, while passing a byte
@@ -619,16 +642,17 @@ will produce the following output:
 
 .. code-block:: shell-session
 
-   amk:~$ python t.py
+   $ python listdir-test.py
    [b'filename\xe4\x94\x80abc', ...]
    ['filename\u4500abc', ...]
 
 The first list contains UTF-8-encoded filenames, and the second list contains
 the Unicode versions.
 
-Note that on most occasions, the Unicode APIs should be used.  The bytes APIs
-should only be used on systems where undecodable file names can be present,
-i.e. Unix systems.
+Note that on most occasions, you should can just stick with using
+Unicode with these APIs.  The bytes APIs should only be used on
+systems where undecodable file names can be present; that's
+pretty much only Unix systems now.
 
 
 Tips for Writing Unicode-aware Programs
@@ -695,10 +719,10 @@ with the ``surrogateescape`` error handler::
        f.write(data)
 
 The ``surrogateescape`` error handler will decode any non-ASCII bytes
-as code points in the Unicode Private Use Area ranging from U+DC80 to
-U+DCFF.  These private code points will then be turned back into the
-same bytes when the ``surrogateescape`` error handler is used when
-encoding the data and writing it back out.
+as code points in a special range running from U+DC80 to
+U+DCFF.  These code points will then turn back into the
+same bytes when the ``surrogateescape`` error handler is used to
+encode the data and write it back out.
 
 
 References
@@ -730,4 +754,5 @@ Andrew Kuchling, and Ezio Melotti.
 Thanks to the following people who have noted errors or offered
 suggestions on this article: Éric Araujo, Nicholas Bastin, Nick
 Coghlan, Marius Gedminas, Kent Johnson, Ken Krugler, Marc-André
-Lemburg, Martin von Löwis, Terry J. Reedy, Chad Whitacre.
+Lemburg, Martin von Löwis, Terry J. Reedy, Serhiy Storchaka,
+Eryk Sun, Chad Whitacre, Graham Wideman.
index 970a7aeb98a7139afb8f9c4d251f3dd617fd05fb..7328907730fb107ae853bf5195a4e6a60228000b 100644 (file)
@@ -45,7 +45,7 @@ Module :mod:`aifc` defines the following function:
    time how many samples you are going to write in total and use
    :meth:`writeframesraw` and :meth:`setnframes`.
    The :func:`.open` function may be used in a :keyword:`with` statement.  When
-   the :keyword:`with` block completes, the :meth:`~aifc.close` method is called.
+   the :keyword:`!with` block completes, the :meth:`~aifc.close` method is called.
 
    .. versionchanged:: 3.4
       Support for the :keyword:`with` statement was added.
index 647b7fc5e7a5820633fef9ea15fe4b233e13fd8f..d59cf055b614171132fc4e54e359a380073e4211 100644 (file)
@@ -960,12 +960,20 @@ Unix signals
 
    Set *callback* as the handler for the *signum* signal.
 
+   The callback will be invoked by *loop*, along with other queued callbacks
+   and runnable coroutines of that event loop. Unlike signal handlers
+   registered using :func:`signal.signal`, a callback registered with this
+   function is allowed to interact with the event loop.
+
    Raise :exc:`ValueError` if the signal number is invalid or uncatchable.
    Raise :exc:`RuntimeError` if there is a problem setting up the handler.
 
    Use :func:`functools.partial` :ref:`to pass keyword arguments
    <asyncio-pass-keywords>` to *callback*.
 
+   Like :func:`signal.signal`, this function must be invoked in the main
+   thread.
+
 .. method:: loop.remove_signal_handler(sig)
 
    Remove the handler for the *sig* signal.
index dbd5df720850bdba1c2b7a73b7cf0cb806e380be..e49577a203e8fb360952b9694b35010aec11f2ff 100644 (file)
@@ -65,11 +65,11 @@ Exceptions
 
 .. exception:: IncompleteReadError
 
-    The requested read operation did not complete fully.
+   The requested read operation did not complete fully.
 
-    Raised by the :ref:`asyncio stream APIs<asyncio-streams>`.
+   Raised by the :ref:`asyncio stream APIs<asyncio-streams>`.
 
-    This exception is a subclass of :exc:`EOFError`.
+   This exception is a subclass of :exc:`EOFError`.
 
    .. attribute:: expected
 
index cab25934d7826bf0c4eb640b3209804951a3611f..07842daa28b80d23994e40409e0ad7cdd59ee930 100644 (file)
@@ -81,7 +81,7 @@ The abstract event loop policy base class is defined as follows:
 
    .. method:: set_child_watcher(watcher)
 
-      Get the current child process watcher to *watcher*.
+      Set the current child process watcher to *watcher*.
 
       This function is Unix specific.
 
index bd0e70c0d9fc5fbb5077086aa091d4f92c849b34..7be1023c80cc66ceb4126b6753cf128061725ad5 100644 (file)
@@ -64,7 +64,7 @@ Queue
       Block until all items in the queue have been received and processed.
 
       The count of unfinished tasks goes up whenever an item is added
-      to the queue. The count goes down whenever a consumer thread calls
+      to the queue. The count goes down whenever a consumer coroutine calls
       :meth:`task_done` to indicate that the item was retrieved and all
       work on it is complete.  When the count of unfinished tasks drops
       to zero, :meth:`join` unblocks.
index 376de8f4042fdb22657f279b95f7f515fabeb3b9..9e685b176486209ed74fb397237cd99b084fa14b 100644 (file)
@@ -604,7 +604,7 @@ Scheduling From Other Threads
    See the :ref:`concurrency and multithreading <asyncio-multithreading>`
    section of the documentation.
 
-   Unlike other asyncio functions this functions requires the *loop*
+   Unlike other asyncio functions this function requires the *loop*
    argument to be passed explicitly.
 
    .. versionadded:: 3.5.1
index a4efef8465725c7461a18cd835ab293091587afb..89ecddc7780fa3812e786db3ce119848773fd0c6 100644 (file)
@@ -152,6 +152,8 @@ The :mod:`binascii` module defines the following functions:
    *data* is converted into the corresponding 2-digit hex representation.  The
    returned bytes object is therefore twice as long as the length of *data*.
 
+   Similar functionality (but returning a text string) is also conveniently
+   accessible using the :meth:`bytes.hex` method.
 
 .. function:: a2b_hex(hexstr)
               unhexlify(hexstr)
@@ -161,6 +163,9 @@ The :mod:`binascii` module defines the following functions:
    of hexadecimal digits (which can be upper or lower case), otherwise an
    :exc:`Error` exception is raised.
 
+   Similar functionality (accepting only text string arguments, but more
+   liberal towards whitespace) is also accessible using the
+   :meth:`bytes.fromhex` class method.
 
 .. exception:: Error
 
index 016e56c4bd0b09802d85a877d3bdf6b0ccaf7637..0413f469228a4beb8a556342e3637f830ee5d5d1 100644 (file)
@@ -100,6 +100,21 @@ The class can be used to simulate nested scopes and is useful in templating.
         :func:`super` function.  A reference to ``d.parents`` is equivalent to:
         ``ChainMap(*d.maps[1:])``.
 
+    Note, the iteration order of a :class:`ChainMap()` is determined by
+    scanning the mappings last to first::
+
+        >>> baseline = {'music': 'bach', 'art': 'rembrandt'}
+        >>> adjustments = {'art': 'van gogh', 'opera': 'carmen'}
+        >>> list(ChainMap(adjustments, baseline))
+        ['music', 'art', 'opera']
+
+    This gives the same ordering as a series of :meth:`dict.update` calls
+    starting with the last mapping::
+
+        >>> combined = baseline.copy()
+        >>> combined.update(adjustments)
+        >>> list(combined)
+        ['music', 'art', 'opera']
 
 .. seealso::
 
@@ -163,8 +178,8 @@ contexts::
         e.maps[-1]            # Root context -- like Python's globals()
         e.parents             # Enclosing context chain -- like Python's nonlocals
 
-        d['x']                # Get first key in the chain of contexts
         d['x'] = 1            # Set value in current context
+        d['x']                # Get first key in the chain of contexts
         del d['x']            # Delete from current context
         list(d)               # All nested values
         k in d                # Check all nested values
@@ -887,7 +902,7 @@ field names, the method and attribute names start with an underscore.
 
 .. method:: somenamedtuple._asdict()
 
-    Return a new :class:`OrderedDict` which maps field names to their corresponding
+    Return a new :class:`dict` which maps field names to their corresponding
     values:
 
     .. doctest::
@@ -1017,17 +1032,41 @@ customize a prototype instance:
 :class:`OrderedDict` objects
 ----------------------------
 
-Ordered dictionaries are just like regular dictionaries but they remember the
-order that items were inserted.  When iterating over an ordered dictionary,
-the items are returned in the order their keys were first added.
+Ordered dictionaries are just like regular dictionaries but have some extra
+capabilities relating to ordering operations.  They have become less
+important now that the built-in :class:`dict` class gained the ability
+to remember insertion order (this new behavior became guaranteed in
+Python 3.7).
+
+Some differences from :class:`dict` still remain:
+
+* The regular :class:`dict` was designed to be very good at mapping
+  operations.  Tracking insertion order was secondary.
+
+* The :class:`OrderedDict` was designed to be good at reordering operations.
+  Space efficiency, iteration speed, and the performance of update
+  operations were secondary.
+
+* Algorithmically, :class:`OrderedDict` can handle frequent reordering
+  operations better than :class:`dict`.  This makes it suitable for tracking
+  recent accesses (for example in an `LRU cache
+  <https://medium.com/@krishankantsinghal/my-first-blog-on-medium-583159139237>`_).
+
+* The equality operation for :class:`OrderedDict` checks for matching order.
+
+* The :meth:`popitem` method of :class:`OrderedDict` has a different
+  signature.  It accepts an optional argument to specify which item is popped.
+
+* :class:`OrderedDict` has a :meth:`move_to_end` method to
+  efficiently reposition an element to an endpoint.
+
+* Until Python 3.8, :class:`dict` lacked a :meth:`__reversed__` method.
+
 
 .. class:: OrderedDict([items])
 
-    Return an instance of a dict subclass, supporting the usual :class:`dict`
-    methods.  An *OrderedDict* is a dict that remembers the order that keys
-    were first inserted. If a new entry overwrites an existing entry, the
-    original insertion position is left unchanged.  Deleting an entry and
-    reinserting it will move it to the end.
+    Return an instance of a :class:`dict` subclass that has methods
+    specialized for rearranging dictionary order.
 
     .. versionadded:: 3.1
 
@@ -1077,29 +1116,7 @@ anywhere a regular dictionary is used.
 :class:`OrderedDict` Examples and Recipes
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Since an ordered dictionary remembers its insertion order, it can be used
-in conjunction with sorting to make a sorted dictionary::
-
-    >>> # regular unsorted dictionary
-    >>> d = {'banana': 3, 'apple': 4, 'pear': 1, 'orange': 2}
-
-    >>> # dictionary sorted by key
-    >>> OrderedDict(sorted(d.items(), key=lambda t: t[0]))
-    OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])
-
-    >>> # dictionary sorted by value
-    >>> OrderedDict(sorted(d.items(), key=lambda t: t[1]))
-    OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])
-
-    >>> # dictionary sorted by length of the key string
-    >>> OrderedDict(sorted(d.items(), key=lambda t: len(t[0])))
-    OrderedDict([('pear', 1), ('apple', 4), ('orange', 2), ('banana', 3)])
-
-The new sorted dictionaries maintain their sort order when entries
-are deleted.  But when new keys are added, the keys are appended
-to the end and the sort is not maintained.
-
-It is also straight-forward to create an ordered dictionary variant
+It is straightforward to create an ordered dictionary variant
 that remembers the order the keys were *last* inserted.
 If a new entry overwrites an existing entry, the
 original insertion position is changed and moved to the end::
@@ -1108,21 +1125,29 @@ original insertion position is changed and moved to the end::
         'Store items in the order the keys were last added'
 
         def __setitem__(self, key, value):
-            if key in self:
-                del self[key]
-            OrderedDict.__setitem__(self, key, value)
+            super().__setitem__(key, value)
+            super().move_to_end(key)
 
-An ordered dictionary can be combined with the :class:`Counter` class
-so that the counter remembers the order elements are first encountered::
+An :class:`OrderedDict` would also be useful for implementing
+variants of :func:`functools.lru_cache`::
 
-    class OrderedCounter(Counter, OrderedDict):
-        'Counter that remembers the order elements are first encountered'
+    class LRU(OrderedDict):
+        'Limit size, evicting the least recently looked-up key when full'
 
-        def __repr__(self):
-            return '%s(%r)' % (self.__class__.__name__, OrderedDict(self))
+        def __init__(self, maxsize=128, *args, **kwds):
+            self.maxsize = maxsize
+            super().__init__(*args, **kwds)
 
-        def __reduce__(self):
-            return self.__class__, (OrderedDict(self),)
+        def __getitem__(self, key):
+            value = super().__getitem__(key)
+            self.move_to_end(key)
+            return value
+
+        def __setitem__(self, key, value):
+            super().__setitem__(key, value)
+            if len(self) > self.maxsize:
+                oldest = next(iter(self))
+                del self[oldest]
 
 
 :class:`UserDict` objects
index 5151f3a5237ae6c1dc5f50e137e7fb00cb612219..258de28e3b6eeb2c09b257cbf348edc1e6079050 100644 (file)
@@ -105,7 +105,7 @@ compile Python sources.
    byte-code file ending in ``.pyc``, never ``.pyo``.
 
 .. versionchanged:: 3.7
-   Added the ``--invalidation-mode`` parameter.
+   Added the ``--invalidation-mode`` option.
 
 
 There is no command-line option to control the optimization level used by the
index 321770242b003c154180687c7499959bab2c9925..95cc352010e0e0517382f31d8bbbe945356a38dc 100644 (file)
@@ -462,7 +462,8 @@ the :meth:`__init__` options:
 
   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 because dict preserves order from Python 3.7.
+  For example:
 
   .. doctest::
 
@@ -477,41 +478,10 @@ the :meth:`__init__` options:
      ...                                'bar': 'y',
      ...                                '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']
+     >>> parser.sections()
+     ['section1', 'section2', 'section3']
+     >>> [option for option in parser['section3']]
+     ['foo', 'bar', 'baz']
 
 * *allow_no_value*, default value: ``False``
 
@@ -891,7 +861,7 @@ interpolation if an option used is not defined elsewhere. ::
 ConfigParser Objects
 --------------------
 
-.. class:: ConfigParser(defaults=None, dict_type=dict, allow_no_value=False, delimiters=('=', ':'), comment_prefixes=('#', ';'), inline_comment_prefixes=None, strict=True, empty_lines_in_values=True, default_section=configparser.DEFAULTSECT, interpolation=BasicInterpolation(), converters={})
+.. class:: ConfigParser(defaults=None, dict_type=collections.OrderedDict, allow_no_value=False, delimiters=('=', ':'), comment_prefixes=('#', ';'), inline_comment_prefixes=None, strict=True, empty_lines_in_values=True, default_section=configparser.DEFAULTSECT, interpolation=BasicInterpolation(), converters={})
 
    The main configuration parser.  When *defaults* is given, it is initialized
    into the dictionary of intrinsic defaults.  When *dict_type* is given, it
@@ -953,10 +923,6 @@ ConfigParser Objects
       providing consistent behavior across the parser: non-string
       keys and values are implicitly converted to strings.
 
-   .. versionchanged:: 3.7
-      The default *dict_type* is :class:`dict`, since it now preserves
-      insertion order.
-
    .. method:: defaults()
 
       Return a dictionary containing the instance-wide defaults.
@@ -1213,7 +1179,7 @@ ConfigParser Objects
 RawConfigParser Objects
 -----------------------
 
-.. class:: RawConfigParser(defaults=None, dict_type=dict, \
+.. class:: RawConfigParser(defaults=None, dict_type=collections.OrderedDict, \
                            allow_no_value=False, *, delimiters=('=', ':'), \
                            comment_prefixes=('#', ';'), \
                            inline_comment_prefixes=None, strict=True, \
@@ -1226,10 +1192,6 @@ RawConfigParser Objects
    names, and values via its unsafe ``add_section`` and ``set`` methods,
    as well as the legacy ``defaults=`` keyword argument handling.
 
-   .. versionchanged:: 3.7
-      The default *dict_type* is :class:`dict`, since it now preserves
-      insertion order.
-
    .. note::
       Consider using :class:`ConfigParser` instead which checks types of
       the values to be stored internally.  If you don't want interpolation, you
index 930c97358e080d7c31fb0974780298b49642d605..017a87a5648c393e634dc54ada60ccf9182a491c 100644 (file)
@@ -1,5 +1,5 @@
-:mod:`contextlib` --- Utilities for :keyword:`with`\ -statement contexts
-========================================================================
+:mod:`!contextlib` --- Utilities for :keyword:`!with`\ -statement contexts
+==========================================================================
 
 .. module:: contextlib
    :synopsis: Utilities for with-statement contexts.
@@ -72,7 +72,7 @@ Functions and classes provided:
 
    The function being decorated must return a :term:`generator`-iterator when
    called. This iterator must yield exactly one value, which will be bound to
-   the targets in the :keyword:`with` statement's :keyword:`as` clause, if any.
+   the targets in the :keyword:`with` statement's :keyword:`!as` clause, if any.
 
    At the point where the generator yields, the block nested in the :keyword:`with`
    statement is executed.  The generator is then resumed after the block is exited.
@@ -82,9 +82,9 @@ Functions and classes provided:
    the error (if any), or ensure that some cleanup takes place. If an exception is
    trapped merely in order to log it or to perform some action (rather than to
    suppress it entirely), the generator must reraise that exception. Otherwise the
-   generator context manager will indicate to the :keyword:`with` statement that
+   generator context manager will indicate to the :keyword:`!with` statement that
    the exception has been handled, and execution will resume with the statement
-   immediately following the :keyword:`with` statement.
+   immediately following the :keyword:`!with` statement.
 
    :func:`contextmanager` uses :class:`ContextDecorator` so the context managers
    it creates can be used as decorators as well as in :keyword:`with` statements.
@@ -346,7 +346,7 @@ Functions and classes provided:
       As the decorated function must be able to be called multiple times, the
       underlying context manager must support use in multiple :keyword:`with`
       statements. If this is not the case, then the original construct with the
-      explicit :keyword:`with` statement inside the function should be used.
+      explicit :keyword:`!with` statement inside the function should be used.
 
    .. versionadded:: 3.2
 
@@ -771,7 +771,7 @@ Reentrant context managers
 
 More sophisticated context managers may be "reentrant". These context
 managers can not only be used in multiple :keyword:`with` statements,
-but may also be used *inside* a :keyword:`with` statement that is already
+but may also be used *inside* a :keyword:`!with` statement that is already
 using the same context manager.
 
 :class:`threading.RLock` is an example of a reentrant context manager, as are
index fe0feeda8b87870098f5935b1181f373d85ba1aa..6af60b6e269495f04624ec6134bec9d9ea965f03 100644 (file)
@@ -51,9 +51,9 @@ Module-level decorators, classes, and functions
 
    The :func:`dataclass` decorator examines the class to find
    ``field``\s.  A ``field`` is defined as class variable that has a
-   type annotation.  With two exceptions described below, nothing in
-   :func:`dataclass` examines the type specified in the variable
-   annotation.
+   :term:`type annotation <variable annotation>`.  With two
+   exceptions described below, nothing in :func:`dataclass`
+   examines the type specified in the variable annotation.
 
    The order of the fields in all of the generated methods is the
    order in which they appear in the class definition.
index db3a6522c24f78141fae6ae5d597135fbdd0f7d0..121f73bbe852471ae245f13375e8dd1ac619b7c0 100644 (file)
@@ -2034,6 +2034,12 @@ calls the platform C library's :func:`strftime` function, and platform
 variations are common.  To see the full set of format codes supported on your
 platform, consult the :manpage:`strftime(3)` documentation.
 
+For the same reason, handling of format strings containing Unicode code points
+that can't be represented in the charset of the current locale is also
+platform-dependent. On some platforms such code points are preserved intact in
+the output, while on others ``strftime`` may raise :exc:`UnicodeError` or return
+an empty string instead.
+
 The following is a list of all the format codes that the C standard (1989
 version) requires, and these work on all platforms with a standard C
 implementation.  Note that the 1999 version of the C standard added additional
index f2a677e6936302e588774781dd28096c077cb892..bcae55eb8217844bb37e30c1f4380407053294d5 100644 (file)
@@ -2115,3 +2115,23 @@ Alternatively, inputs can be rounded upon creation using the
 
    >>> Context(prec=5, rounding=ROUND_DOWN).create_decimal('1.2345678')
    Decimal('1.2345')
+
+Q. Is the CPython implementation fast for large numbers?
+
+A. Yes.  In the CPython and PyPy3 implementations, the C/CFFI versions of
+the decimal module integrate the high speed `libmpdec
+<https://www.bytereef.org/mpdecimal/doc/libmpdec/index.html>`_ library for
+arbitrary precision correctly-rounded decimal floating point arithmetic.
+``libmpdec`` uses `Karatsuba multiplication
+<https://en.wikipedia.org/wiki/Karatsuba_algorithm>`_
+for medium-sized numbers and the `Number Theoretic Transform
+<https://en.wikipedia.org/wiki/Discrete_Fourier_transform_(general)#Number-theoretic_transform>`_
+for very large numbers.  However, to realize this performance gain, the
+context needs to be set for unrounded calculations.
+
+    >>> c = getcontext()
+    >>> c.prec = MAX_PREC
+    >>> c.Emax = MAX_EMAX
+    >>> c.Emin = MIN_EMIN
+
+.. versionadded:: 3.3
\ No newline at end of file
index 81e9766e429b81ac0b1f2c657f2374da3a1a5250..a6285ffaf1911492ad883d27a834502b01509663 100644 (file)
@@ -394,7 +394,7 @@ A new :class:`Enum` class must have one base Enum class, up to one concrete
 data type, and as many :class:`object`-based mixin classes as needed.  The
 order of these base classes is::
 
-    def EnumName([mix-in, ...,] [data-type,] base-enum):
+    class EnumName([mix-in, ...,] [data-type,] base-enum):
         pass
 
 Also, subclassing an enumeration is allowed only if the enumeration does not define
index 5881fefe293276c70b3ea3ae86aad5a28c784d98..1fc11ffce25e051823d7907464c53718178a5871 100644 (file)
@@ -63,7 +63,7 @@ The following function is the primary interface of this module:
 
    The :class:`FileInput` instance can be used as a context manager in the
    :keyword:`with` statement.  In this example, *input* is closed after the
-   :keyword:`with` statement is exited, even if an exception occurs::
+   :keyword:`!with` statement is exited, even if an exception occurs::
 
       with fileinput.input(files=('spam.txt', 'eggs.txt')) as f:
           for line in f:
@@ -155,7 +155,7 @@ available for subclassing as well:
 
    A :class:`FileInput` instance can be used as a context manager in the
    :keyword:`with` statement.  In this example, *input* is closed after the
-   :keyword:`with` statement is exited, even if an exception occurs::
+   :keyword:`!with` statement is exited, even if an exception occurs::
 
       with FileInput(files=('spam.txt', 'eggs.txt')) as input:
           process(input)
index c0f4ffd2cb2a8003b4d71bd765eb0d36df9a30ab..9326b8d0fe7d70dd4c528931178abb87fa7da86b 100644 (file)
@@ -668,6 +668,11 @@ are always available.  They are listed here in alphabetical order.
    topic, and a help page is printed on the console.  If the argument is any other
    kind of object, a help page on the object is generated.
 
+   Note that if a slash(/) appears in the parameter list of a function, when
+   invoking :func:`help`, it means that the parameters prior to the slash are
+   positional-only. For more info, see
+   :ref:`the FAQ entry on positional-only parameters <faq-positional-only-arguments>`.
+
    This function is added to the built-in namespace by the :mod:`site` module.
 
    .. versionchanged:: 3.4
@@ -809,13 +814,14 @@ are always available.  They are listed here in alphabetical order.
 
    See also :ref:`typeiter`.
 
-   One useful application of the second form of :func:`iter` is to read lines of
-   a file until a certain line is reached.  The following example reads a file
-   until the :meth:`~io.TextIOBase.readline` method returns an empty string::
+   One useful application of the second form of :func:`iter` is to build a
+   block-reader. For example, reading fixed-width blocks from a binary
+   database file until the end of file is reached::
 
-      with open('mydata.txt') as fp:
-          for line in iter(fp.readline, ''):
-              process_line(line)
+      from functools import partial
+      with open('mydata.db', 'rb') as f:
+          for block in iter(partial(f.read, 64), b''):
+              process_block(block)
 
 
 .. function:: len(s)
@@ -996,7 +1002,6 @@ are always available.  They are listed here in alphabetical order.
    ``'b'``   binary mode
    ``'t'``   text mode (default)
    ``'+'``   open a disk file for updating (reading and writing)
-   ``'U'``   :term:`universal newlines` mode (deprecated)
    ========= ===============================================================
 
    The default mode is ``'r'`` (open for reading text, synonym of ``'rt'``).
@@ -1011,6 +1016,12 @@ are always available.  They are listed here in alphabetical order.
    first decoded using a platform-dependent encoding or using the specified
    *encoding* if given.
 
+   There is an additional mode character permitted, ``'U'``, which no longer
+   has any effect, and is considered deprecated. It previously enabled
+   :term:`universal newlines` in text mode, which became the default behaviour
+   in Python 3.0. Refer to the documentation of the
+   :ref:`newline <open-newline-parameter>` parameter for further details.
+
    .. note::
 
       Python doesn't depend on the underlying operating system's notion of text
@@ -1077,6 +1088,8 @@ are always available.  They are listed here in alphabetical order.
    .. index::
       single: universal newlines; open() built-in function
 
+   .. _open-newline-parameter:
+
    *newline* controls how :term:`universal newlines` mode works (it only
    applies to text mode).  It can be ``None``, ``''``, ``'\n'``, ``'\r'``, and
    ``'\r\n'``.  It works as follows:
@@ -1655,7 +1668,7 @@ are always available.  They are listed here in alphabetical order.
    This function is invoked by the :keyword:`import` statement.  It can be
    replaced (by importing the :mod:`builtins` module and assigning to
    ``builtins.__import__``) in order to change semantics of the
-   :keyword:`import` statement, but doing so is **strongly** discouraged as it
+   :keyword:`!import` statement, but doing so is **strongly** discouraged as it
    is usually simpler to use import hooks (see :pep:`302`) to attain the same
    goals and does not cause issues with code which assumes the default import
    implementation is in use.  Direct use of :func:`__import__` is also
index c4b7c79730f49ab17246903d206d53ed07fcf40b..3408c103e2f328e06183fa2ed0666f3e1c7b768a 100644 (file)
@@ -497,6 +497,7 @@ Here is an example session that uses the ``GET`` method::
    b'<!doctype html>\n<!--[if"...
    ...
    >>> # Example of an invalid request
+   >>> conn = http.client.HTTPSConnection("docs.python.org")
    >>> conn.request("GET", "/parrot.spam")
    >>> r2 = conn.getresponse()
    >>> print(r2.status, r2.reason)
index 7c34004a3ae0822992414de0e58236bdabfd1dc3..88d62cca3f904167ac09ad608b8417447b5f80dc 100644 (file)
@@ -96,7 +96,7 @@ Code    Enum Name                           Details
 ``413`` ``REQUEST_ENTITY_TOO_LARGE``        HTTP/1.1 :rfc:`7231`, Section 6.5.11
 ``414`` ``REQUEST_URI_TOO_LONG``            HTTP/1.1 :rfc:`7231`, Section 6.5.12
 ``415`` ``UNSUPPORTED_MEDIA_TYPE``          HTTP/1.1 :rfc:`7231`, Section 6.5.13
-``416`` ``REQUEST_RANGE_NOT_SATISFIABLE``   HTTP/1.1 Range Requests :rfc:`7233`, Section 4.4
+``416`` ``REQUESTED_RANGE_NOT_SATISFIABLE`` HTTP/1.1 Range Requests :rfc:`7233`, Section 4.4
 ``417`` ``EXPECTATION_FAILED``              HTTP/1.1 :rfc:`7231`, Section 6.5.14
 ``421`` ``MISDIRECTED_REQUEST``             HTTP/2 :rfc:`7540`, Section 9.1.2
 ``422`` ``UNPROCESSABLE_ENTITY``            WebDAV :rfc:`4918`, Section 11.2
index 384d2bf57dc5a75e9813502638471ac287adedb4..8ef9e2eed534b8df382d3222f7d9097cb848e9b2 100644 (file)
@@ -146,7 +146,7 @@ Go to Line
 
 Show Completions
    Open a scrollable list allowing selection of keywords and attributes. See
-   Completions in the Tips sections below.
+   :ref:`Completions <completions>` in the Editing and navigation section below.
 
 Expand Word
    Expand a prefix you have typed to match a full word in the same window;
@@ -154,11 +154,14 @@ Expand Word
 
 Show call tip
    After an unclosed parenthesis for a function, open a small window with
-   function parameter hints.
+   function parameter hints.  See :ref:`Calltips <calltips>` in the
+   Editing and navigation section below.
 
 Show surrounding parens
    Highlight the surrounding parenthesis.
 
+.. _format-menu:
+
 Format menu (Editor window only)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -232,6 +235,12 @@ View Last Restart
 Restart Shell
   Restart the shell to clean the environment.
 
+Previous History
+  Cycle through earlier commands in history which match the current entry.
+
+Next History
+  Cycle through later commands in history which match the current entry.
+
 Interrupt Execution
   Stop a running program.
 
@@ -267,30 +276,26 @@ Options menu (Shell and Editor)
 Configure IDLE
    Open a configuration dialog and change preferences for the following:
    fonts, indentation, keybindings, text color themes, startup windows and
-   size, additional help sources, and extensions (see below).  On macOS,
-   open the configuration dialog by selecting Preferences in the application
-   menu.  To use a new built-in color theme (IDLE Dark) with older IDLEs,
-   save it as a new custom theme.
+   size, additional help sources, and extensions.  On macOS,  open the
+   configuration dialog by selecting Preferences in the application
+   menu. For more, see
+   :ref:`Setting preferences <preferences>` under Help and preferences.
 
-   Non-default user settings are saved in a .idlerc directory in the user's
-   home directory.  Problems caused by bad user configuration files are solved
-   by editing or deleting one or more of the files in .idlerc.
+Zoom/Restore Height
+   Toggles the window between normal size and maximum height. The initial size
+   defaults to 40 lines by 80 chars unless changed on the General tab of the
+   Configure IDLE dialog.
 
-Code Context (toggle)(Editor Window only)
+Show/Hide Code Context (Editor Window only)
    Open a pane at the top of the edit window which shows the block context
-   of the code which has scrolled above the top of the window.  Clicking a
-   line in this pane exposes that line at the top of the editor.
+   of the code which has scrolled above the top of the window.  See
+   :ref:`Code Context <code-context>` in the Editing and Navigation section below.
 
 Window menu (Shell and Editor)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Zoom Height
-   Toggles the window between normal size and maximum height. The initial size
-   defaults to 40 lines by 80 chars unless changed on the General tab of the
-   Configure IDLE dialog.
-
-The rest of this menu lists the names of all open windows; select one to bring
-it to the foreground (deiconifying it if necessary).
+Lists the names of all open windows; select one to bring it to the foreground
+(deiconifying it if necessary).
 
 Help menu (Shell and Editor)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -310,8 +315,8 @@ Turtle Demo
    Run the turtledemo module with example Python code and turtle drawings.
 
 Additional help sources may be added here with the Configure IDLE dialog under
-the General tab. See the "Help sources" subsection below for more
-on Help menu choices.
+the General tab. See the :ref:`Help sources <help-sources>` subsection below
+for more on Help menu choices.
 
 .. index::
    single: Cut
@@ -359,6 +364,8 @@ Squeeze
    the code above and the prompt below down to a 'Squeezed text' label.
 
 
+.. _editing-and-navigation:
+
 Editing and navigation
 ----------------------
 
@@ -429,7 +436,11 @@ to 4 spaces if they are there. :kbd:`Tab` inserts spaces (in the Python
 Shell window one tab), number depends on Indent width. Currently, tabs
 are restricted to four spaces due to Tcl/Tk limitations.
 
-See also the indent/dedent region commands in the edit menu.
+See also the indent/dedent region commands on the
+:ref:`Format menu <format-menu>`.
+
+
+.. _completions:
 
 Completions
 ^^^^^^^^^^^
@@ -475,6 +486,8 @@ much can be found by default, e.g. the re module.
 If you don't like the ACW popping up unbidden, simply make the delay
 longer or disable the extension.
 
+.. _calltips:
+
 Calltips
 ^^^^^^^^
 
@@ -503,6 +516,25 @@ In an editor, import statements have no effect until one runs the file.  One
 might want to run a file after writing the import statements at the top,
 or immediately run an existing file before editing.
 
+.. _code-context:
+
+Code Context
+^^^^^^^^^^^^
+
+Within an editor window containing Python code, code context can be toggled
+in order to show or hide a pane at the top of the window.  When shown, this
+pane freezes the opening lines for block code, such as those beginning with
+``class``, ``def``, or ``if`` keywords, that would have otherwise scrolled
+out of view.  The size of the pane will be expanded and contracted as needed
+to show the all current levels of context, up to the maximum number of
+lines defined in the Configure IDLE dialog (which defaults to 15).  If there
+are no current context lines and the feature is toggled on, a single blank
+line will display.  Clicking on a line in the context pane will move that
+line to the top of the editor.
+
+The text and background colors for the context pane can be configured under
+the Highlights tab in the Configure IDLE dialog.
+
 Python Shell window
 ^^^^^^^^^^^^^^^^^^^
 
@@ -684,14 +716,33 @@ In contrast, some system text windows only keep the last n lines of output.
 A Windows console, for instance, keeps a user-settable 1 to 9999 lines,
 with 300 the default.
 
-Text widgets display a subset of Unicode, the Basic Multilingual Plane (BMP).
-Which characters get a proper glyph instead of a replacement box depends on
-the operating system and installed fonts.  Newline characters cause following
-text to appear on a new line, but other control characters are either
-replaced with a box or deleted.  However, ``repr()``, which is used for
-interactive echo of expression values, replaces control characters,
-some BMP codepoints, and all non-BMP characters with escape codes
-before they are output.
+A Tk Text widget, and hence IDLE's Shell, displays characters (codepoints)
+in the the BMP (Basic Multilingual Plane) subset of Unicode.
+Which characters are displayed with a proper glyph and which with a
+replacement box depends on the operating system and installed fonts.
+Tab characters cause the following text to begin after
+the next tab stop. (They occur every 8 'characters').
+Newline characters cause following text to appear on a new line.
+Other control characters are ignored or displayed as a space, box, or
+something else, depending on the operating system and font.
+(Moving the text cursor through such output with arrow keys may exhibit
+some surprising spacing behavior.)
+
+.. code-block:: none
+
+   >>> s = 'a\tb\a<\x02><\r>\bc\nd'
+   >>> len(s)
+   14
+   >>> s  # Display repr(s)
+   'a\tb\x07<\x02><\r>\x08c\nd'
+   >>> print(s, end='')  # Display s as is.
+   # Result varies by OS and font.  Try it.
+
+The ``repr`` function is used for interactive echo of expression
+values.  It returns an altered version of the input string in which
+control codes, some BMP codepoints, and all non-BMP codepoints are
+replaced with escape codes. As demonstrated above, it allows one to
+identify the characters in a string, regardless of how they are displayed.
 
 Normal and error output are generally kept separate (on separate lines)
 from code input and each other.  They each get different highlight colors.
@@ -768,6 +819,8 @@ with the default subprocess if at all possible.
 Help and preferences
 --------------------
 
+.. _help-sources:
+
 Help sources
 ^^^^^^^^^^^^
 
@@ -788,13 +841,28 @@ that will be opened instead.
 Selected URLs can be added or removed from the help menu at any time using the
 General tab of the Configure IDLE dialog .
 
+.. _preferences:
+
 Setting preferences
 ^^^^^^^^^^^^^^^^^^^
 
 The font preferences, highlighting, keys, and general preferences can be
-changed via Configure IDLE on the Option menu.  Keys can be user defined;
-IDLE ships with four built-in key sets. In addition, a user can create a
-custom key set in the Configure IDLE dialog under the keys tab.
+changed via Configure IDLE on the Option menu.
+Non-default user settings are saved in a .idlerc directory in the user's
+home directory.  Problems caused by bad user configuration files are solved
+by editing or deleting one or more of the files in .idlerc.
+
+On the Font tab, see the text sample for the effect of font face and size
+on multiple characters in multiple languages.  Edit the sample to add
+other characters of personal interest.  Use the sample to select
+monospaced fonts.  If particular characters have problems in Shell or an
+editor, add them to the top of the sample and try changing first size
+and then font.
+
+On the Highlights and Keys tab, select a built-in or custom color theme
+and key set.  To use a newer built-in color theme or key set with older
+IDLEs, save it as a new custom theme or key set and it well be accessible
+to older IDLEs.
 
 IDLE on macOS
 ^^^^^^^^^^^^^
index 040dab6e9f7a04171ceb4f490a1f9688575f6056..d0709f8b678e43cff639e181cb7a4ad9fdab3c2e 100644 (file)
@@ -39,7 +39,7 @@ base class:
 
    The :class:`IMAP4` class supports the :keyword:`with` statement.  When used
    like this, the IMAP4 ``LOGOUT`` command is issued automatically when the
-   :keyword:`with` statement exits.  E.g.::
+   :keyword:`!with` statement exits.  E.g.::
 
     >>> from imaplib import IMAP4
     >>> with IMAP4("domain.org") as M:
index 1bd6f12b915f89bc9667ad6f4491098349a80860..04f207f58d38daa0ad5f061bdad8d7a5043cfe47 100644 (file)
@@ -179,7 +179,7 @@ This module provides an interface to the mechanisms used to implement the
    If a module imports objects from another module using :keyword:`from` ...
    :keyword:`import` ..., calling :func:`reload` for the other module does not
    redefine the objects imported from it --- one way around this is to re-execute
-   the :keyword:`from` statement, another is to use :keyword:`import` and qualified
+   the :keyword:`!from` statement, another is to use :keyword:`!import` and qualified
    names (*module*.*name*) instead.
 
    If a module instantiates instances of a class, reloading the module that defines
index 0bcfbb1c72631b844ca06b4665d31eebab151d1d..23831c75842f1f26555f1be24e4e656edc26fecf 100644 (file)
@@ -1,5 +1,5 @@
-:mod:`importlib` --- The implementation of :keyword:`import`
-============================================================
+:mod:`!importlib` --- The implementation of :keyword:`!import`
+==============================================================
 
 .. module:: importlib
    :synopsis: The implementation of the import machinery.
@@ -19,7 +19,7 @@ Introduction
 The purpose of the :mod:`importlib` package is two-fold. One is to provide the
 implementation of the :keyword:`import` statement (and thus, by extension, the
 :func:`__import__` function) in Python source code. This provides an
-implementation of :keyword:`import` which is portable to any Python
+implementation of :keyword:`!import` which is portable to any Python
 interpreter. This also provides an implementation which is easier to
 comprehend than one implemented in a programming language other than Python.
 
@@ -197,7 +197,7 @@ Functions
    If a module imports objects from another module using :keyword:`from` ...
    :keyword:`import` ..., calling :func:`reload` for the other module does not
    redefine the objects imported from it --- one way around this is to
-   re-execute the :keyword:`from` statement, another is to use :keyword:`import`
+   re-execute the :keyword:`!from` statement, another is to use :keyword:`!import`
    and qualified names (*module.name*) instead.
 
    If a module instantiates instances of a class, reloading the module that
@@ -1737,7 +1737,8 @@ Python 3.6 and newer for other parts of the code).
           if spec is not None:
               break
       else:
-          raise ImportError(f'No module named {absolute_name!r}')
+          msg = f'No module named {absolute_name!r}'
+          raise ModuleNotFoundError(msg, name=absolute_name)
       module = importlib.util.module_from_spec(spec)
       spec.loader.exec_module(module)
       sys.modules[absolute_name] = module
index f985eeb4f53b7175edab034293683f21c7b1bc36..18cbacf3e8db5272cf6501cd92aa097749473885 100644 (file)
@@ -559,6 +559,10 @@ function.
    Raises :exc:`ValueError` if no signature can be provided, and
    :exc:`TypeError` if that type of object is not supported.
 
+   A slash(/) in the signature of a function denotes that the parameters prior
+   to it are positional-only. For more info, see
+   :ref:`the FAQ entry on positional-only parameters <faq-positional-only-arguments>`.
+
    .. versionadded:: 3.5
       ``follow_wrapped`` parameter. Pass ``False`` to get a signature of
       ``callable`` specifically (``callable.__wrapped__`` will not be used to
index 7068e68ad90f1f06c44cf93864bfe66463528f4e..e623a041acf8d3994744ec9d3d1ee1f7f5374abb 100644 (file)
@@ -249,7 +249,7 @@ I/O Base Classes
 
    :class:`IOBase` is also a context manager and therefore supports the
    :keyword:`with` statement.  In this example, *file* is closed after the
-   :keyword:`with` statement's suite is finished---even if an exception occurs::
+   :keyword:`!with` statement's suite is finished---even if an exception occurs::
 
       with open('spam.txt', 'w') as file:
           file.write('Spam and eggs!')
@@ -349,8 +349,8 @@ I/O Base Classes
       (on most systems, additional bytes are zero-filled).  The new file size
       is returned.
 
-   .. versionchanged:: 3.5
-      Windows will now zero-fill files when extending.
+      .. versionchanged:: 3.5
+         Windows will now zero-fill files when extending.
 
    .. method:: writable()
 
index de805eb955dfbe0f73b0933b1e91b3b551089cdf..cd62adb39a364444fb8c7e0999f4969f95d1535f 100644 (file)
@@ -107,9 +107,9 @@ in :mod:`logging` itself) and defining handlers which are declared either in
                                     enabled. The default is ``True`` because this
                                     enables old behaviour in a
                                     backward-compatible way. This behaviour is to
-                                    disable any existing loggers unless they or
-                                    their ancestors are explicitly named in the
-                                    logging configuration.
+                                    disable any existing non-root loggers unless
+                                    they or their ancestors are explicitly named
+                                    in the logging configuration.
 
    .. versionchanged:: 3.4
       An instance of a subclass of :class:`~configparser.RawConfigParser` is
@@ -308,8 +308,8 @@ otherwise, the context is used to determine what to instantiate.
   If the specified value is ``True``, the configuration is processed
   as described in the section on :ref:`logging-config-dict-incremental`.
 
-* *disable_existing_loggers* - whether any existing loggers are to be
-  disabled. This setting mirrors the parameter of the same name in
+* *disable_existing_loggers* - whether any existing non-root loggers are
+  to be disabled. This setting mirrors the parameter of the same name in
   :func:`fileConfig`. If absent, this parameter defaults to ``True``.
   This value is ignored if *incremental* is ``True``.
 
index 504f3a1c3c33bf8f435b2a99d135548b8e42fdbb..96e0dc831b79564aa343a2c069c117b968e7bd3b 100644 (file)
@@ -186,6 +186,13 @@ A library which wants to use a particular start method should probably
 use :func:`get_context` to avoid interfering with the choice of the
 library user.
 
+.. warning::
+
+   The ``'spawn'`` and ``'forkserver'`` start methods cannot currently
+   be used with "frozen" executables (i.e., binaries produced by
+   packages like **PyInstaller** and **cx_Freeze**) on Unix.
+   The ``'fork'`` start method does work.
+
 
 Exchanging objects between processes
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1638,7 +1645,7 @@ their parent process exits.  The manager classes are defined in the
       Connect a local manager object to a remote manager process::
 
       >>> from multiprocessing.managers import BaseManager
-      >>> m = BaseManager(address=('127.0.0.1', 5000), authkey=b'abc')
+      >>> m = BaseManager(address=('127.0.0.1', 50000), authkey=b'abc')
       >>> m.connect()
 
    .. method:: shutdown()
@@ -2141,6 +2148,10 @@ with the :class:`Pool` class.
       the process pool as separate tasks.  The (approximate) size of these
       chunks can be specified by setting *chunksize* to a positive integer.
 
+      Note that it may cause high memory usage for very long iterables. Consider
+      using :meth:`imap` or :meth:`imap_unordered` with explicit *chunksize*
+      option for better efficiency.
+
    .. method:: map_async(func, iterable[, chunksize[, callback[, error_callback]]])
 
       A variant of the :meth:`.map` method which returns a result object.
@@ -2159,7 +2170,7 @@ with the :class:`Pool` class.
 
    .. method:: imap(func, iterable[, chunksize])
 
-      A lazier version of :meth:`map`.
+      A lazier version of :meth:`.map`.
 
       The *chunksize* argument is the same as the one used by the :meth:`.map`
       method.  For very long iterables using a large value for *chunksize* can
index d8ef8a692a9533c00ac15af51177a32ba4b25ca3..56188c7ef53880c7bb365b638b977f7c7b94d8f5 100644 (file)
@@ -232,10 +232,10 @@ tuples or objects that the method normally returns will be empty.
    .. versionadded:: 3.2
 
 
-.. method:: NNTP.starttls(ssl_context=None)
+.. method:: NNTP.starttls(context=None)
 
    Send a ``STARTTLS`` command.  This will enable encryption on the NNTP
-   connection.  The *ssl_context* argument is optional and should be a
+   connection.  The *context* argument is optional and should be a
    :class:`ssl.SSLContext` object.  Please read :ref:`ssl-security` for best
    practices.
 
index f6ff01097fe37a1e17ce6963951c7418baf2446f..d78ab068a31ea37b72ab050204bcae28bc8a73d4 100644 (file)
@@ -277,10 +277,11 @@ the :mod:`glob` module.)
 
    Return ``True`` if pathname *path* is a :dfn:`mount point`: a point in a
    file system where a different file system has been mounted.  On POSIX, the
-   function checks whether *path*'s parent, :file:`path/..`, is on a different
-   device than *path*, or whether :file:`path/..` and *path* point to the same
+   function checks whether *path*'s parent, :file:`{path}/..`, is on a different
+   device than *path*, or whether :file:`{path}/..` and *path* point to the same
    i-node on the same device --- this should detect mount points for all Unix
-   and POSIX variants.  On Windows, a drive letter root and a share UNC are
+   and POSIX variants.  It is not able to reliably detect bind mounts on the
+   same filesystem.  On Windows, a drive letter root and a share UNC are
    always mount points, and for any other path ``GetVolumePathName`` is called
    to see if it is different from the input path.
 
index c3b699a360247c130f953ad6a5839045552e76be..a302681eca056855c8b458d2412f6d4380833b55 100644 (file)
@@ -63,7 +63,7 @@ of the production as recognized in the input string: these are always sequences
 which have the same form as the parent.  An important aspect of this structure
 which should be noted is that keywords used to identify the parent node type,
 such as the keyword :keyword:`if` in an :const:`if_stmt`, are included in the
-node tree without any special treatment.  For example, the :keyword:`if` keyword
+node tree without any special treatment.  For example, the :keyword:`!if` keyword
 is represented by the tuple ``(1, 'if')``, where ``1`` is the numeric value
 associated with all :const:`NAME` tokens, including variable and function names
 defined by the user.  In an alternate form returned when line number information
index b81c3deb6049d83051337776fe5c4f3de751e1cb..628ae6e9adb6fa99a779a0fab699c79c6749ba84 100644 (file)
Binary files a/Doc/library/pathlib-inheritance.png and b/Doc/library/pathlib-inheritance.png differ
index 9f42005e0a12bdb8e346fdc1b5c61d90e3459bac..49057f678fd7d00e428de68c5a19a7e7833ba5e6 100644 (file)
@@ -1,4 +1 @@
-<?xml version="1.0" standalone="yes"?>
-
-<svg version="1.1" viewBox="0.0 0.0 538.0 496.0" fill="none" stroke="none" stroke-linecap="square" stroke-miterlimit="10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="p.0"><path d="m0 0l538.0 0l0 496.0l-538.0 0l0 -496.0z" clip-rule="nonzero"></path></clipPath><g clip-path="url(#p.0)"><path fill="#000000" fill-opacity="0.0" d="m0 0l538.916 0l0 496.08398l-538.916 0z" fill-rule="nonzero"></path><path fill="#ffffff" d="m176.0 24.0l187.43307 0l0 80.53543l-187.43307 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m176.0 24.0l187.43307 0l0 80.53543l-187.43307 0z" fill-rule="nonzero"></path><path fill="#000000" d="m235.18527 66.877716l0 1.640625l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.265625l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.15625q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.421875 -1.421875 -0.421875l-1.84375 0l0 3.015625zm13.9296875 -2.234375l0 5.484375q0.515625 0 0.75 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-1.515625 0l0 -0.375q-0.6875 0.3125 -1.3125 0.46875q-0.625 0.171875 -1.1875 0.171875q-0.796875 0 -1.375 -0.328125q-0.578125 -0.34375 -0.90625 -0.9375q-0.25 -0.421875 -0.25 -1.046875l0 -3.453125l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.875 0l0 4.765625q0 0.5 0.234375 0.75q0.25 0.234375 0.765625 0.234375q0.484375 0 1.03125 -0.1875q0.5625 -0.203125 1.390625 -0.703125l0 -3.265625l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l2.171875 0zm5.8671875 0l0 1.0q1.015625 -0.734375 1.59375 -0.96875q0.578125 -0.25 1.09375 -0.25q0.78125 0 1.515625 0.578125q0.5 0.390625 0.5 0.796875q0 0.34375 -0.25 0.59375q-0.234375 0.234375 -0.5625 0.234375q-0.296875 0 -0.625 -0.296875q-0.328125 -0.296875 -0.59375 -0.296875q-0.328125 0 -1.0 0.421875q-0.671875 0.421875 -1.671875 1.265625l0 2.40625l2.28125 0q0.578125 0 0.828125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-4.828125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.953125 0l0 -3.890625l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l2.171875 0zm13.9609375 4.359375l-6.578125 0q0.25 0.625 0.890625 1.015625q0.640625 0.375 1.71875 0.375q0.890625 0 2.375 -0.390625q0.609375 -0.15625 0.84375 -0.15625q0.3125 0 0.53125 0.234375q0.21875 0.21875 0.21875 0.5625q0 0.3125 -0.234375 0.53125q-0.3125 0.296875 -1.53125 0.5625q-1.203125 0.265625 -2.3125 0.265625q-1.921875 0 -3.078125 -1.09375q-1.15625 -1.09375 -1.15625 -2.671875q0 -1.6875 1.25 -2.75q1.25 -1.0625 2.875 -1.0625q0.96875 0 1.78125 0.34375q0.828125 0.34375 1.21875 0.75q0.5625 0.578125 0.9375 1.421875q0.25 0.59375 0.25 1.375l0 0.6875zm-1.78125 -1.609375q-0.359375 -0.6875 -0.953125 -1.015625q-0.59375 -0.34375 -1.421875 -0.34375q-0.8125 0 -1.40625 0.34375q-0.59375 0.328125 -0.96875 1.015625l4.75 0zm6.4296875 1.09375l0 1.640625l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.265625l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.15625q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.421875 -1.421875 -0.421875l-1.84375 0l0 3.015625zm11.9765625 4.859375l0 -0.375q-0.609375 0.3125 -1.34375 0.46875q-0.71875 0.171875 -1.3125 0.171875q-1.28125 0 -2.09375 -0.6875q-0.796875 -0.6875 -0.796875 -1.515625q0 -1.0 1.015625 -1.859375q1.03125 -0.875 2.84375 -0.875q0.734375 0 1.6875 0.15625l0 -0.375q0 -0.359375 -0.3125 -0.578125q-0.3125 -0.234375 -1.171875 -0.234375q-0.71875 0 -1.84375 0.28125q-0.421875 0.09375 -0.65625 0.09375q-0.328125 0 -0.546875 -0.21875q-0.21875 -0.234375 -0.21875 -0.59375q0 -0.203125 0.078125 -0.34375q0.078125 -0.15625 0.21875 -0.25q0.140625 -0.09375 0.578125 -0.21875q0.59375 -0.15625 1.203125 -0.25q0.625 -0.109375 1.125 -0.109375q1.5 0 2.3125 0.65625q0.828125 0.640625 0.828125 1.75l0 3.296875l0.28125 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.875 0zm0 -2.875q-0.96875 -0.1875 -1.78125 -0.1875q-0.96875 0 -1.671875 0.484375q-0.4375 0.296875 -0.4375 0.609375q0 0.234375 0.203125 0.375q0.390625 0.25 1.078125 0.25q0.578125 0 1.296875 -0.21875q0.734375 -0.234375 1.3125 -0.625l0 -0.6875zm7.7578125 -2.625l0 3.21875q0 0.515625 0.21875 0.671875q0.328125 0.265625 1.171875 0.265625q1.21875 0 2.265625 -0.53125q0.390625 -0.203125 0.625 -0.203125q0.3125 0 0.53125 0.234375q0.234375 0.234375 0.234375 0.578125q0 0.3125 -0.25 0.53125q-0.375 0.375 -1.515625 0.6875q-1.125 0.3125 -1.890625 0.3125q-1.5 0 -2.25 -0.640625q-0.734375 -0.65625 -0.734375 -1.59375l0 -3.53125l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l0.578125 0l0 -1.453125q0 -0.578125 0.21875 -0.8125q0.21875 -0.25 0.578125 -0.25q0.359375 0 0.578125 0.25q0.21875 0.234375 0.21875 0.8125l0 1.453125l2.96875 0q0.578125 0 0.8125 0.21875q0.25 0.21875 0.25 0.578125q0 0.359375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-2.96875 0zm8.3515625 -4.640625l0 3.421875q0.5 -0.296875 1.0 -0.4375q0.515625 -0.15625 1.046875 -0.15625q0.828125 0 1.46875 0.28125q0.65625 0.28125 1.078125 0.890625q0.421875 0.609375 0.421875 1.53125l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.5625 0 -0.8125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.4375 0.375 -0.671875q0.203125 -0.125 0.796875 -0.125l0 -2.890625q0 -0.625 -0.28125 -0.875q-0.359375 -0.328125 -1.078125 -0.328125q-0.53125 0 -0.953125 0.203125q-0.40625 0.203125 -1.09375 0.890625l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.4375 0.375 -0.671875q0.1875 -0.125 0.796875 -0.125l0 -6.921875l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l1.875 0z" fill-rule="nonzero"></path><path fill="#ffffff" d="m16.0 144.0l187.43306 0l0 80.53543l-187.43306 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m16.0 144.0l187.43306 0l0 80.53543l-187.43306 0z" fill-rule="nonzero"></path><path fill="#000000" d="m51.181374 186.87772l0 1.640625l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.265625l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.15625q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.421875 -1.421875 -0.421875l-1.84375 0l0 3.015625zm13.9296875 -2.234375l0 5.484375q0.515625 0 0.75 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-1.515625 0l0 -0.375q-0.6875 0.3125 -1.3125 0.46875q-0.625 0.171875 -1.1875 0.171875q-0.796875 0 -1.375 -0.328125q-0.578125 -0.34375 -0.90625 -0.9375q-0.25 -0.421875 -0.25 -1.046875l0 -3.453125l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.875 0l0 4.765625q0 0.5 0.234375 0.75q0.25 0.234375 0.765625 0.234375q0.484375 0 1.03125 -0.1875q0.5625 -0.203125 1.390625 -0.703125l0 -3.265625l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l2.171875 0zm5.8671875 0l0 1.0q1.015625 -0.734375 1.59375 -0.96875q0.578125 -0.25 1.09375 -0.25q0.78125 0 1.515625 0.578125q0.5 0.390625 0.5 0.796875q0 0.34375 -0.25 0.59375q-0.234375 0.234375 -0.5625 0.234375q-0.296875 0 -0.625 -0.296875q-0.328125 -0.296875 -0.59375 -0.296875q-0.328125 0 -1.0 0.421875q-0.671875 0.421875 -1.671875 1.265625l0 2.40625l2.28125 0q0.578125 0 0.828125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-4.828125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.953125 0l0 -3.890625l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l2.171875 0zm13.9609375 4.359375l-6.578125 0q0.25 0.625 0.890625 1.015625q0.640625 0.375 1.71875 0.375q0.890625 0 2.375 -0.390625q0.609375 -0.15625 0.84375 -0.15625q0.3125 0 0.53125 0.234375q0.21875 0.21875 0.21875 0.5625q0 0.3125 -0.234375 0.53125q-0.3125 0.296875 -1.53125 0.5625q-1.203125 0.265625 -2.3125 0.265625q-1.921875 0 -3.078125 -1.09375q-1.15625 -1.09375 -1.15625 -2.671875q0 -1.6875 1.25 -2.75q1.25 -1.0625 2.875 -1.0625q0.96875 0 1.78125 0.34375q0.828125 0.34375 1.21875 0.75q0.5625 0.578125 0.9375 1.421875q0.25 0.59375 0.25 1.375l0 0.6875zm-1.78125 -1.609375q-0.359375 -0.6875 -0.953125 -1.015625q-0.59375 -0.34375 -1.421875 -0.34375q-0.8125 0 -1.40625 0.34375q-0.59375 0.328125 -0.96875 1.015625l4.75 0zm6.4296875 1.09375l0 1.640625l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.265625l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.15625q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.421875 -1.421875 -0.421875l-1.84375 0l0 3.015625zm14.6953125 1.4375q0 0.921875 -0.515625 1.796875q-0.515625 0.859375 -1.53125 1.375q-1.0 0.515625 -2.109375 0.515625q-1.09375 0 -2.09375 -0.5q-1.0 -0.515625 -1.53125 -1.375q-0.515625 -0.875 -0.515625 -1.828125q0 -0.953125 0.53125 -1.875q0.53125 -0.9375 1.53125 -1.46875q1.0 -0.53125 2.078125 -0.53125q1.09375 0 2.109375 0.546875q1.015625 0.546875 1.53125 1.46875q0.515625 0.90625 0.515625 1.875zm-1.609375 0.015625q0 -0.78125 -0.546875 -1.421875q-0.765625 -0.875 -2.0 -0.875q-1.078125 0 -1.8125 0.703125q-0.71875 0.6875 -0.71875 1.59375q0 0.75 0.734375 1.40625q0.734375 0.65625 1.796875 0.65625q1.078125 0 1.8125 -0.65625q0.734375 -0.65625 0.734375 -1.40625zm8.7734375 -1.8125q-0.390625 -0.25 -0.828125 -0.359375q-0.421875 -0.125 -0.890625 -0.125q-0.921875 0 -1.46875 0.296875q-0.25 0.140625 -0.25 0.296875q0 0.171875 0.328125 0.34375q0.25 0.125 1.125 0.25q1.59375 0.21875 2.21875 0.4375q0.8125 0.28125 1.25 0.859375q0.453125 0.5625 0.453125 1.203125q0 0.859375 -0.75 1.4375q-1.09375 0.84375 -2.828125 0.84375q-0.6875 0 -1.28125 -0.125q-0.59375 -0.125 -1.078125 -0.359375q-0.125 0.09375 -0.265625 0.15625q-0.125 0.046875 -0.265625 0.046875q-0.375 0 -0.59375 -0.234375q-0.21875 -0.25 -0.21875 -0.828125l0 -0.546875q0 -0.578125 0.21875 -0.8125q0.21875 -0.25 0.578125 -0.25q0.296875 0 0.484375 0.15625q0.203125 0.15625 0.3125 0.546875q0.359375 0.3125 0.875 0.484375q0.515625 0.15625 1.1875 0.15625q1.109375 0 1.71875 -0.34375q0.28125 -0.171875 0.28125 -0.359375q0 -0.3125 -0.40625 -0.515625q-0.421875 -0.203125 -1.71875 -0.34375q-1.921875 -0.203125 -2.578125 -0.78125q-0.640625 -0.578125 -0.640625 -1.40625q0 -0.859375 0.71875 -1.4375q0.984375 -0.78125 2.578125 -0.78125q0.5625 0 1.0625 0.109375q0.515625 0.109375 0.984375 0.328125q0.15625 -0.109375 0.28125 -0.15625q0.125 -0.0625 0.234375 -0.0625q0.328125 0 0.546875 0.25q0.21875 0.234375 0.21875 0.8125l0 0.390625q0 0.53125 -0.125 0.71875q-0.25 0.359375 -0.671875 0.359375q-0.296875 0 -0.515625 -0.171875q-0.21875 -0.1875 -0.28125 -0.484375zm8.4453125 -4.921875l0 1.703125l-1.90625 0l0 -1.703125l1.90625 0zm0.21875 3.046875l0 5.484375l1.921875 0q0.578125 0 0.828125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-5.4375 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l1.921875 0l0 -3.890625l-1.296875 0q-0.5625 0 -0.8125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.234375 -0.578125q0.25 -0.21875 0.828125 -0.21875l2.890625 0zm10.007805 3.40625l2.4375 2.078125q0.4375 0.03125 0.65625 0.25q0.21875 0.21875 0.21875 0.5625q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-1.8125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.28125 0.171875 -0.5q0.1875 -0.21875 0.484375 -0.296875l-1.1875 -1.03125l-1.2187424 1.03125q0.35936737 0.09375 0.5156174 0.296875q0.171875 0.1875 0.171875 0.5q0 0.359375 -0.25 0.59375q-0.23436737 0.21875 -0.8124924 0.21875l-1.8125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.328125 0.21875 -0.546875q0.21875 -0.21875 0.65625 -0.25l2.375 -2.09375l-2.109375 -1.796875q-0.40625 -0.03125 -0.625 -0.25q-0.21875 -0.21875 -0.21875 -0.546875q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.5 0q0.578125 0 0.8124924 0.21875q0.25 0.21875 0.25 0.5625q0 0.46875 -0.43749237 0.75l0.9687424 0.8125l0.953125 -0.828125q-0.421875 -0.296875 -0.421875 -0.703125q0 -0.375 0.234375 -0.59375q0.25 -0.21875 0.828125 -0.21875l1.484375 0q0.578125 0 0.828125 0.21875q0.25 0.21875 0.25 0.578125q0 0.328125 -0.21875 0.546875q-0.21875 0.21875 -0.640625 0.25l-2.109375 1.8125zm7.4765625 0.4375l0 1.640625l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.265625l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.15625q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.421875 -1.421875 -0.421875l-1.84375 0l0 3.015625zm11.9765625 4.859375l0 -0.375q-0.609375 0.3125 -1.34375 0.46875q-0.71875 0.171875 -1.3125 0.171875q-1.28125 0 -2.09375 -0.6875q-0.796875 -0.6875 -0.796875 -1.515625q0 -1.0 1.015625 -1.859375q1.03125 -0.875 2.84375 -0.875q0.734375 0 1.6875 0.15625l0 -0.375q0 -0.359375 -0.3125 -0.578125q-0.3125 -0.234375 -1.171875 -0.234375q-0.71875 0 -1.84375 0.28125q-0.421875 0.09375 -0.65625 0.09375q-0.328125 0 -0.546875 -0.21875q-0.21875 -0.234375 -0.21875 -0.59375q0 -0.203125 0.078125 -0.34375q0.078125 -0.15625 0.21875 -0.25q0.140625 -0.09375 0.578125 -0.21875q0.59375 -0.15625 1.203125 -0.25q0.625 -0.109375 1.125 -0.109375q1.5 0 2.3125 0.65625q0.828125 0.640625 0.828125 1.75l0 3.296875l0.28125 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.875 0zm0 -2.875q-0.96875 -0.1875 -1.78125 -0.1875q-0.96875 0 -1.671875 0.484375q-0.4375 0.296875 -0.4375 0.609375q0 0.234375 0.203125 0.375q0.390625 0.25 1.078125 0.25q0.578125 0 1.296875 -0.21875q0.734375 -0.234375 1.3125 -0.625l0 -0.6875zm7.7578125 -2.625l0 3.21875q0 0.515625 0.21875 0.671875q0.328125 0.265625 1.171875 0.265625q1.21875 0 2.265625 -0.53125q0.390625 -0.203125 0.625 -0.203125q0.3125 0 0.53125 0.234375q0.234375 0.234375 0.234375 0.578125q0 0.3125 -0.25 0.53125q-0.375 0.375 -1.515625 0.6875q-1.125 0.3125 -1.890625 0.3125q-1.5 0 -2.25 -0.640625q-0.734375 -0.65625 -0.734375 -1.59375l0 -3.53125l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l0.578125 0l0 -1.453125q0 -0.578125 0.21875 -0.8125q0.21875 -0.25 0.578125 -0.25q0.359375 0 0.578125 0.25q0.21875 0.234375 0.21875 0.8125l0 1.453125l2.96875 0q0.578125 0 0.8125 0.21875q0.25 0.21875 0.25 0.578125q0 0.359375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-2.96875 0zm8.3515625 -4.640625l0 3.421875q0.5 -0.296875 1.0 -0.4375q0.515625 -0.15625 1.046875 -0.15625q0.828125 0 1.46875 0.28125q0.65625 0.28125 1.078125 0.890625q0.421875 0.609375 0.421875 1.53125l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.5625 0 -0.8125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.4375 0.375 -0.671875q0.203125 -0.125 0.796875 -0.125l0 -2.890625q0 -0.625 -0.28125 -0.875q-0.359375 -0.328125 -1.078125 -0.328125q-0.53125 0 -0.953125 0.203125q-0.40625 0.203125 -1.09375 0.890625l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.4375 0.375 -0.671875q0.1875 -0.125 0.796875 -0.125l0 -6.921875l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l1.875 0z" fill-rule="nonzero"></path><path fill="#ffffff" d="m336.0 143.46457l187.43304 0l0 80.53543l-187.43304 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m336.0 143.46457l187.43304 0l0 80.53543l-187.43304 0z" fill-rule="nonzero"></path><path fill="#000000" d="m361.5798 186.34229l0 1.640625l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.265625l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.15625q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.421875 -1.421875 -0.421875l-1.84375 0l0 3.015625zm13.9296875 -2.234375l0 5.484375q0.515625 0 0.75 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-1.515625 0l0 -0.375q-0.6875 0.3125 -1.3125 0.46875q-0.625 0.171875 -1.1875 0.171875q-0.796875 0 -1.375 -0.328125q-0.578125 -0.34375 -0.90625 -0.9375q-0.25 -0.421875 -0.25 -1.046875l0 -3.453125l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.875 0l0 4.765625q0 0.5 0.234375 0.75q0.25 0.234375 0.765625 0.234375q0.484375 0 1.03125 -0.1875q0.5625 -0.203125 1.390625 -0.703125l0 -3.265625l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l2.171875 0zm5.8671875 0l0 1.0q1.015625 -0.734375 1.59375 -0.96875q0.578125 -0.25 1.09375 -0.25q0.78125 0 1.515625 0.578125q0.5 0.390625 0.5 0.796875q0 0.34375 -0.25 0.59375q-0.234375 0.234375 -0.5625 0.234375q-0.296875 0 -0.625 -0.296875q-0.328125 -0.296875 -0.59375 -0.296875q-0.328125 0 -1.0 0.421875q-0.671875 0.421875 -1.671875 1.265625l0 2.40625l2.28125 0q0.578125 0 0.828125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-4.828125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.953125 0l0 -3.890625l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l2.171875 0zm13.9609375 4.359375l-6.578125 0q0.25 0.625 0.890625 1.015625q0.640625 0.375 1.71875 0.375q0.890625 0 2.375 -0.390625q0.609375 -0.15625 0.84375 -0.15625q0.3125 0 0.53125 0.234375q0.21875 0.21875 0.21875 0.5625q0 0.3125 -0.234375 0.53125q-0.3125 0.296875 -1.53125 0.5625q-1.203125 0.265625 -2.3125 0.265625q-1.921875 0 -3.078125 -1.09375q-1.15625 -1.09375 -1.15625 -2.671875q0 -1.6875 1.25 -2.75q1.25 -1.0625 2.875 -1.0625q0.96875 0 1.78125 0.34375q0.828125 0.34375 1.21875 0.75q0.5625 0.578125 0.9375 1.421875q0.25 0.59375 0.25 1.375l0 0.6875zm-1.78125 -1.609375q-0.359375 -0.6875 -0.953125 -1.015625q-0.59375 -0.34375 -1.421875 -0.34375q-0.8125 0 -1.40625 0.34375q-0.59375 0.328125 -0.96875 1.015625l4.75 0zm7.3671875 -0.203125l-1.484375 4.546875l-1.796875 0l-0.953125 -7.875q-0.375 -0.046875 -0.5625 -0.25q-0.1875 -0.203125 -0.1875 -0.53125q0 -0.375 0.25 -0.59375q0.25 -0.234375 0.828125 -0.234375l2.125 0.015625q0.578125 0 0.828125 0.21875q0.25 0.21875 0.25 0.578125q0 0.359375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-0.828125 0l0.53125 4.484375l1.25 -3.734375l1.671875 0l1.25 3.734375l0.53125 -4.484375l-0.84375 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.21875 -0.234375 -0.578125q0 -0.359375 0.234375 -0.578125q0.25 -0.234375 0.828125 -0.234375l2.125 0.015625q0.578125 0 0.828125 0.21875q0.25 0.21875 0.25 0.578125q0 0.296875 -0.203125 0.515625q-0.1875 0.21875 -0.5625 0.28125l-0.921875 7.875l-1.765625 0l-1.53125 -4.546875zm10.1640625 -5.59375l0 1.703125l-1.90625 0l0 -1.703125l1.90625 0zm0.21875 3.046875l0 5.484375l1.921875 0q0.578125 0 0.828125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-5.4375 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l1.921875 0l0 -3.890625l-1.296875 0q-0.5625 0 -0.8125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.234375 -0.578125q0.25 -0.21875 0.828125 -0.21875l2.890625 0zm7.1953125 0l0 0.53125q0.4375 -0.375 0.953125 -0.5625q0.53125 -0.1875 1.15625 -0.1875q1.421875 0 2.25 0.890625q0.65625 0.703125 0.65625 1.84375l0 2.96875q0.5 0 0.734375 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.453125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.34375 0.234375 -0.5625q0.25 -0.234375 0.75 -0.234375l0 -3.015625q0 -0.53125 -0.28125 -0.765625q-0.359375 -0.3125 -1.09375 -0.3125q-0.5625 0 -0.984375 0.21875q-0.40625 0.203125 -1.046875 0.90625l0 2.96875q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.4375 0.375 -0.671875q0.1875 -0.125 0.796875 -0.125l0 -3.890625q-0.5 0 -0.75 -0.21875q-0.234375 -0.234375 -0.234375 -0.578125q0 -0.359375 0.234375 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.53125 0zm14.8984375 -3.046875l0 8.53125l0.265625 0q0.578125 0 0.828125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-1.875 0l0 -0.390625q-0.546875 0.3125 -1.140625 0.484375q-0.59375 0.171875 -1.234375 0.171875q-1.8125 0 -2.921875 -1.046875q-1.09375 -1.046875 -1.09375 -2.609375q0 -1.625 1.15625 -2.765625q1.15625 -1.15625 2.828125 -1.15625q0.625 0 1.21875 0.203125q0.609375 0.1875 1.1875 0.5625l0 -1.984375l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l1.875 0zm-1.609375 6.796875q0 -0.984375 -0.703125 -1.671875q-0.6875 -0.6875 -1.6875 -0.6875q-1.0 0 -1.703125 0.6875q-0.6875 0.6875 -0.6875 1.65625q0 0.875 0.625 1.453125q0.625 0.5625 1.765625 0.5625q1.125 0 1.75 -0.5625q0.640625 -0.578125 0.640625 -1.4375zm11.6953125 -0.078125q0 0.921875 -0.515625 1.796875q-0.515625 0.859375 -1.53125 1.375q-1.0 0.515625 -2.109375 0.515625q-1.09375 0 -2.09375 -0.5q-1.0 -0.515625 -1.53125 -1.375q-0.515625 -0.875 -0.515625 -1.828125q0 -0.953125 0.53125 -1.875q0.53125 -0.9375 1.53125 -1.46875q1.0 -0.53125 2.078125 -0.53125q1.09375 0 2.109375 0.546875q1.015625 0.546875 1.53125 1.46875q0.515625 0.90625 0.515625 1.875zm-1.609375 0.015625q0 -0.78125 -0.546875 -1.421875q-0.765625 -0.875 -2.0 -0.875q-1.078125 0 -1.8125 0.703125q-0.71875 0.6875 -0.71875 1.59375q0 0.75 0.734375 1.40625q0.734375 0.65625 1.796875 0.65625q1.078125 0 1.8125 -0.65625q0.734375 -0.65625 0.734375 -1.40625zm7.0546875 0.453125l-1.109375 2.953125l-1.5 0l-1.34375 -5.5q-0.4375 -0.015625 -0.671875 -0.234375q-0.21875 -0.234375 -0.21875 -0.5625q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.484375 0q0.578125 0 0.828125 0.21875q0.25 0.21875 0.25 0.578125q0 0.359375 -0.28125 0.609375q-0.21875 0.1875 -0.828125 0.1875l0.609375 2.546875l0.984375 -2.609375l1.421875 0l1.0 2.609375l0.625 -2.546875q-0.59375 0 -0.78125 -0.109375q-0.375 -0.25 -0.375 -0.6875q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.5 0q0.578125 0 0.828125 0.21875q0.25 0.21875 0.25 0.578125q0 0.328125 -0.21875 0.546875q-0.21875 0.21875 -0.640625 0.25l-1.3125 5.5l-1.484375 0l-1.171875 -2.953125zm11.3203125 -2.265625q-0.390625 -0.25 -0.828125 -0.359375q-0.421875 -0.125 -0.890625 -0.125q-0.921875 0 -1.46875 0.296875q-0.25 0.140625 -0.25 0.296875q0 0.171875 0.328125 0.34375q0.25 0.125 1.125 0.25q1.59375 0.21875 2.21875 0.4375q0.8125 0.28125 1.25 0.859375q0.453125 0.5625 0.453125 1.203125q0 0.859375 -0.75 1.4375q-1.09375 0.84375 -2.828125 0.84375q-0.6875 0 -1.28125 -0.125q-0.59375 -0.125 -1.078125 -0.359375q-0.125 0.09375 -0.265625 0.15625q-0.125 0.046875 -0.265625 0.046875q-0.375 0 -0.59375 -0.234375q-0.21875 -0.25 -0.21875 -0.828125l0 -0.546875q0 -0.578125 0.21875 -0.8125q0.21875 -0.25 0.578125 -0.25q0.296875 0 0.484375 0.15625q0.203125 0.15625 0.3125 0.546875q0.359375 0.3125 0.875 0.484375q0.515625 0.15625 1.1875 0.15625q1.109375 0 1.71875 -0.34375q0.28125 -0.171875 0.28125 -0.359375q0 -0.3125 -0.40625 -0.515625q-0.421875 -0.203125 -1.71875 -0.34375q-1.921875 -0.203125 -2.578125 -0.78125q-0.640625 -0.578125 -0.640625 -1.40625q0 -0.859375 0.71875 -1.4375q0.984375 -0.78125 2.578125 -0.78125q0.5625 0 1.0625 0.109375q0.515625 0.109375 0.984375 0.328125q0.15625 -0.109375 0.28125 -0.15625q0.125 -0.0625 0.234375 -0.0625q0.328125 0 0.546875 0.25q0.21875 0.234375 0.21875 0.8125l0 0.390625q0 0.53125 -0.125 0.71875q-0.25 0.359375 -0.671875 0.359375q-0.296875 0 -0.515625 -0.171875q-0.21875 -0.1875 -0.28125 -0.484375zm6.9453125 1.96875l0 1.640625l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.265625l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.15625q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.421875 -1.421875 -0.421875l-1.84375 0l0 3.015625zm11.9765625 4.859375l0 -0.375q-0.609375 0.3125 -1.34375 0.46875q-0.71875 0.171875 -1.3125 0.171875q-1.28125 0 -2.09375 -0.6875q-0.796875 -0.6875 -0.796875 -1.515625q0 -1.0 1.015625 -1.859375q1.03125 -0.875 2.84375 -0.875q0.734375 0 1.6875 0.15625l0 -0.375q0 -0.359375 -0.3125 -0.578125q-0.3125 -0.234375 -1.171875 -0.234375q-0.71875 0 -1.84375 0.28125q-0.421875 0.09375 -0.65625 0.09375q-0.328125 0 -0.546875 -0.21875q-0.21875 -0.234375 -0.21875 -0.59375q0 -0.203125 0.078125 -0.34375q0.078125 -0.15625 0.21875 -0.25q0.140625 -0.09375 0.578125 -0.21875q0.59375 -0.15625 1.203125 -0.25q0.625 -0.109375 1.125 -0.109375q1.5 0 2.3125 0.65625q0.828125 0.640625 0.828125 1.75l0 3.296875l0.28125 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.875 0zm0 -2.875q-0.96875 -0.1875 -1.78125 -0.1875q-0.96875 0 -1.671875 0.484375q-0.4375 0.296875 -0.4375 0.609375q0 0.234375 0.203125 0.375q0.390625 0.25 1.078125 0.25q0.578125 0 1.296875 -0.21875q0.734375 -0.234375 1.3125 -0.625l0 -0.6875zm7.7578125 -2.625l0 3.21875q0 0.515625 0.21875 0.671875q0.328125 0.265625 1.171875 0.265625q1.21875 0 2.265625 -0.53125q0.390625 -0.203125 0.625 -0.203125q0.3125 0 0.53125 0.234375q0.234375 0.234375 0.234375 0.578125q0 0.3125 -0.25 0.53125q-0.375 0.375 -1.515625 0.6875q-1.125 0.3125 -1.890625 0.3125q-1.5 0 -2.25 -0.640625q-0.734375 -0.65625 -0.734375 -1.59375l0 -3.53125l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l0.578125 0l0 -1.453125q0 -0.578125 0.21875 -0.8125q0.21875 -0.25 0.578125 -0.25q0.359375 0 0.578125 0.25q0.21875 0.234375 0.21875 0.8125l0 1.453125l2.96875 0q0.578125 0 0.8125 0.21875q0.25 0.21875 0.25 0.578125q0 0.359375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-2.96875 0zm8.3515625 -4.640625l0 3.421875q0.5 -0.296875 1.0 -0.4375q0.515625 -0.15625 1.046875 -0.15625q0.828125 0 1.46875 0.28125q0.65625 0.28125 1.078125 0.890625q0.421875 0.609375 0.421875 1.53125l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.5625 0 -0.8125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.4375 0.375 -0.671875q0.203125 -0.125 0.796875 -0.125l0 -2.890625q0 -0.625 -0.28125 -0.875q-0.359375 -0.328125 -1.078125 -0.328125q-0.53125 0 -0.953125 0.203125q-0.40625 0.203125 -1.09375 0.890625l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.4375 0.375 -0.671875q0.1875 -0.125 0.796875 -0.125l0 -6.921875l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l1.875 0z" fill-rule="nonzero"></path><path fill="#ffffff" d="m176.0 271.46457l187.43307 0l0 80.53543l-187.43307 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m176.0 271.46457l187.43307 0l0 80.53543l-187.43307 0z" fill-rule="nonzero"></path><path fill="#000000" d="m254.3884 314.3423l0 1.640625l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.265625l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.15625q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.421875 -1.421875 -0.421875l-1.84375 0l0 3.015625zm11.9765625 4.859375l0 -0.375q-0.609375 0.3125 -1.34375 0.46875q-0.71875 0.171875 -1.3125 0.171875q-1.28125 0 -2.09375 -0.6875q-0.796875 -0.6875 -0.796875 -1.515625q0 -1.0 1.015625 -1.859375q1.03125 -0.875 2.84375 -0.875q0.734375 0 1.6875 0.15625l0 -0.375q0 -0.359375 -0.3125 -0.578125q-0.3125 -0.234375 -1.171875 -0.234375q-0.71875 0 -1.84375 0.28125q-0.421875 0.09375 -0.65625 0.09375q-0.328125 0 -0.546875 -0.21875q-0.21875 -0.234375 -0.21875 -0.59375q0 -0.203125 0.078125 -0.34375q0.078125 -0.15625 0.21875 -0.25q0.140625 -0.09375 0.578125 -0.21875q0.59375 -0.15625 1.203125 -0.25q0.625 -0.109375 1.125 -0.109375q1.5 0 2.3125 0.65625q0.828125 0.640625 0.828125 1.75l0 3.296875l0.28125 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.875 0zm0 -2.875q-0.96875 -0.1875 -1.78125 -0.1875q-0.96875 0 -1.671875 0.484375q-0.4375 0.296875 -0.4375 0.609375q0 0.234375 0.203125 0.375q0.390625 0.25 1.078125 0.25q0.578125 0 1.296875 -0.21875q0.734375 -0.234375 1.3125 -0.625l0 -0.6875zm7.7578125 -2.625l0 3.21875q0 0.515625 0.21875 0.671875q0.328125 0.265625 1.171875 0.265625q1.21875 0 2.265625 -0.53125q0.390625 -0.203125 0.625 -0.203125q0.3125 0 0.53125 0.234375q0.234375 0.234375 0.234375 0.578125q0 0.3125 -0.25 0.53125q-0.375 0.375 -1.515625 0.6875q-1.125 0.3125 -1.890625 0.3125q-1.5 0 -2.25 -0.640625q-0.734375 -0.65625 -0.734375 -1.59375l0 -3.53125l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l0.578125 0l0 -1.453125q0 -0.578125 0.21875 -0.8125q0.21875 -0.25 0.578125 -0.25q0.359375 0 0.578125 0.25q0.21875 0.234375 0.21875 0.8125l0 1.453125l2.96875 0q0.578125 0 0.8125 0.21875q0.25 0.21875 0.25 0.578125q0 0.359375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-2.96875 0zm8.3515625 -4.640625l0 3.421875q0.5 -0.296875 1.0 -0.4375q0.515625 -0.15625 1.046875 -0.15625q0.828125 0 1.46875 0.28125q0.65625 0.28125 1.078125 0.890625q0.421875 0.609375 0.421875 1.53125l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.5625 0 -0.8125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.4375 0.375 -0.671875q0.203125 -0.125 0.796875 -0.125l0 -2.890625q0 -0.625 -0.28125 -0.875q-0.359375 -0.328125 -1.078125 -0.328125q-0.53125 0 -0.953125 0.203125q-0.40625 0.203125 -1.09375 0.890625l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.4375 0.375 -0.671875q0.1875 -0.125 0.796875 -0.125l0 -6.921875l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l1.875 0z" fill-rule="nonzero"></path><path fill="#ffffff" d="m16.0 400.0l187.43306 0l0 80.53543l-187.43306 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m16.0 400.0l187.43306 0l0 80.53543l-187.43306 0z" fill-rule="nonzero"></path><path fill="#000000" d="m70.3845 442.87772l0 1.640625l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.265625l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.15625q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.421875 -1.421875 -0.421875l-1.84375 0l0 3.015625zm14.6953125 1.4375q0 0.921875 -0.515625 1.796875q-0.515625 0.859375 -1.53125 1.375q-1.0 0.515625 -2.109375 0.515625q-1.09375 0 -2.09375 -0.5q-1.0 -0.515625 -1.53125 -1.375q-0.515625 -0.875 -0.515625 -1.828125q0 -0.953125 0.53125 -1.875q0.53125 -0.9375 1.53125 -1.46875q1.0 -0.53125 2.078125 -0.53125q1.09375 0 2.109375 0.546875q1.015625 0.546875 1.53125 1.46875q0.515625 0.90625 0.515625 1.875zm-1.609375 0.015625q0 -0.78125 -0.546875 -1.421875q-0.765625 -0.875 -2.0 -0.875q-1.078125 0 -1.8125 0.703125q-0.71875 0.6875 -0.71875 1.59375q0 0.75 0.734375 1.40625q0.734375 0.65625 1.796875 0.65625q1.078125 0 1.8125 -0.65625q0.734375 -0.65625 0.734375 -1.40625zm8.7734375 -1.8125q-0.390625 -0.25 -0.828125 -0.359375q-0.421875 -0.125 -0.890625 -0.125q-0.921875 0 -1.46875 0.296875q-0.25 0.140625 -0.25 0.296875q0 0.171875 0.328125 0.34375q0.25 0.125 1.125 0.25q1.59375 0.21875 2.21875 0.4375q0.8125 0.28125 1.25 0.859375q0.453125 0.5625 0.453125 1.203125q0 0.859375 -0.75 1.4375q-1.09375 0.84375 -2.828125 0.84375q-0.6875 0 -1.28125 -0.125q-0.59375 -0.125 -1.078125 -0.359375q-0.125 0.09375 -0.265625 0.15625q-0.125 0.046875 -0.265625 0.046875q-0.375 0 -0.59375 -0.234375q-0.21875 -0.25 -0.21875 -0.828125l0 -0.546875q0 -0.578125 0.21875 -0.8125q0.21875 -0.25 0.578125 -0.25q0.296875 0 0.484375 0.15625q0.203125 0.15625 0.3125 0.546875q0.359375 0.3125 0.875 0.484375q0.515625 0.15625 1.1875 0.15625q1.109375 0 1.71875 -0.34375q0.28125 -0.171875 0.28125 -0.359375q0 -0.3125 -0.40625 -0.515625q-0.421875 -0.203125 -1.71875 -0.34375q-1.921875 -0.203125 -2.578125 -0.78125q-0.640625 -0.578125 -0.640625 -1.40625q0 -0.859375 0.71875 -1.4375q0.984375 -0.78125 2.578125 -0.78125q0.5625 0 1.0625 0.109375q0.515625 0.109375 0.984375 0.328125q0.15625 -0.109375 0.28125 -0.15625q0.125 -0.0625 0.234375 -0.0625q0.328125 0 0.546875 0.25q0.21875 0.234375 0.21875 0.8125l0 0.390625q0 0.53125 -0.125 0.71875q-0.25 0.359375 -0.671875 0.359375q-0.296875 0 -0.515625 -0.171875q-0.21875 -0.1875 -0.28125 -0.484375zm8.4453125 -4.921875l0 1.703125l-1.90625 0l0 -1.703125l1.90625 0zm0.21875 3.046875l0 5.484375l1.921875 0q0.578125 0 0.828125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-5.4375 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l1.921875 0l0 -3.890625l-1.296875 0q-0.5625 0 -0.8125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.234375 -0.578125q0.25 -0.21875 0.828125 -0.21875l2.890625 0zm10.0078125 3.40625l2.4375 2.078125q0.4375 0.03125 0.65625 0.25q0.21875 0.21875 0.21875 0.5625q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-1.8125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.28125 0.171875 -0.5q0.1875 -0.21875 0.484375 -0.296875l-1.1875 -1.03125l-1.21875 1.03125q0.359375 0.09375 0.515625 0.296875q0.171875 0.1875 0.171875 0.5q0 0.359375 -0.25 0.59375q-0.234375 0.21875 -0.8125 0.21875l-1.8125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.328125 0.21875 -0.546875q0.21875 -0.21875 0.65625 -0.25l2.375 -2.09375l-2.109375 -1.796875q-0.40625 -0.03125 -0.625 -0.25q-0.21875 -0.21875 -0.21875 -0.546875q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.5 0q0.578125 0 0.8125 0.21875q0.25 0.21875 0.25 0.5625q0 0.46875 -0.4375 0.75l0.96875 0.8125l0.953125 -0.828125q-0.421875 -0.296875 -0.421875 -0.703125q0 -0.375 0.234375 -0.59375q0.25 -0.21875 0.828125 -0.21875l1.484375 0q0.578125 0 0.828125 0.21875q0.25 0.21875 0.25 0.578125q0 0.328125 -0.21875 0.546875q-0.21875 0.21875 -0.640625 0.25l-2.109375 1.8125zm7.4765625 0.4375l0 1.640625l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.265625l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.15625q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.421875 -1.421875 -0.421875l-1.84375 0l0 3.015625zm11.976555 4.859375l0 -0.375q-0.609375 0.3125 -1.34375 0.46875q-0.71875 0.171875 -1.3124924 0.171875q-1.28125 0 -2.09375 -0.6875q-0.796875 -0.6875 -0.796875 -1.515625q0 -1.0 1.015625 -1.859375q1.03125 -0.875 2.8437424 -0.875q0.734375 0 1.6875 0.15625l0 -0.375q0 -0.359375 -0.3125 -0.578125q-0.3125 -0.234375 -1.171875 -0.234375q-0.71875 0 -1.8437424 0.28125q-0.421875 0.09375 -0.65625 0.09375q-0.328125 0 -0.546875 -0.21875q-0.21875 -0.234375 -0.21875 -0.59375q0 -0.203125 0.078125 -0.34375q0.078125 -0.15625 0.21875 -0.25q0.140625 -0.09375 0.578125 -0.21875q0.59375 -0.15625 1.203125 -0.25q0.6249924 -0.109375 1.1249924 -0.109375q1.5 0 2.3125 0.65625q0.828125 0.640625 0.828125 1.75l0 3.296875l0.28125 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.875 0zm0 -2.875q-0.96875 -0.1875 -1.78125 -0.1875q-0.9687424 0 -1.6718674 0.484375q-0.4375 0.296875 -0.4375 0.609375q0 0.234375 0.203125 0.375q0.390625 0.25 1.078125 0.25q0.5781174 0 1.2968674 -0.21875q0.734375 -0.234375 1.3125 -0.625l0 -0.6875zm7.7578125 -2.625l0 3.21875q0 0.515625 0.21875 0.671875q0.328125 0.265625 1.171875 0.265625q1.21875 0 2.265625 -0.53125q0.390625 -0.203125 0.625 -0.203125q0.3125 0 0.53125 0.234375q0.234375 0.234375 0.234375 0.578125q0 0.3125 -0.25 0.53125q-0.375 0.375 -1.515625 0.6875q-1.125 0.3125 -1.890625 0.3125q-1.5 0 -2.25 -0.640625q-0.734375 -0.65625 -0.734375 -1.59375l0 -3.53125l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l0.578125 0l0 -1.453125q0 -0.578125 0.21875 -0.8125q0.21875 -0.25 0.578125 -0.25q0.359375 0 0.578125 0.25q0.21875 0.234375 0.21875 0.8125l0 1.453125l2.96875 0q0.578125 0 0.8125 0.21875q0.25 0.21875 0.25 0.578125q0 0.359375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-2.96875 0zm8.3515625 -4.640625l0 3.421875q0.5 -0.296875 1.0 -0.4375q0.515625 -0.15625 1.046875 -0.15625q0.828125 0 1.46875 0.28125q0.65625 0.28125 1.078125 0.890625q0.421875 0.609375 0.421875 1.53125l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.5625 0 -0.8125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.4375 0.375 -0.671875q0.203125 -0.125 0.796875 -0.125l0 -2.890625q0 -0.625 -0.28125 -0.875q-0.359375 -0.328125 -1.078125 -0.328125q-0.53125 0 -0.953125 0.203125q-0.40625 0.203125 -1.09375 0.890625l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.4375 0.375 -0.671875q0.1875 -0.125 0.796875 -0.125l0 -6.921875l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l1.875 0z" fill-rule="nonzero"></path><path fill="#ffffff" d="m336.0 400.0l187.43304 0l0 80.53543l-187.43304 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m336.0 400.0l187.43304 0l0 80.53543l-187.43304 0z" fill-rule="nonzero"></path><path fill="#000000" d="m381.72043 441.58084l-1.484375 4.546875l-1.796875 0l-0.953125 -7.875q-0.375 -0.046875 -0.5625 -0.25q-0.1875 -0.203125 -0.1875 -0.53125q0 -0.375 0.25 -0.59375q0.25 -0.234375 0.828125 -0.234375l2.125 0.015625q0.578125 0 0.828125 0.21875q0.25 0.21875 0.25 0.578125q0 0.359375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-0.828125 0l0.53125 4.484375l1.25 -3.734375l1.671875 0l1.25 3.734375l0.53125 -4.484375l-0.84375 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.21875 -0.234375 -0.578125q0 -0.359375 0.234375 -0.578125q0.25 -0.234375 0.828125 -0.234375l2.125 0.015625q0.578125 0 0.828125 0.21875q0.25 0.21875 0.25 0.578125q0 0.296875 -0.203125 0.515625q-0.1875 0.21875 -0.5625 0.28125l-0.921875 7.875l-1.765625 0l-1.53125 -4.546875zm10.1640625 -5.59375l0 1.703125l-1.90625 0l0 -1.703125l1.90625 0zm0.21875 3.046875l0 5.484375l1.921875 0q0.578125 0 0.828125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-5.4375 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l1.921875 0l0 -3.890625l-1.296875 0q-0.5625 0 -0.8125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.234375 -0.578125q0.25 -0.21875 0.828125 -0.21875l2.890625 0zm7.1953125 0l0 0.53125q0.4375 -0.375 0.953125 -0.5625q0.53125 -0.1875 1.15625 -0.1875q1.421875 0 2.25 0.890625q0.65625 0.703125 0.65625 1.84375l0 2.96875q0.5 0 0.734375 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.453125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.34375 0.234375 -0.5625q0.25 -0.234375 0.75 -0.234375l0 -3.015625q0 -0.53125 -0.28125 -0.765625q-0.359375 -0.3125 -1.09375 -0.3125q-0.5625 0 -0.984375 0.21875q-0.40625 0.203125 -1.046875 0.90625l0 2.96875q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.4375 0.375 -0.671875q0.1875 -0.125 0.796875 -0.125l0 -3.890625q-0.5 0 -0.75 -0.21875q-0.234375 -0.234375 -0.234375 -0.578125q0 -0.359375 0.234375 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.53125 0zm14.8984375 -3.046875l0 8.53125l0.265625 0q0.578125 0 0.828125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-1.875 0l0 -0.390625q-0.546875 0.3125 -1.140625 0.484375q-0.59375 0.171875 -1.234375 0.171875q-1.8125 0 -2.921875 -1.046875q-1.09375 -1.046875 -1.09375 -2.609375q0 -1.625 1.15625 -2.765625q1.15625 -1.15625 2.828125 -1.15625q0.625 0 1.21875 0.203125q0.609375 0.1875 1.1875 0.5625l0 -1.984375l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l1.875 0zm-1.609375 6.796875q0 -0.984375 -0.703125 -1.671875q-0.6875 -0.6875 -1.6875 -0.6875q-1.0 0 -1.703125 0.6875q-0.6875 0.6875 -0.6875 1.65625q0 0.875 0.625 1.453125q0.625 0.5625 1.765625 0.5625q1.125 0 1.75 -0.5625q0.640625 -0.578125 0.640625 -1.4375zm11.6953125 -0.078125q0 0.921875 -0.515625 1.796875q-0.515625 0.859375 -1.53125 1.375q-1.0 0.515625 -2.109375 0.515625q-1.09375 0 -2.09375 -0.5q-1.0 -0.515625 -1.53125 -1.375q-0.515625 -0.875 -0.515625 -1.828125q0 -0.953125 0.53125 -1.875q0.53125 -0.9375 1.53125 -1.46875q1.0 -0.53125 2.078125 -0.53125q1.09375 0 2.109375 0.546875q1.015625 0.546875 1.53125 1.46875q0.515625 0.90625 0.515625 1.875zm-1.609375 0.015625q0 -0.78125 -0.546875 -1.421875q-0.765625 -0.875 -2.0 -0.875q-1.078125 0 -1.8125 0.703125q-0.71875 0.6875 -0.71875 1.59375q0 0.75 0.734375 1.40625q0.734375 0.65625 1.796875 0.65625q1.078125 0 1.8125 -0.65625q0.734375 -0.65625 0.734375 -1.40625zm7.0546875 0.453125l-1.109375 2.953125l-1.5 0l-1.34375 -5.5q-0.4375 -0.015625 -0.671875 -0.234375q-0.21875 -0.234375 -0.21875 -0.5625q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.484375 0q0.578125 0 0.828125 0.21875q0.25 0.21875 0.25 0.578125q0 0.359375 -0.28125 0.609375q-0.21875 0.1875 -0.828125 0.1875l0.609375 2.546875l0.984375 -2.609375l1.421875 0l1.0 2.609375l0.625 -2.546875q-0.59375 0 -0.78125 -0.109375q-0.375 -0.25 -0.375 -0.6875q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.5 0q0.578125 0 0.828125 0.21875q0.25 0.21875 0.25 0.578125q0 0.328125 -0.21875 0.546875q-0.21875 0.21875 -0.640625 0.25l-1.3125 5.5l-1.484375 0l-1.171875 -2.953125zm11.3203125 -2.265625q-0.390625 -0.25 -0.828125 -0.359375q-0.421875 -0.125 -0.890625 -0.125q-0.921875 0 -1.46875 0.296875q-0.25 0.140625 -0.25 0.296875q0 0.171875 0.328125 0.34375q0.25 0.125 1.125 0.25q1.59375 0.21875 2.21875 0.4375q0.8125 0.28125 1.25 0.859375q0.453125 0.5625 0.453125 1.203125q0 0.859375 -0.75 1.4375q-1.09375 0.84375 -2.828125 0.84375q-0.6875 0 -1.28125 -0.125q-0.59375 -0.125 -1.078125 -0.359375q-0.125 0.09375 -0.265625 0.15625q-0.125 0.046875 -0.265625 0.046875q-0.375 0 -0.59375 -0.234375q-0.21875 -0.25 -0.21875 -0.828125l0 -0.546875q0 -0.578125 0.21875 -0.8125q0.21875 -0.25 0.578125 -0.25q0.296875 0 0.484375 0.15625q0.203125 0.15625 0.3125 0.546875q0.359375 0.3125 0.875 0.484375q0.515625 0.15625 1.1875 0.15625q1.109375 0 1.71875 -0.34375q0.28125 -0.171875 0.28125 -0.359375q0 -0.3125 -0.40625 -0.515625q-0.421875 -0.203125 -1.71875 -0.34375q-1.921875 -0.203125 -2.578125 -0.78125q-0.640625 -0.578125 -0.640625 -1.40625q0 -0.859375 0.71875 -1.4375q0.984375 -0.78125 2.578125 -0.78125q0.5625 0 1.0625 0.109375q0.515625 0.109375 0.984375 0.328125q0.15625 -0.109375 0.28125 -0.15625q0.125 -0.0625 0.234375 -0.0625q0.328125 0 0.546875 0.25q0.21875 0.234375 0.21875 0.8125l0 0.390625q0 0.53125 -0.125 0.71875q-0.25 0.359375 -0.671875 0.359375q-0.296875 0 -0.515625 -0.171875q-0.21875 -0.1875 -0.28125 -0.484375zm6.9453125 1.96875l0 1.640625l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.265625l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.15625q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.421875 -1.421875 -0.421875l-1.84375 0l0 3.015625zm11.9765625 4.859375l0 -0.375q-0.609375 0.3125 -1.34375 0.46875q-0.71875 0.171875 -1.3125 0.171875q-1.28125 0 -2.09375 -0.6875q-0.796875 -0.6875 -0.796875 -1.515625q0 -1.0 1.015625 -1.859375q1.03125 -0.875 2.84375 -0.875q0.734375 0 1.6875 0.15625l0 -0.375q0 -0.359375 -0.3125 -0.578125q-0.3125 -0.234375 -1.171875 -0.234375q-0.71875 0 -1.84375 0.28125q-0.421875 0.09375 -0.65625 0.09375q-0.328125 0 -0.546875 -0.21875q-0.21875 -0.234375 -0.21875 -0.59375q0 -0.203125 0.078125 -0.34375q0.078125 -0.15625 0.21875 -0.25q0.140625 -0.09375 0.578125 -0.21875q0.59375 -0.15625 1.203125 -0.25q0.625 -0.109375 1.125 -0.109375q1.5 0 2.3125 0.65625q0.828125 0.640625 0.828125 1.75l0 3.296875l0.28125 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.875 0zm0 -2.875q-0.96875 -0.1875 -1.78125 -0.1875q-0.96875 0 -1.671875 0.484375q-0.4375 0.296875 -0.4375 0.609375q0 0.234375 0.203125 0.375q0.390625 0.25 1.078125 0.25q0.578125 0 1.296875 -0.21875q0.734375 -0.234375 1.3125 -0.625l0 -0.6875zm7.7578125 -2.625l0 3.21875q0 0.515625 0.21875 0.671875q0.328125 0.265625 1.171875 0.265625q1.21875 0 2.265625 -0.53125q0.390625 -0.203125 0.625 -0.203125q0.3125 0 0.53125 0.234375q0.234375 0.234375 0.234375 0.578125q0 0.3125 -0.25 0.53125q-0.375 0.375 -1.515625 0.6875q-1.125 0.3125 -1.890625 0.3125q-1.5 0 -2.25 -0.640625q-0.734375 -0.65625 -0.734375 -1.59375l0 -3.53125l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l0.578125 0l0 -1.453125q0 -0.578125 0.21875 -0.8125q0.21875 -0.25 0.578125 -0.25q0.359375 0 0.578125 0.25q0.21875 0.234375 0.21875 0.8125l0 1.453125l2.96875 0q0.578125 0 0.8125 0.21875q0.25 0.21875 0.25 0.578125q0 0.359375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-2.96875 0zm8.3515625 -4.640625l0 3.421875q0.5 -0.296875 1.0 -0.4375q0.515625 -0.15625 1.046875 -0.15625q0.828125 0 1.46875 0.28125q0.65625 0.28125 1.078125 0.890625q0.421875 0.609375 0.421875 1.53125l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.5625 0 -0.8125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.4375 0.375 -0.671875q0.203125 -0.125 0.796875 -0.125l0 -2.890625q0 -0.625 -0.28125 -0.875q-0.359375 -0.328125 -1.078125 -0.328125q-0.53125 0 -0.953125 0.203125q-0.40625 0.203125 -1.09375 0.890625l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.4375 0.375 -0.671875q0.1875 -0.125 0.796875 -0.125l0 -6.921875l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l1.875 0z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m96.0 144.0l0 -80.0l80.0 0" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m96.0 144.0l0 -80.0l68.0 0" fill-rule="evenodd"></path><path stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m164.0 67.30347l9.076202 -3.3034668l-9.076202 -3.303463z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m431.5013 143.08398l0 -78.99999l-68.0 0" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m431.5013 143.08398l0 -78.99999l-56.0 0" fill-rule="evenodd"></path><path stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m375.5013 60.780525l-9.076202 3.3034668l9.076202 3.3034592z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m269.71652 104.53543l0 166.92914" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m269.71652 116.53543l0 154.92914" fill-rule="evenodd"></path><path stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m273.02 116.53543l-3.3034668 -9.076195l-3.3034668 9.076195z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m65.0 223.08398l-1.0078735 176.91339" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m64.93163 235.08379l-0.93950653 164.91359" fill-rule="evenodd"></path><path stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m68.23505 235.10262l-3.2517014 -9.094864l-3.3551178 9.05722z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m471.0 224.38058l-1.0078735 176.91336" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m470.93164 236.38037l-0.93951416 164.9136" fill-rule="evenodd"></path><path stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m474.23505 236.3992l-3.251709 -9.094864l-3.3551025 9.05722z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m128.50131 400.00266l0 -86.168l47.496002 0" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m128.50131 400.00266l0 -86.168l35.496002 0" fill-rule="evenodd"></path><path stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m163.99731 317.13812l9.076202 -3.3034668l-9.076202 -3.3034668z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m414.71902 400.00266l0 -86.168l-51.216003 0" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m414.71902 400.00266l0 -86.168l-39.216003 0" fill-rule="evenodd"></path><path stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m375.50302 310.5312l-9.076172 3.3034668l9.076172 3.3034668z" fill-rule="evenodd"></path></g></svg>
-
+<svg version="1.1" viewBox="0.0 0.0 539.005249343832 319.40944881889766" fill="none" stroke="none" stroke-linecap="square" stroke-miterlimit="10" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg"><clipPath id="p.0"><path d="m0 0l539.00525 0l0 319.40945l-539.00525 0l0 -319.40945z" clip-rule="nonzero"/></clipPath><g clip-path="url(#p.0)"><path fill="#000000" fill-opacity="0.0" d="m0 0l539.00525 0l0 319.40945l-539.00525 0z" fill-rule="evenodd"/><path fill="#ffffff" d="m203.43307 37.929134l113.98425 0l0 61.165356l-113.98425 0z" fill-rule="evenodd"/><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m203.43307 37.929134l113.98425 0l0 61.165356l-113.98425 0z" fill-rule="evenodd"/><path fill="#000000" d="m225.89395 71.12181l0 1.640625l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.265625l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.15625q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.421875 -1.421875 -0.421875l-1.84375 0l0 3.015625zm13.9296875 -2.234375l0 5.484375q0.515625 0 0.75 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-1.515625 0l0 -0.375q-0.6875 0.3125 -1.3125 0.46875q-0.625 0.171875 -1.1875 0.171875q-0.796875 0 -1.375 -0.328125q-0.578125 -0.34375 -0.90625 -0.9375q-0.25 -0.421875 -0.25 -1.046875l0 -3.453125l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.875 0l0 4.765625q0 0.5 0.234375 0.75q0.25 0.234375 0.765625 0.234375q0.484375 0 1.03125 -0.1875q0.5625 -0.203125 1.390625 -0.703125l0 -3.265625l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l2.171875 0zm5.8671875 0l0 1.0q1.015625 -0.734375 1.59375 -0.96875q0.578125 -0.25 1.09375 -0.25q0.78125 0 1.515625 0.578125q0.5 0.390625 0.5 0.796875q0 0.34375 -0.25 0.59375q-0.234375 0.234375 -0.5625 0.234375q-0.296875 0 -0.625 -0.296875q-0.328125 -0.296875 -0.59375 -0.296875q-0.328125 0 -1.0 0.421875q-0.671875 0.421875 -1.671875 1.265625l0 2.40625l2.28125 0q0.578125 0 0.828125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-4.828125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.953125 0l0 -3.890625l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l2.171875 0zm13.9609375 4.359375l-6.578125 0q0.25 0.625 0.890625 1.015625q0.640625 0.375 1.71875 0.375q0.890625 0 2.375 -0.390625q0.609375 -0.15625 0.84375 -0.15625q0.3125 0 0.53125 0.234375q0.21875 0.21875 0.21875 0.5625q0 0.3125 -0.234375 0.53125q-0.3125 0.296875 -1.53125 0.5625q-1.203125 0.265625 -2.3125 0.265625q-1.921875 0 -3.078125 -1.09375q-1.15625 -1.09375 -1.15625 -2.671875q0 -1.6875 1.25 -2.75q1.25 -1.0625 2.875 -1.0625q0.96875 0 1.78125 0.34375q0.828125 0.34375 1.21875 0.75q0.5625 0.578125 0.9375 1.421875q0.25 0.59375 0.25 1.375l0 0.6875zm-1.78125 -1.609375q-0.359375 -0.6875 -0.953125 -1.015625q-0.59375 -0.34375 -1.421875 -0.34375q-0.8125 0 -1.40625 0.34375q-0.59375 0.328125 -0.96875 1.015625l4.75 0zm6.4296875 1.09375l0 1.640625l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.265625l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.15625q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.421875 -1.421875 -0.421875l-1.84375 0l0 3.015625zm11.9765625 4.859375l0 -0.375q-0.609375 0.3125 -1.34375 0.46875q-0.71875 0.171875 -1.3125 0.171875q-1.28125 0 -2.09375 -0.6875q-0.796875 -0.6875 -0.796875 -1.515625q0 -1.0 1.015625 -1.859375q1.03125 -0.875 2.84375 -0.875q0.734375 0 1.6875 0.15625l0 -0.375q0 -0.359375 -0.3125 -0.578125q-0.3125 -0.234375 -1.171875 -0.234375q-0.71875 0 -1.84375 0.28125q-0.421875 0.09375 -0.65625 0.09375q-0.328125 0 -0.546875 -0.21875q-0.21875 -0.234375 -0.21875 -0.59375q0 -0.203125 0.078125 -0.34375q0.078125 -0.15625 0.21875 -0.25q0.140625 -0.09375 0.578125 -0.21875q0.59375 -0.15625 1.203125 -0.25q0.625 -0.109375 1.125 -0.109375q1.5 0 2.3125 0.65625q0.828125 0.640625 0.828125 1.75l0 3.296875l0.28125 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.875 0zm0 -2.875q-0.96875 -0.1875 -1.78125 -0.1875q-0.96875 0 -1.671875 0.484375q-0.4375 0.296875 -0.4375 0.609375q0 0.234375 0.203125 0.375q0.390625 0.25 1.078125 0.25q0.578125 0 1.296875 -0.21875q0.734375 -0.234375 1.3125 -0.625l0 -0.6875zm7.7578125 -2.625l0 3.21875q0 0.515625 0.21875 0.671875q0.328125 0.265625 1.171875 0.265625q1.21875 0 2.265625 -0.53125q0.390625 -0.203125 0.625 -0.203125q0.3125 0 0.53125 0.234375q0.234375 0.234375 0.234375 0.578125q0 0.3125 -0.25 0.53125q-0.375 0.375 -1.515625 0.6875q-1.125 0.3125 -1.890625 0.3125q-1.5 0 -2.25 -0.640625q-0.734375 -0.65625 -0.734375 -1.59375l0 -3.53125l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l0.578125 0l0 -1.453125q0 -0.578125 0.21875 -0.8125q0.21875 -0.25 0.578125 -0.25q0.359375 0 0.578125 0.25q0.21875 0.234375 0.21875 0.8125l0 1.453125l2.96875 0q0.578125 0 0.8125 0.21875q0.25 0.21875 0.25 0.578125q0 0.359375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-2.96875 0zm8.3515625 -4.640625l0 3.421875q0.5 -0.296875 1.0 -0.4375q0.515625 -0.15625 1.046875 -0.15625q0.828125 0 1.46875 0.28125q0.65625 0.28125 1.078125 0.890625q0.421875 0.609375 0.421875 1.53125l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.5625 0 -0.8125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.4375 0.375 -0.671875q0.203125 -0.125 0.796875 -0.125l0 -2.890625q0 -0.625 -0.28125 -0.875q-0.359375 -0.328125 -1.078125 -0.328125q-0.53125 0 -0.953125 0.203125q-0.40625 0.203125 -1.09375 0.890625l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.4375 0.375 -0.671875q0.1875 -0.125 0.796875 -0.125l0 -6.921875l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l1.875 0z" fill-rule="nonzero"/><path fill="#ffffff" d="m26.64567 99.10499l158.20471 0l0 61.16535l-158.20471 0z" fill-rule="evenodd"/><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m26.64567 99.10499l158.20471 0l0 61.16535l-158.20471 0z" fill-rule="evenodd"/><path fill="#000000" d="m47.212875 132.29767l0 1.640625l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.2656326l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.1562576q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.42188263 -1.421875 -0.42188263l-1.84375 0l0 3.0156326zm13.9296875 -2.234375l0 5.484375q0.515625 0 0.75 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-1.515625 0l0 -0.375q-0.6875 0.3125 -1.3125 0.46875q-0.625 0.171875 -1.1875 0.171875q-0.796875 0 -1.375 -0.328125q-0.578125 -0.34375 -0.90625 -0.9375q-0.25 -0.421875 -0.25 -1.046875l0 -3.453125l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.875 0l0 4.765625q0 0.5 0.234375 0.75q0.25 0.234375 0.765625 0.234375q0.484375 0 1.03125 -0.1875q0.5625 -0.203125 1.390625 -0.703125l0 -3.265625l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l2.171875 0zm5.8671875 0l0 1.0q1.015625 -0.734375 1.59375 -0.96875q0.578125 -0.25 1.09375 -0.25q0.78125 0 1.515625 0.578125q0.5 0.390625 0.5 0.796875q0 0.34375 -0.25 0.59375q-0.234375 0.234375 -0.5625 0.234375q-0.296875 0 -0.625 -0.296875q-0.328125 -0.296875 -0.59375 -0.296875q-0.328125 0 -1.0 0.421875q-0.671875 0.421875 -1.671875 1.265625l0 2.40625l2.28125 0q0.578125 0 0.828125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-4.828125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.953125 0l0 -3.890625l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l2.171875 0zm13.9609375 4.359375l-6.578125 0q0.25 0.625 0.890625 1.015625q0.640625 0.375 1.71875 0.375q0.890625 0 2.375 -0.390625q0.609375 -0.15625 0.84375 -0.15625q0.3125 0 0.53125 0.234375q0.21875 0.21875 0.21875 0.5625q0 0.3125 -0.234375 0.53125q-0.3125 0.296875 -1.53125 0.5625q-1.203125 0.265625 -2.3125 0.265625q-1.921875 0 -3.078125 -1.09375q-1.15625 -1.09375 -1.15625 -2.671875q0 -1.6875 1.25 -2.75q1.25 -1.0625 2.875 -1.0625q0.96875 0 1.78125 0.34375q0.828125 0.34375 1.21875 0.75q0.5625 0.578125 0.9375 1.421875q0.25 0.59375 0.25 1.375l0 0.6875zm-1.78125 -1.609375q-0.359375 -0.6875 -0.953125 -1.015625q-0.59375 -0.34375 -1.421875 -0.34375q-0.8125 0 -1.40625 0.34375q-0.59375 0.328125 -0.96875 1.015625l4.75 0zm6.4296875 1.09375l0 1.640625l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.2656326l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.1562576q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.42188263 -1.421875 -0.42188263l-1.84375 0l0 3.0156326zm14.6953125 1.4375q0 0.921875 -0.515625 1.796875q-0.515625 0.859375 -1.53125 1.375q-1.0 0.515625 -2.109375 0.515625q-1.09375 0 -2.09375 -0.5q-1.0 -0.515625 -1.53125 -1.375q-0.515625 -0.875 -0.515625 -1.828125q0 -0.953125 0.53125 -1.875q0.53125 -0.9375 1.53125 -1.46875q1.0 -0.53125 2.078125 -0.53125q1.09375 0 2.109375 0.546875q1.015625 0.546875 1.53125 1.46875q0.515625 0.90625 0.515625 1.875zm-1.609375 0.015625q0 -0.78125 -0.546875 -1.421875q-0.765625 -0.875 -2.0 -0.875q-1.078125 0 -1.8125 0.703125q-0.71875 0.6875 -0.71875 1.59375q0 0.75 0.734375 1.40625q0.734375 0.65625 1.796875 0.65625q1.078125 0 1.8125 -0.65625q0.734375 -0.65625 0.734375 -1.40625zm8.7734375 -1.8125q-0.390625 -0.25 -0.828125 -0.359375q-0.421875 -0.125 -0.890625 -0.125q-0.921875 0 -1.46875 0.296875q-0.25 0.140625 -0.25 0.296875q0 0.171875 0.328125 0.34375q0.25 0.125 1.125 0.25q1.59375 0.21875 2.21875 0.4375q0.8125 0.28125 1.25 0.859375q0.453125 0.5625 0.453125 1.203125q0 0.859375 -0.75 1.4375q-1.09375 0.84375 -2.828125 0.84375q-0.6875 0 -1.28125 -0.125q-0.59375 -0.125 -1.078125 -0.359375q-0.125 0.09375 -0.265625 0.15625q-0.125 0.046875 -0.265625 0.046875q-0.375 0 -0.59375 -0.234375q-0.21875 -0.25 -0.21875 -0.828125l0 -0.546875q0 -0.578125 0.21875 -0.8125q0.21875 -0.25 0.578125 -0.25q0.296875 0 0.484375 0.15625q0.203125 0.15625 0.3125 0.546875q0.359375 0.3125 0.875 0.484375q0.515625 0.15625 1.1875 0.15625q1.109375 0 1.71875 -0.34375q0.28125 -0.171875 0.28125 -0.359375q0 -0.3125 -0.40625 -0.515625q-0.421875 -0.203125 -1.71875 -0.34375q-1.921875 -0.203125 -2.578125 -0.78125q-0.640625 -0.578125 -0.640625 -1.40625q0 -0.859375 0.71875 -1.4375q0.984375 -0.78125 2.578125 -0.78125q0.5625 0 1.0625 0.109375q0.515625 0.109375 0.984375 0.328125q0.15625 -0.109375 0.28125 -0.15625q0.125 -0.0625 0.234375 -0.0625q0.328125 0 0.546875 0.25q0.21875 0.234375 0.21875 0.8125l0 0.390625q0 0.53125 -0.125 0.71875q-0.25 0.359375 -0.671875 0.359375q-0.296875 0 -0.515625 -0.171875q-0.21875 -0.1875 -0.28125 -0.484375zm8.4453125 -4.9218826l0 1.703125l-1.90625 0l0 -1.703125l1.90625 0zm0.21875 3.0468826l0 5.484375l1.921875 0q0.578125 0 0.828125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-5.4375 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l1.921875 0l0 -3.890625l-1.296875 0q-0.5625 0 -0.8125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.234375 -0.578125q0.25 -0.21875 0.828125 -0.21875l2.890625 0zm10.0078125 3.40625l2.4375 2.078125q0.4375 0.03125 0.65625 0.25q0.21875 0.21875 0.21875 0.5625q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-1.8125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.28125 0.171875 -0.5q0.1875 -0.21875 0.484375 -0.296875l-1.1875 -1.03125l-1.21875 1.03125q0.359375 0.09375 0.515625 0.296875q0.171875 0.1875 0.171875 0.5q0 0.359375 -0.25 0.59375q-0.234375 0.21875 -0.8125 0.21875l-1.8125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.328125 0.21875 -0.546875q0.21875 -0.21875 0.65625 -0.25l2.375 -2.09375l-2.109375 -1.796875q-0.40625 -0.03125 -0.625 -0.25q-0.21875 -0.21875 -0.21875 -0.546875q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.5 0q0.578125 0 0.8125 0.21875q0.25 0.21875 0.25 0.5625q0 0.46875 -0.4375 0.75l0.96875 0.8125l0.953125 -0.828125q-0.421875 -0.296875 -0.421875 -0.703125q0 -0.375 0.234375 -0.59375q0.25 -0.21875 0.828125 -0.21875l1.484375 0q0.578125 0 0.828125 0.21875q0.25 0.21875 0.25 0.578125q0 0.328125 -0.21875 0.546875q-0.21875 0.21875 -0.640625 0.25l-2.109375 1.8125zm7.4765625 0.4375l0 1.640625l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.2656326l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.1562576q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.42188263 -1.421875 -0.42188263l-1.84375 0l0 3.0156326zm11.9765625 4.859375l0 -0.375q-0.609375 0.3125 -1.34375 0.46875q-0.71875 0.171875 -1.3125 0.171875q-1.28125 0 -2.09375 -0.6875q-0.796875 -0.6875 -0.796875 -1.515625q0 -1.0 1.015625 -1.859375q1.03125 -0.875 2.84375 -0.875q0.734375 0 1.6875 0.15625l0 -0.375q0 -0.359375 -0.3125 -0.578125q-0.3125 -0.234375 -1.171875 -0.234375q-0.71875 0 -1.84375 0.28125q-0.421875 0.09375 -0.65625 0.09375q-0.328125 0 -0.546875 -0.21875q-0.21875 -0.234375 -0.21875 -0.59375q0 -0.203125 0.078125 -0.34375q0.078125 -0.15625 0.21875 -0.25q0.140625 -0.09375 0.578125 -0.21875q0.59375 -0.15625 1.203125 -0.25q0.625 -0.109375 1.125 -0.109375q1.5 0 2.3125 0.65625q0.828125 0.640625 0.828125 1.75l0 3.296875l0.28125 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.875 0zm0 -2.875q-0.96875 -0.1875 -1.78125 -0.1875q-0.96875 0 -1.671875 0.484375q-0.4375 0.296875 -0.4375 0.609375q0 0.234375 0.203125 0.375q0.390625 0.25 1.078125 0.25q0.578125 0 1.296875 -0.21875q0.734375 -0.234375 1.3125 -0.625l0 -0.6875zm7.7578125 -2.625l0 3.21875q0 0.515625 0.21875 0.671875q0.328125 0.265625 1.171875 0.265625q1.21875 0 2.265625 -0.53125q0.390625 -0.203125 0.625 -0.203125q0.3125 0 0.53125 0.234375q0.234375 0.234375 0.234375 0.578125q0 0.3125 -0.25 0.53125q-0.375 0.375 -1.515625 0.6875q-1.125 0.3125 -1.890625 0.3125q-1.5 0 -2.25 -0.640625q-0.734375 -0.65625 -0.734375 -1.59375l0 -3.53125l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l0.578125 0l0 -1.4531326q0 -0.578125 0.21875 -0.8125q0.21875 -0.25 0.578125 -0.25q0.359375 0 0.578125 0.25q0.21875 0.234375 0.21875 0.8125l0 1.4531326l2.96875 0q0.578125 0 0.8125 0.21875q0.25 0.21875 0.25 0.578125q0 0.359375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-2.96875 0zm8.3515625 -4.6406326l0 3.4218826q0.5 -0.296875 1.0 -0.4375q0.515625 -0.15625 1.046875 -0.15625q0.828125 0 1.46875 0.28125q0.65625 0.28125 1.078125 0.890625q0.421875 0.609375 0.421875 1.53125l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.5625 0 -0.8125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.4375 0.375 -0.671875q0.203125 -0.125 0.796875 -0.125l0 -2.890625q0 -0.625 -0.28125 -0.875q-0.359375 -0.328125 -1.078125 -0.328125q-0.53125 0 -0.953125 0.203125q-0.40625 0.203125 -1.09375 0.890625l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.4375 0.375 -0.671875q0.1875 -0.125 0.796875 -0.125l0 -6.9218826l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l1.875 0z" fill-rule="nonzero"/><path fill="#ffffff" d="m336.0 99.10499l174.04724 0l0 61.16535l-174.04724 0z" fill-rule="evenodd"/><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m336.0 99.10499l174.04724 0l0 61.16535l-174.04724 0z" fill-rule="evenodd"/><path fill="#000000" d="m354.8869 132.29767l0 1.640625l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.2656326l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.1562576q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.42188263 -1.421875 -0.42188263l-1.84375 0l0 3.0156326zm13.9296875 -2.234375l0 5.484375q0.515625 0 0.75 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-1.515625 0l0 -0.375q-0.6875 0.3125 -1.3125 0.46875q-0.625 0.171875 -1.1875 0.171875q-0.796875 0 -1.375 -0.328125q-0.578125 -0.34375 -0.90625 -0.9375q-0.25 -0.421875 -0.25 -1.046875l0 -3.453125l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.875 0l0 4.765625q0 0.5 0.234375 0.75q0.25 0.234375 0.765625 0.234375q0.484375 0 1.03125 -0.1875q0.5625 -0.203125 1.390625 -0.703125l0 -3.265625l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l2.171875 0zm5.8671875 0l0 1.0q1.015625 -0.734375 1.59375 -0.96875q0.578125 -0.25 1.09375 -0.25q0.78125 0 1.515625 0.578125q0.5 0.390625 0.5 0.796875q0 0.34375 -0.25 0.59375q-0.234375 0.234375 -0.5625 0.234375q-0.296875 0 -0.625 -0.296875q-0.328125 -0.296875 -0.59375 -0.296875q-0.328125 0 -1.0 0.421875q-0.671875 0.421875 -1.671875 1.265625l0 2.40625l2.28125 0q0.578125 0 0.828125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-4.828125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.953125 0l0 -3.890625l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l2.171875 0zm13.9609375 4.359375l-6.578125 0q0.25 0.625 0.890625 1.015625q0.640625 0.375 1.71875 0.375q0.890625 0 2.375 -0.390625q0.609375 -0.15625 0.84375 -0.15625q0.3125 0 0.53125 0.234375q0.21875 0.21875 0.21875 0.5625q0 0.3125 -0.234375 0.53125q-0.3125 0.296875 -1.53125 0.5625q-1.203125 0.265625 -2.3125 0.265625q-1.921875 0 -3.078125 -1.09375q-1.15625 -1.09375 -1.15625 -2.671875q0 -1.6875 1.25 -2.75q1.25 -1.0625 2.875 -1.0625q0.96875 0 1.78125 0.34375q0.828125 0.34375 1.21875 0.75q0.5625 0.578125 0.9375 1.421875q0.25 0.59375 0.25 1.375l0 0.6875zm-1.78125 -1.609375q-0.359375 -0.6875 -0.953125 -1.015625q-0.59375 -0.34375 -1.421875 -0.34375q-0.8125 0 -1.40625 0.34375q-0.59375 0.328125 -0.96875 1.015625l4.75 0zm7.3671875 -0.203125l-1.484375 4.546875l-1.796875 0l-0.953125 -7.8750076q-0.375 -0.046875 -0.5625 -0.25q-0.1875 -0.203125 -0.1875 -0.53125q0 -0.375 0.25 -0.59375q0.25 -0.234375 0.828125 -0.234375l2.125 0.015625q0.578125 0 0.828125 0.21875q0.25 0.21875 0.25 0.578125q0 0.359375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-0.828125 0l0.53125 4.4843826l1.25 -3.734375l1.671875 0l1.25 3.734375l0.53125 -4.4843826l-0.84375 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.21875 -0.234375 -0.578125q0 -0.359375 0.234375 -0.578125q0.25 -0.234375 0.828125 -0.234375l2.125 0.015625q0.578125 0 0.828125 0.21875q0.25 0.21875 0.25 0.578125q0 0.296875 -0.203125 0.515625q-0.1875 0.21875 -0.5625 0.28125l-0.921875 7.8750076l-1.765625 0l-1.53125 -4.546875zm10.1640625 -5.5937576l0 1.703125l-1.90625 0l0 -1.703125l1.90625 0zm0.21875 3.0468826l0 5.484375l1.921875 0q0.578125 0 0.828125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-5.4375 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l1.921875 0l0 -3.890625l-1.296875 0q-0.5625 0 -0.8125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.234375 -0.578125q0.25 -0.21875 0.828125 -0.21875l2.890625 0zm7.1953125 0l0 0.53125q0.4375 -0.375 0.953125 -0.5625q0.53125 -0.1875 1.15625 -0.1875q1.421875 0 2.25 0.890625q0.65625 0.703125 0.65625 1.84375l0 2.96875q0.5 0 0.734375 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.453125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.34375 0.234375 -0.5625q0.25 -0.234375 0.75 -0.234375l0 -3.015625q0 -0.53125 -0.28125 -0.765625q-0.359375 -0.3125 -1.09375 -0.3125q-0.5625 0 -0.984375 0.21875q-0.40625 0.203125 -1.046875 0.90625l0 2.96875q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.4375 0.375 -0.671875q0.1875 -0.125 0.796875 -0.125l0 -3.890625q-0.5 0 -0.75 -0.21875q-0.234375 -0.234375 -0.234375 -0.578125q0 -0.359375 0.234375 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.53125 0zm14.8984375 -3.0468826l0 8.531258l0.265625 0q0.578125 0 0.828125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-1.875 0l0 -0.390625q-0.546875 0.3125 -1.140625 0.484375q-0.59375 0.171875 -1.234375 0.171875q-1.8125 0 -2.921875 -1.046875q-1.09375 -1.046875 -1.09375 -2.609375q0 -1.625 1.15625 -2.765625q1.15625 -1.15625 2.828125 -1.15625q0.625 0 1.21875 0.203125q0.609375 0.1875 1.1875 0.5625l0 -1.9843826l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l1.875 0zm-1.609375 6.7968826q0 -0.984375 -0.703125 -1.671875q-0.6875 -0.6875 -1.6875 -0.6875q-1.0 0 -1.703125 0.6875q-0.6875 0.6875 -0.6875 1.65625q0 0.875 0.625 1.453125q0.625 0.5625 1.765625 0.5625q1.125 0 1.75 -0.5625q0.640625 -0.578125 0.640625 -1.4375zm11.6953125 -0.078125q0 0.921875 -0.515625 1.796875q-0.515625 0.859375 -1.53125 1.375q-1.0 0.515625 -2.109375 0.515625q-1.09375 0 -2.09375 -0.5q-1.0 -0.515625 -1.53125 -1.375q-0.515625 -0.875 -0.515625 -1.828125q0 -0.953125 0.53125 -1.875q0.53125 -0.9375 1.53125 -1.46875q1.0 -0.53125 2.078125 -0.53125q1.09375 0 2.109375 0.546875q1.015625 0.546875 1.53125 1.46875q0.515625 0.90625 0.515625 1.875zm-1.609375 0.015625q0 -0.78125 -0.546875 -1.421875q-0.765625 -0.875 -2.0 -0.875q-1.078125 0 -1.8125 0.703125q-0.71875 0.6875 -0.71875 1.59375q0 0.75 0.734375 1.40625q0.734375 0.65625 1.796875 0.65625q1.078125 0 1.8125 -0.65625q0.734375 -0.65625 0.734375 -1.40625zm7.0546875 0.453125l-1.109375 2.953125l-1.5 0l-1.34375 -5.5q-0.4375 -0.015625 -0.671875 -0.234375q-0.21875 -0.234375 -0.21875 -0.5625q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.484375 0q0.578125 0 0.828125 0.21875q0.25 0.21875 0.25 0.578125q0 0.359375 -0.28125 0.609375q-0.21875 0.1875 -0.828125 0.1875l0.609375 2.546875l0.984375 -2.609375l1.421875 0l1.0 2.609375l0.625 -2.546875q-0.59375 0 -0.78125 -0.109375q-0.375 -0.25 -0.375 -0.6875q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.5 0q0.578125 0 0.828125 0.21875q0.25 0.21875 0.25 0.578125q0 0.328125 -0.21875 0.546875q-0.21875 0.21875 -0.640625 0.25l-1.3125 5.5l-1.484375 0l-1.171875 -2.953125zm11.3203125 -2.265625q-0.390625 -0.25 -0.828125 -0.359375q-0.421875 -0.125 -0.890625 -0.125q-0.921875 0 -1.46875 0.296875q-0.25 0.140625 -0.25 0.296875q0 0.171875 0.328125 0.34375q0.25 0.125 1.125 0.25q1.59375 0.21875 2.21875 0.4375q0.8125 0.28125 1.25 0.859375q0.453125 0.5625 0.453125 1.203125q0 0.859375 -0.75 1.4375q-1.09375 0.84375 -2.828125 0.84375q-0.6875 0 -1.28125 -0.125q-0.59375 -0.125 -1.078125 -0.359375q-0.125 0.09375 -0.265625 0.15625q-0.125 0.046875 -0.265625 0.046875q-0.375 0 -0.59375 -0.234375q-0.21875 -0.25 -0.21875 -0.828125l0 -0.546875q0 -0.578125 0.21875 -0.8125q0.21875 -0.25 0.578125 -0.25q0.296875 0 0.484375 0.15625q0.203125 0.15625 0.3125 0.546875q0.359375 0.3125 0.875 0.484375q0.515625 0.15625 1.1875 0.15625q1.109375 0 1.71875 -0.34375q0.28125 -0.171875 0.28125 -0.359375q0 -0.3125 -0.40625 -0.515625q-0.421875 -0.203125 -1.71875 -0.34375q-1.921875 -0.203125 -2.578125 -0.78125q-0.640625 -0.578125 -0.640625 -1.40625q0 -0.859375 0.71875 -1.4375q0.984375 -0.78125 2.578125 -0.78125q0.5625 0 1.0625 0.109375q0.515625 0.109375 0.984375 0.328125q0.15625 -0.109375 0.28125 -0.15625q0.125 -0.0625 0.234375 -0.0625q0.328125 0 0.546875 0.25q0.21875 0.234375 0.21875 0.8125l0 0.390625q0 0.53125 -0.125 0.71875q-0.25 0.359375 -0.671875 0.359375q-0.296875 0 -0.515625 -0.171875q-0.21875 -0.1875 -0.28125 -0.484375zm6.9453125 1.96875l0 1.640625l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.2656326l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.1562576q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.42188263 -1.421875 -0.42188263l-1.84375 0l0 3.0156326zm11.9765625 4.859375l0 -0.375q-0.609375 0.3125 -1.34375 0.46875q-0.71875 0.171875 -1.3125 0.171875q-1.28125 0 -2.09375 -0.6875q-0.796875 -0.6875 -0.796875 -1.515625q0 -1.0 1.015625 -1.859375q1.03125 -0.875 2.84375 -0.875q0.734375 0 1.6875 0.15625l0 -0.375q0 -0.359375 -0.3125 -0.578125q-0.3125 -0.234375 -1.171875 -0.234375q-0.71875 0 -1.84375 0.28125q-0.421875 0.09375 -0.65625 0.09375q-0.328125 0 -0.546875 -0.21875q-0.21875 -0.234375 -0.21875 -0.59375q0 -0.203125 0.078125 -0.34375q0.078125 -0.15625 0.21875 -0.25q0.140625 -0.09375 0.578125 -0.21875q0.59375 -0.15625 1.203125 -0.25q0.625 -0.109375 1.125 -0.109375q1.5 0 2.3125 0.65625q0.828125 0.640625 0.828125 1.75l0 3.296875l0.28125 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.875 0zm0 -2.875q-0.96875 -0.1875 -1.78125 -0.1875q-0.96875 0 -1.671875 0.484375q-0.4375 0.296875 -0.4375 0.609375q0 0.234375 0.203125 0.375q0.390625 0.25 1.078125 0.25q0.578125 0 1.296875 -0.21875q0.734375 -0.234375 1.3125 -0.625l0 -0.6875zm7.7578125 -2.625l0 3.21875q0 0.515625 0.21875 0.671875q0.328125 0.265625 1.171875 0.265625q1.21875 0 2.265625 -0.53125q0.390625 -0.203125 0.625 -0.203125q0.3125 0 0.53125 0.234375q0.234375 0.234375 0.234375 0.578125q0 0.3125 -0.25 0.53125q-0.375 0.375 -1.515625 0.6875q-1.125 0.3125 -1.890625 0.3125q-1.5 0 -2.25 -0.640625q-0.734375 -0.65625 -0.734375 -1.59375l0 -3.53125l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l0.578125 0l0 -1.4531326q0 -0.578125 0.21875 -0.8125q0.21875 -0.25 0.578125 -0.25q0.359375 0 0.578125 0.25q0.21875 0.234375 0.21875 0.8125l0 1.4531326l2.96875 0q0.578125 0 0.8125 0.21875q0.25 0.21875 0.25 0.578125q0 0.359375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-2.96875 0zm8.3515625 -4.6406326l0 3.4218826q0.5 -0.296875 1.0 -0.4375q0.515625 -0.15625 1.046875 -0.15625q0.828125 0 1.46875 0.28125q0.65625 0.28125 1.078125 0.890625q0.421875 0.609375 0.421875 1.53125l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.5625 0 -0.8125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.4375 0.375 -0.671875q0.203125 -0.125 0.796875 -0.125l0 -2.890625q0 -0.625 -0.28125 -0.875q-0.359375 -0.328125 -1.078125 -0.328125q-0.53125 0 -0.953125 0.203125q-0.40625 0.203125 -1.09375 0.890625l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.4375 0.375 -0.671875q0.1875 -0.125 0.796875 -0.125l0 -6.9218826l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l1.875 0z" fill-rule="nonzero"/><path fill="#ffffff" d="m203.43307 160.27034l113.98425 0l0 61.16536l-113.98425 0z" fill-rule="evenodd"/><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m203.43307 160.27034l113.98425 0l0 61.16536l-113.98425 0z" fill-rule="evenodd"/><path fill="#000000" d="m245.09708 193.46301l0 1.640625l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.265625l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.15625q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.421875 -1.421875 -0.421875l-1.84375 0l0 3.015625zm11.9765625 4.859375l0 -0.375q-0.609375 0.3125 -1.34375 0.46875q-0.71875 0.171875 -1.3125 0.171875q-1.28125 0 -2.09375 -0.6875q-0.796875 -0.6875 -0.796875 -1.515625q0 -1.0 1.015625 -1.859375q1.03125 -0.875 2.84375 -0.875q0.734375 0 1.6875 0.15625l0 -0.375q0 -0.359375 -0.3125 -0.578125q-0.3125 -0.234375 -1.171875 -0.234375q-0.71875 0 -1.84375 0.28125q-0.421875 0.09375 -0.65625 0.09375q-0.328125 0 -0.546875 -0.21875q-0.21875 -0.234375 -0.21875 -0.59375q0 -0.203125 0.078125 -0.34375q0.078125 -0.15625 0.21875 -0.25q0.140625 -0.09375 0.578125 -0.21875q0.59375 -0.15625 1.203125 -0.25q0.625 -0.109375 1.125 -0.109375q1.5 0 2.3125 0.65625q0.828125 0.640625 0.828125 1.75l0 3.296875l0.28125 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.875 0zm0 -2.875q-0.96875 -0.1875 -1.78125 -0.1875q-0.96875 0 -1.671875 0.484375q-0.4375 0.296875 -0.4375 0.609375q0 0.234375 0.203125 0.375q0.390625 0.25 1.078125 0.25q0.578125 0 1.296875 -0.21875q0.734375 -0.234375 1.3125 -0.625l0 -0.6875zm7.7578125 -2.625l0 3.21875q0 0.515625 0.21875 0.671875q0.328125 0.265625 1.171875 0.265625q1.21875 0 2.265625 -0.53125q0.390625 -0.203125 0.625 -0.203125q0.3125 0 0.53125 0.234375q0.234375 0.234375 0.234375 0.578125q0 0.3125 -0.25 0.53125q-0.375 0.375 -1.515625 0.6875q-1.125 0.3125 -1.890625 0.3125q-1.5 0 -2.25 -0.640625q-0.734375 -0.65625 -0.734375 -1.59375l0 -3.53125l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l0.578125 0l0 -1.453125q0 -0.578125 0.21875 -0.8125q0.21875 -0.25 0.578125 -0.25q0.359375 0 0.578125 0.25q0.21875 0.234375 0.21875 0.8125l0 1.453125l2.96875 0q0.578125 0 0.8125 0.21875q0.25 0.21875 0.25 0.578125q0 0.359375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-2.96875 0zm8.3515625 -4.640625l0 3.421875q0.5 -0.296875 1.0 -0.4375q0.515625 -0.15625 1.046875 -0.15625q0.828125 0 1.46875 0.28125q0.65625 0.28125 1.078125 0.890625q0.421875 0.609375 0.421875 1.53125l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.5625 0 -0.8125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.4375 0.375 -0.671875q0.203125 -0.125 0.796875 -0.125l0 -2.890625q0 -0.625 -0.28125 -0.875q-0.359375 -0.328125 -1.078125 -0.328125q-0.53125 0 -0.953125 0.203125q-0.40625 0.203125 -1.09375 0.890625l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.4375 0.375 -0.671875q0.1875 -0.125 0.796875 -0.125l0 -6.921875l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l1.875 0z" fill-rule="nonzero"/><path fill="#ffffff" d="m26.64567 221.4357l158.20471 0l0 61.165344l-158.20471 0z" fill-rule="evenodd"/><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m26.64567 221.4357l158.20471 0l0 61.165344l-158.20471 0z" fill-rule="evenodd"/><path fill="#000000" d="m66.416 254.62837l0 1.6406097l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.2656097l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.15625q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.421875 -1.421875 -0.421875l-1.84375 0l0 3.015625zm14.6953125 1.4375q0 0.921875 -0.515625 1.7968597q-0.515625 0.859375 -1.53125 1.375q-1.0 0.515625 -2.109375 0.515625q-1.09375 0 -2.09375 -0.5q-1.0 -0.515625 -1.53125 -1.375q-0.515625 -0.87498474 -0.515625 -1.8281097q0 -0.953125 0.53125 -1.875q0.53125 -0.9375 1.53125 -1.46875q1.0 -0.53125 2.078125 -0.53125q1.09375 0 2.109375 0.546875q1.015625 0.546875 1.53125 1.46875q0.515625 0.90625 0.515625 1.875zm-1.609375 0.015625q0 -0.78125 -0.546875 -1.421875q-0.765625 -0.875 -2.0 -0.875q-1.078125 0 -1.8125 0.703125q-0.71875 0.6875 -0.71875 1.59375q0 0.75 0.734375 1.40625q0.734375 0.65623474 1.796875 0.65623474q1.078125 0 1.8125 -0.65623474q0.734375 -0.65625 0.734375 -1.40625zm8.7734375 -1.8125q-0.390625 -0.25 -0.828125 -0.359375q-0.421875 -0.125 -0.890625 -0.125q-0.921875 0 -1.46875 0.296875q-0.25 0.140625 -0.25 0.296875q0 0.171875 0.328125 0.34375q0.25 0.125 1.125 0.25q1.59375 0.21875 2.21875 0.4375q0.8125 0.28125 1.25 0.859375q0.453125 0.5625 0.453125 1.203125q0 0.85935974 -0.75 1.4374847q-1.09375 0.84375 -2.828125 0.84375q-0.6875 0 -1.28125 -0.125q-0.59375 -0.125 -1.078125 -0.359375q-0.125 0.09375 -0.265625 0.15625q-0.125 0.046875 -0.265625 0.046875q-0.375 0 -0.59375 -0.234375q-0.21875 -0.25 -0.21875 -0.828125l0 -0.546875q0 -0.57810974 0.21875 -0.81248474q0.21875 -0.25 0.578125 -0.25q0.296875 0 0.484375 0.15625q0.203125 0.15625 0.3125 0.546875q0.359375 0.31248474 0.875 0.48435974q0.515625 0.15625 1.1875 0.15625q1.109375 0 1.71875 -0.34375q0.28125 -0.171875 0.28125 -0.35935974q0 -0.3125 -0.40625 -0.515625q-0.421875 -0.203125 -1.71875 -0.34375q-1.921875 -0.203125 -2.578125 -0.78125q-0.640625 -0.578125 -0.640625 -1.40625q0 -0.859375 0.71875 -1.4375q0.984375 -0.78125 2.578125 -0.78125q0.5625 0 1.0625 0.109375q0.515625 0.109375 0.984375 0.328125q0.15625 -0.109375 0.28125 -0.15625q0.125 -0.0625 0.234375 -0.0625q0.328125 0 0.546875 0.25q0.21875 0.234375 0.21875 0.8125l0 0.390625q0 0.53125 -0.125 0.71875q-0.25 0.359375 -0.671875 0.359375q-0.296875 0 -0.515625 -0.171875q-0.21875 -0.1875 -0.28125 -0.484375zm8.4453125 -4.921875l0 1.703125l-1.90625 0l0 -1.703125l1.90625 0zm0.21875 3.046875l0 5.4843597l1.921875 0q0.578125 0 0.828125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-5.4375 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l1.921875 0l0 -3.8906097l-1.296875 0q-0.5625 0 -0.8125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.234375 -0.578125q0.25 -0.21875 0.828125 -0.21875l2.890625 0zm10.0078125 3.40625l2.4375 2.0781097q0.4375 0.03125 0.65625 0.25q0.21875 0.21875 0.21875 0.5625q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-1.8125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.28125 0.171875 -0.5q0.1875 -0.21875 0.484375 -0.296875l-1.1875 -1.0312347l-1.21875 1.0312347q0.359375 0.09375 0.515625 0.296875q0.171875 0.1875 0.171875 0.5q0 0.359375 -0.25 0.59375q-0.234375 0.21875 -0.8125 0.21875l-1.8125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.328125 0.21875 -0.546875q0.21875 -0.21875 0.65625 -0.25l2.375 -2.0937347l-2.109375 -1.796875q-0.40625 -0.03125 -0.625 -0.25q-0.21875 -0.21875 -0.21875 -0.546875q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.5 0q0.578125 0 0.8125 0.21875q0.25 0.21875 0.25 0.5625q0 0.46875 -0.4375 0.75l0.96875 0.8125l0.953125 -0.828125q-0.421875 -0.296875 -0.421875 -0.703125q0 -0.375 0.234375 -0.59375q0.25 -0.21875 0.828125 -0.21875l1.484375 0q0.578125 0 0.828125 0.21875q0.25 0.21875 0.25 0.578125q0 0.328125 -0.21875 0.546875q-0.21875 0.21875 -0.640625 0.25l-2.109375 1.8125zm7.4765625 0.4375l0 1.6406097l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.2656097l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.15625q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.421875 -1.421875 -0.421875l-1.84375 0l0 3.015625zm11.9765625 4.8593597l0 -0.375q-0.609375 0.3125 -1.34375 0.46875q-0.71875 0.171875 -1.3125 0.171875q-1.28125 0 -2.09375 -0.6875q-0.796875 -0.6875 -0.796875 -1.5156097q0 -1.0 1.015625 -1.859375q1.03125 -0.875 2.84375 -0.875q0.734375 0 1.6875 0.15625l0 -0.375q0 -0.359375 -0.3125 -0.578125q-0.3125 -0.234375 -1.171875 -0.234375q-0.71875 0 -1.84375 0.28125q-0.421875 0.09375 -0.65625 0.09375q-0.328125 0 -0.546875 -0.21875q-0.21875 -0.234375 -0.21875 -0.59375q0 -0.203125 0.078125 -0.34375q0.078125 -0.15625 0.21875 -0.25q0.140625 -0.09375 0.578125 -0.21875q0.59375 -0.15625 1.203125 -0.25q0.625 -0.109375 1.125 -0.109375q1.5 0 2.3125 0.65625q0.828125 0.640625 0.828125 1.75l0 3.2968597l0.28125 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.875 0zm0 -2.8749847q-0.96875 -0.1875 -1.78125 -0.1875q-0.96875 0 -1.671875 0.484375q-0.4375 0.296875 -0.4375 0.609375q0 0.23435974 0.203125 0.37498474q0.390625 0.25 1.078125 0.25q0.578125 0 1.296875 -0.21875q0.734375 -0.234375 1.3125 -0.62498474l0 -0.6875zm7.7578125 -2.625l0 3.21875q0 0.51560974 0.21875 0.67185974q0.328125 0.265625 1.171875 0.265625q1.21875 0 2.265625 -0.53125q0.390625 -0.20310974 0.625 -0.20310974q0.3125 0 0.53125 0.23435974q0.234375 0.234375 0.234375 0.578125q0 0.3125 -0.25 0.53125q-0.375 0.375 -1.515625 0.6875q-1.125 0.3125 -1.890625 0.3125q-1.5 0 -2.25 -0.640625q-0.734375 -0.65625 -0.734375 -1.5937347l0 -3.53125l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l0.578125 0l0 -1.453125q0 -0.578125 0.21875 -0.8125q0.21875 -0.25 0.578125 -0.25q0.359375 0 0.578125 0.25q0.21875 0.234375 0.21875 0.8125l0 1.453125l2.96875 0q0.578125 0 0.8125 0.21875q0.25 0.21875 0.25 0.578125q0 0.359375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-2.96875 0zm8.3515625 -4.640625l0 3.421875q0.5 -0.296875 1.0 -0.4375q0.515625 -0.15625 1.046875 -0.15625q0.828125 0 1.46875 0.28125q0.65625 0.28125 1.078125 0.890625q0.421875 0.609375 0.421875 1.53125l0 2.9999847q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.5625 0 -0.8125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.4375 0.375 -0.671875q0.203125 -0.125 0.796875 -0.125l0 -2.8906097q0 -0.625 -0.28125 -0.875q-0.359375 -0.328125 -1.078125 -0.328125q-0.53125 0 -0.953125 0.203125q-0.40625 0.203125 -1.09375 0.890625l0 2.9999847q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.4375 0.375 -0.671875q0.1875 -0.125 0.796875 -0.125l0 -6.9218597l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l1.875 0z" fill-rule="nonzero"/><path fill="#ffffff" d="m336.0 221.4357l174.04724 0l0 61.165344l-174.04724 0z" fill-rule="evenodd"/><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m336.0 221.4357l174.04724 0l0 61.165344l-174.04724 0z" fill-rule="evenodd"/><path fill="#000000" d="m375.02753 253.3315l-1.484375 4.5468597l-1.796875 0l-0.953125 -7.8749847q-0.375 -0.046875 -0.5625 -0.25q-0.1875 -0.203125 -0.1875 -0.53125q0 -0.375 0.25 -0.59375q0.25 -0.234375 0.828125 -0.234375l2.125 0.015625q0.578125 0 0.828125 0.21875q0.25 0.21875 0.25 0.578125q0 0.359375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-0.828125 0l0.53125 4.484375l1.25 -3.734375l1.671875 0l1.25 3.734375l0.53125 -4.484375l-0.84375 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.21875 -0.234375 -0.578125q0 -0.359375 0.234375 -0.578125q0.25 -0.234375 0.828125 -0.234375l2.125 0.015625q0.578125 0 0.828125 0.21875q0.25 0.21875 0.25 0.578125q0 0.296875 -0.203125 0.515625q-0.1875 0.21875 -0.5625 0.28125l-0.921875 7.8749847l-1.765625 0l-1.53125 -4.5468597zm10.1640625 -5.59375l0 1.703125l-1.90625 0l0 -1.703125l1.90625 0zm0.21875 3.046875l0 5.4843597l1.921875 0q0.578125 0 0.828125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-5.4375 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l1.921875 0l0 -3.8906097l-1.296875 0q-0.5625 0 -0.8125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.234375 -0.578125q0.25 -0.21875 0.828125 -0.21875l2.890625 0zm7.1953125 0l0 0.53125q0.4375 -0.375 0.953125 -0.5625q0.53125 -0.1875 1.15625 -0.1875q1.421875 0 2.25 0.890625q0.65625 0.703125 0.65625 1.84375l0 2.9687347q0.5 0 0.734375 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.453125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.34375 0.234375 -0.5625q0.25 -0.234375 0.75 -0.234375l0 -3.0156097q0 -0.53125 -0.28125 -0.765625q-0.359375 -0.3125 -1.09375 -0.3125q-0.5625 0 -0.984375 0.21875q-0.40625 0.203125 -1.046875 0.90625l0 2.9687347q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.4375 0.375 -0.671875q0.1875 -0.125 0.796875 -0.125l0 -3.8906097q-0.5 0 -0.75 -0.21875q-0.234375 -0.234375 -0.234375 -0.578125q0 -0.359375 0.234375 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.53125 0zm14.8984375 -3.046875l0 8.531235l0.265625 0q0.578125 0 0.828125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-1.875 0l0 -0.390625q-0.546875 0.3125 -1.140625 0.484375q-0.59375 0.171875 -1.234375 0.171875q-1.8125 0 -2.921875 -1.046875q-1.09375 -1.046875 -1.09375 -2.6093597q0 -1.625 1.15625 -2.765625q1.15625 -1.15625 2.828125 -1.15625q0.625 0 1.21875 0.203125q0.609375 0.1875 1.1875 0.5625l0 -1.984375l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l1.875 0zm-1.609375 6.796875q0 -0.984375 -0.703125 -1.671875q-0.6875 -0.6875 -1.6875 -0.6875q-1.0 0 -1.703125 0.6875q-0.6875 0.6875 -0.6875 1.65625q0 0.875 0.625 1.453125q0.625 0.56248474 1.765625 0.56248474q1.125 0 1.75 -0.56248474q0.640625 -0.578125 0.640625 -1.4375zm11.6953125 -0.078125q0 0.921875 -0.515625 1.7968597q-0.515625 0.859375 -1.53125 1.375q-1.0 0.515625 -2.109375 0.515625q-1.09375 0 -2.09375 -0.5q-1.0 -0.515625 -1.53125 -1.375q-0.515625 -0.87498474 -0.515625 -1.8281097q0 -0.953125 0.53125 -1.875q0.53125 -0.9375 1.53125 -1.46875q1.0 -0.53125 2.078125 -0.53125q1.09375 0 2.109375 0.546875q1.015625 0.546875 1.53125 1.46875q0.515625 0.90625 0.515625 1.875zm-1.609375 0.015625q0 -0.78125 -0.546875 -1.421875q-0.765625 -0.875 -2.0 -0.875q-1.078125 0 -1.8125 0.703125q-0.71875 0.6875 -0.71875 1.59375q0 0.75 0.734375 1.40625q0.734375 0.65623474 1.796875 0.65623474q1.078125 0 1.8125 -0.65623474q0.734375 -0.65625 0.734375 -1.40625zm7.0546875 0.453125l-1.109375 2.9531097l-1.5 0l-1.34375 -5.4999847q-0.4375 -0.015625 -0.671875 -0.234375q-0.21875 -0.234375 -0.21875 -0.5625q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.484375 0q0.578125 0 0.828125 0.21875q0.25 0.21875 0.25 0.578125q0 0.359375 -0.28125 0.609375q-0.21875 0.1875 -0.828125 0.1875l0.609375 2.546875l0.984375 -2.609375l1.421875 0l1.0 2.609375l0.625 -2.546875q-0.59375 0 -0.78125 -0.109375q-0.375 -0.25 -0.375 -0.6875q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.5 0q0.578125 0 0.828125 0.21875q0.25 0.21875 0.25 0.578125q0 0.328125 -0.21875 0.546875q-0.21875 0.21875 -0.640625 0.25l-1.3125 5.4999847l-1.484375 0l-1.171875 -2.9531097zm11.3203125 -2.265625q-0.390625 -0.25 -0.828125 -0.359375q-0.421875 -0.125 -0.890625 -0.125q-0.921875 0 -1.46875 0.296875q-0.25 0.140625 -0.25 0.296875q0 0.171875 0.328125 0.34375q0.25 0.125 1.125 0.25q1.59375 0.21875 2.21875 0.4375q0.8125 0.28125 1.25 0.859375q0.453125 0.5625 0.453125 1.203125q0 0.85935974 -0.75 1.4374847q-1.09375 0.84375 -2.828125 0.84375q-0.6875 0 -1.28125 -0.125q-0.59375 -0.125 -1.078125 -0.359375q-0.125 0.09375 -0.265625 0.15625q-0.125 0.046875 -0.265625 0.046875q-0.375 0 -0.59375 -0.234375q-0.21875 -0.25 -0.21875 -0.828125l0 -0.546875q0 -0.57810974 0.21875 -0.81248474q0.21875 -0.25 0.578125 -0.25q0.296875 0 0.484375 0.15625q0.203125 0.15625 0.3125 0.546875q0.359375 0.31248474 0.875 0.48435974q0.515625 0.15625 1.1875 0.15625q1.109375 0 1.71875 -0.34375q0.28125 -0.171875 0.28125 -0.35935974q0 -0.3125 -0.40625 -0.515625q-0.421875 -0.203125 -1.71875 -0.34375q-1.921875 -0.203125 -2.578125 -0.78125q-0.640625 -0.578125 -0.640625 -1.40625q0 -0.859375 0.71875 -1.4375q0.984375 -0.78125 2.578125 -0.78125q0.5625 0 1.0625 0.109375q0.515625 0.109375 0.984375 0.328125q0.15625 -0.109375 0.28125 -0.15625q0.125 -0.0625 0.234375 -0.0625q0.328125 0 0.546875 0.25q0.21875 0.234375 0.21875 0.8125l0 0.390625q0 0.53125 -0.125 0.71875q-0.25 0.359375 -0.671875 0.359375q-0.296875 0 -0.515625 -0.171875q-0.21875 -0.1875 -0.28125 -0.484375zm6.9453125 1.96875l0 1.6406097l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.2656097l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.15625q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.421875 -1.421875 -0.421875l-1.84375 0l0 3.015625zm11.9765625 4.8593597l0 -0.375q-0.609375 0.3125 -1.34375 0.46875q-0.71875 0.171875 -1.3125 0.171875q-1.28125 0 -2.09375 -0.6875q-0.796875 -0.6875 -0.796875 -1.5156097q0 -1.0 1.015625 -1.859375q1.03125 -0.875 2.84375 -0.875q0.734375 0 1.6875 0.15625l0 -0.375q0 -0.359375 -0.3125 -0.578125q-0.3125 -0.234375 -1.171875 -0.234375q-0.71875 0 -1.84375 0.28125q-0.421875 0.09375 -0.65625 0.09375q-0.328125 0 -0.546875 -0.21875q-0.21875 -0.234375 -0.21875 -0.59375q0 -0.203125 0.078125 -0.34375q0.078125 -0.15625 0.21875 -0.25q0.140625 -0.09375 0.578125 -0.21875q0.59375 -0.15625 1.203125 -0.25q0.625 -0.109375 1.125 -0.109375q1.5 0 2.3125 0.65625q0.828125 0.640625 0.828125 1.75l0 3.2968597l0.28125 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.875 0zm0 -2.8749847q-0.96875 -0.1875 -1.78125 -0.1875q-0.96875 0 -1.671875 0.484375q-0.4375 0.296875 -0.4375 0.609375q0 0.23435974 0.203125 0.37498474q0.390625 0.25 1.078125 0.25q0.578125 0 1.296875 -0.21875q0.734375 -0.234375 1.3125 -0.62498474l0 -0.6875zm7.7578125 -2.625l0 3.21875q0 0.51560974 0.21875 0.67185974q0.328125 0.265625 1.171875 0.265625q1.21875 0 2.265625 -0.53125q0.390625 -0.20310974 0.625 -0.20310974q0.3125 0 0.53125 0.23435974q0.234375 0.234375 0.234375 0.578125q0 0.3125 -0.25 0.53125q-0.375 0.375 -1.515625 0.6875q-1.125 0.3125 -1.890625 0.3125q-1.5 0 -2.25 -0.640625q-0.734375 -0.65625 -0.734375 -1.5937347l0 -3.53125l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l0.578125 0l0 -1.453125q0 -0.578125 0.21875 -0.8125q0.21875 -0.25 0.578125 -0.25q0.359375 0 0.578125 0.25q0.21875 0.234375 0.21875 0.8125l0 1.453125l2.96875 0q0.578125 0 0.8125 0.21875q0.25 0.21875 0.25 0.578125q0 0.359375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-2.96875 0zm8.3515625 -4.640625l0 3.421875q0.5 -0.296875 1.0 -0.4375q0.515625 -0.15625 1.046875 -0.15625q0.828125 0 1.46875 0.28125q0.65625 0.28125 1.078125 0.890625q0.421875 0.609375 0.421875 1.53125l0 2.9999847q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.5625 0 -0.8125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.4375 0.375 -0.671875q0.203125 -0.125 0.796875 -0.125l0 -2.8906097q0 -0.625 -0.28125 -0.875q-0.359375 -0.328125 -1.078125 -0.328125q-0.53125 0 -0.953125 0.203125q-0.40625 0.203125 -1.09375 0.890625l0 2.9999847q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.4375 0.375 -0.671875q0.1875 -0.125 0.796875 -0.125l0 -6.9218597l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l1.875 0z" fill-rule="nonzero"/><path fill="#000000" fill-opacity="0.0" d="m105.74803 99.10499l97.70079 -30.58268" fill-rule="evenodd"/><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m105.74803 99.10499l91.97476 -28.79029" fill-rule="evenodd"/><path fill="#000000" stroke="#000000" stroke-width="1.0" stroke-linecap="butt" d="m198.21622 71.891l3.8374481 -2.9319763l-4.824295 -0.22064209z" fill-rule="evenodd"/><path fill="#000000" fill-opacity="0.0" d="m423.02362 99.10499l-105.60629 -30.58268" fill-rule="evenodd"/><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m423.02362 99.10499l-99.84308 -28.913704" fill-rule="evenodd"/><path fill="#000000" stroke="#000000" stroke-width="1.0" stroke-linecap="butt" d="m323.63998 68.60474l-4.818451 0.32421875l3.8995361 2.848877z" fill-rule="evenodd"/><path fill="#000000" fill-opacity="0.0" d="m105.74803 221.4357l0 -61.16536" fill-rule="evenodd"/><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m105.74803 221.4357l0 -55.16536" fill-rule="evenodd"/><path fill="#000000" stroke="#000000" stroke-width="1.0" stroke-linecap="butt" d="m107.399765 166.27034l-1.6517334 -4.538101l-1.6517334 4.538101z" fill-rule="evenodd"/><path fill="#000000" fill-opacity="0.0" d="m423.02362 221.4357l0 -61.16536" fill-rule="evenodd"/><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m423.02362 221.4357l0 -55.16536" fill-rule="evenodd"/><path fill="#000000" stroke="#000000" stroke-width="1.0" stroke-linecap="butt" d="m424.67535 166.27034l-1.6517334 -4.538101l-1.6517334 4.538101z" fill-rule="evenodd"/><path fill="#000000" fill-opacity="0.0" d="m260.4252 160.27034l0 -61.16535" fill-rule="evenodd"/><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m260.4252 160.27034l0 -55.16535" fill-rule="evenodd"/><path fill="#000000" stroke="#000000" stroke-width="1.0" stroke-linecap="butt" d="m262.07693 105.10499l-1.6517334 -4.538101l-1.6517334 4.538101z" fill-rule="evenodd"/><path fill="#000000" fill-opacity="0.0" d="m105.74803 221.4357l97.70079 -30.582687" fill-rule="evenodd"/><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m105.74803 221.4357l91.97476 -28.790298" fill-rule="evenodd"/><path fill="#000000" stroke="#000000" stroke-width="1.0" stroke-linecap="butt" d="m198.21622 194.22171l3.8374481 -2.9319763l-4.824295 -0.22064209z" fill-rule="evenodd"/><path fill="#000000" fill-opacity="0.0" d="m423.02362 221.4357l-105.60629 -30.582687" fill-rule="evenodd"/><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m423.02362 221.4357l-99.84308 -28.913696" fill-rule="evenodd"/><path fill="#000000" stroke="#000000" stroke-width="1.0" stroke-linecap="butt" d="m323.63998 190.93544l-4.818451 0.32421875l3.8995361 2.848877z" fill-rule="evenodd"/></g></svg>
\ No newline at end of file
index b4ae293d14b8ce232e27ff45ad597c71397b0c05..7d4b41b1dd12b50f428cd6989bc3b5685d4eb9c0 100644 (file)
@@ -718,7 +718,7 @@ call fails (for example because the path doesn't exist):
 
 .. method:: Path.glob(pattern)
 
-   Glob the given *pattern* in the directory represented by this path,
+   Glob the given relative *pattern* in the directory represented by this path,
    yielding all matching files (of any kind)::
 
       >>> sorted(Path('.').glob('*.py'))
@@ -970,8 +970,8 @@ call fails (for example because the path doesn't exist):
 
 .. method:: Path.rglob(pattern)
 
-   This is like calling :meth:`Path.glob` with "``**``" added in front of the
-   given *pattern*::
+   This is like calling :func:`Path.glob` with "``**/``" added in front of the
+   given relative *pattern*::
 
       >>> sorted(Path().rglob("*.py"))
       [PosixPath('build/lib/pathlib.py'),
index a72876f3f5a8c072fe7bd5db25236ccf055e443e..c7864e9e3f222565df26796c2e8697a8118a51a3 100644 (file)
@@ -76,6 +76,10 @@ at the location you want to break into the debugger.  You can then step through
 the code following this statement, and continue running without the debugger
 using the :pdbcmd:`continue` command.
 
+.. versionadded:: 3.7
+   The built-in :func:`breakpoint()`, when called with defaults, can be used
+   instead of ``import pdb; pdb.set_trace()``.
+
 The typical usage to inspect a crashed program is::
 
    >>> import pdb
index 36f66a159bf2689bbb4413e685454306e38c3888..2d01d8b7ab2502d7ed4729058de0f2db3ff3968a 100644 (file)
@@ -923,7 +923,7 @@ The following example reads the resulting pickled data. ::
 .. [#] Don't confuse this with the :mod:`marshal` module
 
 .. [#] This is why :keyword:`lambda` functions cannot be pickled:  all
-    :keyword:`lambda` functions share the same name:  ``<lambda>``.
+    :keyword:`!lambda` functions share the same name:  ``<lambda>``.
 
 .. [#] The exception raised will likely be an :exc:`ImportError` or an
    :exc:`AttributeError` but it could be something else.
index 4f251574a32726873ac58755c801216c6485526a..7d051e185429d52cbf4d9d67a951df3560ce5f3f 100644 (file)
@@ -162,6 +162,13 @@ Functions for sequences
    with the :class:`float` values returned by :func:`random` (that includes
    integers, floats, and fractions but excludes decimals).
 
+   For a given seed, the :func:`choices` function with equal weighting
+   typically produces a different sequence than repeated calls to
+   :func:`choice`.  The algorithm used by :func:`choices` uses floating
+   point arithmetic for internal consistency and speed.  The algorithm used
+   by :func:`choice` defaults to integer arithmetic with repeated selections
+   to avoid small biases from round-off error.
+
    .. versionadded:: 3.6
 
 
@@ -378,12 +385,16 @@ Simulations::
 
    >>> # Estimate the probability of getting 5 or more heads from 7 spins
    >>> # of a biased coin that settles on heads 60% of the time.
-   >>> trial = lambda: choices('HT', cum_weights=(0.60, 1.00), k=7).count('H') >= 5
+   >>> def trial():
+   ...     return choices('HT', cum_weights=(0.60, 1.00), k=7).count('H') >= 5
+   ...
    >>> sum(trial() for i in range(10000)) / 10000
    0.4169
 
    >>> # Probability of the median of 5 samples being in middle two quartiles
-   >>> trial = lambda : 2500 <= sorted(choices(range(10000), k=5))[2]  < 7500
+   >>> def trial():
+   ...     return 2500 <= sorted(choices(range(10000), k=5))[2] < 7500
+   ...
    >>> sum(trial() for i in range(10000)) / 10000
    0.7958
 
index e6455bb359dfe1e44f2045920d587757cfc3c364..dc3f428b8a19c0a7cd203c91f36f28a2a4256da1 100644 (file)
@@ -368,6 +368,8 @@ The special characters are:
 ``(?#...)``
    A comment; the contents of the parentheses are simply ignored.
 
+.. index:: single: (?=; in regular expressions
+
 ``(?=...)``
    Matches if ``...`` matches next, but doesn't consume any of the string.  This is
    called a :dfn:`lookahead assertion`.  For example, ``Isaac (?=Asimov)`` will match
@@ -568,7 +570,8 @@ accepted by the regular expression parser::
 only inside character classes.)
 
 ``'\u'`` and ``'\U'`` escape sequences are only recognized in Unicode
-patterns.  In bytes patterns they are errors.
+patterns.  In bytes patterns they are errors.  Unknown escapes of ASCII
+letters are reserved for future use and treated as errors.
 
 Octal escapes are included in a limited form.  If the first digit is a 0, or if
 there are three octal digits, it is considered an octal escape. Otherwise, it is
@@ -842,7 +845,9 @@ form.
    *string* is returned unchanged.  *repl* can be a string or a function; if it is
    a string, any backslash escapes in it are processed.  That is, ``\n`` is
    converted to a single newline character, ``\r`` is converted to a carriage return, and
-   so forth.  Unknown escapes such as ``\&`` are left alone.  Backreferences, such
+   so forth.  Unknown escapes of ASCII letters are reserved for future use and
+   treated as errors.  Other unknown escapes such as ``\&`` are left alone.
+   Backreferences, such
    as ``\6``, are replaced with the substring matched by group 6 in the pattern.
    For example::
 
index 955ac2a8ef425525cb84ebc0983195a961d2fe7c..5b8fd7ee805c5216c6ce6ff9046688144c878ac3 100644 (file)
@@ -317,6 +317,9 @@ Edge and Level Trigger Polling (epoll) Objects
    | :const:`EPOLLMSG`       | Ignored.                                      |
    +-------------------------+-----------------------------------------------+
 
+   .. versionadded:: 3.6
+      :const:`EPOLLEXCLUSIVE` was added.  It's only supported by Linux Kernel 4.5
+      or later.
 
 .. method:: epoll.close()
 
index f59c18409411601a85e62a94ca047577ca2ba3ea..2c3a5f0c6f729647bef2dcb9ba61ffb8dfb1b480 100644 (file)
@@ -46,7 +46,7 @@ Protocol) and :rfc:`1869` (SMTP Service Extensions).
 
    The :class:`SMTP` class supports the :keyword:`with` statement.  When used
    like this, the SMTP ``QUIT`` command is issued automatically when the
-   :keyword:`with` statement exits.  E.g.::
+   :keyword:`!with` statement exits.  E.g.::
 
     >>> from smtplib import SMTP
     >>> with SMTP("domain.org") as smtp:
index 1b3062da6df9d973a96ff821ce3785e5a5c6241d..7c8c8d52e03d95461b425ba5e80af3cb73d78a4a 100644 (file)
@@ -57,7 +57,7 @@ the server in a :keyword:`with` statement. Then call the
 :meth:`~BaseServer.handle_request` or
 :meth:`~BaseServer.serve_forever` method of the server object to
 process one or many requests.  Finally, call :meth:`~BaseServer.server_close`
-to close the socket (unless you used a :keyword:`with` statement).
+to close the socket (unless you used a :keyword:`!with` statement).
 
 When inheriting from :class:`ThreadingMixIn` for threaded connection behavior,
 you should explicitly declare how you want your threads to behave on an abrupt
index 0835e9ae04e6f0e4f37dd92f456d8821b5b2debc..fba9d5a63dd0069cded8b21ffdf1a4e8dd80a694 100644 (file)
@@ -1328,12 +1328,12 @@ SSL sockets also have the following additional methods and attributes:
    If any precondition isn't met (e.g. not TLS 1.3, PHA not enabled), an
    :exc:`SSLError` is raised.
 
-   .. versionadded:: 3.7.1
-
    .. note::
       Only available with OpenSSL 1.1.1 and TLS 1.3 enabled. Without TLS 1.3
       support, the method raises :exc:`NotImplementedError`.
 
+   .. versionadded:: 3.7.1
+
 .. method:: SSLSocket.version()
 
    Return the actual SSL protocol version negotiated by the connection
@@ -1922,6 +1922,8 @@ to speed up repeated connections from the same clients.
      This attribute is not available unless the ssl module is compiled
      with OpenSSL 1.1.0g or newer.
 
+   .. versionadded:: 3.7
+
 .. attribute:: SSLContext.minimum_version
 
    Like :attr:`SSLContext.maximum_version` except it is the lowest
@@ -1932,6 +1934,8 @@ to speed up repeated connections from the same clients.
      This attribute is not available unless the ssl module is compiled
      with OpenSSL 1.1.0g or newer.
 
+   .. versionadded:: 3.7
+
 .. attribute:: SSLContext.options
 
    An integer representing the set of SSL options enabled on this context.
@@ -1965,12 +1969,12 @@ to speed up repeated connections from the same clients.
    :meth:`SSLSocket.verify_client_post_handshake` is called and some I/O is
    performed.
 
-   .. versionadded:: 3.7.1
-
    .. note::
       Only available with OpenSSL 1.1.1 and TLS 1.3 enabled. Without TLS 1.3
       support, the property value is None and can't be modified
 
+   .. versionadded:: 3.7.1
+
 .. attribute:: SSLContext.protocol
 
    The protocol version chosen when constructing the context.  This attribute
@@ -1982,11 +1986,11 @@ to speed up repeated connections from the same clients.
    subject common name in the absence of a subject alternative name
    extension (default: true).
 
-   .. versionadded:: 3.7
-
    .. note::
       Only writeable with OpenSSL 1.1.0 or higher.
 
+   .. versionadded:: 3.7
+
 .. attribute:: SSLContext.verify_flags
 
    The flags for certificate verification operations. You can set flags like
index 42c92824b25ebc8b7f03cb1ca5cc9bdb03b39a99..c21cb0d9ea0f4ae13036571af0532d717e64e2bf 100644 (file)
@@ -74,8 +74,8 @@ one of their operands.)
 
 .. _boolean:
 
-Boolean Operations --- :keyword:`and`, :keyword:`or`, :keyword:`not`
-====================================================================
+Boolean Operations --- :keyword:`!and`, :keyword:`!or`, :keyword:`!not`
+=======================================================================
 
 .. index:: pair: Boolean; operations
 
@@ -3975,7 +3975,7 @@ The constructors for both classes work the same:
 
    .. method:: copy()
 
-      Return a new set with a shallow copy of *s*.
+      Return a shallow copy of the set.
 
 
    Note, the non-operator versions of :meth:`union`, :meth:`intersection`,
@@ -4201,9 +4201,9 @@ pairs within braces, for example: ``{'jack': 4098, 'sjoerd': 4127}`` or ``{4098:
 
       Return a shallow copy of the dictionary.
 
-   .. classmethod:: fromkeys(seq[, value])
+   .. classmethod:: fromkeys(iterable[, value])
 
-      Create a new dictionary with keys from *seq* and values set to *value*.
+      Create a new dictionary with keys from *iterable* and values set to *value*.
 
       :meth:`fromkeys` is a class method that returns a new dictionary. *value*
       defaults to ``None``.
@@ -4393,7 +4393,7 @@ before the statement body is executed and exited when the statement ends:
 
    Enter the runtime context and return either this object or another object
    related to the runtime context. The value returned by this method is bound to
-   the identifier in the :keyword:`as` clause of :keyword:`with` statements using
+   the identifier in the :keyword:`!as` clause of :keyword:`with` statements using
    this context manager.
 
    An example of a context manager that returns itself is a :term:`file object`.
@@ -4405,7 +4405,7 @@ before the statement body is executed and exited when the statement ends:
    decimal context to a copy of the original decimal context and then return the
    copy. This allows changes to be made to the current decimal context in the body
    of the :keyword:`with` statement without affecting code outside the
-   :keyword:`with` statement.
+   :keyword:`!with` statement.
 
 
 .. method:: contextmanager.__exit__(exc_type, exc_val, exc_tb)
@@ -4417,10 +4417,10 @@ before the statement body is executed and exited when the statement ends:
 
    Returning a true value from this method will cause the :keyword:`with` statement
    to suppress the exception and continue execution with the statement immediately
-   following the :keyword:`with` statement. Otherwise the exception continues
+   following the :keyword:`!with` statement. Otherwise the exception continues
    propagating after this method has finished executing. Exceptions that occur
    during execution of this method will replace any exception that occurred in the
-   body of the :keyword:`with` statement.
+   body of the :keyword:`!with` statement.
 
    The exception passed in should never be reraised explicitly - instead, this
    method should return a false value to indicate that the method completed
index 4a10c7a7d9c72f956d97f9eeae3aaaf423de6cb3..18be75c10ce45b06fa3b4ecb45304d9b245e5592 100644 (file)
@@ -572,9 +572,7 @@ Exceptions
 ^^^^^^^^^^
 
 Exceptions raised in the child process, before the new program has started to
-execute, will be re-raised in the parent.  Additionally, the exception object
-will have one extra attribute called :attr:`child_traceback`, which is a string
-containing traceback information from the child's point of view.
+execute, will be re-raised in the parent.
 
 The most common exception raised is :exc:`OSError`.  This occurs, for example,
 when trying to execute a non-existent file.  Applications should prepare for
@@ -961,7 +959,7 @@ The :mod:`subprocess` module exposes the following constants.
 .. data:: CREATE_NO_WINDOW
 
    A :class:`Popen` ``creationflags`` parameter to specify that a new process
-   will not create a window
+   will not create a window.
 
    .. versionadded:: 3.7
 
@@ -1297,7 +1295,7 @@ Replacing functions from the :mod:`popen2` module
 
 * :class:`Popen` raises an exception if the execution fails.
 
-* the *capturestderr* argument is replaced with the *stderr* argument.
+* The *capturestderr* argument is replaced with the *stderr* argument.
 
 * ``stdin=PIPE`` and ``stdout=PIPE`` must be specified.
 
index 63861abb431aca0e0e879099f3e1cbe27e147ee9..ace0e2808b184a67a6ffb1b711c1023d3a619faf 100644 (file)
@@ -1348,13 +1348,30 @@ always available.
    returned by the :func:`open` function.  Their parameters are chosen as
    follows:
 
-   * The character encoding is platform-dependent.  Under Windows, if the stream
-     is interactive (that is, if its :meth:`isatty` method returns ``True``), the
-     console codepage is used, otherwise the ANSI code page.  Under other
-     platforms, the locale encoding is used (see :meth:`locale.getpreferredencoding`).
-
-     Under all platforms though, you can override this value by setting the
-     :envvar:`PYTHONIOENCODING` environment variable before starting Python.
+   * The character encoding is platform-dependent.  Non-Windows
+     platforms use the locale encoding (see
+     :meth:`locale.getpreferredencoding()`).
+
+     On Windows, UTF-8 is used for the console device.  Non-character
+     devices such as disk files and pipes use the system locale
+     encoding (i.e. the ANSI codepage).  Non-console character
+     devices such as NUL (i.e. where isatty() returns True) use the
+     value of the console input and output codepages at startup,
+     respectively for stdin and stdout/stderr. This defaults to the
+     system locale encoding if the process is not initially attached
+     to a console.
+
+     The special behaviour of the console can be overridden
+     by setting the environment variable PYTHONLEGACYWINDOWSSTDIO
+     before starting Python. In that case, the console codepages are
+     used as for any other character device.
+
+     Under all platforms, you can override the character encoding by
+     setting the :envvar:`PYTHONIOENCODING` environment variable before
+     starting Python or by using the new :option:`-X` ``utf8`` command
+     line option and :envvar:`PYTHONUTF8` environment variable.  However,
+     for the Windows console, this only applies when
+     :envvar:`PYTHONLEGACYWINDOWSSTDIO` is also set.
 
    * When interactive, ``stdout`` and ``stderr`` streams are line-buffered.
      Otherwise, they are block-buffered like regular text files.  You can
index f9c5153e3f58acffc34ac59cb3680b765c9f0819..4ba426425277f9fb22c006a6f3b21fb92bf9ce5a 100644 (file)
@@ -44,7 +44,7 @@ Character), EL (Erase Line), GA (Go Ahead), SB (Subnegotiation Begin).
    an empty string for other reasons.  See the individual descriptions below.
 
    A :class:`Telnet` object is a context manager and can be used in a
-   :keyword:`with` statement.  When the :keyword:`with` block ends, the
+   :keyword:`with` statement.  When the :keyword:`!with` block ends, the
    :meth:`close` method is called::
 
        >>> from telnetlib import Telnet
index 0d0da4d62e4725fc9d0719127cbda91d758f7a2c..746adb1eee484151e88829babaa65f7341e5733d 100644 (file)
@@ -115,7 +115,7 @@ The module defines the following user-callable items:
 
    The directory name can be retrieved from the :attr:`name` attribute of the
    returned object.  When the returned object is used as a context manager, the
-   :attr:`name` will be assigned to the target of the :keyword:`as` clause in
+   :attr:`name` will be assigned to the target of the :keyword:`!as` clause in
    the :keyword:`with` statement, if there is one.
 
    The directory can be explicitly cleaned up by calling the
index 95d7f54ba4425350105f4d882c38af079f257da9..de79cdfc5fa9f3e83bd25c142f9018b1e64cbb9e 100644 (file)
@@ -356,6 +356,10 @@ The :mod:`test.support` module defines the following constants:
 
    Check for presence of docstrings.
 
+.. data:: TEST_HTTP_URL
+
+   Define the URL of a dedicated HTTP server for the network tests.
+
 
 
 The :mod:`test.support` module defines the following functions:
index a9d5268dd2b86523ebffbe541d209ca6a0186f06..d7dbcb107ddadb90ad9dd941861d88c91b2322a1 100644 (file)
@@ -973,8 +973,8 @@ As an example, here is a simple way to synchronize a client and server thread::
 
 .. _with-locks:
 
-Using locks, conditions, and semaphores in the :keyword:`with` statement
-------------------------------------------------------------------------
+Using locks, conditions, and semaphores in the :keyword:`!with` statement
+-------------------------------------------------------------------------
 
 All of the objects provided by this module that have :meth:`acquire` and
 :meth:`release` methods can be used as context managers for a :keyword:`with`
index c6a1f337d695c0b83071406a9141ba5e3e7d46df..8c6813bb7361930ae18266f335bf3d7936da0905 100644 (file)
@@ -293,17 +293,9 @@ Functions
    The reference point of the returned value is undefined, so that only the
    difference between the results of consecutive calls is valid.
 
-   On Windows versions older than Vista, :func:`monotonic` detects
-   :c:func:`GetTickCount` integer overflow (32 bits, roll-over after 49.7 days).
-   It increases an internal epoch (reference time) by 2\ :sup:`32` each time
-   that an overflow is detected.  The epoch is stored in the process-local state
-   and so the value of :func:`monotonic` may be different in two Python
-   processes running for more than 49 days. On more recent versions of Windows
-   and on other operating systems, :func:`monotonic` is system-wide.
-
    .. versionadded:: 3.3
    .. versionchanged:: 3.5
-      The function is now always available.
+      The function is now always available and always system-wide.
 
 
 .. function:: monotonic_ns() -> int
@@ -780,7 +772,7 @@ These constants are used as parameters for :func:`clock_getres` and
    Similar to :data:`CLOCK_MONOTONIC`, but provides access to a raw
    hardware-based time that is not subject to NTP adjustments.
 
-   Availability: Linux 2.6.28 or later.
+   .. availability:: Linux 2.6.28 and newer, macOS 10.12 and newer.
 
    .. versionadded:: 3.3
 
@@ -807,7 +799,7 @@ These constants are used as parameters for :func:`clock_getres` and
 
    Thread-specific CPU-time clock.
 
-   Availability: Unix.
+   .. availability::  Unix.
 
    .. versionadded:: 3.3
 
index 93ca940ef5bdcb44dfad06a8fb8272ed040343b0..8ca37034f79b7c6a03364fa35ef34834e7b0323c 100644 (file)
@@ -129,7 +129,7 @@ The module defines three convenience functions and a public class:
 
          By default, :meth:`.timeit` temporarily turns off :term:`garbage
          collection` during the timing.  The advantage of this approach is that
-         it makes independent timings more comparable.  This disadvantage is
+         it makes independent timings more comparable.  The disadvantage is
          that GC may be an important component of the performance of the
          function being measured.  If so, GC can be re-enabled as the first
          statement in the *setup* string.  For example::
@@ -292,7 +292,7 @@ The same can be done using the :class:`Timer` class and its methods::
    >>> t.timeit()
    0.3955516149999312
    >>> t.repeat()
-   [0.40193588800002544, 0.3960157959998014, 0.39594301399984033]
+   [0.40183617287970225, 0.37027556854118704, 0.38344867356679524, 0.3712595970846668, 0.37866875250654886]
 
 
 The following examples show how to time expressions that contain multiple lines.
index 11ed755137785d161d48065f72f53f919f6cf1a4..88b936c47a6d24b7deb86541fc1091e9176bd093 100644 (file)
@@ -76,17 +76,6 @@ the following::
    root = tix.Tk()
    root.tk.eval('package require Tix')
 
-If this fails, you have a Tk installation problem which must be resolved before
-proceeding. Use the environment variable :envvar:`TIX_LIBRARY` to point to the
-installed Tix library directory, and make sure you have the dynamic
-object library (:file:`tix8183.dll` or :file:`libtix8183.so`) in  the same
-directory that contains your Tk dynamic object library (:file:`tk8183.dll` or
-:file:`libtk8183.so`). The directory with the dynamic object library should also
-have a file called :file:`pkgIndex.tcl` (case sensitive), which contains the
-line::
-
-   package ifneeded Tix 8.1 [list load "[file join $dir tix8183.dll]" Tix]
-
 
 Tix Widgets
 -----------
index e17070022cd2ede364653288c7b9561f4204100d..b19aa0273ef52cd4d06382ca89b7e5547c71973b 100644 (file)
@@ -8,7 +8,7 @@
 
 --------------
 
-This module defines utility function to assist in dynamic creation of
+This module defines utility functions to assist in dynamic creation of
 new types.
 
 It also defines names for some object types that are used by the standard
index 0f37fc60896fee29dbcf0985f98457fdf22f4379..e756062240c9297f0b3ea6eba2d978259426ac7d 100644 (file)
@@ -50,20 +50,20 @@ A type alias is defined by assigning the type to the alias. In this example,
 
 Type aliases are useful for simplifying complex type signatures. For example::
 
-   from typing import Dict, Tuple, List
+   from typing import Dict, Tuple, Sequence
 
    ConnectionOptions = Dict[str, str]
    Address = Tuple[str, int]
    Server = Tuple[Address, ConnectionOptions]
 
-   def broadcast_message(message: str, servers: List[Server]) -> None:
+   def broadcast_message(message: str, servers: Sequence[Server]) -> None:
        ...
 
    # The static type checker will treat the previous type signature as
    # being exactly equivalent to this one.
    def broadcast_message(
            message: str,
-           servers: List[Tuple[Tuple[str, int], Dict[str, str]]]) -> None:
+           servers: Sequence[Tuple[Tuple[str, int], Dict[str, str]]]) -> None:
        ...
 
 Note that ``None`` as a type hint is a special case and is replaced by
@@ -568,6 +568,10 @@ The module defines the following classes, functions and decorators:
 .. class:: Mapping(Sized, Collection[KT], Generic[VT_co])
 
     A generic version of :class:`collections.abc.Mapping`.
+    This type can be used as follows::
+
+      def get_position_in_index(word_list: Mapping[str, int], word: str) -> int:
+          return word_list[word]
 
 .. class:: MutableMapping(Mapping[KT, VT])
 
@@ -601,8 +605,8 @@ The module defines the following classes, functions and decorators:
 
    Generic version of :class:`list`.
    Useful for annotating return types. To annotate arguments it is preferred
-   to use abstract collection types such as :class:`Mapping`, :class:`Sequence`,
-   or :class:`AbstractSet`.
+   to use an abstract collection type such as :class:`Sequence` or
+   :class:`Iterable`.
 
    This type may be used as follows::
 
@@ -617,6 +621,8 @@ The module defines the following classes, functions and decorators:
 .. class:: Set(set, MutableSet[T])
 
    A generic version of :class:`builtins.set <set>`.
+   Useful for annotating return types. To annotate arguments it is preferred
+   to use an abstract collection type such as :class:`AbstractSet`.
 
 .. class:: FrozenSet(frozenset, AbstractSet[T_co])
 
@@ -678,10 +684,13 @@ The module defines the following classes, functions and decorators:
 .. class:: Dict(dict, MutableMapping[KT, VT])
 
    A generic version of :class:`dict`.
-   The usage of this type is as follows::
+   Useful for annotating return types. To annotate arguments it is preferred
+   to use an abstract collection type such as :class:`Mapping`.
 
-      def get_position_in_index(word_list: Dict[str, int], word: str) -> int:
-          return word_list[word]
+   This type can be used as follows::
+
+      def count_words(text: str) -> Dict[str, int]:
+          ...
 
 .. class:: DefaultDict(collections.defaultdict, MutableMapping[KT, VT])
 
@@ -949,7 +958,7 @@ The module defines the following classes, functions and decorators:
       def stop() -> NoReturn:
           raise RuntimeError('no way')
 
-   .. versionadded:: 3.6.5
+   .. versionadded:: 3.5.4
 
 .. data:: Union
 
index f1b25958a670f4f1554b72484ef9707966141bd6..6daf0feca3ce00f2f7ab8b7db213d8c9bf4ba34b 100644 (file)
@@ -1097,13 +1097,13 @@ patch
     Instead of ``autospec=True`` you can pass ``autospec=some_object`` to use an
     arbitrary object as the spec instead of the one being replaced.
 
-    By default :func:`patch` will fail to replace attributes that don't exist. If
-    you pass in ``create=True``, and the attribute doesn't exist, patch will
-    create the attribute for you when the patched function is called, and
-    delete it again afterwards. This is useful for writing tests against
-    attributes that your production code creates at runtime. It is off by
-    default because it can be dangerous. With it switched on you can write
-    passing tests against APIs that don't actually exist!
+    By default :func:`patch` will fail to replace attributes that don't exist.
+    If you pass in ``create=True``, and the attribute doesn't exist, patch will
+    create the attribute for you when the patched function is called, and delete
+    it again after the patched function has exited. This is useful for writing
+    tests against attributes that your production code creates at runtime. It is
+    off by default because it can be dangerous. With it switched on you can
+    write passing tests against APIs that don't actually exist!
 
     .. note::
 
@@ -1225,6 +1225,27 @@ into a :func:`patch` call using ``**``:
       ...
     KeyError
 
+By default, attempting to patch a function in a module (or a method or an
+attribute in a class) that does not exist will fail with :exc:`AttributeError`::
+
+    >>> @patch('sys.non_existing_attribute', 42)
+    ... def test():
+    ...     assert sys.non_existing_attribute == 42
+    ...
+    >>> test()
+    Traceback (most recent call last):
+      ...
+    AttributeError: <module 'sys' (built-in)> does not have the attribute 'non_existing'
+
+but adding ``create=True`` in the call to :func:`patch` will make the previous example
+work as expected::
+
+    >>> @patch('sys.non_existing_attribute', 42, create=True)
+    ... def test(mock_stdout):
+    ...     assert sys.non_existing_attribute == 42
+    ...
+    >>> test()
+
 
 patch.object
 ~~~~~~~~~~~~
index 774b0875bbf1cebae3b5ae92686923a6a489b508..3e9e38c074a2d882d6574eebaf9b25c7e077a841 100644 (file)
@@ -2050,7 +2050,7 @@ Loading and running tests
 
    .. method:: run(test)
 
-      This method is the main public interface to the `TextTestRunner`. This
+      This method is the main public interface to the ``TextTestRunner``. This
       method takes a :class:`TestSuite` or :class:`TestCase` instance. A
       :class:`TestResult` is created by calling
       :func:`_makeResult` and the test(s) are run and the
index 0c8f0f607314a0c558f918d2d7b903184d5acf3a..b565e1edd32192fe7fc35d24b4e093bda9f182bb 100644 (file)
@@ -124,6 +124,11 @@ or on combining URL components into a URL string.
    Unmatched square brackets in the :attr:`netloc` attribute will raise a
    :exc:`ValueError`.
 
+   Characters in the :attr:`netloc` attribute that decompose under NFKC
+   normalization (as used by the IDNA encoding) into any of ``/``, ``?``,
+   ``#``, ``@``, or ``:`` will raise a :exc:`ValueError`. If the URL is
+   decomposed before parsing, no error will be raised.
+
    .. versionchanged:: 3.2
       Added IPv6 URL parsing capabilities.
 
@@ -136,6 +141,10 @@ or on combining URL components into a URL string.
       Out-of-range port numbers now raise :exc:`ValueError`, instead of
       returning :const:`None`.
 
+   .. versionchanged:: 3.7.3
+      Characters that affect netloc parsing under NFKC normalization will
+      now raise :exc:`ValueError`.
+
 
 .. function:: parse_qs(qs, keep_blank_values=False, strict_parsing=False, encoding='utf-8', errors='replace', max_num_fields=None)
 
@@ -257,10 +266,19 @@ or on combining URL components into a URL string.
    Unmatched square brackets in the :attr:`netloc` attribute will raise a
    :exc:`ValueError`.
 
+   Characters in the :attr:`netloc` attribute that decompose under NFKC
+   normalization (as used by the IDNA encoding) into any of ``/``, ``?``,
+   ``#``, ``@``, or ``:`` will raise a :exc:`ValueError`. If the URL is
+   decomposed before parsing, no error will be raised.
+
    .. versionchanged:: 3.6
       Out-of-range port numbers now raise :exc:`ValueError`, instead of
       returning :const:`None`.
 
+   .. versionchanged:: 3.7.3
+      Characters that affect netloc parsing under NFKC normalization will
+      now raise :exc:`ValueError`.
+
 
 .. function:: urlunsplit(parts)
 
index 53f3d2640566057125cd0564998a1dd995881354..fefc522b45d16eb7c4318ee4e718b643c9530194 100644 (file)
@@ -114,8 +114,7 @@ creation according to their needs, the :class:`EnvBuilder` class.
       any existing target directory, before creating the environment.
 
     * ``symlinks`` -- a Boolean value indicating whether to attempt to symlink the
-      Python binary (and any necessary DLLs or other binaries,
-      e.g. ``pythonw.exe``), rather than copying.
+      Python binary rather than copying.
 
     * ``upgrade`` -- a Boolean value which, if true, will upgrade an existing
       environment with the running Python - for use when that Python has been
@@ -181,15 +180,15 @@ creation according to their needs, the :class:`EnvBuilder` class.
 
     .. method:: setup_python(context)
 
-        Creates a copy of the Python executable in the environment on POSIX
-        systems. If a specific executable ``python3.x`` was used, symlinks to
-        ``python`` and ``python3`` will be created pointing to that executable,
-        unless files with those names already exist.
+        Creates a copy or symlink to the Python executable in the environment.
+        On POSIX systems, if a specific executable ``python3.x`` was used,
+        symlinks to ``python`` and ``python3`` will be created pointing to that
+        executable, unless files with those names already exist.
 
     .. method:: setup_scripts(context)
 
         Installs activation scripts appropriate to the platform into the virtual
-        environment. On Windows, also installs the ``python[w].exe`` scripts.
+        environment.
 
     .. method:: post_setup(context)
 
@@ -199,8 +198,13 @@ creation according to their needs, the :class:`EnvBuilder` class.
 
     .. versionchanged:: 3.7.2
        Windows now uses redirector scripts for ``python[w].exe`` instead of
-       copying the actual binaries, and so :meth:`setup_python` does nothing
-       unless running from a build in the source tree.
+       copying the actual binaries. In 3.7.2 only :meth:`setup_python` does
+       nothing unless running from a build in the source tree.
+
+    .. versionchanged:: 3.7.3
+       Windows copies the redirector scripts as part of :meth:`setup_python`
+       instead of :meth:`setup_scripts`. This was not the case in 3.7.2.
+       When using symlinks, the original executables will be linked.
 
     In addition, :class:`EnvBuilder` provides this utility method that can be
     called from :meth:`setup_scripts` or :meth:`post_setup` in subclasses to
index 5c315c5161757c12187b8cb27893910b730507b7..60d19a8d5f7dc079d35723aee36d1ea30e6d2a53 100644 (file)
@@ -40,7 +40,7 @@ The :mod:`wave` module defines the following function and exception:
    the file object.
 
    The :func:`.open` function may be used in a :keyword:`with` statement.  When
-   the :keyword:`with` block completes, the :meth:`Wave_read.close()
+   the :keyword:`!with` block completes, the :meth:`Wave_read.close()
    <wave.Wave_read.close>` or :meth:`Wave_write.close()
    <wave.Wave_write.close()>` method is called.
 
index 15b1cb0cbf78f0c639d621043c34c6dc0af402c0..a37caf62a374b6c27cb805b0384c027c0f2e618a 100644 (file)
@@ -126,7 +126,7 @@ module documentation.  This section lists the differences between the API and
 
    You can avoid calling this method explicitly by using the :keyword:`with`
    statement. The following code will automatically unlink *dom* when the
-   :keyword:`with` block is exited::
+   :keyword:`!with` block is exited::
 
       with xml.dom.minidom.parse(datasource) as dom:
           ... # Work with dom.
index 6298f1396ae294de94c8ab45d11f5c51f46deb78..5f799aba994d709fa4fd1e6ca68b95cebec3309d 100644 (file)
@@ -490,10 +490,12 @@ Functions
    *elem* is an element tree or an individual element.
 
 
-.. function:: fromstring(text)
+.. function:: fromstring(text, parser=None)
 
    Parses an XML section from a string constant.  Same as :func:`XML`.  *text*
-   is a string containing XML data.  Returns an :class:`Element` instance.
+   is a string containing XML data.  *parser* is an optional parser instance.
+   If not given, the standard :class:`XMLParser` parser is used.
+   Returns an :class:`Element` instance.
 
 
 .. function:: fromstringlist(sequence, parser=None)
index e1f8b9a4a32a6ea0d65d252757a5e07b628973fb..6fb03a0e31454dc61c2e4affbfc5980b2f8c4409 100644 (file)
@@ -175,7 +175,7 @@ ZipFile Objects
 
    ZipFile is also a context manager and therefore supports the
    :keyword:`with` statement.  In the example, *myzip* is closed after the
-   :keyword:`with` statement's suite is finished---even if an exception occurs::
+   :keyword:`!with` statement's suite is finished---even if an exception occurs::
 
       with ZipFile('spam.zip', 'w') as myzip:
           myzip.write('eggs.txt')
index 5f78240002f801c1a6ab3af1ff5e5a2fd144aeab..a315b6f8134d48bc5a34b8a9978ed3f18145e43b 100644 (file)
@@ -87,7 +87,7 @@ PSF LICENSE AGREEMENT FOR PYTHON |release|
       analyze, test, perform and/or display publicly, prepare derivative works,
       distribute, and otherwise use Python |release| alone or in any derivative
       version, provided, however, that PSF's License Agreement and PSF's notice of
-      copyright, i.e., "Copyright © 2001-2018 Python Software Foundation; All Rights
+      copyright, i.e., "Copyright © 2001-2019 Python Software Foundation; All Rights
       Reserved" are retained in Python |release| alone or in any derivative version
       prepared by Licensee.
 
index 34b8bf7b32d4bfca2c1dec924cf0a24d3bdbf7d0..8701d20111d0eb80a998d6aa906cb7f06af38039 100644 (file)
@@ -41,7 +41,7 @@ if exist "%HTMLHELP%" goto :skiphhcsearch
 \r
 rem Search for HHC in likely places\r
 set HTMLHELP=\r
-where hhc /q && set HTMLHELP=hhc && goto :skiphhcsearch\r
+where hhc /q && set "HTMLHELP=hhc" && goto :skiphhcsearch\r
 where /R ..\externals hhc > "%TEMP%\hhc.loc" 2> nul && set /P HTMLHELP= < "%TEMP%\hhc.loc" & del "%TEMP%\hhc.loc"\r
 if not exist "%HTMLHELP%" where /R "%ProgramFiles(x86)%" hhc > "%TEMP%\hhc.loc" 2> nul && set /P HTMLHELP= < "%TEMP%\hhc.loc" & del "%TEMP%\hhc.loc"\r
 if not exist "%HTMLHELP%" where /R "%ProgramFiles%" hhc > "%TEMP%\hhc.loc" 2> nul && set /P HTMLHELP= < "%TEMP%\hhc.loc" & del "%TEMP%\hhc.loc"\r
index f98785a5780d42ce29b79962b10de6272accc29e..1d84274b7996536f30fea8bb9a2a49d5ff53d61d 100644 (file)
@@ -78,11 +78,11 @@ on a separate line for clarity.
 .. _elif:
 .. _else:
 
-The :keyword:`if` statement
-===========================
+The :keyword:`!if` statement
+============================
 
 .. index::
-   statement: if
+   statement: if
    keyword: elif
    keyword: else
    single: : (colon); compound statement
@@ -103,14 +103,13 @@ false, the suite of the :keyword:`else` clause, if present, is executed.
 
 .. _while:
 
-The :keyword:`while` statement
-==============================
+The :keyword:`!while` statement
+===============================
 
 .. index::
-   statement: while
+   statement: while
    keyword: else
    pair: loop; statement
-   keyword: else
    single: : (colon); compound statement
 
 The :keyword:`while` statement is used for repeated execution as long as an
@@ -122,7 +121,7 @@ expression is true:
 
 This repeatedly tests the expression and, if it is true, executes the first
 suite; if the expression is false (which may be the first time it is tested) the
-suite of the :keyword:`else` clause, if present, is executed and the loop
+suite of the :keyword:`!else` clause, if present, is executed and the loop
 terminates.
 
 .. index::
@@ -130,25 +129,22 @@ terminates.
    statement: continue
 
 A :keyword:`break` statement executed in the first suite terminates the loop
-without executing the :keyword:`else` clause's suite.  A :keyword:`continue`
+without executing the :keyword:`!else` clause's suite.  A :keyword:`continue`
 statement executed in the first suite skips the rest of the suite and goes back
 to testing the expression.
 
 
 .. _for:
 
-The :keyword:`for` statement
-============================
+The :keyword:`!for` statement
+=============================
 
 .. index::
-   statement: for
+   statement: for
    keyword: in
    keyword: else
    pair: target; list
    pair: loop; statement
-   keyword: in
-   keyword: else
-   pair: target; list
    object: sequence
    single: : (colon); compound statement
 
@@ -166,16 +162,16 @@ by the iterator.  Each item in turn is assigned to the target list using the
 standard rules for assignments (see :ref:`assignment`), and then the suite is
 executed.  When the items are exhausted (which is immediately when the sequence
 is empty or an iterator raises a :exc:`StopIteration` exception), the suite in
-the :keyword:`else` clause, if present, is executed, and the loop terminates.
+the :keyword:`!else` clause, if present, is executed, and the loop terminates.
 
 .. index::
    statement: break
    statement: continue
 
 A :keyword:`break` statement executed in the first suite terminates the loop
-without executing the :keyword:`else` clause's suite.  A :keyword:`continue`
+without executing the :keyword:`!else` clause's suite.  A :keyword:`continue`
 statement executed in the first suite skips the rest of the suite and continues
-with the next item, or with the :keyword:`else` clause if there is no next
+with the next item, or with the :keyword:`!else` clause if there is no next
 item.
 
 The for-loop makes assignments to the variables(s) in the target list.
@@ -224,11 +220,11 @@ returns the list ``[0, 1, 2]``.
 .. _except:
 .. _finally:
 
-The :keyword:`try` statement
-============================
+The :keyword:`!try` statement
+=============================
 
 .. index::
-   statement: try
+   statement: try
    keyword: except
    keyword: finally
    keyword: else
@@ -250,7 +246,7 @@ for a group of statements:
 
 The :keyword:`except` clause(s) specify one or more exception handlers. When no
 exception occurs in the :keyword:`try` clause, no exception handler is executed.
-When an exception occurs in the :keyword:`try` suite, a search for an exception
+When an exception occurs in the :keyword:`!try` suite, a search for an exception
 handler is started.  This search inspects the except clauses in turn until one
 is found that matches the exception.  An expression-less except clause, if
 present, must be last; it matches any exception.  For an except clause with an
@@ -270,7 +266,7 @@ as if the entire :keyword:`try` statement raised the exception).
 .. index:: single: as; except clause
 
 When a matching except clause is found, the exception is assigned to the target
-specified after the :keyword:`as` keyword in that except clause, if present, and
+specified after the :keyword:`!as` keyword in that except clause, if present, and
 the except clause's suite is executed.  All except clauses must have an
 executable block.  When the end of this block is reached, execution continues
 normally after the entire try statement.  (This means that if two nested
@@ -314,22 +310,22 @@ from a function that handled an exception.
    statement: break
    statement: continue
 
-The optional :keyword:`else` clause is executed if the control flow leaves the
+The optional :keyword:`!else` clause is executed if the control flow leaves the
 :keyword:`try` suite, no exception was raised, and no :keyword:`return`,
 :keyword:`continue`, or :keyword:`break` statement was executed.  Exceptions in
-the :keyword:`else` clause are not handled by the preceding :keyword:`except`
+the :keyword:`!else` clause are not handled by the preceding :keyword:`except`
 clauses.
 
 .. index:: keyword: finally
 
 If :keyword:`finally` is present, it specifies a 'cleanup' handler.  The
 :keyword:`try` clause is executed, including any :keyword:`except` and
-:keyword:`else` clauses.  If an exception occurs in any of the clauses and is
-not handled, the exception is temporarily saved. The :keyword:`finally` clause
+:keyword:`!else` clauses.  If an exception occurs in any of the clauses and is
+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
+: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`
+If the :keyword:`!finally` clause executes a :keyword:`return` or :keyword:`break`
 statement, the saved exception is discarded::
 
    >>> def f():
@@ -350,15 +346,15 @@ the :keyword:`finally` clause.
    statement: continue
 
 When a :keyword:`return`, :keyword:`break` or :keyword:`continue` statement is
-executed in the :keyword:`try` suite of a :keyword:`try`...\ :keyword:`finally`
+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
+: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).
 
 The return value of a function is determined by the last :keyword:`return`
 statement executed.  Since the :keyword:`finally` clause always executes, a
-:keyword:`return` statement executed in the :keyword:`finally` clause will
+:keyword:`!return` statement executed in the :keyword:`!finally` clause will
 always be the last one executed::
 
    >>> def foo():
@@ -378,11 +374,11 @@ may be found in section :ref:`raise`.
 .. _with:
 .. _as:
 
-The :keyword:`with` statement
-=============================
+The :keyword:`!with` statement
+==============================
 
 .. index::
-   statement: with
+   statement: with
    keyword: as
    single: as; with statement
    single: , (comma); with statement
@@ -574,8 +570,8 @@ used keyword arguments.
    single: ->; function annotations
    single: : (colon); function annotations
 
-Parameters may have annotations of the form "``: expression``" following the
-parameter name.  Any parameter may have an annotation even those of the form
+Parameters may have an :term:`annotation <function annotation>` of the form "``: expression``"
+following the parameter name.  Any parameter may have an annotation, even those of the form
 ``*identifier`` or ``**identifier``.  Functions may have "return" annotation of
 the form "``-> expression``" after the parameter list.  These annotations can be
 any valid Python expression.  The presence of annotations does not change the
@@ -594,7 +590,7 @@ name), for immediate use in expressions.  This uses lambda expressions, describe
 section :ref:`lambda`.  Note that the lambda expression is merely a shorthand for a
 simplified function definition; a function defined in a ":keyword:`def`"
 statement can be passed around or assigned to another name just like a function
-defined by a lambda expression.  The ":keyword:`def`" form is actually more powerful
+defined by a lambda expression.  The ":keyword:`!def`" form is actually more powerful
 since it allows the execution of multiple statements and annotations.
 
 **Programmer's note:** Functions are first-class objects.  A "``def``" statement
@@ -757,8 +753,8 @@ An example of a coroutine function::
 .. index:: statement: async for
 .. _`async for`:
 
-The :keyword:`async for` statement
-----------------------------------
+The :keyword:`!async for` statement
+-----------------------------------
 
 .. productionlist::
    async_for_stmt: "async" `for_stmt`
@@ -801,8 +797,8 @@ body of a coroutine function.
 .. index:: statement: async with
 .. _`async with`:
 
-The :keyword:`async with` statement
------------------------------------
+The :keyword:`!async with` statement
+------------------------------------
 
 .. productionlist::
    async_with_stmt: "async" `with_stmt`
index e6fa8a0d2a6fe0a08b7a833e31fa3635c045d8ab..22c9b4153e205d51add8a4ef2f6dc5868fcccc68 100644 (file)
@@ -620,7 +620,7 @@ Callable types
       called, always returns an iterator object which can be used to execute the
       body of the function:  calling the iterator's :meth:`iterator.__next__`
       method will cause the function to execute until it provides a value
-      using the :keyword:`yield` statement.  When the function executes a
+      using the :keyword:`!yield` statement.  When the function executes a
       :keyword:`return` statement or falls off the end, a :exc:`StopIteration`
       exception is raised and the iterator will have reached the end of the set of
       values to be returned.
@@ -700,7 +700,7 @@ Modules
 
    Modules are a basic organizational unit of Python code, and are created by
    the :ref:`import system <importsystem>` as invoked either by the
-   :keyword:`import` statement (see :keyword:`import`), or by calling
+   :keyword:`import` statement, or by calling
    functions such as :func:`importlib.import_module` and built-in
    :func:`__import__`.  A module object has a namespace implemented by a
    dictionary object (this is the dictionary referenced by the ``__globals__``
@@ -1725,6 +1725,7 @@ properties) and deny the creation of *__dict__* and *__weakref__*
 (unless explicitly declared in *__slots__* or available in a parent.)
 
 The space saved over using *__dict__* can be significant.
+Attribute lookup speed can be significantly improved as well.
 
 .. data:: object.__slots__
 
@@ -2424,7 +2425,7 @@ A :dfn:`context manager` is an object that defines the runtime context to be
 established when executing a :keyword:`with` statement. The context manager
 handles the entry into, and the exit from, the desired runtime context for the
 execution of the block of code.  Context managers are normally invoked using the
-:keyword:`with` statement (described in section :ref:`with`), but can also be
+:keyword:`!with` statement (described in section :ref:`with`), but can also be
 used by directly invoking their methods.
 
 .. index::
@@ -2441,7 +2442,7 @@ For more information on context managers, see :ref:`typecontextmanager`.
 
    Enter the runtime context related to this object. The :keyword:`with` statement
    will bind this method's return value to the target(s) specified in the
-   :keyword:`as` clause of the statement, if any.
+   :keyword:`!as` clause of the statement, if any.
 
 
 .. method:: object.__exit__(self, exc_type, exc_value, traceback)
index 1a69e972f2cb7db6d9b7103d5da48e59975a35f6..ba7130d6362163620e73a695cab83ad7a7b42bd7 100644 (file)
@@ -58,8 +58,8 @@ The following constructs bind names: formal parameters to functions,
 :keyword:`import` statements, class and function definitions (these bind the
 class or function name in the defining block), and targets that are identifiers
 if occurring in an assignment, :keyword:`for` loop header, or after
-:keyword:`as` in a :keyword:`with` statement or :keyword:`except` clause.
-The :keyword:`import` statement
+:keyword:`!as` in a :keyword:`with` statement or :keyword:`except` clause.
+The :keyword:`!import` statement
 of the form ``from ... import *`` binds all names defined in the imported
 module, except those beginning with an underscore.  This form may only be used
 at the module level.
@@ -123,7 +123,7 @@ namespace.  Names are resolved in the top-level namespace by searching the
 global namespace, i.e. the namespace of the module containing the code block,
 and the builtins namespace, the namespace of the module :mod:`builtins`.  The
 global namespace is searched first.  If the name is not found there, the
-builtins namespace is searched.  The :keyword:`global` statement must precede
+builtins namespace is searched.  The :keyword:`!global` statement must precede
 all uses of the name.
 
 The :keyword:`global` statement has the same scope as a name binding operation
index 3e7db901b849154ed0ca7f8047445bbad18f43e2..d7da7ad4b8b219a609f24ae65d55e9a2fe793fa3 100644 (file)
@@ -185,20 +185,20 @@ Common syntax elements for comprehensions are:
    comp_if: "if" `expression_nocond` [`comp_iter`]
 
 The comprehension consists of a single expression followed by at least one
-:keyword:`for` clause and zero or more :keyword:`for` or :keyword:`if` clauses.
+:keyword:`!for` clause and zero or more :keyword:`!for` or :keyword:`!if` clauses.
 In this case, the elements of the new container are those that would be produced
-by considering each of the :keyword:`for` or :keyword:`if` clauses a block,
+by considering each of the :keyword:`!for` or :keyword:`!if` clauses a block,
 nesting from left to right, and evaluating the expression to produce an element
 each time the innermost block is reached.
 
-However, aside from the iterable expression in the leftmost :keyword:`for` clause,
+However, aside from the iterable expression in the leftmost :keyword:`!for` clause,
 the comprehension is executed in a separate implicitly nested scope. This ensures
 that names assigned to in the target list don't "leak" into the enclosing scope.
 
-The iterable expression in the leftmost :keyword:`for` clause is evaluated
+The iterable expression in the leftmost :keyword:`!for` clause is evaluated
 directly in the enclosing scope and then passed as an argument to the implictly
-nested scope. Subsequent :keyword:`for` clauses and any filter condition in the
-leftmost :keyword:`for` clause cannot be evaluated in the enclosing scope as
+nested scope. Subsequent :keyword:`!for` clauses and any filter condition in the
+leftmost :keyword:`!for` clause cannot be evaluated in the enclosing scope as
 they may depend on the values obtained from the leftmost iterable. For example:
 ``[x*y for x in range(10) for y in range(x, x+10)]``.
 
@@ -210,14 +210,14 @@ when compiled, in Python 3.8+ they will emit :exc:`SyntaxError`).
 .. index::
    single: await; in comprehensions
 
-Since Python 3.6, in an :keyword:`async def` function, an :keyword:`async for`
+Since Python 3.6, in an :keyword:`async def` function, an :keyword:`!async for`
 clause may be used to iterate over a :term:`asynchronous iterator`.
-A comprehension in an :keyword:`async def` function may consist of either a
-:keyword:`for` or :keyword:`async for` clause following the leading
-expression, may contain additional :keyword:`for` or :keyword:`async for`
+A comprehension in an :keyword:`!async def` function may consist of either a
+:keyword:`!for` or :keyword:`!async for` clause following the leading
+expression, may contain additional :keyword:`!for` or :keyword:`!async for`
 clauses, and may also use :keyword:`await` expressions.
-If a comprehension contains either :keyword:`async for` clauses
-or :keyword:`await` expressions it is called an
+If a comprehension contains either :keyword:`!async for` clauses
+or :keyword:`!await` expressions it is called an
 :dfn:`asynchronous comprehension`.  An asynchronous comprehension may
 suspend the execution of the coroutine function in which it appears.
 See also :pep:`530`.
@@ -361,11 +361,11 @@ brackets or curly braces.
 Variables used in the generator expression are evaluated lazily when the
 :meth:`~generator.__next__` method is called for the generator object (in the same
 fashion as normal generators).  However, the iterable expression in the
-leftmost :keyword:`for` clause is immediately evaluated, so that an error
+leftmost :keyword:`!for` clause is immediately evaluated, so that an error
 produced by it will be emitted at the point where the generator expression
 is defined, rather than at the point where the first value is retrieved.
-Subsequent :keyword:`for` clauses and any filter condition in the leftmost
-:keyword:`for` clause cannot be evaluated in the enclosing scope as they may
+Subsequent :keyword:`!for` clauses and any filter condition in the leftmost
+:keyword:`!for` clause cannot be evaluated in the enclosing scope as they may
 depend on the values obtained from the leftmost iterable. For example:
 ``(x*y for x in range(10) for y in range(x, x+10))``.
 
@@ -378,7 +378,7 @@ implicitly defined generator (in Python 3.7, such expressions emit
 :exc:`DeprecationWarning` when compiled, in Python 3.8+ they will emit
 :exc:`SyntaxError`).
 
-If a generator expression contains either :keyword:`async for`
+If a generator expression contains either :keyword:`!async for`
 clauses or :keyword:`await` expressions it is called an
 :dfn:`asynchronous generator expression`.  An asynchronous generator
 expression returns a new asynchronous generator object,
@@ -642,12 +642,12 @@ that method.
 In an asynchronous generator function, yield expressions are allowed anywhere
 in a :keyword:`try` construct. However, if an asynchronous generator is not
 resumed before it is finalized (by reaching a zero reference count or by
-being garbage collected), then a yield expression within a :keyword:`try`
+being garbage collected), then a yield expression within a :keyword:`!try`
 construct could result in a failure to execute pending :keyword:`finally`
 clauses.  In this case, it is the responsibility of the event loop or
 scheduler running the asynchronous generator to call the asynchronous
 generator-iterator's :meth:`~agen.aclose` method and run the resulting
-coroutine object, thus allowing any pending :keyword:`finally` clauses
+coroutine object, thus allowing any pending :keyword:`!finally` clauses
 to execute.
 
 To take care of finalization, an event loop should define
@@ -1553,7 +1553,7 @@ Membership test operations
 The operators :keyword:`in` and :keyword:`not in` test for membership.  ``x in
 s`` evaluates to ``True`` if *x* is a member of *s*, and ``False`` otherwise.
 ``x not in s`` returns the negation of ``x in s``.  All built-in sequences and
-set types support this as well as dictionary, for which :keyword:`in` tests
+set types support this as well as dictionary, for which :keyword:`!in` tests
 whether the dictionary has a given key. For container types such as list, tuple,
 set, frozenset, dict, or collections.deque, the expression ``x in y`` is equivalent
 to ``any(x is e or x == e for e in y)``.
@@ -1653,6 +1653,8 @@ returns a boolean value regardless of the type of its argument
 (for example, ``not 'foo'`` produces ``False`` rather than ``''``.)
 
 
+.. _if_expr:
+
 Conditional expressions
 =======================
 
@@ -1795,7 +1797,7 @@ precedence and have a left-to-right chaining feature as described in the
 +===============================================+=====================================+
 | :keyword:`lambda`                             | Lambda expression                   |
 +-----------------------------------------------+-------------------------------------+
-| :keyword:`if` -- :keyword:`else`              | Conditional expression              |
+| :keyword:`if <if_expr>` -- :keyword:`!else`   | Conditional expression              |
 +-----------------------------------------------+-------------------------------------+
 | :keyword:`or`                                 | Boolean OR                          |
 +-----------------------------------------------+-------------------------------------+
index d36d7d6a707ebf0a7afd1908db785c38d12e79c9..9a0ab39d3b4a3ef8f2c458d4ea7090f1b8b02c9e 100644 (file)
@@ -15,11 +15,11 @@ way.  Functions such as :func:`importlib.import_module` and built-in
 
 The :keyword:`import` statement combines two operations; it searches for the
 named module, then it binds the results of that search to a name in the local
-scope.  The search operation of the :keyword:`import` statement is defined as
+scope.  The search operation of the :keyword:`!import` statement is defined as
 a call to the :func:`__import__` function, with the appropriate arguments.
 The return value of :func:`__import__` is used to perform the name
-binding operation of the :keyword:`import` statement.  See the
-:keyword:`import` statement for the exact details of that name binding
+binding operation of the :keyword:`!import` statement.  See the
+:keyword:`!import` statement for the exact details of that name binding
 operation.
 
 A direct call to :func:`__import__` performs only the module search and, if
index 33ae0512830d043b8aa22c789eb2e09d0a08e425..07072d954384060e599ea1f35fa75726708b17fa 100644 (file)
@@ -325,8 +325,8 @@ Annotated assignment statements
    single: statement; assignment, annotated
    single: : (colon); annotated variable
 
-Annotation assignment is the combination, in a single statement,
-of a variable or attribute annotation and an optional assignment statement:
+:term:`Annotation <variable annotation>` assignment is the combination, in a single
+statement, of a variable or attribute annotation and an optional assignment statement:
 
 .. productionlist::
    annotated_assignment_stmt: `augtarget` ":" `expression` ["=" `expression`]
@@ -369,11 +369,11 @@ target, then the interpreter evaluates the target except for the last
 
 .. _assert:
 
-The :keyword:`assert` statement
-===============================
+The :keyword:`!assert` statement
+================================
 
 .. index::
-   statement: assert
+   statement: assert
    pair: debugging; assertions
    single: , (comma); expression list
 
@@ -412,8 +412,8 @@ is determined when the interpreter starts.
 
 .. _pass:
 
-The :keyword:`pass` statement
-=============================
+The :keyword:`!pass` statement
+==============================
 
 .. index::
    statement: pass
@@ -434,11 +434,11 @@ code needs to be executed, for example::
 
 .. _del:
 
-The :keyword:`del` statement
-============================
+The :keyword:`!del` statement
+=============================
 
 .. index::
-   statement: del
+   statement: del
    pair: deletion; target
    triple: deletion; target; list
 
@@ -473,11 +473,11 @@ the sliced object).
 
 .. _return:
 
-The :keyword:`return` statement
-===============================
+The :keyword:`!return` statement
+================================
 
 .. index::
-   statement: return
+   statement: return
    pair: function; definition
    pair: class; definition
 
@@ -495,7 +495,7 @@ If an expression list is present, it is evaluated, else ``None`` is substituted.
 .. index:: keyword: finally
 
 When :keyword:`return` passes control out of a :keyword:`try` statement with a
-:keyword:`finally` clause, that :keyword:`finally` clause is executed before
+:keyword:`finally` clause, that :keyword:`!finally` clause is executed before
 really leaving the function.
 
 In a generator function, the :keyword:`return` statement indicates that the
@@ -505,13 +505,13 @@ becomes the :attr:`StopIteration.value` attribute.
 
 In an asynchronous generator function, an empty :keyword:`return` statement
 indicates that the asynchronous generator is done and will cause
-:exc:`StopAsyncIteration` to be raised.  A non-empty :keyword:`return`
+:exc:`StopAsyncIteration` to be raised.  A non-empty :keyword:`!return`
 statement is a syntax error in an asynchronous generator function.
 
 .. _yield:
 
-The :keyword:`yield` statement
-==============================
+The :keyword:`!yield` statement
+===============================
 
 .. index::
    statement: yield
@@ -546,11 +546,11 @@ For full details of :keyword:`yield` semantics, refer to the
 
 .. _raise:
 
-The :keyword:`raise` statement
-==============================
+The :keyword:`!raise` statement
+===============================
 
 .. index::
-   statement: raise
+   statement: raise
    single: exception
    pair: raising; exception
    single: __traceback__ (exception attribute)
@@ -649,11 +649,11 @@ and information about handling exceptions is in section :ref:`try`.
 
 .. _break:
 
-The :keyword:`break` statement
-==============================
+The :keyword:`!break` statement
+===============================
 
 .. index::
-   statement: break
+   statement: break
    statement: for
    statement: while
    pair: loop; statement
@@ -668,7 +668,7 @@ that loop.
 .. index:: keyword: else
            pair: loop control; target
 
-It terminates the nearest enclosing loop, skipping the optional :keyword:`else`
+It terminates the nearest enclosing loop, skipping the optional :keyword:`!else`
 clause if the loop has one.
 
 If a :keyword:`for` loop is terminated by :keyword:`break`, the loop control
@@ -677,17 +677,17 @@ target keeps its current value.
 .. index:: keyword: finally
 
 When :keyword:`break` passes control out of a :keyword:`try` statement with a
-:keyword:`finally` clause, that :keyword:`finally` clause is executed before
+:keyword:`finally` clause, that :keyword:`!finally` clause is executed before
 really leaving the loop.
 
 
 .. _continue:
 
-The :keyword:`continue` statement
-=================================
+The :keyword:`!continue` statement
+==================================
 
 .. index::
-   statement: continue
+   statement: continue
    statement: for
    statement: while
    pair: loop; statement
@@ -702,18 +702,18 @@ The :keyword:`continue` statement
 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
+:keyword:`finally` clause, that :keyword:`!finally` clause is executed before
 really starting the next loop cycle.
 
 
 .. _import:
 .. _from:
 
-The :keyword:`import` statement
-===============================
+The :keyword:`!import` statement
+================================
 
 .. index::
-   statement: import
+   statement: import
    single: module; importing
    pair: name; binding
    keyword: from
@@ -756,8 +756,8 @@ available in the local namespace in one of three ways:
 
 .. index:: single: as; import statement
 
-* If the module name is followed by :keyword:`as`, then the name
-  following :keyword:`as` is bound directly to the imported module.
+* If the module name is followed by :keyword:`!as`, then the name
+  following :keyword:`!as` is bound directly to the imported module.
 * If no other name is specified, and the module being imported is a top
   level module, the module's name is bound in the local namespace as a
   reference to the imported module
@@ -782,7 +782,7 @@ The :keyword:`from` form uses a slightly more complex process:
       check the imported module again for that attribute
    #. if the attribute is not found, :exc:`ImportError` is raised.
    #. otherwise, a reference to that value is stored in the local namespace,
-      using the name in the :keyword:`as` clause if it is present,
+      using the name in the :keyword:`!as` clause if it is present,
       otherwise using the attribute name
 
 Examples::
@@ -923,11 +923,11 @@ after the script is executed.
 
 .. _global:
 
-The :keyword:`global` statement
-===============================
+The :keyword:`!global` statement
+================================
 
 .. index::
-   statement: global
+   statement: global
    triple: global; name; binding
    single: , (comma); identifier list
 
@@ -937,11 +937,11 @@ The :keyword:`global` statement
 The :keyword:`global` statement is a declaration which holds for the entire
 current code block.  It means that the listed identifiers are to be interpreted
 as globals.  It would be impossible to assign to a global variable without
-:keyword:`global`, although free variables may refer to globals without being
+:keyword:`!global`, although free variables may refer to globals without being
 declared global.
 
 Names listed in a :keyword:`global` statement must not be used in the same code
-block textually preceding that :keyword:`global` statement.
+block textually preceding that :keyword:`!global` statement.
 
 Names listed in a :keyword:`global` statement must not be defined as formal
 parameters or in a :keyword:`for` loop control target, :keyword:`class`
@@ -960,18 +960,18 @@ annotation.
    builtin: compile
 
 **Programmer's note:** :keyword:`global` is a directive to the parser.  It
-applies only to code parsed at the same time as the :keyword:`global` statement.
-In particular, a :keyword:`global` statement contained in a string or code
+applies only to code parsed at the same time as the :keyword:`!global` statement.
+In particular, a :keyword:`!global` statement contained in a string or code
 object supplied to the built-in :func:`exec` function does not affect the code
 block *containing* the function call, and code contained in such a string is
-unaffected by :keyword:`global` statements in the code containing the function
+unaffected by :keyword:`!global` statements in the code containing the function
 call.  The same applies to the :func:`eval` and :func:`compile` functions.
 
 
 .. _nonlocal:
 
-The :keyword:`nonlocal` statement
-=================================
+The :keyword:`!nonlocal` statement
+==================================
 
 .. index:: statement: nonlocal
    single: , (comma); identifier list
index baa39f3b44646ad5f55fd95766ba04be5fd1a9c5..fa8244a8fd318e9b68cb3178f5e2eba51788f51c 100644 (file)
@@ -87,7 +87,7 @@ class Annotations(dict):
             entry = self.get(name)
             if not entry:
                 continue
-            elif entry.result_type not in ("PyObject*", "PyVarObject*"):
+            elif not entry.result_type.endswith("Object*"):
                 continue
             if entry.result_refs is None:
                 rc = 'Return value: Always NULL.'
index e69e9a305425f643b27203bc35aaa1924ae90518..1181f7179c6c6805149d97dae5e11c1bc7445dbc 100644 (file)
@@ -4,7 +4,7 @@
 <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.6/">{% trans %}Python 3.6 (security-fixes){% 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>
   <li><a href="https://www.python.org/doc/versions/">{% trans %}All versions{% endtrans %}</a></li>
index 914da426df3616b7a04a724d6358ba9925993c3d..2538c3106187030aea234dcdb95b750bc4b0161f 100644 (file)
@@ -783,7 +783,7 @@ calls :func:`iter` on the container object.  The function returns an iterator
 object that defines the method :meth:`~iterator.__next__` which accesses
 elements in the container one at a time.  When there are no more elements,
 :meth:`~iterator.__next__` raises a :exc:`StopIteration` exception which tells the
-:keyword:`for` loop to terminate.  You can call the :meth:`~iterator.__next__` method
+:keyword:`!for` loop to terminate.  You can call the :meth:`~iterator.__next__` method
 using the :func:`next` built-in function; this example shows how it all works::
 
    >>> s = 'abc'
index bf6fbe21a7f710cf955ad3ffeec4f5dd3cbd5f56..905734539c685171f51f212dd08154c856e02293 100644 (file)
@@ -10,8 +10,8 @@ control flow statements known from other languages, with some twists.
 
 .. _tut-if:
 
-:keyword:`if` Statements
-========================
+:keyword:`!if` Statements
+=========================
 
 Perhaps the most well-known statement type is the :keyword:`if` statement.  For
 example::
@@ -31,16 +31,16 @@ example::
    More
 
 There can be zero or more :keyword:`elif` parts, and the :keyword:`else` part is
-optional.  The keyword ':keyword:`elif`' is short for 'else if', and is useful
-to avoid excessive indentation.  An  :keyword:`if` ... :keyword:`elif` ...
-:keyword:`elif` ... sequence is a substitute for the ``switch`` or
+optional.  The keyword ':keyword:`!elif`' is short for 'else if', and is useful
+to avoid excessive indentation.  An  :keyword:`!if` ... :keyword:`!elif` ...
+:keyword:`!elif` ... sequence is a substitute for the ``switch`` or
 ``case`` statements found in other languages.
 
 
 .. _tut-for:
 
-:keyword:`for` Statements
-=========================
+:keyword:`!for` Statements
+==========================
 
 .. index::
    statement: for
@@ -48,7 +48,7 @@ to avoid excessive indentation.  An  :keyword:`if` ... :keyword:`elif` ...
 The :keyword:`for` statement in Python differs a bit from what you may be used
 to in C or Pascal.  Rather than always iterating over an arithmetic progression
 of numbers (like in Pascal), or giving the user the ability to define both the
-iteration step and halting condition (as C), Python's :keyword:`for` statement
+iteration step and halting condition (as C), Python's :keyword:`!for` statement
 iterates over the items of any sequence (a list or a string), in the order that
 they appear in the sequence.  For example (no pun intended):
 
@@ -154,13 +154,13 @@ Later we will see more functions that return iterables and take iterables as arg
 
 .. _tut-break:
 
-:keyword:`break` and :keyword:`continue` Statements, and :keyword:`else` Clauses on Loops
-=========================================================================================
+:keyword:`!break` and :keyword:`!continue` Statements, and :keyword:`!else` Clauses on Loops
+============================================================================================
 
 The :keyword:`break` statement, like in C, breaks out of the innermost enclosing
 :keyword:`for` or :keyword:`while` loop.
 
-Loop statements may have an ``else`` clause; it is executed when the loop
+Loop statements may have an :keyword:`!else` clause; it is executed when the loop
 terminates through exhaustion of the list (with :keyword:`for`) or when the
 condition becomes false (with :keyword:`while`), but not when the loop is
 terminated by a :keyword:`break` statement.  This is exemplified by the
@@ -189,9 +189,9 @@ the :keyword:`for` loop, **not** the :keyword:`if` statement.)
 
 When used with a loop, the ``else`` clause has more in common with the
 ``else`` clause of a :keyword:`try` statement than it does that of
-:keyword:`if` statements: a :keyword:`try` statement's ``else`` clause runs
+:keyword:`if` statements: a :keyword:`!try` statement's ``else`` clause runs
 when no exception occurs, and a loop's ``else`` clause runs when no ``break``
-occurs. For more on the :keyword:`try` statement and exceptions, see
+occurs. For more on the :keyword:`!try` statement and exceptions, see
 :ref:`tut-handling`.
 
 The :keyword:`continue` statement, also borrowed from C, continues with the next
@@ -213,8 +213,8 @@ iteration of the loop::
 
 .. _tut-pass:
 
-:keyword:`pass` Statements
-==========================
+:keyword:`!pass` Statements
+===========================
 
 The :keyword:`pass` statement does nothing. It can be used when a statement is
 required syntactically but the program requires no action. For example::
@@ -231,7 +231,7 @@ This is commonly used for creating minimal classes::
 
 Another place :keyword:`pass` can be used is as a place-holder for a function or
 conditional body when you are working on new code, allowing you to keep thinking
-at a more abstract level.  The :keyword:`pass` is silently ignored::
+at a more abstract level.  The :keyword:`!pass` is silently ignored::
 
    >>> def initlog(*args):
    ...     pass   # Remember to implement this!
@@ -331,7 +331,7 @@ Fibonacci series, instead of printing it::
 This example, as usual, demonstrates some new Python features:
 
 * The :keyword:`return` statement returns with a value from a function.
-  :keyword:`return` without an expression argument returns ``None``. Falling off
+  :keyword:`!return` without an expression argument returns ``None``. Falling off
   the end of a function also returns ``None``.
 
 * The statement ``result.append(a)`` calls a *method* of the list object
@@ -682,10 +682,10 @@ Function Annotations
 information about the types used by user-defined functions (see :pep:`3107` and
 :pep:`484` for more information).
 
-Annotations are stored in the :attr:`__annotations__` attribute of the function
-as a dictionary and have no effect on any other part of the function.  Parameter
-annotations are defined by a colon after the parameter name, followed by an
-expression evaluating to the value of the annotation.  Return annotations are
+:term:`Annotations <function annotation>` are stored in the :attr:`__annotations__`
+attribute of the function as a dictionary and have no effect on any other part of the
+function.  Parameter annotations are defined by a colon after the parameter name, followed
+by an expression evaluating to the value of the annotation.  Return annotations are
 defined by a literal ``->``, followed by an expression, between the parameter
 list and the colon denoting the end of the :keyword:`def` statement.  The
 following example has a positional argument, a keyword argument, and the return
index b291d11595a89b7fd6bb790c0eca29e7f48d79b5..b4db3f01591215cf4e71ae1744d287e51ab9e37d 100644 (file)
@@ -216,9 +216,9 @@ or, equivalently::
 which is more concise and readable.
 
 A list comprehension consists of brackets containing an expression followed
-by a :keyword:`for` clause, then zero or more :keyword:`for` or :keyword:`if`
+by a :keyword:`!for` clause, then zero or more :keyword:`!for` or :keyword:`!if`
 clauses.  The result will be a new list resulting from evaluating the expression
-in the context of the :keyword:`for` and :keyword:`if` clauses which follow it.
+in the context of the :keyword:`!for` and :keyword:`!if` clauses which follow it.
 For example, this listcomp combines the elements of two lists if they are not
 equal::
 
@@ -330,12 +330,12 @@ See :ref:`tut-unpacking-arguments` for details on the asterisk in this line.
 
 .. _tut-del:
 
-The :keyword:`del` statement
-============================
+The :keyword:`!del` statement
+=============================
 
 There is a way to remove an item from a list given its index instead of its
 value: the :keyword:`del` statement.  This differs from the :meth:`pop` method
-which returns a value.  The :keyword:`del` statement can also be used to remove
+which returns a value.  The :keyword:`!del` statement can also be used to remove
 slices from a list or clear the entire list (which we did earlier by assignment
 of an empty list to the slice).  For example::
 
index 957cbf962b203f2ea8f35a28c550c2c65d79179d..4e287bbd8d29ff45adcf6e2404047798d4928f71 100644 (file)
@@ -114,7 +114,7 @@ The :keyword:`try` statement works as follows.
 A :keyword:`try` statement may have more than one except clause, to specify
 handlers for different exceptions.  At most one handler will be executed.
 Handlers only handle exceptions that occur in the corresponding try clause, not
-in other handlers of the same :keyword:`try` statement.  An except clause may
+in other handlers of the same :keyword:`!try` statement.  An except clause may
 name multiple exceptions as a parenthesized tuple, for example::
 
    ... except (RuntimeError, TypeError, NameError):
@@ -180,10 +180,10 @@ example::
            print(arg, 'has', len(f.readlines()), 'lines')
            f.close()
 
-The use of the :keyword:`else` clause is better than adding additional code to
+The use of the :keyword:`!else` clause is better than adding additional code to
 the :keyword:`try` clause because it avoids accidentally catching an exception
-that wasn't raised by the code being protected by the :keyword:`try` ...
-:keyword:`except` statement.
+that wasn't raised by the code being protected by the :keyword:`!try` ...
+:keyword:`!except` statement.
 
 When an exception occurs, it may have an associated value, also known as the
 exception's *argument*. The presence and type of the argument depend on the
@@ -343,11 +343,11 @@ example::
 
 A *finally clause* is always executed before leaving the :keyword:`try`
 statement, whether an exception has occurred or not. When an exception has
-occurred in the :keyword:`try` clause and has not been handled by an
-:keyword:`except` clause (or it has occurred in an :keyword:`except` or
-:keyword:`else` clause), it is re-raised after the :keyword:`finally` clause has
-been executed.  The :keyword:`finally` clause is also executed "on the way out"
-when any other clause of the :keyword:`try` statement is left via a
+occurred in the :keyword:`!try` clause and has not been handled by an
+:keyword:`except` clause (or it has occurred in an :keyword:`!except` or
+:keyword:`!else` clause), it is re-raised after the :keyword:`finally` clause has
+been executed.  The :keyword:`!finally` clause is also executed "on the way out"
+when any other clause of the :keyword:`!try` statement is left via a
 :keyword:`break`, :keyword:`continue` or :keyword:`return` statement.  A more
 complicated example::
 
@@ -376,7 +376,7 @@ complicated example::
 
 As you can see, the :keyword:`finally` clause is executed in any event.  The
 :exc:`TypeError` raised by dividing two strings is not handled by the
-:keyword:`except` clause and therefore re-raised after the :keyword:`finally`
+:keyword:`except` clause and therefore re-raised after the :keyword:`!finally`
 clause has been executed.
 
 In real world applications, the :keyword:`finally` clause is useful for
index 785de29ac9d8faf63959a940685ef127169b5249..79427860f518ff842fa4e262f0cc63ba8e8c6be4 100644 (file)
@@ -317,7 +317,7 @@ reading and writing such files.
 It is good practice to use the :keyword:`with` keyword when dealing
 with file objects.  The advantage is that the file is properly closed
 after its suite finishes, even if an exception is raised at some
-point.  Using :keyword:`with` is also much shorter than writing
+point.  Using :keyword:`!with` is also much shorter than writing
 equivalent :keyword:`try`\ -\ :keyword:`finally` blocks::
 
     >>> with open('workfile') as f:
index 0aadad309a8279790b7605aaf7040614c185d182..accc30649f24effdd19a639bd6acbcdbbbd43d24 100644 (file)
@@ -112,8 +112,8 @@ Note that in general the practice of importing ``*`` from a module or package is
 frowned upon, since it often causes poorly readable code. However, it is okay to
 use it to save typing in interactive sessions.
 
-If the module name is followed by :keyword:`as`, then the name
-following :keyword:`as` is bound directly to the imported module.
+If the module name is followed by :keyword:`!as`, then the name
+following :keyword:`!as` is bound directly to the imported module.
 
 ::
 
index 45abd59d18688d8996501339e3a53700c9197c4a..1ada83c07a67f15032a8db8a106677a69d434063 100644 (file)
@@ -7,9 +7,10 @@ Running this command creates the target directory (creating any parent
 directories that don't exist already) and places a ``pyvenv.cfg`` file in it
 with a ``home`` key pointing to the Python installation from which the command
 was run.  It also creates a ``bin`` (or ``Scripts`` on Windows) subdirectory
-containing a copy of the ``python`` binary (or binaries, in the case of
-Windows).  It also creates an (initially empty) ``lib/pythonX.Y/site-packages``
-subdirectory (on Windows, this is ``Lib\site-packages``). If an existing
+containing a copy/symlink of the Python binary/binaries (as appropriate for the
+platform or arguments used at environment creation time). It also creates an
+(initially empty) ``lib/pythonX.Y/site-packages`` subdirectory
+(on Windows, this is ``Lib\site-packages``). If an existing
 directory is specified, it will be re-used.
 
 .. deprecated:: 3.6
@@ -34,7 +35,7 @@ your :ref:`Python installation <using-on-windows>`::
 The command, if run with ``-h``, will show the available options::
 
     usage: venv [-h] [--system-site-packages] [--symlinks | --copies] [--clear]
-                [--upgrade] [--without-pip]
+                [--upgrade] [--without-pip] [--prompt PROMPT]
                 ENV_DIR [ENV_DIR ...]
 
     Creates virtual Python environments in one or more target directories.
@@ -57,6 +58,8 @@ The command, if run with ``-h``, will show the available options::
                             of Python, assuming Python has been upgraded in-place.
       --without-pip         Skips installing or upgrading pip in the virtual
                             environment (pip is bootstrapped by default)
+      --prompt PROMPT       Provides an alternative prompt prefix for this
+                            environment.
 
     Once an environment has been created, you may wish to activate it, e.g. by
     sourcing an activate script in its bin directory.
@@ -69,6 +72,11 @@ The command, if run with ``-h``, will show the available options::
    In earlier versions, if the target directory already existed, an error was
    raised, unless the ``--clear`` or ``--upgrade`` option was provided.
 
+.. note::
+   While symlinks are supported on Windows, they are not recommended. Of
+   particular note is that double-clicking ``python.exe`` in File Explorer
+   will resolve the symlink eagerly and ignore the virtual environment.
+
 The created ``pyvenv.cfg`` file also includes the
 ``include-system-site-packages`` key, set to ``true`` if ``venv`` is
 run with the ``--system-site-packages`` option, ``false`` otherwise.
index 5cbf50112385f4db0f143a16ee336e65958d6ddd..e6a39e24c95eb219b7b65507b31ddb72b110b6e4 100644 (file)
@@ -284,7 +284,7 @@ write the following to do it::
                      L)
 
 Because of Python's scoping rules, a default argument is used so that the
-anonymous function created by the :keyword:`lambda` statement knows what
+anonymous function created by the :keyword:`lambda` expression knows what
 substring is being searched for.  List comprehensions make this cleaner::
 
    sublist = [ s for s in L if string.find(s, S) != -1 ]
@@ -296,11 +296,11 @@ List comprehensions have the form::
                 for exprN in sequenceN
                 if condition ]
 
-The :keyword:`for`...\ :keyword:`in` clauses contain the sequences to be
+The :keyword:`!for`...\ :keyword:`!in` clauses contain the sequences to be
 iterated over.  The sequences do not have to be the same length, because they
 are *not* iterated over in parallel, but from left to right; this is explained
 more clearly in the following paragraphs.  The elements of the generated list
-will be the successive values of *expression*.  The final :keyword:`if` clause
+will be the successive values of *expression*.  The final :keyword:`!if` clause
 is optional; if present, *expression* is only evaluated and added to the result
 if *condition* is true.
 
@@ -316,7 +316,7 @@ following Python code::
                      # the expression to the
                      # resulting list.
 
-This means that when there are multiple :keyword:`for`...\ :keyword:`in`
+This means that when there are multiple :keyword:`!for`...\ :keyword:`!in`
 clauses, the resulting list will be equal to the product of the lengths of all
 the sequences.  If you have two lists of length 3, the output list is 9 elements
 long::
@@ -541,8 +541,8 @@ true if *obj* is present in the sequence *seq*; Python computes this by simply
 trying every index of the sequence until either *obj* is found or an
 :exc:`IndexError` is encountered.  Moshe Zadka contributed a patch which adds a
 :meth:`__contains__` magic method for providing a custom implementation for
-:keyword:`in`. Additionally, new built-in objects written in C can define what
-:keyword:`in` means for them via a new slot in the sequence protocol.
+:keyword:`!in`. Additionally, new built-in objects written in C can define what
+:keyword:`!in` means for them via a new slot in the sequence protocol.
 
 Earlier versions of Python used a recursive algorithm for deleting objects.
 Deeply nested data structures could cause the interpreter to fill up the C stack
index 3486cddc05e9f4cbe360d510e91d497631197390..9537361fe29ef1cf7c37ce887cff4f52020add10 100644 (file)
@@ -52,7 +52,7 @@ The function :func:`g` will always raise a :exc:`NameError` exception, because
 the binding of the name ``g`` isn't in either its local namespace or in the
 module-level namespace.  This isn't much of a problem in practice (how often do
 you recursively define interior functions like this?), but this also made using
-the :keyword:`lambda` statement clumsier, and this was a problem in practice.
+the :keyword:`lambda` expression clumsier, and this was a problem in practice.
 In code which uses :keyword:`lambda` you can often find local variables being
 copied by passing them as the default values of arguments. ::
 
@@ -143,7 +143,7 @@ The syntax uses a ``from...import`` statement using the reserved module name
 While it looks like a normal :keyword:`import` statement, it's not; there are
 strict rules on where such a future statement can be put. They can only be at
 the top of a module, and must precede any Python code or regular
-:keyword:`import` statements.  This is because such statements can affect how
+:keyword:`!import` statements.  This is because such statements can affect how
 the Python bytecode compiler parses code and generates bytecode, so they must
 precede any statement that will result in bytecodes being produced.
 
index c2ae866b73b8b93fd451fca125ce901f114ae372..b4cd4341f4be43fb161f40431fc23b46176871bf 100644 (file)
@@ -121,7 +121,7 @@ added so if no built-in type is suitable, you can just subclass
 This means that :keyword:`class` statements that don't have any base classes are
 always classic classes in Python 2.2.  (Actually you can also change this by
 setting a module-level variable named :attr:`__metaclass__` --- see :pep:`253`
-for the details --- but it's easier to just subclass :keyword:`object`.)
+for the details --- but it's easier to just subclass :class:`object`.)
 
 The type objects for the built-in types are available as built-ins, named using
 a clever trick.  Python has always had built-in functions named :func:`int`,
@@ -560,7 +560,7 @@ Here's the simplest example of a generator function::
            yield i
 
 A new keyword, :keyword:`yield`, was introduced for generators.  Any function
-containing a :keyword:`yield` statement is a generator function; this is
+containing a :keyword:`!yield` statement is a generator function; this is
 detected by Python's bytecode compiler which compiles the function specially as
 a result.  Because a new keyword was introduced, generators must be explicitly
 enabled in a module by including a ``from __future__ import generators``
@@ -571,14 +571,14 @@ When you call a generator function, it doesn't return a single value; instead it
 returns a generator object that supports the iterator protocol.  On executing
 the :keyword:`yield` statement, the generator outputs the value of ``i``,
 similar to a :keyword:`return` statement.  The big difference between
-:keyword:`yield` and a :keyword:`return` statement is that on reaching a
-:keyword:`yield` the generator's state of execution is suspended and local
+:keyword:`!yield` and a :keyword:`!return` statement is that on reaching a
+:keyword:`!yield` the generator's state of execution is suspended and local
 variables are preserved.  On the next call to the generator's ``next()`` method,
-the function will resume executing immediately after the :keyword:`yield`
-statement.  (For complicated reasons, the :keyword:`yield` statement isn't
-allowed inside the :keyword:`try` block of a
+the function will resume executing immediately after the :keyword:`!yield`
+statement.  (For complicated reasons, the :keyword:`!yield` statement isn't
+allowed inside the :keyword:`!try` block of a
 :keyword:`try`...\ :keyword:`finally` statement; read :pep:`255` for a full
-explanation of the interaction between :keyword:`yield` and exceptions.)
+explanation of the interaction between :keyword:`!yield` and exceptions.)
 
 Here's a sample usage of the :func:`generate_ints` generator::
 
@@ -602,7 +602,7 @@ generate_ints(3)``.
 
 Inside a generator function, the :keyword:`return` statement can only be used
 without a value, and signals the end of the procession of values; afterwards the
-generator cannot return any further values. :keyword:`return` with a value, such
+generator cannot return any further values. :keyword:`!return` with a value, such
 as ``return 5``, is a syntax error inside a generator function.  The end of the
 generator's results can also be indicated by raising :exc:`StopIteration`
 manually, or by just letting the flow of execution fall off the bottom of the
@@ -863,8 +863,8 @@ The function :func:`g` will always raise a :exc:`NameError` exception, because
 the binding of the name ``g`` isn't in either its local namespace or in the
 module-level namespace.  This isn't much of a problem in practice (how often do
 you recursively define interior functions like this?), but this also made using
-the :keyword:`lambda` statement clumsier, and this was a problem in practice.
-In code which uses :keyword:`lambda` you can often find local variables being
+the :keyword:`lambda` expression clumsier, and this was a problem in practice.
+In code which uses :keyword:`!lambda` you can often find local variables being
 copied by passing them as the default values of arguments. ::
 
    def find(self, name):
index 37ba7c09c9172ef9ae0bfbbc4b2c4e0f23924150..dac0e63649288aafeb8d80f11384fe020f3f38fb 100644 (file)
@@ -149,7 +149,7 @@ Here's the simplest example of a generator function::
            yield i
 
 A new keyword, :keyword:`yield`, was introduced for generators.  Any function
-containing a :keyword:`yield` statement is a generator function; this is
+containing a :keyword:`!yield` statement is a generator function; this is
 detected by Python's bytecode compiler which compiles the function specially as
 a result.
 
@@ -157,14 +157,14 @@ When you call a generator function, it doesn't return a single value; instead it
 returns a generator object that supports the iterator protocol.  On executing
 the :keyword:`yield` statement, the generator outputs the value of ``i``,
 similar to a :keyword:`return` statement.  The big difference between
-:keyword:`yield` and a :keyword:`return` statement is that on reaching a
-:keyword:`yield` the generator's state of execution is suspended and local
+:keyword:`!yield` and a :keyword:`!return` statement is that on reaching a
+:keyword:`!yield` the generator's state of execution is suspended and local
 variables are preserved.  On the next call to the generator's ``.next()``
 method, the function will resume executing immediately after the
-:keyword:`yield` statement.  (For complicated reasons, the :keyword:`yield`
+:keyword:`!yield` statement.  (For complicated reasons, the :keyword:`!yield`
 statement isn't allowed inside the :keyword:`try` block of a
-:keyword:`try`...\ :keyword:`finally` statement; read :pep:`255` for a full
-explanation of the interaction between :keyword:`yield` and exceptions.)
+:keyword:`!try`...\ :keyword:`!finally` statement; read :pep:`255` for a full
+explanation of the interaction between :keyword:`!yield` and exceptions.)
 
 Here's a sample usage of the :func:`generate_ints` generator::
 
@@ -188,7 +188,7 @@ generate_ints(3)``.
 
 Inside a generator function, the :keyword:`return` statement can only be used
 without a value, and signals the end of the procession of values; afterwards the
-generator cannot return any further values. :keyword:`return` with a value, such
+generator cannot return any further values. :keyword:`!return` with a value, such
 as ``return 5``, is a syntax error inside a generator function.  The end of the
 generator's results can also be indicated by raising :exc:`StopIteration`
 manually, or by just letting the flow of execution fall off the bottom of the
@@ -589,7 +589,7 @@ strict language such as Pascal would also prevent you performing arithmetic with
 Booleans, and would require that the expression in an :keyword:`if` statement
 always evaluate to a Boolean result.  Python is not this strict and never will
 be, as :pep:`285` explicitly says.  This means you can still use any expression
-in an :keyword:`if` statement, even ones that evaluate to a list or tuple or
+in an :keyword:`!if` statement, even ones that evaluate to a list or tuple or
 some random object.  The Boolean type is a subclass of the :class:`int` class so
 that arithmetic using a Boolean still works. ::
 
index 7a3384cbaa5d8de7d466f611f302ad450c36b368..4caacae02556fcad9b94ea60e2b8894c0e3d69a1 100644 (file)
@@ -370,7 +370,7 @@ PEP 341: Unified try/except/finally
 Until Python 2.5, the :keyword:`try` statement came in two flavours. You could
 use a :keyword:`finally` block to ensure that code is always executed, or one or
 more :keyword:`except` blocks to catch  specific exceptions.  You couldn't
-combine both :keyword:`except` blocks and a :keyword:`finally` block, because
+combine both :keyword:`!except` blocks and a :keyword:`!finally` block, because
 generating the right bytecode for the combined version was complicated and it
 wasn't clear what the semantics of the combined statement should be.
 
@@ -435,10 +435,10 @@ When you call ``counter(10)``, the result is an iterator that returns the values
 from 0 up to 9.  On encountering the :keyword:`yield` statement, the iterator
 returns the provided value and suspends the function's execution, preserving the
 local variables. Execution resumes on the following call to the iterator's
-:meth:`next` method, picking up after the :keyword:`yield` statement.
+:meth:`next` method, picking up after the :keyword:`!yield` statement.
 
 In Python 2.3, :keyword:`yield` was a statement; it didn't return any value.  In
-2.5, :keyword:`yield` is now an expression, returning a value that can be
+2.5, :keyword:`!yield` is now an expression, returning a value that can be
 assigned to a variable or otherwise operated on::
 
    val = (yield i)
@@ -458,7 +458,7 @@ expression on the right-hand side of an assignment.  This means you can write
 Values are sent into a generator by calling its ``send(value)`` method.  The
 generator's code is then resumed and the :keyword:`yield` expression returns the
 specified *value*.  If the regular :meth:`next` method is called, the
-:keyword:`yield` returns :const:`None`.
+:keyword:`!yield` returns :const:`None`.
 
 Here's the previous example, modified to allow changing the value of the
 internal counter. ::
@@ -644,7 +644,7 @@ Writing Context Managers
 ------------------------
 
 Under the hood, the ':keyword:`with`' statement is fairly complicated. Most
-people will only use ':keyword:`with`' in company with existing objects and
+people will only use ':keyword:`!with`' in company with existing objects and
 don't need to know these details, so you can skip the rest of this section if
 you like.  Authors of new objects will need to understand the details of the
 underlying implementation and should keep reading.
@@ -750,9 +750,9 @@ generator function instead of defining a new class.  The generator should yield
 exactly one value.  The code up to the :keyword:`yield` will be executed as the
 :meth:`__enter__` method, and the value yielded will be the method's return
 value that will get bound to the variable in the ':keyword:`with`' statement's
-:keyword:`as` clause, if any.  The code after the :keyword:`yield` will be
+:keyword:`!as` clause, if any.  The code after the :keyword:`yield` will be
 executed in the :meth:`__exit__` method.  Any exception raised in the block will
-be raised by the :keyword:`yield` statement.
+be raised by the :keyword:`!yield` statement.
 
 Our database example from the previous section could be written  using this
 decorator as::
@@ -776,7 +776,7 @@ decorator as::
 
 The :mod:`contextlib` module also has a ``nested(mgr1, mgr2, ...)`` function
 that combines a number of context managers so you don't need to write nested
-':keyword:`with`' statements.  In this example, the single ':keyword:`with`'
+':keyword:`with`' statements.  In this example, the single ':keyword:`!with`'
 statement both starts a database transaction and acquires a thread lock::
 
    lock = threading.Lock()
index ccfdbdce03e99fb94a86c6ff188c62362a378b41..512b8edb357ae963d301feff8b791a84e7ab7404 100644 (file)
@@ -250,10 +250,10 @@ PEP 343: The 'with' statement
 The previous version, Python 2.5, added the ':keyword:`with`'
 statement as an optional feature, to be enabled by a ``from __future__
 import with_statement`` directive.  In 2.6 the statement no longer needs to
-be specially enabled; this means that :keyword:`with` is now always a
+be specially enabled; this means that :keyword:`!with` is now always a
 keyword.  The rest of this section is a copy of the corresponding
 section from the "What's New in Python 2.5" document; if you're
-familiar with the ':keyword:`with`' statement
+familiar with the ':keyword:`!with`' statement
 from Python 2.5, you can skip this section.
 
 The ':keyword:`with`' statement clarifies code that previously would use
@@ -331,7 +331,7 @@ Writing Context Managers
 ------------------------
 
 Under the hood, the ':keyword:`with`' statement is fairly complicated. Most
-people will only use ':keyword:`with`' in company with existing objects and
+people will only use ':keyword:`!with`' in company with existing objects and
 don't need to know these details, so you can skip the rest of this section if
 you like.  Authors of new objects will need to understand the details of the
 underlying implementation and should keep reading.
@@ -438,9 +438,9 @@ generator function instead of defining a new class.  The generator should yield
 exactly one value.  The code up to the :keyword:`yield` will be executed as the
 :meth:`__enter__` method, and the value yielded will be the method's return
 value that will get bound to the variable in the ':keyword:`with`' statement's
-:keyword:`as` clause, if any.  The code after the :keyword:`yield` will be
+:keyword:`!as` clause, if any.  The code after the :keyword:`!yield` will be
 executed in the :meth:`__exit__` method.  Any exception raised in the block will
-be raised by the :keyword:`yield` statement.
+be raised by the :keyword:`!yield` statement.
 
 Using this decorator, our database example from the previous section
 could be written as::
@@ -464,7 +464,7 @@ could be written as::
 
 The :mod:`contextlib` module also has a ``nested(mgr1, mgr2, ...)`` function
 that combines a number of context managers so you don't need to write nested
-':keyword:`with`' statements.  In this example, the single ':keyword:`with`'
+':keyword:`with`' statements.  In this example, the single ':keyword:`!with`'
 statement both starts a database transaction and acquires a thread lock::
 
    lock = threading.Lock()
@@ -1684,7 +1684,7 @@ Some smaller changes made to the core Python language are:
 * An obscure change: when you use the :func:`locals` function inside a
   :keyword:`class` statement, the resulting dictionary no longer returns free
   variables.  (Free variables, in this case, are variables referenced in the
-  :keyword:`class` statement  that aren't attributes of the class.)
+  :keyword:`!class` statement  that aren't attributes of the class.)
 
 .. ======================================================================
 
index fd59c1611fcd92ff4860aada89ccf559e6b2b27e..9f8d9f202c43413370438395fede18a7891863a9 100644 (file)
@@ -708,7 +708,7 @@ Some smaller changes made to the core Python language are:
 
 * The :keyword:`with` statement can now use multiple context managers
   in one statement.  Context managers are processed from left to right
-  and each one is treated as beginning a new :keyword:`with` statement.
+  and each one is treated as beginning a new :keyword:`!with` statement.
   This means that::
 
    with A() as a, B() as b:
@@ -844,7 +844,7 @@ Some smaller changes made to the core Python language are:
 
 * The :keyword:`import` statement will no longer try an absolute import
   if a relative import (e.g. ``from .os import sep``) fails.  This
-  fixes a bug, but could possibly break certain :keyword:`import`
+  fixes a bug, but could possibly break certain :keyword:`!import`
   statements that were only working by accident.  (Fixed by Meador Inge;
   :issue:`7902`.)
 
@@ -1158,7 +1158,7 @@ changes, or look through the Subversion logs for all the details.
 
 * Deprecated function: :func:`contextlib.nested`, which allows
   handling more than one context manager with a single :keyword:`with`
-  statement, has been deprecated, because the :keyword:`with` statement
+  statement, has been deprecated, because the :keyword:`!with` statement
   now supports multiple context managers.
 
 * The :mod:`cookielib` module now ignores cookies that have an invalid
index 5ecf2ebfe79c4b64b3614aa4788477eb50e775a7..880958d3edb900c822b80be9dd6ad94fe42698d2 100644 (file)
@@ -373,7 +373,7 @@ New Syntax
 
 * :pep:`3104`: :keyword:`nonlocal` statement.  Using ``nonlocal x``
   you can now assign directly to a variable in an outer (but
-  non-global) scope.  :keyword:`nonlocal` is a new reserved word.
+  non-global) scope.  :keyword:`!nonlocal` is a new reserved word.
 
 * :pep:`3132`: Extended Iterable Unpacking.  You can now write things
   like ``a, b, *rest = some_sequence``.  And even ``*rest, a =
@@ -408,14 +408,14 @@ Changed Syntax
 * :pep:`3109` and :pep:`3134`: new :keyword:`raise` statement syntax:
   :samp:`raise [{expr} [from {expr}]]`.  See below.
 
-* :keyword:`as` and :keyword:`with` are now reserved words.  (Since
+* :keyword:`!as` and :keyword:`with` are now reserved words.  (Since
   2.6, actually.)
 
 * ``True``, ``False``, and ``None`` are reserved words.  (2.6 partially enforced
   the restrictions on ``None`` already.)
 
 * Change from :keyword:`except` *exc*, *var* to
-  :keyword:`except` *exc* :keyword:`as` *var*.  See :pep:`3110`.
+  :keyword:`!except` *exc* :keyword:`!as` *var*.  See :pep:`3110`.
 
 * :pep:`3115`: New Metaclass Syntax.  Instead of::
 
@@ -507,9 +507,9 @@ consulted for longer descriptions.
 * :ref:`pep-3105`.  This is now a standard feature and no longer needs
   to be imported from :mod:`__future__`.  More details were given above.
 
-* :ref:`pep-3110`.  The :keyword:`except` *exc* :keyword:`as` *var*
-  syntax is now standard and :keyword:`except` *exc*, *var* is no
-  longer supported.  (Of course, the :keyword:`as` *var* part is still
+* :ref:`pep-3110`.  The :keyword:`except` *exc* :keyword:`!as` *var*
+  syntax is now standard and :keyword:`!except` *exc*, *var* is no
+  longer supported.  (Of course, the :keyword:`!as` *var* part is still
   optional.)
 
 * :ref:`pep-3112`.  The ``b"..."`` string literal notation (and its
index 10996233ff6ec097604208147c5ec67c1d6478b8..845e327cabc86c84af85580fd73c3641e570ff04 100644 (file)
@@ -1352,7 +1352,7 @@ shelve
 ------
 
 :class:`~shelve.Shelf` instances may now be used in :keyword:`with` statements,
-and will be automatically closed at the end of the :keyword:`with` block.
+and will be automatically closed at the end of the :keyword:`!with` block.
 (Contributed by Filip Gruszczyński in :issue:`13896`.)
 
 
index 936ea2dc321e45711639dd04b5e4e63f8503c95a..3f5f5200f122f6f2d987ee59539154d08be542f1 100644 (file)
@@ -2316,6 +2316,17 @@ Changes in the Python API
   a :exc:`DeprecationWarning` in Python 3.6 and a :exc:`RuntimeError` in
   Python 3.8.
 
+* With the introduction of :exc:`ModuleNotFoundError`, import system consumers
+  may start expecting import system replacements to raise that more specific
+  exception when appropriate, rather than the less-specific :exc:`ImportError`.
+  To provide future compatibility with such consumers, implementors of
+  alternative import systems that completely replace :func:`__import__` will
+  need to update their implementations to raise the new subclass when a module
+  can't be found at all. Implementors of compliant plugins to the default
+  import system shouldn't need to make any changes, as the default import
+  system will raise the new subclass when appropriate.
+
+
 Changes in the C API
 --------------------
 
index 7d4c4f91993b3dc1f4db7df6017b88202567dd63..e8572ec0b4922fd230293aa1619782c3cc80ac2e 100644 (file)
@@ -1909,7 +1909,7 @@ Deprecated Python Behavior
 
 Yield expressions (both ``yield`` and ``yield from`` clauses) are now deprecated
 in comprehensions and generator expressions (aside from the iterable expression
-in the leftmost :keyword:`for` clause). This ensures that comprehensions
+in the leftmost :keyword:`!for` clause). This ensures that comprehensions
 always immediately return a container of the appropriate type (rather than
 potentially returning a :term:`generator iterator` object), while generator
 expressions won't attempt to interleave their implicit output with the output
index 05113735c156443a6b169bdcf08b883623c67dee..54ea3214810e1b1cb731740f3d3795f222cf70c0 100644 (file)
 #include <unistd.h>
 #endif
 #ifdef HAVE_CRYPT_H
+#if defined(HAVE_CRYPT_R) && !defined(_GNU_SOURCE)
+/* Required for glibc to expose the crypt_r() function prototype. */
+#  define _GNU_SOURCE
+#  define _Py_GNU_SOURCE_FOR_CRYPT
+#endif
 #include <crypt.h>
+#ifdef _Py_GNU_SOURCE_FOR_CRYPT
+/* Don't leak the _GNU_SOURCE define to other headers. */
+#  undef _GNU_SOURCE
+#  undef _Py_GNU_SOURCE_FOR_CRYPT
+#endif
 #endif
 
 /* For size_t? */
index cd35daa225f76c5019c1955ca6469cbf0057478f..61ed4c4896a3d51f3f75f24695fb1e3bf7b51195 100644 (file)
 /*--start constants--*/
 #define PY_MAJOR_VERSION        3
 #define PY_MINOR_VERSION        7
-#define PY_MICRO_VERSION        2
+#define PY_MICRO_VERSION        3
 #define PY_RELEASE_LEVEL        PY_RELEASE_LEVEL_FINAL
 #define PY_RELEASE_SERIAL       0
 
 /* Version as a string */
-#define PY_VERSION              "3.7.2"
+#define PY_VERSION              "3.7.3"
 /*--end constants--*/
 
 /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2.
diff --git a/LICENSE b/LICENSE
index 1afbedba92b33c6b418c343f7b4c6948318eb197..9dc010d80348fcce0c7ec1a57da2123e79412566 100644 (file)
--- a/LICENSE
+++ b/LICENSE
@@ -73,8 +73,8 @@ analyze, test, perform and/or display publicly, prepare derivative works,
 distribute, and otherwise use Python alone or in any derivative version,
 provided, however, that PSF's License Agreement and PSF's notice of copyright,
 i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
-2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 Python Software Foundation; All
-Rights Reserved" are retained in Python alone or in any derivative version
+2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 Python Software Foundation;
+All Rights Reserved" are retained in Python alone or in any derivative version
 prepared by Licensee.
 
 3. In the event Licensee prepares a derivative work that is based on
index e350e8bc0c2485ccd30b40f0701078ae0dabdccc..a638cceda5e4af7aa7cb3f763d88e1c5387d0726 100644 (file)
@@ -110,7 +110,7 @@ class _ProactorBasePipeTransport(transports._FlowControlMixin,
             self._force_close(exc)
 
     def _force_close(self, exc):
-        if self._empty_waiter is not None:
+        if self._empty_waiter is not None and not self._empty_waiter.done():
             if exc is None:
                 self._empty_waiter.set_result(None)
             else:
@@ -634,7 +634,13 @@ class BaseProactorEventLoop(base_events.BaseEventLoop):
             f.add_done_callback(self._loop_self_reading)
 
     def _write_to_self(self):
-        self._csock.send(b'\0')
+        try:
+            self._csock.send(b'\0')
+        except OSError:
+            if self._debug:
+                logger.debug("Fail to write a null byte into the "
+                             "self-pipe socket",
+                             exc_info=True)
 
     def _start_serving(self, protocol_factory, sock,
                        sslcontext=None, server=None, backlog=100,
index 2ec542764375e9b4a177a79226acaa69d0e6b6a3..e3778688ab5be48d3d4b8a06b5e128e644666529 100644 (file)
@@ -7,6 +7,7 @@ import math
 import msvcrt
 import socket
 import struct
+import time
 import weakref
 
 from . import events
@@ -392,10 +393,16 @@ class IocpProactor:
         self._unregistered = []
         self._stopped_serving = weakref.WeakSet()
 
+    def _check_closed(self):
+        if self._iocp is None:
+            raise RuntimeError('IocpProactor is closed')
+
     def __repr__(self):
-        return ('<%s overlapped#=%s result#=%s>'
-                % (self.__class__.__name__, len(self._cache),
-                   len(self._results)))
+        info = ['overlapped#=%s' % len(self._cache),
+                'result#=%s' % len(self._results)]
+        if self._iocp is None:
+            info.append('closed')
+        return '<%s %s>' % (self.__class__.__name__, " ".join(info))
 
     def set_loop(self, loop):
         self._loop = loop
@@ -602,6 +609,8 @@ class IocpProactor:
         return fut
 
     def _wait_for_handle(self, handle, timeout, _is_cancel):
+        self._check_closed()
+
         if timeout is None:
             ms = _winapi.INFINITE
         else:
@@ -644,6 +653,8 @@ class IocpProactor:
             # that succeed immediately.
 
     def _register(self, ov, obj, callback):
+        self._check_closed()
+
         # Return a future which will be set with the result of the
         # operation when it completes.  The future's value is actually
         # the value returned by callback().
@@ -680,6 +691,7 @@ class IocpProactor:
         already be signalled (pending in the proactor event queue). It is also
         safe if the event is never signalled (because it was cancelled).
         """
+        self._check_closed()
         self._unregistered.append(ov)
 
     def _get_accept_socket(self, family):
@@ -749,6 +761,10 @@ class IocpProactor:
         self._stopped_serving.add(obj)
 
     def close(self):
+        if self._iocp is None:
+            # already closed
+            return
+
         # Cancel remaining registered operations.
         for address, (fut, ov, obj, callback) in list(self._cache.items()):
             if fut.cancelled():
@@ -771,14 +787,25 @@ class IocpProactor:
                             context['source_traceback'] = fut._source_traceback
                         self._loop.call_exception_handler(context)
 
+        # Wait until all cancelled overlapped complete: don't exit with running
+        # overlapped to prevent a crash. Display progress every second if the
+        # loop is still running.
+        msg_update = 1.0
+        start_time = time.monotonic()
+        next_msg = start_time + msg_update
         while self._cache:
-            if not self._poll(1):
-                logger.debug('taking long time to close proactor')
+            if next_msg <= time.monotonic():
+                logger.debug('%r is running after closing for %.1f seconds',
+                             self, time.monotonic() - start_time)
+                next_msg = time.monotonic() + msg_update
+
+            # handle a few events, or timeout
+            self._poll(msg_update)
 
         self._results = []
-        if self._iocp is not None:
-            _winapi.CloseHandle(self._iocp)
-            self._iocp = None
+
+        _winapi.CloseHandle(self._iocp)
+        self._iocp = None
 
     def __del__(self):
         self.close()
index e28e141394de8abc78f3fa7906ff878518142754..5434efda10c0572dd09de128eb880bf05be58ba0 100644 (file)
@@ -54,6 +54,13 @@ class StringArrayTestCase(unittest.TestCase):
 ##        print BUF.from_param(c_char_p("python"))
 ##        print BUF.from_param(BUF(*"pyth"))
 
+    def test_del_segfault(self):
+        BUF = c_char * 4
+        buf = BUF()
+        with self.assertRaises(AttributeError):
+            del buf.raw
+
+
 @need_symbol('c_wchar')
 class WStringArrayTestCase(unittest.TestCase):
     def test(self):
index 71d9896a10524a9e1265fc5aa058edcad6e9d59a..325b822d9f06f110127e252015d6cc80c95899a0 100644 (file)
@@ -241,7 +241,7 @@ class Field:
         self.hash = hash
         self.compare = compare
         self.metadata = (_EMPTY_METADATA
-                         if metadata is None or len(metadata) == 0 else
+                         if metadata is None else
                          types.MappingProxyType(metadata))
         self._field_type = None
 
index 84b4ef59599deda4d160bf775b0ca62e2dbf2344..58b20a2102473394a64b627de3339da2e6cc5fe4 100644 (file)
@@ -78,6 +78,7 @@ def _find_vc2017():
             "-prerelease",
             "-requires", "Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
             "-property", "installationPath",
+            "-products", "*",
         ], encoding="mbcs", errors="strict").strip()
     except (subprocess.CalledProcessError, OSError, UnicodeDecodeError):
         return None, None
index 158465d2338c201a4778b8030b5477b9ccba7d08..0428466b00c902f8a0f2e5d655f1cb0352b932b4 100644 (file)
@@ -161,9 +161,10 @@ class build_ext(Command):
 
         # Put the Python "system" include dir at the end, so that
         # any local include dirs take precedence.
-        self.include_dirs.append(py_include)
+        self.include_dirs.extend(py_include.split(os.path.pathsep))
         if plat_py_include != py_include:
-            self.include_dirs.append(plat_py_include)
+            self.include_dirs.extend(
+                plat_py_include.split(os.path.pathsep))
 
         self.ensure_string_list('libraries')
         self.ensure_string_list('link_objects')
index e07a6c8b94ec79a7f1bf82beb61651c7dab2c65b..83160f8dcc593905512c5a61f7684051a25f6b5a 100644 (file)
@@ -29,9 +29,7 @@ if "_PYTHON_PROJECT_BASE" in os.environ:
     project_base = os.path.abspath(os.environ["_PYTHON_PROJECT_BASE"])
 else:
     project_base = os.path.dirname(os.path.abspath(sys.executable))
-if (os.name == 'nt' and
-    project_base.lower().endswith(('\\pcbuild\\win32', '\\pcbuild\\amd64'))):
-    project_base = os.path.dirname(os.path.dirname(project_base))
+
 
 # python_build: (Boolean) if true, we're either building Python or
 # building an extension with an un-installed Python, so we use
@@ -43,16 +41,26 @@ def _is_python_source_dir(d):
         if os.path.isfile(os.path.join(d, "Modules", fn)):
             return True
     return False
+
 _sys_home = getattr(sys, '_home', None)
-if (_sys_home and os.name == 'nt' and
-    _sys_home.lower().endswith(('\\pcbuild\\win32', '\\pcbuild\\amd64'))):
-    _sys_home = os.path.dirname(os.path.dirname(_sys_home))
+
+if os.name == 'nt':
+    def _fix_pcbuild(d):
+        if d and os.path.normcase(d).startswith(
+                os.path.normcase(os.path.join(PREFIX, "PCbuild"))):
+            return PREFIX
+        return d
+    project_base = _fix_pcbuild(project_base)
+    _sys_home = _fix_pcbuild(_sys_home)
+
 def _python_build():
     if _sys_home:
         return _is_python_source_dir(_sys_home)
     return _is_python_source_dir(project_base)
+
 python_build = _python_build()
 
+
 # Calculate the build qualifier flags if they are defined.  Adding the flags
 # to the include and lib directories only makes sense for an installation, not
 # an in-source build.
@@ -101,6 +109,11 @@ def get_python_inc(plat_specific=0, prefix=None):
         python_dir = 'python' + get_python_version() + build_flags
         return os.path.join(prefix, "include", python_dir)
     elif os.name == "nt":
+        if python_build:
+            # Include both the include and PC dir to ensure we can find
+            # pyconfig.h
+            return (os.path.join(prefix, "include") + os.path.pathsep +
+                    os.path.join(prefix, "PC"))
         return os.path.join(prefix, "include")
     else:
         raise DistutilsPlatformError(
index a72218274ca90eb9baccc67a78427ad7347adf8e..88847f9e9aa7b1a83cbaef1686930cb8deb9c156 100644 (file)
@@ -177,10 +177,12 @@ class BuildExtTestCase(TempdirManager,
         cmd.finalize_options()
 
         py_include = sysconfig.get_python_inc()
-        self.assertIn(py_include, cmd.include_dirs)
+        for p in py_include.split(os.path.pathsep):
+            self.assertIn(p, cmd.include_dirs)
 
         plat_py_include = sysconfig.get_python_inc(plat_specific=1)
-        self.assertIn(plat_py_include, cmd.include_dirs)
+        for p in plat_py_include.split(os.path.pathsep):
+            self.assertIn(p, cmd.include_dirs)
 
         # make sure cmd.libraries is turned into a list
         # if it's a string
index e2fc3809587faa329f096846188a7df85edde48c..bf0d4333f9aeaad97720a44ca4e058501930b9dc 100644 (file)
@@ -4,6 +4,7 @@ import sys
 import unittest
 from copy import copy
 from test.support import run_unittest
+from unittest import mock
 
 from distutils.errors import DistutilsPlatformError, DistutilsByteCompileError
 from distutils.util import (get_platform, convert_path, change_root,
@@ -234,20 +235,35 @@ class UtilTestCase(support.EnvironGuard, unittest.TestCase):
 
     def test_check_environ(self):
         util._environ_checked = 0
-        if 'HOME' in os.environ:
-            del os.environ['HOME']
+        os.environ.pop('HOME', None)
 
-        # posix without HOME
-        if os.name == 'posix':  # this test won't run on windows
-            check_environ()
-            import pwd
-            self.assertEqual(os.environ['HOME'], pwd.getpwuid(os.getuid())[5])
-        else:
-            check_environ()
+        check_environ()
 
         self.assertEqual(os.environ['PLAT'], get_platform())
         self.assertEqual(util._environ_checked, 1)
 
+    @unittest.skipUnless(os.name == 'posix', 'specific to posix')
+    def test_check_environ_getpwuid(self):
+        util._environ_checked = 0
+        os.environ.pop('HOME', None)
+
+        import pwd
+
+        # only set pw_dir field, other fields are not used
+        result = pwd.struct_passwd((None, None, None, None, None,
+                                    '/home/distutils', None))
+        with mock.patch.object(pwd, 'getpwuid', return_value=result):
+            check_environ()
+            self.assertEqual(os.environ['HOME'], '/home/distutils')
+
+        util._environ_checked = 0
+        os.environ.pop('HOME', None)
+
+        # bpo-10496: Catch pwd.getpwuid() error
+        with mock.patch.object(pwd, 'getpwuid', side_effect=KeyError):
+            check_environ()
+            self.assertNotIn('HOME', os.environ)
+
     def test_split_quoted(self):
         self.assertEqual(split_quoted('""one"" "two" \'three\' \\four'),
                          ['one', 'two', 'three', 'four'])
index ab4d4de15661985db84e06b552ded1d82bf7caa0..d10a78da311405f1152c93a063ffc1c702bde8fe 100644 (file)
@@ -188,7 +188,15 @@ class UnixCCompiler(CCompiler):
                         i = 1
                         while '=' in linker[i]:
                             i += 1
-                    linker[i] = self.compiler_cxx[i]
+
+                    if os.path.basename(linker[i]) == 'ld_so_aix':
+                        # AIX platforms prefix the compiler with the ld_so_aix
+                        # script, so we need to adjust our linker index
+                        offset = 1
+                    else:
+                        offset = 0
+
+                    linker[i+offset] = self.compiler_cxx[i]
 
                 if sys.platform == 'darwin':
                     linker = _osx_support.compiler_fixup(linker, ld_args)
index 83682628ba680cfc261c0aeb81d9bf0043c8554d..30a21e4afa1f74f6c7d99ef1fd3ea1c26bece00f 100644 (file)
@@ -157,8 +157,13 @@ def check_environ ():
         return
 
     if os.name == 'posix' and 'HOME' not in os.environ:
-        import pwd
-        os.environ['HOME'] = pwd.getpwuid(os.getuid())[5]
+        try:
+            import pwd
+            os.environ['HOME'] = pwd.getpwuid(os.getuid())[5]
+        except (ImportError, KeyError):
+            # bpo-10496: if the current user identifier doesn't exist in the
+            # password database, do nothing
+            pass
 
     if 'PLAT' not in os.environ:
         os.environ['PLAT'] = get_platform()
index c1d8a1db111ddd4c523f0366af7f7bffb7503a6d..79d91a040c2eeeff533f100f8342ac2ed7b71d9a 100644 (file)
@@ -1690,8 +1690,6 @@ class OutputChecker:
                 kind = 'ndiff with -expected +actual'
             else:
                 assert 0, 'Bad diff option'
-            # Remove trailing whitespace on diff output.
-            diff = [line.rstrip() + '\n' for line in diff]
             return 'Differences (%s):\n' % kind + _indent(''.join(diff))
 
         # If we're not using diff, then simply list the expected
index 09c572db71cb2732f42e394682faef7c1c40121c..526dfd004a41d8daa7492de7a56ddad9627b638b 100644 (file)
@@ -8,9 +8,9 @@ import tempfile
 __all__ = ["version", "bootstrap"]
 
 
-_SETUPTOOLS_VERSION = "40.6.2"
+_SETUPTOOLS_VERSION = "40.8.0"
 
-_PIP_VERSION = "18.1"
+_PIP_VERSION = "19.0.3"
 
 _PROJECTS = [
     ("setuptools", _SETUPTOOLS_VERSION),
diff --git a/Lib/ensurepip/_bundled/pip-18.1-py2.py3-none-any.whl b/Lib/ensurepip/_bundled/pip-18.1-py2.py3-none-any.whl
deleted file mode 100644 (file)
index c3c146f..0000000
Binary files a/Lib/ensurepip/_bundled/pip-18.1-py2.py3-none-any.whl and /dev/null differ
diff --git a/Lib/ensurepip/_bundled/pip-19.0.3-py2.py3-none-any.whl b/Lib/ensurepip/_bundled/pip-19.0.3-py2.py3-none-any.whl
new file mode 100644 (file)
index 0000000..24f247c
Binary files /dev/null and b/Lib/ensurepip/_bundled/pip-19.0.3-py2.py3-none-any.whl differ
diff --git a/Lib/ensurepip/_bundled/setuptools-40.6.2-py2.py3-none-any.whl b/Lib/ensurepip/_bundled/setuptools-40.6.2-py2.py3-none-any.whl
deleted file mode 100644 (file)
index 4c8a619..0000000
Binary files a/Lib/ensurepip/_bundled/setuptools-40.6.2-py2.py3-none-any.whl and /dev/null differ
diff --git a/Lib/ensurepip/_bundled/setuptools-40.8.0-py2.py3-none-any.whl b/Lib/ensurepip/_bundled/setuptools-40.8.0-py2.py3-none-any.whl
new file mode 100644 (file)
index 0000000..fdc66e9
Binary files /dev/null and b/Lib/ensurepip/_bundled/setuptools-40.8.0-py2.py3-none-any.whl differ
index e5a80cd609d498e2ed7a0d960fc012cb09081262..5e97a9e8d810c1b77df7ece149c1f6348951ea11 100644 (file)
@@ -25,18 +25,19 @@ def _is_descriptor(obj):
 
 def _is_dunder(name):
     """Returns True if a __dunder__ name, False otherwise."""
-    return (name[:2] == name[-2:] == '__' and
-            name[2:3] != '_' and
-            name[-3:-2] != '_' and
-            len(name) > 4)
+    return (len(name) > 4 and
+            name[:2] == name[-2:] == '__' and
+            name[2] != '_' and
+            name[-3] != '_')
 
 
 def _is_sunder(name):
     """Returns True if a _sunder_ name, False otherwise."""
-    return (name[0] == name[-1] == '_' and
+    return (len(name) > 2 and
+            name[0] == name[-1] == '_' and
             name[1:2] != '_' and
-            name[-2:-1] != '_' and
-            len(name) > 2)
+            name[-2:-1] != '_')
+
 
 def _make_class_unpicklable(cls):
     """Make the given class un-picklable."""
@@ -156,7 +157,7 @@ class EnumMeta(type):
         _order_ = classdict.pop('_order_', None)
 
         # check for illegal enum names (any others?)
-        invalid_names = set(enum_members) & {'mro', }
+        invalid_names = set(enum_members) & {'mro', ''}
         if invalid_names:
             raise ValueError('Invalid enum member name: {0}'.format(
                 ','.join(invalid_names)))
@@ -427,7 +428,7 @@ class EnumMeta(type):
         if module is None:
             try:
                 module = sys._getframe(2).f_globals['__name__']
-            except (AttributeError, ValueError) as exc:
+            except (AttributeError, ValueError, KeyError) as exc:
                 pass
         if module is None:
             _make_class_unpicklable(enum_class)
@@ -532,8 +533,10 @@ class Enum(metaclass=EnumMeta):
         # by-value search for a matching enum member
         # see if it's in the reverse mapping (for hashable values)
         try:
-            if value in cls._value2member_map_:
-                return cls._value2member_map_[value]
+            return cls._value2member_map_[value]
+        except KeyError:
+            # Not found, no need to do long O(n) search
+            pass
         except TypeError:
             # not there, now do long search -- O(n) behavior
             for member in cls._member_map_.values():
index 24b011dc0428c00d2348adc6f91ae53aadfc1e71..b734899b56de8a2379a0c1b47668049ba64b51f5 100644 (file)
@@ -413,7 +413,7 @@ class _HashedSeq(list):
 
 def _make_key(args, kwds, typed,
              kwd_mark = (object(),),
-             fasttypes = {int, str, frozenset, type(None)},
+             fasttypes = {int, str},
              tuple=tuple, type=type, len=len):
     """Make a cache key from optionally typed positional and keyword arguments
 
@@ -469,8 +469,11 @@ def lru_cache(maxsize=128, typed=False):
 
     # Early detection of an erroneous call to @lru_cache without any arguments
     # resulting in the inner function being passed to maxsize instead of an
-    # integer or None.
-    if maxsize is not None and not isinstance(maxsize, int):
+    # integer or None.  Negative maxsize is treated as 0.
+    if isinstance(maxsize, int):
+        if maxsize < 0:
+            maxsize = 0
+    elif maxsize is not None:
         raise TypeError('Expected maxsize to be an integer or None')
 
     def decorating_function(user_function):
@@ -497,10 +500,10 @@ def _lru_cache_wrapper(user_function, maxsize, typed, _CacheInfo):
     if maxsize == 0:
 
         def wrapper(*args, **kwds):
-            # No caching -- just a statistics update after a successful call
+            # No caching -- just a statistics update
             nonlocal misses
-            result = user_function(*args, **kwds)
             misses += 1
+            result = user_function(*args, **kwds)
             return result
 
     elif maxsize is None:
@@ -513,9 +516,9 @@ def _lru_cache_wrapper(user_function, maxsize, typed, _CacheInfo):
             if result is not sentinel:
                 hits += 1
                 return result
+            misses += 1
             result = user_function(*args, **kwds)
             cache[key] = result
-            misses += 1
             return result
 
     else:
@@ -537,6 +540,7 @@ def _lru_cache_wrapper(user_function, maxsize, typed, _CacheInfo):
                     link[NEXT] = root
                     hits += 1
                     return result
+                misses += 1
             result = user_function(*args, **kwds)
             with lock:
                 if key in cache:
@@ -574,7 +578,6 @@ def _lru_cache_wrapper(user_function, maxsize, typed, _CacheInfo):
                     # Use the cache_len bound method instead of the len() function
                     # which could potentially be wrapped in an lru_cache itself.
                     full = (cache_len() >= maxsize)
-                misses += 1
             return result
 
     def cache_info():
index e0f1032b2816d7f6206fa5edc00a95918a110a50..d63544a5f52e2325a77d1f5434e4ff9bea10f6f0 100644 (file)
@@ -990,7 +990,7 @@ class DefaultCookiePolicy(CookiePolicy):
             req_path = request_path(request)
             if ((cookie.version > 0 or
                  (cookie.version == 0 and self.strict_ns_set_path)) and
-                not req_path.startswith(cookie.path)):
+                not self.path_return_ok(cookie.path, request)):
                 _debug("   path attribute %s is not a prefix of request "
                        "path %s", cookie.path, req_path)
                 return False
@@ -1145,6 +1145,11 @@ class DefaultCookiePolicy(CookiePolicy):
         req_host, erhn = eff_request_host(request)
         domain = cookie.domain
 
+        if domain and not domain.startswith("."):
+            dotdomain = "." + domain
+        else:
+            dotdomain = domain
+
         # strict check of non-domain cookies: Mozilla does this, MSIE5 doesn't
         if (cookie.version == 0 and
             (self.strict_ns_domain & self.DomainStrictNonDomain) and
@@ -1157,7 +1162,7 @@ class DefaultCookiePolicy(CookiePolicy):
             _debug("   effective request-host name %s does not domain-match "
                    "RFC 2965 cookie domain %s", erhn, domain)
             return False
-        if cookie.version == 0 and not ("."+erhn).endswith(domain):
+        if cookie.version == 0 and not ("."+erhn).endswith(dotdomain):
             _debug("   request-host %s does not match Netscape cookie domain "
                    "%s", req_host, domain)
             return False
@@ -1171,7 +1176,11 @@ class DefaultCookiePolicy(CookiePolicy):
             req_host = "."+req_host
         if not erhn.startswith("."):
             erhn = "."+erhn
-        if not (req_host.endswith(domain) or erhn.endswith(domain)):
+        if domain and not domain.startswith("."):
+            dotdomain = "." + domain
+        else:
+            dotdomain = domain
+        if not (req_host.endswith(dotdomain) or erhn.endswith(dotdomain)):
             #_debug("   request domain %s does not match cookie domain %s",
             #       req_host, domain)
             return False
@@ -1188,11 +1197,15 @@ class DefaultCookiePolicy(CookiePolicy):
     def path_return_ok(self, path, request):
         _debug("- checking cookie path=%s", path)
         req_path = request_path(request)
-        if not req_path.startswith(path):
-            _debug("  %s does not path-match %s", req_path, path)
-            return False
-        return True
+        pathlen = len(path)
+        if req_path == path:
+            return True
+        elif (req_path.startswith(path) and
+              (path.endswith("/") or req_path[pathlen:pathlen+1] == "/")):
+            return True
 
+        _debug("  %s does not path-match %s", req_path, path)
+        return False
 
 def vals_sorted_by_key(adict):
     keys = sorted(adict.keys())
index b93769e73bbb538997452e063bc16378bfc671ab..c343538a29c20e3b3cbaf524a90b173fc6467f90 100644 (file)
@@ -1,8 +1,66 @@
-What's New in IDLE 3.7.2
-Released on 2018-07-31?
+What's New in IDLE 3.7.3
+Released on 2019-??-??
 ======================================
 
 
+bpo-36176: Fix IDLE autocomplete & calltip popup colors.
+Prevent conflicts with Linux dark themes
+(and slightly darken calltip background).
+
+bpo-36152: Remove colorizer.ColorDelegator.close_when_done and the
+corresponding argument of .close().  In IDLE, both have always been
+None or False since 2007.
+
+bpo-36096: Make colorizer state variables instance-only.
+
+bpo-24310: Document settings dialog font tab sample.
+
+bpo-35689: Add docstrings and tests for colorizer.
+
+bpo-35833: Revise IDLE doc for control codes sent to Shell.
+Add a code example block.
+
+bpo-35770: IDLE macosx deletes Options => Configure IDLE.
+It previously deleted Window => Zoom Height by mistake.
+(Zoom Height is now on the Options menu).  On Mac, the settings
+dialog is accessed via Preferences on the IDLE menu.
+
+bpo-35769: Change new file name from 'Untitled' to 'untitled'.
+
+bpo-35660: Fix imports in window module.
+
+bpo-35641: Properly format calltip for function without docstring.
+
+bpo-33987: Use ttk Frame for ttk widgets.
+
+bpo-34055: Fix erroneous 'smart' indents and newlines in IDLE Shell.
+
+bpo-28097: Add Previous/Next History entries to Shell menu.
+
+bpo-35591: Find Selection now works when selection not found.
+
+bpo-35598: Update config_key: use PEP 8 names and ttk widgets,
+make some objects global, and add tests.
+
+bpo-35196: Speed up squeezer line counting.
+
+bpo-35208: Squeezer now counts wrapped lines before newlines.
+
+bpo-35555: Gray out Code Context menu entry when it's not applicable.
+
+bpo-22703: Improve the Code Context and Zoom Height menu labels.
+The Code Context menu label now toggles between Show/Hide Code Context.
+The Zoom Height menu now toggles between Zoom/Restore Height.
+Zoom Height has moved from the Window menu to the Options menu.
+
+bpo-35521: Document the editor code context feature.
+Add some internal references within the IDLE doc.
+
+
+What's New in IDLE 3.7.2
+Released on 2018-12-21?
+======================================
+
 bpo-34864: When starting IDLE on MacOS, warn if the system setting
 "Prefer tabs when opening documents" is "Always".  As previous
 documented for this issue, running IDLE with this setting causes
index 9e0d336523d4799fe53450fabd69288e40b4edb6..c249625277369f86bfbb93513edb4315aaac67ec 100644 (file)
@@ -4,7 +4,7 @@ An auto-completion window for IDLE, used by the autocomplete extension
 import platform
 
 from tkinter import *
-from tkinter.ttk import Scrollbar
+from tkinter.ttk import Frame, Scrollbar
 
 from idlelib.autocomplete import COMPLETE_FILES, COMPLETE_ATTRIBUTES
 from idlelib.multicall import MC_SHIFT
@@ -189,7 +189,7 @@ class AutoCompleteWindow:
             pass
         self.scrollbar = scrollbar = Scrollbar(acw, orient=VERTICAL)
         self.listbox = listbox = Listbox(acw, yscrollcommand=scrollbar.set,
-                                         exportselection=False, bg="white")
+                                         exportselection=False)
         for item in self.completions:
             listbox.insert(END, item)
         self.origselforeground = listbox.cget("selectforeground")
index 758569a45fdf5810b187398d64a4fe9e2d86202e..2a9a131ed96b3c74d8f852d0678cc1c1782d4cfb 100644 (file)
@@ -167,7 +167,7 @@ def get_argspec(ob):
             if len(line) > _MAX_COLS:
                 line = line[: _MAX_COLS - 3] + '...'
             lines.append(line)
-        argspec = '\n'.join(lines)
+    argspec = '\n'.join(lines)
     if not argspec:
         argspec = _default_callable_argspec
     return argspec
index 7553dfefc55c0bd8a52a0525a752893bf390e020..1e0404aa49f56287462d48400ecc76c1eaa57262 100644 (file)
@@ -80,7 +80,8 @@ class CalltipWindow(TooltipBase):
     def showcontents(self):
         """Create the call-tip widget."""
         self.label = Label(self.tipwindow, text=self.text, justify=LEFT,
-                           background="#ffffe0", relief=SOLID, borderwidth=1,
+                           background="#ffffd0", foreground="black",
+                           relief=SOLID, borderwidth=1,
                            font=self.anchor_widget['font'])
         self.label.pack()
 
index ef8852852d1f808e1d2951427e35a1c54b9a3401..2aed76de7fb6f870ac3f0fb2fe4255b6a91b74e1 100644 (file)
@@ -122,9 +122,13 @@ class CodeContext:
             # thus ensuring that it will appear directly above text_frame.
             self.context.pack(side=TOP, fill=X, expand=False,
                             before=self.editwin.text_frame)
+            menu_status = 'Hide'
         else:
             self.context.destroy()
             self.context = None
+            menu_status = 'Show'
+        self.editwin.update_menu_label(menu='options', index='* Code Context',
+                                       label=f'{menu_status} Code Context')
         return "break"
 
     def get_context(self, new_topvisible, stopline=1, stopindent=0):
index d4e592b6ebe077e2fc0cedb46aa534de3788d329..facbef8bb189191cc36d9e9300155d4ac150f35e 100644 (file)
@@ -53,14 +53,46 @@ def color_config(text):
 
 
 class ColorDelegator(Delegator):
+    """Delegator for syntax highlighting (text coloring).
+
+    Instance variables:
+        delegate: Delegator below this one in the stack, meaning the
+                one this one delegates to.
+
+        Used to track state:
+        after_id: Identifier for scheduled after event, which is a
+                timer for colorizing the text.
+        allow_colorizing: Boolean toggle for applying colorizing.
+        colorizing: Boolean flag when colorizing is in process.
+        stop_colorizing: Boolean flag to end an active colorizing
+                process.
+    """
 
     def __init__(self):
         Delegator.__init__(self)
+        self.init_state()
         self.prog = prog
         self.idprog = idprog
         self.LoadTagDefs()
 
+    def init_state(self):
+        "Initialize variables that track colorizing state."
+        self.after_id = None
+        self.allow_colorizing = True
+        self.stop_colorizing = False
+        self.colorizing = False
+
     def setdelegate(self, delegate):
+        """Set the delegate for this instance.
+
+        A delegate is an instance of a Delegator class and each
+        delegate points to the next delegator in the stack.  This
+        allows multiple delegators to be chained together for a
+        widget.  The bottom delegate for a colorizer is a Text
+        widget.
+
+        If there is a delegate, also start the colorizing process.
+        """
         if self.delegate is not None:
             self.unbind("<<toggle-auto-coloring>>")
         Delegator.setdelegate(self, delegate)
@@ -69,17 +101,18 @@ class ColorDelegator(Delegator):
             self.bind("<<toggle-auto-coloring>>", self.toggle_colorize_event)
             self.notify_range("1.0", "end")
         else:
-            # No delegate - stop any colorizing
+            # No delegate - stop any colorizing.
             self.stop_colorizing = True
             self.allow_colorizing = False
 
     def config_colors(self):
+        "Configure text widget tags with colors from tagdefs."
         for tag, cnf in self.tagdefs.items():
-            if cnf:
-                self.tag_configure(tag, **cnf)
+            self.tag_configure(tag, **cnf)
         self.tag_raise('sel')
 
     def LoadTagDefs(self):
+        "Create dictionary of tag names to text colors."
         theme = idleConf.CurrentTheme()
         self.tagdefs = {
             "COMMENT": idleConf.GetHighlight(theme, "comment"),
@@ -97,20 +130,19 @@ class ColorDelegator(Delegator):
         if DEBUG: print('tagdefs',self.tagdefs)
 
     def insert(self, index, chars, tags=None):
+        "Insert chars into widget at index and mark for colorizing."
         index = self.index(index)
         self.delegate.insert(index, chars, tags)
         self.notify_range(index, index + "+%dc" % len(chars))
 
     def delete(self, index1, index2=None):
+        "Delete chars between indexes and mark for colorizing."
         index1 = self.index(index1)
         self.delegate.delete(index1, index2)
         self.notify_range(index1)
 
-    after_id = None
-    allow_colorizing = True
-    colorizing = False
-
     def notify_range(self, index1, index2=None):
+        "Mark text changes for processing and restart colorizing, if active."
         self.tag_add("TODO", index1, index2)
         if self.after_id:
             if DEBUG: print("colorizing already scheduled")
@@ -121,10 +153,9 @@ class ColorDelegator(Delegator):
         if self.allow_colorizing:
             if DEBUG: print("schedule colorizing")
             self.after_id = self.after(1, self.recolorize)
+        return
 
-    close_when_done = None # Window to be closed when done colorizing
-
-    def close(self, close_when_done=None):
+    def close(self):
         if self.after_id:
             after_id = self.after_id
             self.after_id = None
@@ -132,13 +163,15 @@ class ColorDelegator(Delegator):
             self.after_cancel(after_id)
         self.allow_colorizing = False
         self.stop_colorizing = True
-        if close_when_done:
-            if not self.colorizing:
-                close_when_done.destroy()
-            else:
-                self.close_when_done = close_when_done
 
-    def toggle_colorize_event(self, event):
+    def toggle_colorize_event(self, event=None):
+        """Toggle colorizing on and off.
+
+        When toggling off, if colorizing is scheduled or is in
+        process, it will be cancelled and/or stopped.
+
+        When toggling on, colorizing will be scheduled.
+        """
         if self.after_id:
             after_id = self.after_id
             self.after_id = None
@@ -156,6 +189,15 @@ class ColorDelegator(Delegator):
         return "break"
 
     def recolorize(self):
+        """Timer event (every 1ms) to colorize text.
+
+        Colorizing is only attempted when the text widget exists,
+        when colorizing is toggled on, and when the colorizing
+        process is not already running.
+
+        After colorizing is complete, some cleanup is done to
+        make sure that all the text has been colorized.
+        """
         self.after_id = None
         if not self.delegate:
             if DEBUG: print("no delegate")
@@ -179,12 +221,9 @@ class ColorDelegator(Delegator):
         if self.allow_colorizing and self.tag_nextrange("TODO", "1.0"):
             if DEBUG: print("reschedule colorizing")
             self.after_id = self.after(1, self.recolorize)
-        if self.close_when_done:
-            top = self.close_when_done
-            self.close_when_done = None
-            top.destroy()
 
     def recolorize_main(self):
+        "Evaluate text and apply colorizing tags."
         next = "1.0"
         while True:
             item = self.tag_nextrange("TODO", next)
@@ -250,6 +289,7 @@ class ColorDelegator(Delegator):
                     return
 
     def removecolors(self):
+        "Remove all colorizing tags."
         for tag in self.tagdefs:
             self.tag_remove(tag, "1.0", "end")
 
@@ -273,7 +313,7 @@ def _color_delegator(parent):  # htest #
         "'x', '''x''', \"x\", \"\"\"x\"\"\"\n"
         "r'x', u'x', R'x', U'x', f'x', F'x'\n"
         "fr'x', Fr'x', fR'x', FR'x', rf'x', rF'x', Rf'x', RF'x'\n"
-        "b'x',B'x', br'x',Br'x',bR'x',BR'x', rb'x'.rB'x',Rb'x',RB'x'\n"
+        "b'x',B'x', br'x',Br'x',bR'x',BR'x', rb'x'rB'x',Rb'x',RB'x'\n"
         "# Invalid combinations of legal characters should be half colored.\n"
         "ur'x', ru'x', uf'x', fu'x', UR'x', ufr'x', rfu'x', xf'x', fx'x'\n"
         )
index abab74265f3ef81f0033c08188a01d5573a565d8..4478323fcc2c51eb07621289c23ecde52ba3f22d 100644 (file)
@@ -1,51 +1,85 @@
 """
 Dialog for building Tkinter accelerator key bindings
 """
-from tkinter import *
-from tkinter.ttk import Scrollbar
+from tkinter import Toplevel, Listbox, Text, StringVar, TclError
+from tkinter.ttk import Frame, Button, Checkbutton, Entry, Label, Scrollbar
 from tkinter import messagebox
 import string
 import sys
 
 
+FUNCTION_KEYS = ('F1', 'F2' ,'F3' ,'F4' ,'F5' ,'F6',
+                 'F7', 'F8' ,'F9' ,'F10' ,'F11' ,'F12')
+ALPHANUM_KEYS = tuple(string.ascii_lowercase + string.digits)
+PUNCTUATION_KEYS = tuple('~!@#%^&*()_-+={}[]|;:,.<>/?')
+WHITESPACE_KEYS = ('Tab', 'Space', 'Return')
+EDIT_KEYS = ('BackSpace', 'Delete', 'Insert')
+MOVE_KEYS = ('Home', 'End', 'Page Up', 'Page Down', 'Left Arrow',
+             'Right Arrow', 'Up Arrow', 'Down Arrow')
+AVAILABLE_KEYS = (ALPHANUM_KEYS + PUNCTUATION_KEYS + FUNCTION_KEYS +
+                  WHITESPACE_KEYS + EDIT_KEYS + MOVE_KEYS)
+
+
+def translate_key(key, modifiers):
+    "Translate from keycap symbol to the Tkinter keysym."
+    mapping = {'Space':'space',
+            '~':'asciitilde', '!':'exclam', '@':'at', '#':'numbersign',
+            '%':'percent', '^':'asciicircum', '&':'ampersand',
+            '*':'asterisk', '(':'parenleft', ')':'parenright',
+            '_':'underscore', '-':'minus', '+':'plus', '=':'equal',
+            '{':'braceleft', '}':'braceright',
+            '[':'bracketleft', ']':'bracketright', '|':'bar',
+            ';':'semicolon', ':':'colon', ',':'comma', '.':'period',
+            '<':'less', '>':'greater', '/':'slash', '?':'question',
+            'Page Up':'Prior', 'Page Down':'Next',
+            'Left Arrow':'Left', 'Right Arrow':'Right',
+            'Up Arrow':'Up', 'Down Arrow': 'Down', 'Tab':'Tab'}
+    key = mapping.get(key, key)
+    if 'Shift' in modifiers and key in string.ascii_lowercase:
+        key = key.upper()
+    return f'Key-{key}'
+
+
 class GetKeysDialog(Toplevel):
 
     # Dialog title for invalid key sequence
     keyerror_title = 'Key Sequence Error'
 
-    def __init__(self, parent, title, action, currentKeySequences,
+    def __init__(self, parent, title, action, current_key_sequences,
                  *, _htest=False, _utest=False):
         """
+        parent - parent of this dialog
+        title - string which is the title of the popup dialog
         action - string, the name of the virtual event these keys will be
                  mapped to
-        currentKeys - list, a list of all key sequence lists currently mapped
-                 to virtual events, for overlap checking
-        _utest - bool, do not wait when running unittest
+        current_key_sequences - list, a list of all key sequence lists
+                 currently mapped to virtual events, for overlap checking
         _htest - bool, change box location when running htest
+        _utest - bool, do not wait when running unittest
         """
         Toplevel.__init__(self, parent)
-        self.withdraw() #hide while setting geometry
+        self.withdraw()  # Hide while setting geometry.
         self.configure(borderwidth=5)
-        self.resizable(height=FALSE, width=FALSE)
+        self.resizable(height=False, width=False)
         self.title(title)
         self.transient(parent)
         self.grab_set()
-        self.protocol("WM_DELETE_WINDOW", self.Cancel)
+        self.protocol("WM_DELETE_WINDOW", self.cancel)
         self.parent = parent
-        self.action=action
-        self.currentKeySequences = currentKeySequences
+        self.action = action
+        self.current_key_sequences = current_key_sequences
         self.result = ''
-        self.keyString = StringVar(self)
-        self.keyString.set('')
-        self.SetModifiersForPlatform() # set self.modifiers, self.modifier_label
+        self.key_string = StringVar(self)
+        self.key_string.set('')
+        # Set self.modifiers, self.modifier_label.
+        self.set_modifiers_for_platform()
         self.modifier_vars = []
         for modifier in self.modifiers:
             variable = StringVar(self)
             variable.set('')
             self.modifier_vars.append(variable)
         self.advanced = False
-        self.CreateWidgets()
-        self.LoadFinalKeyList()
+        self.create_widgets()
         self.update_idletasks()
         self.geometry(
                 "+%d+%d" % (
@@ -54,83 +88,100 @@ class GetKeysDialog(Toplevel):
                     parent.winfo_rooty() +
                     ((parent.winfo_height()/2 - self.winfo_reqheight()/2)
                     if not _htest else 150)
-                ) )  #centre dialog over parent (or below htest box)
+                ) )  # Center dialog over parent (or below htest box).
         if not _utest:
-            self.deiconify() #geometry set, unhide
+            self.deiconify()  # Geometry set, unhide.
             self.wait_window()
 
     def showerror(self, *args, **kwargs):
         # Make testing easier.  Replace in #30751.
         messagebox.showerror(*args, **kwargs)
 
-    def CreateWidgets(self):
-        frameMain = Frame(self,borderwidth=2,relief=SUNKEN)
-        frameMain.pack(side=TOP,expand=TRUE,fill=BOTH)
-        frameButtons=Frame(self)
-        frameButtons.pack(side=BOTTOM,fill=X)
-        self.buttonOK = Button(frameButtons,text='OK',
-                width=8,command=self.OK)
-        self.buttonOK.grid(row=0,column=0,padx=5,pady=5)
-        self.buttonCancel = Button(frameButtons,text='Cancel',
-                width=8,command=self.Cancel)
-        self.buttonCancel.grid(row=0,column=1,padx=5,pady=5)
-        self.frameKeySeqBasic = Frame(frameMain)
-        self.frameKeySeqAdvanced = Frame(frameMain)
-        self.frameControlsBasic = Frame(frameMain)
-        self.frameHelpAdvanced = Frame(frameMain)
-        self.frameKeySeqAdvanced.grid(row=0,column=0,sticky=NSEW,padx=5,pady=5)
-        self.frameKeySeqBasic.grid(row=0,column=0,sticky=NSEW,padx=5,pady=5)
-        self.frameKeySeqBasic.lift()
-        self.frameHelpAdvanced.grid(row=1,column=0,sticky=NSEW,padx=5)
-        self.frameControlsBasic.grid(row=1,column=0,sticky=NSEW,padx=5)
-        self.frameControlsBasic.lift()
-        self.buttonLevel = Button(frameMain,command=self.ToggleLevel,
-                text='Advanced Key Binding Entry >>')
-        self.buttonLevel.grid(row=2,column=0,stick=EW,padx=5,pady=5)
-        labelTitleBasic = Label(self.frameKeySeqBasic,
-                text="New keys for  '"+self.action+"' :")
-        labelTitleBasic.pack(anchor=W)
-        labelKeysBasic = Label(self.frameKeySeqBasic,justify=LEFT,
-                textvariable=self.keyString,relief=GROOVE,borderwidth=2)
-        labelKeysBasic.pack(ipadx=5,ipady=5,fill=X)
+    def create_widgets(self):
+        self.frame = frame = Frame(self, borderwidth=2, relief='sunken')
+        frame.pack(side='top', expand=True, fill='both')
+
+        frame_buttons = Frame(self)
+        frame_buttons.pack(side='bottom', fill='x')
+
+        self.button_ok = Button(frame_buttons, text='OK',
+                                width=8, command=self.ok)
+        self.button_ok.grid(row=0, column=0, padx=5, pady=5)
+        self.button_cancel = Button(frame_buttons, text='Cancel',
+                                   width=8, command=self.cancel)
+        self.button_cancel.grid(row=0, column=1, padx=5, pady=5)
+
+        # Basic entry key sequence.
+        self.frame_keyseq_basic = Frame(frame, name='keyseq_basic')
+        self.frame_keyseq_basic.grid(row=0, column=0, sticky='nsew',
+                                      padx=5, pady=5)
+        basic_title = Label(self.frame_keyseq_basic,
+                            text=f"New keys for '{self.action}' :")
+        basic_title.pack(anchor='w')
+
+        basic_keys = Label(self.frame_keyseq_basic, justify='left',
+                           textvariable=self.key_string, relief='groove',
+                           borderwidth=2)
+        basic_keys.pack(ipadx=5, ipady=5, fill='x')
+
+        # Basic entry controls.
+        self.frame_controls_basic = Frame(frame)
+        self.frame_controls_basic.grid(row=1, column=0, sticky='nsew', padx=5)
+
+        # Basic entry modifiers.
         self.modifier_checkbuttons = {}
         column = 0
         for modifier, variable in zip(self.modifiers, self.modifier_vars):
             label = self.modifier_label.get(modifier, modifier)
-            check=Checkbutton(self.frameControlsBasic,
-                command=self.BuildKeyString,
-                text=label,variable=variable,onvalue=modifier,offvalue='')
-            check.grid(row=0,column=column,padx=2,sticky=W)
+            check = Checkbutton(self.frame_controls_basic,
+                                command=self.build_key_string, text=label,
+                                variable=variable, onvalue=modifier, offvalue='')
+            check.grid(row=0, column=column, padx=2, sticky='w')
             self.modifier_checkbuttons[modifier] = check
             column += 1
-        labelFnAdvice=Label(self.frameControlsBasic,justify=LEFT,
-                            text=\
-                            "Select the desired modifier keys\n"+
-                            "above, and the final key from the\n"+
-                            "list on the right.\n\n" +
-                            "Use upper case Symbols when using\n" +
-                            "the Shift modifier.  (Letters will be\n" +
-                            "converted automatically.)")
-        labelFnAdvice.grid(row=1,column=0,columnspan=4,padx=2,sticky=W)
-        self.listKeysFinal=Listbox(self.frameControlsBasic,width=15,height=10,
-                selectmode=SINGLE)
-        self.listKeysFinal.bind('<ButtonRelease-1>',self.FinalKeySelected)
-        self.listKeysFinal.grid(row=0,column=4,rowspan=4,sticky=NS)
-        scrollKeysFinal=Scrollbar(self.frameControlsBasic,orient=VERTICAL,
-                command=self.listKeysFinal.yview)
-        self.listKeysFinal.config(yscrollcommand=scrollKeysFinal.set)
-        scrollKeysFinal.grid(row=0,column=5,rowspan=4,sticky=NS)
-        self.buttonClear=Button(self.frameControlsBasic,
-                text='Clear Keys',command=self.ClearKeySeq)
-        self.buttonClear.grid(row=2,column=0,columnspan=4)
-        labelTitleAdvanced = Label(self.frameKeySeqAdvanced,justify=LEFT,
-                text="Enter new binding(s) for  '"+self.action+"' :\n"+
-                "(These bindings will not be checked for validity!)")
-        labelTitleAdvanced.pack(anchor=W)
-        self.entryKeysAdvanced=Entry(self.frameKeySeqAdvanced,
-                textvariable=self.keyString)
-        self.entryKeysAdvanced.pack(fill=X)
-        labelHelpAdvanced=Label(self.frameHelpAdvanced,justify=LEFT,
+
+        # Basic entry help text.
+        help_basic = Label(self.frame_controls_basic, justify='left',
+                           text="Select the desired modifier keys\n"+
+                                "above, and the final key from the\n"+
+                                "list on the right.\n\n" +
+                                "Use upper case Symbols when using\n" +
+                                "the Shift modifier.  (Letters will be\n" +
+                                "converted automatically.)")
+        help_basic.grid(row=1, column=0, columnspan=4, padx=2, sticky='w')
+
+        # Basic entry key list.
+        self.list_keys_final = Listbox(self.frame_controls_basic, width=15,
+                                       height=10, selectmode='single')
+        self.list_keys_final.insert('end', *AVAILABLE_KEYS)
+        self.list_keys_final.bind('<ButtonRelease-1>', self.final_key_selected)
+        self.list_keys_final.grid(row=0, column=4, rowspan=4, sticky='ns')
+        scroll_keys_final = Scrollbar(self.frame_controls_basic,
+                                      orient='vertical',
+                                      command=self.list_keys_final.yview)
+        self.list_keys_final.config(yscrollcommand=scroll_keys_final.set)
+        scroll_keys_final.grid(row=0, column=5, rowspan=4, sticky='ns')
+        self.button_clear = Button(self.frame_controls_basic,
+                                   text='Clear Keys',
+                                   command=self.clear_key_seq)
+        self.button_clear.grid(row=2, column=0, columnspan=4)
+
+        # Advanced entry key sequence.
+        self.frame_keyseq_advanced = Frame(frame, name='keyseq_advanced')
+        self.frame_keyseq_advanced.grid(row=0, column=0, sticky='nsew',
+                                         padx=5, pady=5)
+        advanced_title = Label(self.frame_keyseq_advanced, justify='left',
+                               text=f"Enter new binding(s) for '{self.action}' :\n" +
+                                     "(These bindings will not be checked for validity!)")
+        advanced_title.pack(anchor='w')
+        self.advanced_keys = Entry(self.frame_keyseq_advanced,
+                                   textvariable=self.key_string)
+        self.advanced_keys.pack(fill='x')
+
+        # Advanced entry help text.
+        self.frame_help_advanced = Frame(frame)
+        self.frame_help_advanced.grid(row=1, column=0, sticky='nsew', padx=5)
+        help_advanced = Label(self.frame_help_advanced, justify='left',
             text="Key bindings are specified using Tkinter keysyms as\n"+
                  "in these samples: <Control-f>, <Shift-F2>, <F12>,\n"
                  "<Control-space>, <Meta-less>, <Control-Alt-Shift-X>.\n"
@@ -140,13 +191,19 @@ class GetKeysDialog(Toplevel):
                  "is the 'do-nothing' keybinding.\n\n" +
                  "Multiple separate bindings for one action should be\n"+
                  "separated by a space, eg., <Alt-v> <Meta-v>." )
-        labelHelpAdvanced.grid(row=0,column=0,sticky=NSEW)
+        help_advanced.grid(row=0, column=0, sticky='nsew')
+
+        # Switch between basic and advanced.
+        self.button_level = Button(frame, command=self.toggle_level,
+                                  text='<< Basic Key Binding Entry')
+        self.button_level.grid(row=2, column=0, stick='ew', padx=5, pady=5)
+        self.toggle_level()
 
-    def SetModifiersForPlatform(self):
+    def set_modifiers_for_platform(self):
         """Determine list of names of key modifiers for this platform.
 
         The names are used to build Tk bindings -- it doesn't matter if the
-        keyboard has these keys, it matters if Tk understands them. The
+        keyboard has these keys; it matters if Tk understands them.  The
         order is also important: key binding equality depends on it, so
         config-keys.def must use the same ordering.
         """
@@ -154,118 +211,87 @@ class GetKeysDialog(Toplevel):
             self.modifiers = ['Shift', 'Control', 'Option', 'Command']
         else:
             self.modifiers = ['Control', 'Alt', 'Shift']
-        self.modifier_label = {'Control': 'Ctrl'} # short name
-
-    def ToggleLevel(self):
-        if  self.buttonLevel.cget('text')[:8]=='Advanced':
-            self.ClearKeySeq()
-            self.buttonLevel.config(text='<< Basic Key Binding Entry')
-            self.frameKeySeqAdvanced.lift()
-            self.frameHelpAdvanced.lift()
-            self.entryKeysAdvanced.focus_set()
+        self.modifier_label = {'Control': 'Ctrl'}  # Short name.
+
+    def toggle_level(self):
+        "Toggle between basic and advanced keys."
+        if  self.button_level.cget('text').startswith('Advanced'):
+            self.clear_key_seq()
+            self.button_level.config(text='<< Basic Key Binding Entry')
+            self.frame_keyseq_advanced.lift()
+            self.frame_help_advanced.lift()
+            self.advanced_keys.focus_set()
             self.advanced = True
         else:
-            self.ClearKeySeq()
-            self.buttonLevel.config(text='Advanced Key Binding Entry >>')
-            self.frameKeySeqBasic.lift()
-            self.frameControlsBasic.lift()
+            self.clear_key_seq()
+            self.button_level.config(text='Advanced Key Binding Entry >>')
+            self.frame_keyseq_basic.lift()
+            self.frame_controls_basic.lift()
             self.advanced = False
 
-    def FinalKeySelected(self,event):
-        self.BuildKeyString()
+    def final_key_selected(self, event=None):
+        "Handler for clicking on key in basic settings list."
+        self.build_key_string()
 
-    def BuildKeyString(self):
-        keyList = modifiers = self.GetModifiers()
-        finalKey = self.listKeysFinal.get(ANCHOR)
-        if finalKey:
-            finalKey = self.TranslateKey(finalKey, modifiers)
-            keyList.append(finalKey)
-        self.keyString.set('<' + '-'.join(keyList) + '>')
+    def build_key_string(self):
+        "Create formatted string of modifiers plus the key."
+        keylist = modifiers = self.get_modifiers()
+        final_key = self.list_keys_final.get('anchor')
+        if final_key:
+            final_key = translate_key(final_key, modifiers)
+            keylist.append(final_key)
+        self.key_string.set(f"<{'-'.join(keylist)}>")
 
-    def GetModifiers(self):
-        modList = [variable.get() for variable in self.modifier_vars]
-        return [mod for mod in modList if mod]
+    def get_modifiers(self):
+        "Return ordered list of modifiers that have been selected."
+        mod_list = [variable.get() for variable in self.modifier_vars]
+        return [mod for mod in mod_list if mod]
 
-    def ClearKeySeq(self):
-        self.listKeysFinal.select_clear(0,END)
-        self.listKeysFinal.yview(MOVETO, '0.0')
+    def clear_key_seq(self):
+        "Clear modifiers and keys selection."
+        self.list_keys_final.select_clear(0, 'end')
+        self.list_keys_final.yview('moveto', '0.0')
         for variable in self.modifier_vars:
             variable.set('')
-        self.keyString.set('')
-
-    def LoadFinalKeyList(self):
-        #these tuples are also available for use in validity checks
-        self.functionKeys=('F1','F2','F3','F4','F5','F6','F7','F8','F9',
-                'F10','F11','F12')
-        self.alphanumKeys=tuple(string.ascii_lowercase+string.digits)
-        self.punctuationKeys=tuple('~!@#%^&*()_-+={}[]|;:,.<>/?')
-        self.whitespaceKeys=('Tab','Space','Return')
-        self.editKeys=('BackSpace','Delete','Insert')
-        self.moveKeys=('Home','End','Page Up','Page Down','Left Arrow',
-                'Right Arrow','Up Arrow','Down Arrow')
-        #make a tuple of most of the useful common 'final' keys
-        keys=(self.alphanumKeys+self.punctuationKeys+self.functionKeys+
-                self.whitespaceKeys+self.editKeys+self.moveKeys)
-        self.listKeysFinal.insert(END, *keys)
-
-    def TranslateKey(self, key, modifiers):
-        "Translate from keycap symbol to the Tkinter keysym"
-        translateDict = {'Space':'space',
-                '~':'asciitilde','!':'exclam','@':'at','#':'numbersign',
-                '%':'percent','^':'asciicircum','&':'ampersand','*':'asterisk',
-                '(':'parenleft',')':'parenright','_':'underscore','-':'minus',
-                '+':'plus','=':'equal','{':'braceleft','}':'braceright',
-                '[':'bracketleft',']':'bracketright','|':'bar',';':'semicolon',
-                ':':'colon',',':'comma','.':'period','<':'less','>':'greater',
-                '/':'slash','?':'question','Page Up':'Prior','Page Down':'Next',
-                'Left Arrow':'Left','Right Arrow':'Right','Up Arrow':'Up',
-                'Down Arrow': 'Down', 'Tab':'Tab'}
-        if key in translateDict:
-            key = translateDict[key]
-        if 'Shift' in modifiers and key in string.ascii_lowercase:
-            key = key.upper()
-        key = 'Key-' + key
-        return key
-
-    def OK(self, event=None):
-        keys = self.keyString.get().strip()
+        self.key_string.set('')
+
+    def ok(self, event=None):
+        keys = self.key_string.get().strip()
         if not keys:
             self.showerror(title=self.keyerror_title, parent=self,
                            message="No key specified.")
             return
-        if (self.advanced or self.KeysOK(keys)) and self.bind_ok(keys):
+        if (self.advanced or self.keys_ok(keys)) and self.bind_ok(keys):
             self.result = keys
         self.grab_release()
         self.destroy()
 
-    def Cancel(self, event=None):
-        self.result=''
+    def cancel(self, event=None):
+        self.result = ''
         self.grab_release()
         self.destroy()
 
-    def KeysOK(self, keys):
-        '''Validity check on user's 'basic' keybinding selection.
+    def keys_ok(self, keys):
+        """Validity check on user's 'basic' keybinding selection.
 
         Doesn't check the string produced by the advanced dialog because
         'modifiers' isn't set.
-
-        '''
-        finalKey = self.listKeysFinal.get(ANCHOR)
-        modifiers = self.GetModifiers()
-        keysOK = False
+        """
+        final_key = self.list_keys_final.get('anchor')
+        modifiers = self.get_modifiers()
         title = self.keyerror_title
-        key_sequences = [key for keylist in self.currentKeySequences
+        key_sequences = [key for keylist in self.current_key_sequences
                              for key in keylist]
         if not keys.endswith('>'):
             self.showerror(title, parent=self,
                            message='Missing the final Key')
         elif (not modifiers
-              and finalKey not in self.functionKeys + self.moveKeys):
+              and final_key not in FUNCTION_KEYS + MOVE_KEYS):
             self.showerror(title=title, parent=self,
                            message='No modifier key(s) specified.')
         elif (modifiers == ['Shift']) \
-                 and (finalKey not in
-                      self.functionKeys + self.moveKeys + ('Tab', 'Space')):
+                 and (final_key not in
+                      FUNCTION_KEYS + MOVE_KEYS + ('Tab', 'Space')):
             msg = 'The shift modifier by itself may not be used with'\
                   ' this key symbol.'
             self.showerror(title=title, parent=self, message=msg)
@@ -273,12 +299,11 @@ class GetKeysDialog(Toplevel):
             msg = 'This key combination is already in use.'
             self.showerror(title=title, parent=self, message=msg)
         else:
-            keysOK = True
-        return keysOK
+            return True
+        return False
 
     def bind_ok(self, keys):
         "Return True if Tcl accepts the new keys else show message."
-
         try:
             binding = self.bind(keys, lambda: None)
         except TclError as err:
index 229dc89874332259e8f20791c9ba186f14de6c5b..5fdaf82de4de7091490b943ca171a83942c7d164 100644 (file)
@@ -14,7 +14,7 @@ from tkinter import (Toplevel, Listbox, Text, Scale, Canvas,
                      TOP, BOTTOM, RIGHT, LEFT, SOLID, GROOVE,
                      NONE, BOTH, X, Y, W, E, EW, NS, NSEW, NW,
                      HORIZONTAL, VERTICAL, ANCHOR, ACTIVE, END)
-from tkinter.ttk import (Button, Checkbutton, Entry, Frame, Label, LabelFrame,
+from tkinter.ttk import (Frame, LabelFrame, Button, Checkbutton, Entry, Label,
                          OptionMenu, Notebook, Radiobutton, Scrollbar, Style)
 import tkinter.colorchooser as tkColorChooser
 import tkinter.font as tkFont
index 09f912c9af336dd4bd490039b5b20f2179d522a4..ccd03e46e161479925f0a7171e9e5a6f9363a8ad 100644 (file)
@@ -2,7 +2,7 @@ import bdb
 import os
 
 from tkinter import *
-from tkinter.ttk import Scrollbar
+from tkinter.ttk import Frame, Scrollbar
 
 from idlelib import macosx
 from idlelib.scrolledlist import ScrolledList
index 6689af64c429be123e789b6347f6f2abbcff64a3..83260329640e1ad96d1275cfe4ed42fac4c5c2dc 100644 (file)
@@ -317,9 +317,6 @@ class EditorWindow(object):
         text.bind("<<zoom-height>>", self.ZoomHeight(self).zoom_height_event)
         text.bind("<<toggle-code-context>>",
                   self.CodeContext(self).toggle_code_context_event)
-        squeezer = self.Squeezer(self)
-        text.bind("<<squeeze-current-text>>",
-                  squeezer.squeeze_current_text_event)
 
     def _filename_to_unicode(self, filename):
         """Return filename as BMP unicode so diplayable in Tk."""
@@ -446,6 +443,16 @@ class EditorWindow(object):
             menu.delete(self.wmenu_end+1, end)
         window.add_windows_to_menu(menu)
 
+    def update_menu_label(self, menu, index, label):
+        "Update label for menu item at index."
+        menuitem = self.menudict[menu]
+        menuitem.entryconfig(index, label=label)
+
+    def update_menu_state(self, menu, index, state):
+        "Update state for menu item at index."
+        menuitem = self.menudict[menu]
+        menuitem.entryconfig(index, state=state)
+
     def handle_yview(self, event, *args):
         "Handle scrollbar."
         if event == 'moveto':
@@ -936,7 +943,7 @@ class EditorWindow(object):
         elif long:
             title = long
         else:
-            title = "Untitled"
+            title = "untitled"
         icon = short or long or title
         if not self.get_saved():
             title = "*%s*" % title
@@ -958,7 +965,7 @@ class EditorWindow(object):
         if filename:
             filename = os.path.basename(filename)
         else:
-            filename = "Untitled"
+            filename = "untitled"
         # return unicode string to display non-ASCII chars correctly
         return self._filename_to_unicode(filename)
 
@@ -1026,7 +1033,7 @@ class EditorWindow(object):
         self.io = None
         self.undo = None
         if self.color:
-            self.color.close(False)
+            self.color.close()
             self.color = None
         self.text = None
         self.tkinter_vars = None
index 8cc293c380dec67f0fb3bc3819976b8100a5d9d8..873233ec15439cc495cb7140b31f3c5321b66762 100644 (file)
@@ -8,7 +8,7 @@ import os
 import sys
 
 from tkinter import StringVar, BooleanVar
-from tkinter.ttk import Checkbutton
+from tkinter.ttk import Checkbutton  # Frame imported in ...Base
 
 from idlelib.searchbase import SearchDialogBase
 from idlelib import searchengine
@@ -173,15 +173,18 @@ class GrepDialog(SearchDialogBase):
 
 def _grep_dialog(parent):  # htest #
     from tkinter import Toplevel, Text, SEL, END
-    from tkinter.ttk import Button
+    from tkinter.ttk import Frame, Button
     from idlelib.pyshell import PyShellFileList
+
     top = Toplevel(parent)
     top.title("Test GrepDialog")
     x, y = map(int, parent.geometry().split('+')[1:])
     top.geometry(f"+{x}+{y + 175}")
 
     flist = PyShellFileList(top)
-    text = Text(top, height=5)
+    frame = Frame(top)
+    frame.pack()
+    text = Text(frame, height=5)
     text.pack()
 
     def show_grep_dialog():
@@ -189,7 +192,7 @@ def _grep_dialog(parent):  # htest #
         grep(text, flist=flist)
         text.tag_remove(SEL, "1.0", END)
 
-    button = Button(top, text="Show GrepDialog", command=show_grep_dialog)
+    button = Button(frame, text="Show GrepDialog", command=show_grep_dialog)
     button.pack()
 
 if __name__ == "__main__":
index e2bf773478e8a58c8d39fd8d8cd85773e41225bf..b654ab7f2c5f863e0272f7b194ec197a3b9a4150 100644 (file)
@@ -6,7 +6,7 @@
   <head>
     <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-    <title>IDLE &#8212; Python 3.8.0a0 documentation</title>
+    <title>IDLE &#8212; Python 3.8.0a1 documentation</title>
     <link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
     <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
 
@@ -19,7 +19,7 @@
     <script type="text/javascript" src="../_static/sidebar.js"></script>
 
     <link rel="search" type="application/opensearchdescription+xml"
-          title="Search within Python 3.8.0a0 documentation"
+          title="Search within Python 3.8.0a1 documentation"
           href="../_static/opensearch.xml"/>
     <link rel="author" title="About these documents" href="../about.html" />
     <link rel="index" title="Index" href="../genindex.html" />
@@ -72,7 +72,7 @@
 
 
     <li>
-      <a href="../index.html">3.8.0a0 Documentation</a> &#187;
+      <a href="../index.html">3.8.0a1 Documentation</a> &#187;
     </li>
 
           <li class="nav-item nav-item-1"><a href="index.html" >The Python Standard Library</a> &#187;</li>
@@ -202,19 +202,20 @@ be undone.</dd>
 <dd>Move cursor to the line number requested and make that line visible.</dd>
 <dt>Show Completions</dt>
 <dd>Open a scrollable list allowing selection of keywords and attributes. See
-Completions in the Tips sections below.</dd>
+<a class="reference internal" href="#completions"><span class="std std-ref">Completions</span></a> in the Editing and navigation section below.</dd>
 <dt>Expand Word</dt>
 <dd>Expand a prefix you have typed to match a full word in the same window;
 repeat to get a different expansion.</dd>
 <dt>Show call tip</dt>
 <dd>After an unclosed parenthesis for a function, open a small window with
-function parameter hints.</dd>
+function parameter hints.  See <a class="reference internal" href="#calltips"><span class="std std-ref">Calltips</span></a> in the
+Editing and navigation section below.</dd>
 <dt>Show surrounding parens</dt>
 <dd>Highlight the surrounding parenthesis.</dd>
 </dl>
 </div>
 <div class="section" id="format-menu-editor-window-only">
-<h3>Format menu (Editor window only)<a class="headerlink" href="#format-menu-editor-window-only" title="Permalink to this headline">¶</a></h3>
+<span id="format-menu"></span><h3>Format menu (Editor window only)<a class="headerlink" href="#format-menu-editor-window-only" title="Permalink to this headline">¶</a></h3>
 <dl class="docutils">
 <dt>Indent Region</dt>
 <dd>Shift selected lines right by the indent width (default 4 spaces).</dd>
@@ -272,6 +273,10 @@ line.</dd>
 <dd>Scroll the shell window to the last Shell restart.</dd>
 <dt>Restart Shell</dt>
 <dd>Restart the shell to clean the environment.</dd>
+<dt>Previous History</dt>
+<dd>Cycle through earlier commands in history which match the current entry.</dd>
+<dt>Next History</dt>
+<dd>Cycle through later commands in history which match the current entry.</dd>
 <dt>Interrupt Execution</dt>
 <dd>Stop a running program.</dd>
 </dl>
@@ -302,32 +307,26 @@ access to locals and globals.</dd>
 <h3>Options menu (Shell and Editor)<a class="headerlink" href="#options-menu-shell-and-editor" title="Permalink to this headline">¶</a></h3>
 <dl class="docutils">
 <dt>Configure IDLE</dt>
-<dd><p class="first">Open a configuration dialog and change preferences for the following:
+<dd>Open a configuration dialog and change preferences for the following:
 fonts, indentation, keybindings, text color themes, startup windows and
-size, additional help sources, and extensions (see below).  On macOS,
-open the configuration dialog by selecting Preferences in the application
-menu.  To use a new built-in color theme (IDLE Dark) with older IDLEs,
-save it as a new custom theme.</p>
-<p class="last">Non-default user settings are saved in a .idlerc directory in the user’s
-home directory.  Problems caused by bad user configuration files are solved
-by editing or deleting one or more of the files in .idlerc.</p>
-</dd>
-<dt>Code Context (toggle)(Editor Window only)</dt>
+size, additional help sources, and extensions.  On macOS,  open the
+configuration dialog by selecting Preferences in the application
+menu. For more, see
+<a class="reference internal" href="#preferences"><span class="std std-ref">Setting preferences</span></a> under Help and preferences.</dd>
+<dt>Zoom/Restore Height</dt>
+<dd>Toggles the window between normal size and maximum height. The initial size
+defaults to 40 lines by 80 chars unless changed on the General tab of the
+Configure IDLE dialog.</dd>
+<dt>Show/Hide Code Context (Editor Window only)</dt>
 <dd>Open a pane at the top of the edit window which shows the block context
-of the code which has scrolled above the top of the window.  Clicking a
-line in this pane exposes that line at the top of the editor.</dd>
+of the code which has scrolled above the top of the window.  See
+<a class="reference internal" href="#code-context"><span class="std std-ref">Code Context</span></a> in the Editing and Navigation section below.</dd>
 </dl>
 </div>
 <div class="section" id="window-menu-shell-and-editor">
 <h3>Window menu (Shell and Editor)<a class="headerlink" href="#window-menu-shell-and-editor" title="Permalink to this headline">¶</a></h3>
-<dl class="docutils">
-<dt>Zoom Height</dt>
-<dd>Toggles the window between normal size and maximum height. The initial size
-defaults to 40 lines by 80 chars unless changed on the General tab of the
-Configure IDLE dialog.</dd>
-</dl>
-<p>The rest of this menu lists the names of all open windows; select one to bring
-it to the foreground (deiconifying it if necessary).</p>
+<p>Lists the names of all open windows; select one to bring it to the foreground
+(deiconifying it if necessary).</p>
 </div>
 <div class="section" id="help-menu-shell-and-editor">
 <h3>Help menu (Shell and Editor)<a class="headerlink" href="#help-menu-shell-and-editor" title="Permalink to this headline">¶</a></h3>
@@ -344,8 +343,8 @@ and open docs.python.org showing the latest Python documentation.</dd>
 <dd>Run the turtledemo module with example Python code and turtle drawings.</dd>
 </dl>
 <p>Additional help sources may be added here with the Configure IDLE dialog under
-the General tab. See the “Help sources” subsection below for more
-on Help menu choices.</p>
+the General tab. See the <a class="reference internal" href="#help-sources"><span class="std std-ref">Help sources</span></a> subsection below
+for more on Help menu choices.</p>
 </div>
 <div class="section" id="context-menus">
 <span id="index-4"></span><h3>Context Menus<a class="headerlink" href="#context-menus" title="Permalink to this headline">¶</a></h3>
@@ -383,7 +382,7 @@ the code above and the prompt below down to a ‘Squeezed text’ label.</dd>
 </div>
 </div>
 <div class="section" id="editing-and-navigation">
-<h2>Editing and navigation<a class="headerlink" href="#editing-and-navigation" title="Permalink to this headline">¶</a></h2>
+<span id="id2"></span><h2>Editing and navigation<a class="headerlink" href="#editing-and-navigation" title="Permalink to this headline">¶</a></h2>
 <div class="section" id="editor-windows">
 <h3>Editor windows<a class="headerlink" href="#editor-windows" title="Permalink to this headline">¶</a></h3>
 <p>IDLE may open editor windows when it starts, depending on settings
@@ -442,10 +441,11 @@ the next line is dedented.  In leading indentation, <kbd class="kbd docutils lit
 to 4 spaces if they are there. <kbd class="kbd docutils literal notranslate">Tab</kbd> inserts spaces (in the Python
 Shell window one tab), number depends on Indent width. Currently, tabs
 are restricted to four spaces due to Tcl/Tk limitations.</p>
-<p>See also the indent/dedent region commands in the edit menu.</p>
+<p>See also the indent/dedent region commands on the
+<a class="reference internal" href="#format-menu"><span class="std std-ref">Format menu</span></a>.</p>
 </div>
 <div class="section" id="completions">
-<h3>Completions<a class="headerlink" href="#completions" title="Permalink to this headline">¶</a></h3>
+<span id="id3"></span><h3>Completions<a class="headerlink" href="#completions" title="Permalink to this headline">¶</a></h3>
 <p>Completions are supplied for functions, classes, and attributes of classes,
 both built-in and user-defined. Completions are also provided for
 filenames.</p>
@@ -480,7 +480,7 @@ much can be found by default, e.g. the re module.</p>
 longer or disable the extension.</p>
 </div>
 <div class="section" id="calltips">
-<h3>Calltips<a class="headerlink" href="#calltips" title="Permalink to this headline">¶</a></h3>
+<span id="id4"></span><h3>Calltips<a class="headerlink" href="#calltips" title="Permalink to this headline">¶</a></h3>
 <p>A calltip is shown when one types <kbd class="kbd docutils literal notranslate">(</kbd> after the name of an <em>accessible</em>
 function.  A name expression may include dots and subscripts.  A calltip
 remains until it is clicked, the cursor is moved out of the argument area,
@@ -502,6 +502,21 @@ not import turtle.  The menu or shortcut do nothing either.  Enter
 might want to run a file after writing the import statements at the top,
 or immediately run an existing file before editing.</p>
 </div>
+<div class="section" id="code-context">
+<span id="id5"></span><h3>Code Context<a class="headerlink" href="#code-context" title="Permalink to this headline">¶</a></h3>
+<p>Within an editor window containing Python code, code context can be toggled
+in order to show or hide a pane at the top of the window.  When shown, this
+pane freezes the opening lines for block code, such as those beginning with
+<code class="docutils literal notranslate"><span class="pre">class</span></code>, <code class="docutils literal notranslate"><span class="pre">def</span></code>, or <code class="docutils literal notranslate"><span class="pre">if</span></code> keywords, that would have otherwise scrolled
+out of view.  The size of the pane will be expanded and contracted as needed
+to show the all current levels of context, up to the maximum number of
+lines defined in the Configure IDLE dialog (which defaults to 15).  If there
+are no current context lines and the feature is toggled on, a single blank
+line will display.  Clicking on a line in the context pane will move that
+line to the top of the editor.</p>
+<p>The text and background colors for the context pane can be configured under
+the Highlights tab in the Configure IDLE dialog.</p>
+</div>
 <div class="section" id="python-shell-window">
 <h3>Python Shell window<a class="headerlink" href="#python-shell-window" title="Permalink to this headline">¶</a></h3>
 <p>With IDLE’s Shell, one enters, edits, and recalls complete statements.
@@ -658,14 +673,31 @@ output to Shell will eventually fill memory, resulting in a memory error.
 In contrast, some system text windows only keep the last n lines of output.
 A Windows console, for instance, keeps a user-settable 1 to 9999 lines,
 with 300 the default.</p>
-<p>Text widgets display a subset of Unicode, the Basic Multilingual Plane (BMP).
-Which characters get a proper glyph instead of a replacement box depends on
-the operating system and installed fonts.  Newline characters cause following
-text to appear on a new line, but other control characters are either
-replaced with a box or deleted.  However, <code class="docutils literal notranslate"><span class="pre">repr()</span></code>, which is used for
-interactive echo of expression values, replaces control characters,
-some BMP codepoints, and all non-BMP characters with escape codes
-before they are output.</p>
+<p>A Tk Text widget, and hence IDLE’s Shell, displays characters (codepoints)
+in the the BMP (Basic Multilingual Plane) subset of Unicode.
+Which characters are displayed with a proper glyph and which with a
+replacement box depends on the operating system and installed fonts.
+Tab characters cause the following text to begin after
+the next tab stop. (They occur every 8 ‘characters’).
+Newline characters cause following text to appear on a new line.
+Other control characters are ignored or displayed as a space, box, or
+something else, depending on the operating system and font.
+(Moving the text cursor through such output with arrow keys may exhibit
+some surprising spacing behavior.)</p>
+<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt;&gt;&gt; s = &#39;a\tb\a&lt;\x02&gt;&lt;\r&gt;\bc\nd&#39;
+&gt;&gt;&gt; len(s)
+14
+&gt;&gt;&gt; s  # Display repr(s)
+&#39;a\tb\x07&lt;\x02&gt;&lt;\r&gt;\x08c\nd&#39;
+&gt;&gt;&gt; print(s, end=&#39;&#39;)  # Display s as is.
+# Result varies by OS and font.  Try it.
+</pre></div>
+</div>
+<p>The <code class="docutils literal notranslate"><span class="pre">repr</span></code> function is used for interactive echo of expression
+values.  It returns an altered version of the input string in which
+control codes, some BMP codepoints, and all non-BMP codepoints are
+replaced with escape codes. As demonstrated above, it allows one to
+identify the characters in a string, regardless of how they are displayed.</p>
 <p>Normal and error output are generally kept separate (on separate lines)
 from code input and each other.  They each get different highlight colors.</p>
 <p>For SyntaxError tracebacks, the normal ‘^’ marking where the error was
@@ -733,7 +765,7 @@ with the default subprocess if at all possible.</p>
 <div class="section" id="help-and-preferences">
 <h2>Help and preferences<a class="headerlink" href="#help-and-preferences" title="Permalink to this headline">¶</a></h2>
 <div class="section" id="help-sources">
-<h3>Help sources<a class="headerlink" href="#help-sources" title="Permalink to this headline">¶</a></h3>
+<span id="id6"></span><h3>Help sources<a class="headerlink" href="#help-sources" title="Permalink to this headline">¶</a></h3>
 <p>Help menu entry “IDLE Help” displays a formatted html version of the
 IDLE chapter of the Library Reference.  The result, in a read-only
 tkinter text window, is close to what one sees in a web browser.
@@ -750,11 +782,22 @@ that will be opened instead.</p>
 General tab of the Configure IDLE dialog .</p>
 </div>
 <div class="section" id="setting-preferences">
-<h3>Setting preferences<a class="headerlink" href="#setting-preferences" title="Permalink to this headline">¶</a></h3>
+<span id="preferences"></span><h3>Setting preferences<a class="headerlink" href="#setting-preferences" title="Permalink to this headline">¶</a></h3>
 <p>The font preferences, highlighting, keys, and general preferences can be
-changed via Configure IDLE on the Option menu.  Keys can be user defined;
-IDLE ships with four built-in key sets. In addition, a user can create a
-custom key set in the Configure IDLE dialog under the keys tab.</p>
+changed via Configure IDLE on the Option menu.
+Non-default user settings are saved in a .idlerc directory in the user’s
+home directory.  Problems caused by bad user configuration files are solved
+by editing or deleting one or more of the files in .idlerc.</p>
+<p>On the Font tab, see the text sample for the effect of font face and size
+on multiple characters in multiple languages.  Edit the sample to add
+other characters of personal interest.  Use the sample to select
+monospaced fonts.  If particular characters have problems in Shell or an
+editor, add them to the top of the sample and try changing first size
+and then font.</p>
+<p>On the Highlights and Keys tab, select a built-in or custom color theme
+and key set.  To use a newer built-in color theme or key set with older
+IDLEs, save it as a new custom theme or key set and it well be accessible
+to older IDLEs.</p>
 </div>
 <div class="section" id="idle-on-macos">
 <h3>IDLE on macOS<a class="headerlink" href="#idle-on-macos" title="Permalink to this headline">¶</a></h3>
@@ -801,6 +844,7 @@ also used for testing.</p>
 <li><a class="reference internal" href="#automatic-indentation">Automatic indentation</a></li>
 <li><a class="reference internal" href="#completions">Completions</a></li>
 <li><a class="reference internal" href="#calltips">Calltips</a></li>
+<li><a class="reference internal" href="#code-context">Code Context</a></li>
 <li><a class="reference internal" href="#python-shell-window">Python Shell window</a></li>
 <li><a class="reference internal" href="#text-colors">Text colors</a></li>
 </ul>
@@ -868,7 +912,7 @@ also used for testing.</p>
 
 
     <li>
-      <a href="../index.html">3.8.0a0 Documentation</a> &#187;
+      <a href="../index.html">3.8.0a1 Documentation</a> &#187;
     </li>
 
           <li class="nav-item nav-item-1"><a href="index.html" >The Python Standard Library</a> &#187;</li>
@@ -891,7 +935,7 @@ also used for testing.</p>
       </ul>
     </div>
     <div class="footer">
-    &copy; <a href="../copyright.html">Copyright</a> 2001-2018, Python Software Foundation.
+    &copy; <a href="../copyright.html">Copyright</a> 2001-2019, Python Software Foundation.
     <br />
 
     The Python Software Foundation is a non-profit corporation.
@@ -899,7 +943,7 @@ also used for testing.</p>
 <br />
     <br />
 
-    Last updated on Nov 12, 2018.
+    Last updated on Feb 23, 2019.
     <a href="https://docs.python.org/3/bugs.html">Found a bug</a>?
     <br />
 
index 583e607b767e2e1243acf64b3280402e4e855707..429081f7ef25a8a423c8434bbdcf4fc071376a54 100644 (file)
@@ -141,12 +141,11 @@ _editor_window_spec = {
            "Best to close editor first."
     }
 
-# Update once issue21519 is resolved.
 GetKeysDialog_spec = {
     'file': 'config_key',
     'kwds': {'title': 'Test keybindings',
              'action': 'find-again',
-             'currentKeySequences': [''] ,
+             'current_key_sequences': [['<Control-Key-g>', '<Key-F3>', '<Control-Key-G>']],
              '_htest': True,
              },
     'msg': "Test for different key modifier sequences.\n"
index 0698d4f8b99ea993091ca3ee357054ceb800c8b1..833351bd799601de55c6c445c637a2f929ed76db 100644 (file)
@@ -99,6 +99,35 @@ non-overlapping occurrences o...''')
     drop_whitespace=True, break_on_hyphens=True, tabsize=8, *, max_lines=None,
     placeholder=' [...]')''')
 
+    def test_properly_formated(self):
+        def foo(s='a'*100):
+            pass
+
+        def bar(s='a'*100):
+            """Hello Guido"""
+            pass
+
+        def baz(s='a'*100, z='b'*100):
+            pass
+
+        indent = calltip._INDENT
+
+        str_foo = "(s='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"\
+                  "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + indent + "aaaaaaaaa"\
+                  "aaaaaaaaaa')"
+        str_bar = "(s='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"\
+                  "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + indent + "aaaaaaaaa"\
+                  "aaaaaaaaaa')\nHello Guido"
+        str_baz = "(s='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"\
+                  "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + indent + "aaaaaaaaa"\
+                  "aaaaaaaaaa', z='bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"\
+                  "bbbbbbbbbbbbbbbbb\n" + indent + "bbbbbbbbbbbbbbbbbbbbbb"\
+                  "bbbbbbbbbbbbbbbbbbbbbb')"
+
+        self.assertEqual(calltip.get_argspec(foo), str_foo)
+        self.assertEqual(calltip.get_argspec(bar), str_bar)
+        self.assertEqual(calltip.get_argspec(baz), str_baz)
+
     def test_docline_truncation(self):
         def f(): pass
         f.__doc__ = 'a'*300
index ef8170e3b6964d7987eab200a81d31eed66d5664..6c6893580f42f6c9ed584c50eafe3f9aaa518bfc 100644 (file)
@@ -40,6 +40,10 @@ class DummyEditwin:
         self.top = root
         self.text_frame = frame
         self.text = text
+        self.label = ''
+
+    def update_menu_label(self, **kwargs):
+        self.label = kwargs['label']
 
 
 class CodeContextTest(unittest.TestCase):
@@ -127,10 +131,12 @@ class CodeContextTest(unittest.TestCase):
         eq(cc.context['fg'], cc.colors['foreground'])
         eq(cc.context['bg'], cc.colors['background'])
         eq(cc.context.get('1.0', 'end-1c'), '')
+        eq(cc.editwin.label, 'Hide Code Context')
 
         # Toggle off.
         eq(toggle(), 'break')
         self.assertIsNone(cc.context)
+        eq(cc.editwin.label, 'Show Code Context')
 
     def test_get_context(self):
         eq = self.assertEqual
index 1e74bed1f0c0f08bea31c30c5627eec23c327b76..c31c49236ca0b9854d1272ca5e6f59a953a176d4 100644 (file)
-"Test colorizer, coverage 25%."
+"Test colorizer, coverage 93%."
 
 from idlelib import colorizer
 from test.support import requires
-from tkinter import Tk, Text
 import unittest
+from unittest import mock
+
+from functools import partial
+from tkinter import Tk, Text
+from idlelib import config
+from idlelib.percolator import Percolator
+
+
+usercfg = colorizer.idleConf.userCfg
+testcfg = {
+    'main': config.IdleUserConfParser(''),
+    'highlight': config.IdleUserConfParser(''),
+    'keys': config.IdleUserConfParser(''),
+    'extensions': config.IdleUserConfParser(''),
+}
+
+source = (
+    "if True: int ('1') # keyword, builtin, string, comment\n"
+    "elif False: print(0)  # 'string' in comment\n"
+    "else: float(None)  # if in comment\n"
+    "if iF + If + IF: 'keyword matching must respect case'\n"
+    "if'': x or''  # valid string-keyword no-space combinations\n"
+    "async def f(): await g()\n"
+    "'x', '''x''', \"x\", \"\"\"x\"\"\"\n"
+    )
+
+
+def setUpModule():
+    colorizer.idleConf.userCfg = testcfg
+
+
+def tearDownModule():
+    colorizer.idleConf.userCfg = usercfg
 
 
 class FunctionTest(unittest.TestCase):
 
     def test_any(self):
-        self.assertTrue(colorizer.any('test', ('a', 'b')))
+        self.assertEqual(colorizer.any('test', ('a', 'b', 'cd')),
+                         '(?P<test>a|b|cd)')
 
     def test_make_pat(self):
+        # Tested in more detail by testing prog.
         self.assertTrue(colorizer.make_pat())
 
+    def test_prog(self):
+        prog = colorizer.prog
+        eq = self.assertEqual
+        line = 'def f():\n    print("hello")\n'
+        m = prog.search(line)
+        eq(m.groupdict()['KEYWORD'], 'def')
+        m = prog.search(line, m.end())
+        eq(m.groupdict()['SYNC'], '\n')
+        m = prog.search(line, m.end())
+        eq(m.groupdict()['BUILTIN'], 'print')
+        m = prog.search(line, m.end())
+        eq(m.groupdict()['STRING'], '"hello"')
+        m = prog.search(line, m.end())
+        eq(m.groupdict()['SYNC'], '\n')
+
+    def test_idprog(self):
+        idprog = colorizer.idprog
+        m = idprog.match('nospace')
+        self.assertIsNone(m)
+        m = idprog.match(' space')
+        self.assertEqual(m.group(0), ' space')
+
 
 class ColorConfigTest(unittest.TestCase):
 
     @classmethod
     def setUpClass(cls):
         requires('gui')
-        cls.root = Tk()
-        cls.text = Text(cls.root)
+        root = cls.root = Tk()
+        root.withdraw()
+        cls.text = Text(root)
+
+    @classmethod
+    def tearDownClass(cls):
+        del cls.text
+        cls.root.update_idletasks()
+        cls.root.destroy()
+        del cls.root
+
+    def test_color_config(self):
+        text = self.text
+        eq = self.assertEqual
+        colorizer.color_config(text)
+        # Uses IDLE Classic theme as default.
+        eq(text['background'], '#ffffff')
+        eq(text['foreground'], '#000000')
+        eq(text['selectbackground'], 'gray')
+        eq(text['selectforeground'], '#000000')
+        eq(text['insertbackground'], 'black')
+        eq(text['inactiveselectbackground'], 'gray')
+
+
+class ColorDelegatorInstantiationTest(unittest.TestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        requires('gui')
+        root = cls.root = Tk()
+        root.withdraw()
+        text = cls.text = Text(root)
 
     @classmethod
     def tearDownClass(cls):
         del cls.text
+        cls.root.update_idletasks()
         cls.root.destroy()
         del cls.root
 
-    def test_colorizer(self):
-        colorizer.color_config(self.text)
+    def setUp(self):
+        self.color = colorizer.ColorDelegator()
+
+    def tearDown(self):
+        self.color.close()
+        self.text.delete('1.0', 'end')
+        self.color.resetcache()
+        del self.color
+
+    def test_init(self):
+        color = self.color
+        self.assertIsInstance(color, colorizer.ColorDelegator)
+
+    def test_init_state(self):
+        # init_state() is called during the instantiation of
+        # ColorDelegator in setUp().
+        color = self.color
+        self.assertIsNone(color.after_id)
+        self.assertTrue(color.allow_colorizing)
+        self.assertFalse(color.colorizing)
+        self.assertFalse(color.stop_colorizing)
 
 
 class ColorDelegatorTest(unittest.TestCase):
@@ -38,15 +144,279 @@ class ColorDelegatorTest(unittest.TestCase):
     @classmethod
     def setUpClass(cls):
         requires('gui')
-        cls.root = Tk()
+        root = cls.root = Tk()
+        root.withdraw()
+        text = cls.text = Text(root)
+        cls.percolator = Percolator(text)
+        # Delegator stack = [Delegator(text)]
 
     @classmethod
     def tearDownClass(cls):
+        cls.percolator.redir.close()
+        del cls.percolator, cls.text
+        cls.root.update_idletasks()
         cls.root.destroy()
         del cls.root
 
-    def test_colorizer(self):
-        colorizer.ColorDelegator()
+    def setUp(self):
+        self.color = colorizer.ColorDelegator()
+        self.percolator.insertfilter(self.color)
+        # Calls color.setdelegate(Delegator(text)).
+
+    def tearDown(self):
+        self.color.close()
+        self.percolator.removefilter(self.color)
+        self.text.delete('1.0', 'end')
+        self.color.resetcache()
+        del self.color
+
+    def test_setdelegate(self):
+        # Called in setUp when filter is attached to percolator.
+        color = self.color
+        self.assertIsInstance(color.delegate, colorizer.Delegator)
+        # It is too late to mock notify_range, so test side effect.
+        self.assertEqual(self.root.tk.call(
+            'after', 'info', color.after_id)[1], 'timer')
+
+    def test_LoadTagDefs(self):
+        highlight = partial(config.idleConf.GetHighlight, theme='IDLE Classic')
+        for tag, colors in self.color.tagdefs.items():
+            with self.subTest(tag=tag):
+                self.assertIn('background', colors)
+                self.assertIn('foreground', colors)
+                if tag not in ('SYNC', 'TODO'):
+                    self.assertEqual(colors, highlight(element=tag.lower()))
+
+    def test_config_colors(self):
+        text = self.text
+        highlight = partial(config.idleConf.GetHighlight, theme='IDLE Classic')
+        for tag in self.color.tagdefs:
+            for plane in ('background', 'foreground'):
+                with self.subTest(tag=tag, plane=plane):
+                    if tag in ('SYNC', 'TODO'):
+                        self.assertEqual(text.tag_cget(tag, plane), '')
+                    else:
+                        self.assertEqual(text.tag_cget(tag, plane),
+                                         highlight(element=tag.lower())[plane])
+        # 'sel' is marked as the highest priority.
+        self.assertEqual(text.tag_names()[-1], 'sel')
+
+    @mock.patch.object(colorizer.ColorDelegator, 'notify_range')
+    def test_insert(self, mock_notify):
+        text = self.text
+        # Initial text.
+        text.insert('insert', 'foo')
+        self.assertEqual(text.get('1.0', 'end'), 'foo\n')
+        mock_notify.assert_called_with('1.0', '1.0+3c')
+        # Additional text.
+        text.insert('insert', 'barbaz')
+        self.assertEqual(text.get('1.0', 'end'), 'foobarbaz\n')
+        mock_notify.assert_called_with('1.3', '1.3+6c')
+
+    @mock.patch.object(colorizer.ColorDelegator, 'notify_range')
+    def test_delete(self, mock_notify):
+        text = self.text
+        # Initialize text.
+        text.insert('insert', 'abcdefghi')
+        self.assertEqual(text.get('1.0', 'end'), 'abcdefghi\n')
+        # Delete single character.
+        text.delete('1.7')
+        self.assertEqual(text.get('1.0', 'end'), 'abcdefgi\n')
+        mock_notify.assert_called_with('1.7')
+        # Delete multiple characters.
+        text.delete('1.3', '1.6')
+        self.assertEqual(text.get('1.0', 'end'), 'abcgi\n')
+        mock_notify.assert_called_with('1.3')
+
+    def test_notify_range(self):
+        text = self.text
+        color = self.color
+        eq = self.assertEqual
+
+        # Colorizing already scheduled.
+        save_id = color.after_id
+        eq(self.root.tk.call('after', 'info', save_id)[1], 'timer')
+        self.assertFalse(color.colorizing)
+        self.assertFalse(color.stop_colorizing)
+        self.assertTrue(color.allow_colorizing)
+
+        # Coloring scheduled and colorizing in progress.
+        color.colorizing = True
+        color.notify_range('1.0', 'end')
+        self.assertFalse(color.stop_colorizing)
+        eq(color.after_id, save_id)
+
+        # No colorizing scheduled and colorizing in progress.
+        text.after_cancel(save_id)
+        color.after_id = None
+        color.notify_range('1.0', '1.0+3c')
+        self.assertTrue(color.stop_colorizing)
+        self.assertIsNotNone(color.after_id)
+        eq(self.root.tk.call('after', 'info', color.after_id)[1], 'timer')
+        # New event scheduled.
+        self.assertNotEqual(color.after_id, save_id)
+
+        # No colorizing scheduled and colorizing off.
+        text.after_cancel(color.after_id)
+        color.after_id = None
+        color.allow_colorizing = False
+        color.notify_range('1.4', '1.4+10c')
+        # Nothing scheduled when colorizing is off.
+        self.assertIsNone(color.after_id)
+
+    def test_toggle_colorize_event(self):
+        color = self.color
+        eq = self.assertEqual
+
+        # Starts with colorizing allowed and scheduled.
+        self.assertFalse(color.colorizing)
+        self.assertFalse(color.stop_colorizing)
+        self.assertTrue(color.allow_colorizing)
+        eq(self.root.tk.call('after', 'info', color.after_id)[1], 'timer')
+
+        # Toggle colorizing off.
+        color.toggle_colorize_event()
+        self.assertIsNone(color.after_id)
+        self.assertFalse(color.colorizing)
+        self.assertFalse(color.stop_colorizing)
+        self.assertFalse(color.allow_colorizing)
+
+        # Toggle on while colorizing in progress (doesn't add timer).
+        color.colorizing = True
+        color.toggle_colorize_event()
+        self.assertIsNone(color.after_id)
+        self.assertTrue(color.colorizing)
+        self.assertFalse(color.stop_colorizing)
+        self.assertTrue(color.allow_colorizing)
+
+        # Toggle off while colorizing in progress.
+        color.toggle_colorize_event()
+        self.assertIsNone(color.after_id)
+        self.assertTrue(color.colorizing)
+        self.assertTrue(color.stop_colorizing)
+        self.assertFalse(color.allow_colorizing)
+
+        # Toggle on while colorizing not in progress.
+        color.colorizing = False
+        color.toggle_colorize_event()
+        eq(self.root.tk.call('after', 'info', color.after_id)[1], 'timer')
+        self.assertFalse(color.colorizing)
+        self.assertTrue(color.stop_colorizing)
+        self.assertTrue(color.allow_colorizing)
+
+    @mock.patch.object(colorizer.ColorDelegator, 'recolorize_main')
+    def test_recolorize(self, mock_recmain):
+        text = self.text
+        color = self.color
+        eq = self.assertEqual
+        # Call recolorize manually and not scheduled.
+        text.after_cancel(color.after_id)
+
+        # No delegate.
+        save_delegate = color.delegate
+        color.delegate = None
+        color.recolorize()
+        mock_recmain.assert_not_called()
+        color.delegate = save_delegate
+
+        # Toggle off colorizing.
+        color.allow_colorizing = False
+        color.recolorize()
+        mock_recmain.assert_not_called()
+        color.allow_colorizing = True
+
+        # Colorizing in progress.
+        color.colorizing = True
+        color.recolorize()
+        mock_recmain.assert_not_called()
+        color.colorizing = False
+
+        # Colorizing is done, but not completed, so rescheduled.
+        color.recolorize()
+        self.assertFalse(color.stop_colorizing)
+        self.assertFalse(color.colorizing)
+        mock_recmain.assert_called()
+        eq(mock_recmain.call_count, 1)
+        # Rescheduled when TODO tag still exists.
+        eq(self.root.tk.call('after', 'info', color.after_id)[1], 'timer')
+
+        # No changes to text, so no scheduling added.
+        text.tag_remove('TODO', '1.0', 'end')
+        color.recolorize()
+        self.assertFalse(color.stop_colorizing)
+        self.assertFalse(color.colorizing)
+        mock_recmain.assert_called()
+        eq(mock_recmain.call_count, 2)
+        self.assertIsNone(color.after_id)
+
+    @mock.patch.object(colorizer.ColorDelegator, 'notify_range')
+    def test_recolorize_main(self, mock_notify):
+        text = self.text
+        color = self.color
+        eq = self.assertEqual
+
+        text.insert('insert', source)
+        expected = (('1.0', ('KEYWORD',)), ('1.2', ()), ('1.3', ('KEYWORD',)),
+                    ('1.7', ()), ('1.9', ('BUILTIN',)), ('1.14', ('STRING',)),
+                    ('1.19', ('COMMENT',)),
+                    ('2.1', ('KEYWORD',)), ('2.18', ()), ('2.25', ('COMMENT',)),
+                    ('3.6', ('BUILTIN',)), ('3.12', ('KEYWORD',)), ('3.21', ('COMMENT',)),
+                    ('4.0', ('KEYWORD',)), ('4.3', ()), ('4.6', ()),
+                    ('5.2', ('STRING',)), ('5.8', ('KEYWORD',)), ('5.10', ('STRING',)),
+                    ('6.0', ('KEYWORD',)), ('6.10', ('DEFINITION',)), ('6.11', ()),
+                    ('7.0', ('STRING',)), ('7.4', ()), ('7.5', ('STRING',)),
+                    ('7.12', ()), ('7.14', ('STRING',)),
+                    # SYNC at the end of every line.
+                    ('1.55', ('SYNC',)), ('2.50', ('SYNC',)), ('3.34', ('SYNC',)),
+                   )
+
+        # Nothing marked to do therefore no tags in text.
+        text.tag_remove('TODO', '1.0', 'end')
+        color.recolorize_main()
+        for tag in text.tag_names():
+            with self.subTest(tag=tag):
+                eq(text.tag_ranges(tag), ())
+
+        # Source marked for processing.
+        text.tag_add('TODO', '1.0', 'end')
+        # Check some indexes.
+        color.recolorize_main()
+        for index, expected_tags in expected:
+            with self.subTest(index=index):
+                eq(text.tag_names(index), expected_tags)
+
+        # Check for some tags for ranges.
+        eq(text.tag_nextrange('TODO', '1.0'), ())
+        eq(text.tag_nextrange('KEYWORD', '1.0'), ('1.0', '1.2'))
+        eq(text.tag_nextrange('COMMENT', '2.0'), ('2.22', '2.43'))
+        eq(text.tag_nextrange('SYNC', '2.0'), ('2.43', '3.0'))
+        eq(text.tag_nextrange('STRING', '2.0'), ('4.17', '4.53'))
+        eq(text.tag_nextrange('STRING', '7.0'), ('7.0', '7.3'))
+        eq(text.tag_nextrange('STRING', '7.3'), ('7.5', '7.12'))
+        eq(text.tag_nextrange('STRING', '7.12'), ('7.14', '7.17'))
+        eq(text.tag_nextrange('STRING', '7.17'), ('7.19', '7.26'))
+        eq(text.tag_nextrange('SYNC', '7.0'), ('7.26', '9.0'))
+
+    @mock.patch.object(colorizer.ColorDelegator, 'recolorize')
+    @mock.patch.object(colorizer.ColorDelegator, 'notify_range')
+    def test_removecolors(self, mock_notify, mock_recolorize):
+        text = self.text
+        color = self.color
+        text.insert('insert', source)
+
+        color.recolorize_main()
+        # recolorize_main doesn't add these tags.
+        text.tag_add("ERROR", "1.0")
+        text.tag_add("TODO", "1.0")
+        text.tag_add("hit", "1.0")
+        for tag in color.tagdefs:
+            with self.subTest(tag=tag):
+                self.assertNotEqual(text.tag_ranges(tag), ())
+
+        color.removecolors()
+        for tag in color.tagdefs:
+            with self.subTest(tag=tag):
+                self.assertEqual(text.tag_ranges(tag), ())
 
 
 if __name__ == '__main__':
index abe574912c55d949ed93e549609ea49c1a7558e6..b7fe7fd6b5ec106edf705678b1e8942837bb84c9 100644 (file)
@@ -1,23 +1,31 @@
-"Test config_key, coverage 75%"
+"""Test config_key, coverage 98%.
+
+Coverage is effectively 100%.  Tkinter dialog is mocked, Mac-only line
+may be skipped, and dummy function in bind test should not be called.
+Not tested: exit with 'self.advanced or self.keys_ok(keys)) ...' False.
+"""
 
 from idlelib import config_key
 from test.support import requires
 import unittest
-from tkinter import Tk
+from unittest import mock
+from tkinter import Tk, TclError
 from idlelib.idle_test.mock_idle import Func
 from idlelib.idle_test.mock_tk import Mbox_func
 
+gkd = config_key.GetKeysDialog
+
 
 class ValidationTest(unittest.TestCase):
-    "Test validation methods: OK, KeysOK, bind_ok."
+    "Test validation methods: ok, keys_ok, bind_ok."
 
-    class Validator(config_key.GetKeysDialog):
+    class Validator(gkd):
         def __init__(self, *args, **kwargs):
             config_key.GetKeysDialog.__init__(self, *args, **kwargs)
-            class listKeysFinal:
+            class list_keys_final:
                 get = Func()
-            self.listKeysFinal = listKeysFinal
-        GetModifiers = Func()
+            self.list_keys_final = list_keys_final
+        get_modifiers = Func()
         showerror = Mbox_func()
 
     @classmethod
@@ -31,7 +39,7 @@ class ValidationTest(unittest.TestCase):
 
     @classmethod
     def tearDownClass(cls):
-        cls.dialog.Cancel()
+        cls.dialog.cancel()
         cls.root.update_idletasks()
         cls.root.destroy()
         del cls.dialog, cls.root
@@ -42,49 +50,49 @@ class ValidationTest(unittest.TestCase):
     # A test that sets a non-blank modifier list should reset it to [].
 
     def test_ok_empty(self):
-        self.dialog.keyString.set(' ')
-        self.dialog.OK()
+        self.dialog.key_string.set(' ')
+        self.dialog.ok()
         self.assertEqual(self.dialog.result, '')
         self.assertEqual(self.dialog.showerror.message, 'No key specified.')
 
     def test_ok_good(self):
-        self.dialog.keyString.set('<Key-F11>')
-        self.dialog.listKeysFinal.get.result = 'F11'
-        self.dialog.OK()
+        self.dialog.key_string.set('<Key-F11>')
+        self.dialog.list_keys_final.get.result = 'F11'
+        self.dialog.ok()
         self.assertEqual(self.dialog.result, '<Key-F11>')
         self.assertEqual(self.dialog.showerror.message, '')
 
     def test_keys_no_ending(self):
-        self.assertFalse(self.dialog.KeysOK('<Control-Shift'))
+        self.assertFalse(self.dialog.keys_ok('<Control-Shift'))
         self.assertIn('Missing the final', self.dialog.showerror.message)
 
     def test_keys_no_modifier_bad(self):
-        self.dialog.listKeysFinal.get.result = 'A'
-        self.assertFalse(self.dialog.KeysOK('<Key-A>'))
+        self.dialog.list_keys_final.get.result = 'A'
+        self.assertFalse(self.dialog.keys_ok('<Key-A>'))
         self.assertIn('No modifier', self.dialog.showerror.message)
 
     def test_keys_no_modifier_ok(self):
-        self.dialog.listKeysFinal.get.result = 'F11'
-        self.assertTrue(self.dialog.KeysOK('<Key-F11>'))
+        self.dialog.list_keys_final.get.result = 'F11'
+        self.assertTrue(self.dialog.keys_ok('<Key-F11>'))
         self.assertEqual(self.dialog.showerror.message, '')
 
     def test_keys_shift_bad(self):
-        self.dialog.listKeysFinal.get.result = 'a'
-        self.dialog.GetModifiers.result = ['Shift']
-        self.assertFalse(self.dialog.KeysOK('<a>'))
+        self.dialog.list_keys_final.get.result = 'a'
+        self.dialog.get_modifiers.result = ['Shift']
+        self.assertFalse(self.dialog.keys_ok('<a>'))
         self.assertIn('shift modifier', self.dialog.showerror.message)
-        self.dialog.GetModifiers.result = []
+        self.dialog.get_modifiers.result = []
 
     def test_keys_dup(self):
         for mods, final, seq in (([], 'F12', '<Key-F12>'),
                                  (['Control'], 'x', '<Control-Key-x>'),
                                  (['Control'], 'X', '<Control-Key-X>')):
             with self.subTest(m=mods, f=final, s=seq):
-                self.dialog.listKeysFinal.get.result = final
-                self.dialog.GetModifiers.result = mods
-                self.assertFalse(self.dialog.KeysOK(seq))
+                self.dialog.list_keys_final.get.result = final
+                self.dialog.get_modifiers.result = mods
+                self.assertFalse(self.dialog.keys_ok(seq))
                 self.assertIn('already in use', self.dialog.showerror.message)
-        self.dialog.GetModifiers.result = []
+        self.dialog.get_modifiers.result = []
 
     def test_bind_ok(self):
         self.assertTrue(self.dialog.bind_ok('<Control-Shift-Key-a>'))
@@ -95,5 +103,189 @@ class ValidationTest(unittest.TestCase):
         self.assertIn('not accepted', self.dialog.showerror.message)
 
 
+class ToggleLevelTest(unittest.TestCase):
+    "Test toggle between Basic and Advanced frames."
+
+    @classmethod
+    def setUpClass(cls):
+        requires('gui')
+        cls.root = Tk()
+        cls.root.withdraw()
+        cls.dialog = gkd(cls.root, 'Title', '<<Test>>', [], _utest=True)
+
+    @classmethod
+    def tearDownClass(cls):
+        cls.dialog.cancel()
+        cls.root.update_idletasks()
+        cls.root.destroy()
+        del cls.dialog, cls.root
+
+    def test_toggle_level(self):
+        dialog = self.dialog
+
+        def stackorder():
+            """Get the stack order of the children of the frame.
+
+            winfo_children() stores the children in stack order, so
+            this can be used to check whether a frame is above or
+            below another one.
+            """
+            for index, child in enumerate(dialog.frame.winfo_children()):
+                if child._name == 'keyseq_basic':
+                    basic = index
+                if child._name == 'keyseq_advanced':
+                    advanced = index
+            return basic, advanced
+
+        # New window starts at basic level.
+        self.assertFalse(dialog.advanced)
+        self.assertIn('Advanced', dialog.button_level['text'])
+        basic, advanced = stackorder()
+        self.assertGreater(basic, advanced)
+
+        # Toggle to advanced.
+        dialog.toggle_level()
+        self.assertTrue(dialog.advanced)
+        self.assertIn('Basic', dialog.button_level['text'])
+        basic, advanced = stackorder()
+        self.assertGreater(advanced, basic)
+
+        # Toggle to basic.
+        dialog.button_level.invoke()
+        self.assertFalse(dialog.advanced)
+        self.assertIn('Advanced', dialog.button_level['text'])
+        basic, advanced = stackorder()
+        self.assertGreater(basic, advanced)
+
+
+class KeySelectionTest(unittest.TestCase):
+    "Test selecting key on Basic frames."
+
+    class Basic(gkd):
+        def __init__(self, *args, **kwargs):
+            super().__init__(*args, **kwargs)
+            class list_keys_final:
+                get = Func()
+                select_clear = Func()
+                yview = Func()
+            self.list_keys_final = list_keys_final
+        def set_modifiers_for_platform(self):
+            self.modifiers = ['foo', 'bar', 'BAZ']
+            self.modifier_label = {'BAZ': 'ZZZ'}
+        showerror = Mbox_func()
+
+    @classmethod
+    def setUpClass(cls):
+        requires('gui')
+        cls.root = Tk()
+        cls.root.withdraw()
+        cls.dialog = cls.Basic(cls.root, 'Title', '<<Test>>', [], _utest=True)
+
+    @classmethod
+    def tearDownClass(cls):
+        cls.dialog.cancel()
+        cls.root.update_idletasks()
+        cls.root.destroy()
+        del cls.dialog, cls.root
+
+    def setUp(self):
+        self.dialog.clear_key_seq()
+
+    def test_get_modifiers(self):
+        dialog = self.dialog
+        gm = dialog.get_modifiers
+        eq = self.assertEqual
+
+        # Modifiers are set on/off by invoking the checkbutton.
+        dialog.modifier_checkbuttons['foo'].invoke()
+        eq(gm(), ['foo'])
+
+        dialog.modifier_checkbuttons['BAZ'].invoke()
+        eq(gm(), ['foo', 'BAZ'])
+
+        dialog.modifier_checkbuttons['foo'].invoke()
+        eq(gm(), ['BAZ'])
+
+    @mock.patch.object(gkd, 'get_modifiers')
+    def test_build_key_string(self, mock_modifiers):
+        dialog = self.dialog
+        key = dialog.list_keys_final
+        string = dialog.key_string.get
+        eq = self.assertEqual
+
+        key.get.result = 'a'
+        mock_modifiers.return_value = []
+        dialog.build_key_string()
+        eq(string(), '<Key-a>')
+
+        mock_modifiers.return_value = ['mymod']
+        dialog.build_key_string()
+        eq(string(), '<mymod-Key-a>')
+
+        key.get.result = ''
+        mock_modifiers.return_value = ['mymod', 'test']
+        dialog.build_key_string()
+        eq(string(), '<mymod-test>')
+
+    @mock.patch.object(gkd, 'get_modifiers')
+    def test_final_key_selected(self, mock_modifiers):
+        dialog = self.dialog
+        key = dialog.list_keys_final
+        string = dialog.key_string.get
+        eq = self.assertEqual
+
+        mock_modifiers.return_value = ['Shift']
+        key.get.result = '{'
+        dialog.final_key_selected()
+        eq(string(), '<Shift-Key-braceleft>')
+
+
+class CancelTest(unittest.TestCase):
+    "Simulate user clicking [Cancel] button."
+
+    @classmethod
+    def setUpClass(cls):
+        requires('gui')
+        cls.root = Tk()
+        cls.root.withdraw()
+        cls.dialog = gkd(cls.root, 'Title', '<<Test>>', [], _utest=True)
+
+    @classmethod
+    def tearDownClass(cls):
+        cls.dialog.cancel()
+        cls.root.update_idletasks()
+        cls.root.destroy()
+        del cls.dialog, cls.root
+
+    def test_cancel(self):
+        self.assertEqual(self.dialog.winfo_class(), 'Toplevel')
+        self.dialog.button_cancel.invoke()
+        with self.assertRaises(TclError):
+            self.dialog.winfo_class()
+        self.assertEqual(self.dialog.result, '')
+
+
+class HelperTest(unittest.TestCase):
+    "Test module level helper functions."
+
+    def test_translate_key(self):
+        tr = config_key.translate_key
+        eq = self.assertEqual
+
+        # Letters return unchanged with no 'Shift'.
+        eq(tr('q', []), 'Key-q')
+        eq(tr('q', ['Control', 'Alt']), 'Key-q')
+
+        # 'Shift' uppercases single lowercase letters.
+        eq(tr('q', ['Shift']), 'Key-Q')
+        eq(tr('q', ['Control', 'Shift']), 'Key-Q')
+        eq(tr('q', ['Control', 'Alt', 'Shift']), 'Key-Q')
+
+        # Convert key name to keysym.
+        eq(tr('Page Up', []), 'Key-Prior')
+        # 'Shift' doesn't change case when it's not a single char.
+        eq(tr('*', ['Shift']), 'Key-asterisk')
+
+
 if __name__ == '__main__':
     unittest.main(verbosity=2)
index 5839b5d045d89e2f53fd32f898dbc6052912b87d..7c148d23a135b64e143d7e8587b84b62ec71d7c5 100644 (file)
@@ -61,6 +61,8 @@ class LiveDialogTest(unittest.TestCase):
                 button.invoke()
                 get = dialog._current_textview.viewframe.textframe.text.get
                 lines = printer._Printer__lines
+                if len(lines) < 2:
+                    self.fail(name + ' full text was not found')
                 self.assertEqual(lines[0], get('1.0', '1.end'))
                 self.assertEqual(lines[1], get('2.0', '2.end'))
                 dialog._current_textview.destroy()
index 46c3ad111d179336122f24604553589eb19053de..09a7fff51de1dc5bcbe0d8b65649bb7ceb584065 100644 (file)
@@ -4,7 +4,8 @@
 
 import unittest
 from test.support import requires
-from tkinter import Tk, Frame  ##, BooleanVar, StringVar
+from tkinter import Tk
+from tkinter.ttk import Frame
 from idlelib import searchengine as se
 from idlelib import searchbase as sdb
 from idlelib.idle_test.mock_idle import Func
@@ -97,11 +98,12 @@ class SearchDialogBaseTest(unittest.TestCase):
         self.dialog.top = self.root
         frame, label = self.dialog.make_frame()
         self.assertEqual(label, '')
-        self.assertIsInstance(frame, Frame)
+        self.assertEqual(str(type(frame)), "<class 'tkinter.ttk.Frame'>")
+        # self.assertIsInstance(frame, Frame) fails when test is run by
+        # test_idle not run from IDLE editor.  See issue 33987 PR.
 
         frame, label = self.dialog.make_frame('testlabel')
         self.assertEqual(label['text'], 'testlabel')
-        self.assertIsInstance(frame, Frame)
 
     def btn_test_setup(self, meth):
         self.dialog.top = self.root
index ca8b674cc236dd08b7d16f43ab9ce2e780eafb25..4e3da030a3adce048ba52ebdf99b9305fc53bf06 100644 (file)
@@ -1,4 +1,7 @@
+"Test squeezer, coverage 95%"
+
 from collections import namedtuple
+from textwrap import dedent
 from tkinter import Text, Tk
 import unittest
 from unittest.mock import Mock, NonCallableMagicMock, patch, sentinel, ANY
@@ -32,10 +35,10 @@ def get_test_tk_root(test_instance):
 
 class CountLinesTest(unittest.TestCase):
     """Tests for the count_lines_with_wrapping function."""
-    def check(self, expected, text, linewidth, tabwidth):
+    def check(self, expected, text, linewidth):
         return self.assertEqual(
             expected,
-            count_lines_with_wrapping(text, linewidth, tabwidth),
+            count_lines_with_wrapping(text, linewidth),
         )
 
     def test_count_empty(self):
@@ -54,99 +57,94 @@ class CountLinesTest(unittest.TestCase):
         """Test with several lines of text."""
         self.assertEqual(count_lines_with_wrapping("1\n2\n3\n"), 3)
 
-    def test_tab_width(self):
-        """Test with various tab widths and line widths."""
-        self.check(expected=1, text='\t' * 1, linewidth=8, tabwidth=4)
-        self.check(expected=1, text='\t' * 2, linewidth=8, tabwidth=4)
-        self.check(expected=2, text='\t' * 3, linewidth=8, tabwidth=4)
-        self.check(expected=2, text='\t' * 4, linewidth=8, tabwidth=4)
-        self.check(expected=3, text='\t' * 5, linewidth=8, tabwidth=4)
+    def test_empty_lines(self):
+        self.check(expected=1, text='\n', linewidth=80)
+        self.check(expected=2, text='\n\n', linewidth=80)
+        self.check(expected=10, text='\n' * 10, linewidth=80)
 
-        # test longer lines and various tab widths
-        self.check(expected=4, text='\t' * 10, linewidth=12, tabwidth=4)
-        self.check(expected=10, text='\t' * 10, linewidth=12, tabwidth=8)
-        self.check(expected=2, text='\t' * 4, linewidth=10, tabwidth=3)
+    def test_long_line(self):
+        self.check(expected=3, text='a' * 200, linewidth=80)
+        self.check(expected=3, text='a' * 200 + '\n', linewidth=80)
 
-        # test tabwidth=1
-        self.check(expected=2, text='\t' * 9, linewidth=5, tabwidth=1)
-        self.check(expected=2, text='\t' * 10, linewidth=5, tabwidth=1)
-        self.check(expected=3, text='\t' * 11, linewidth=5, tabwidth=1)
+    def test_several_lines_different_lengths(self):
+        text = dedent("""\
+            13 characters
+            43 is the number of characters on this line
 
-        # test for off-by-one errors
-        self.check(expected=2, text='\t' * 6, linewidth=12, tabwidth=4)
-        self.check(expected=3, text='\t' * 6, linewidth=11, tabwidth=4)
-        self.check(expected=2, text='\t' * 6, linewidth=13, tabwidth=4)
+            7 chars
+            13 characters""")
+        self.check(expected=5, text=text, linewidth=80)
+        self.check(expected=5, text=text + '\n', linewidth=80)
+        self.check(expected=6, text=text, linewidth=40)
+        self.check(expected=7, text=text, linewidth=20)
+        self.check(expected=11, text=text, linewidth=10)
 
 
 class SqueezerTest(unittest.TestCase):
     """Tests for the Squeezer class."""
-    def make_mock_editor_window(self):
+    def tearDown(self):
+        # Clean up the Squeezer class's reference to its instance,
+        # to avoid side-effects from one test case upon another.
+        if Squeezer._instance_weakref is not None:
+            Squeezer._instance_weakref = None
+
+    def make_mock_editor_window(self, with_text_widget=False):
         """Create a mock EditorWindow instance."""
         editwin = NonCallableMagicMock()
         # isinstance(editwin, PyShell) must be true for Squeezer to enable
-        # auto-squeezing; in practice this will always be true
+        # auto-squeezing; in practice this will always be true.
         editwin.__class__ = PyShell
+
+        if with_text_widget:
+            editwin.root = get_test_tk_root(self)
+            text_widget = self.make_text_widget(root=editwin.root)
+            editwin.text = editwin.per.bottom = text_widget
+
         return editwin
 
     def make_squeezer_instance(self, editor_window=None):
         """Create an actual Squeezer instance with a mock EditorWindow."""
         if editor_window is None:
             editor_window = self.make_mock_editor_window()
-        return Squeezer(editor_window)
+        squeezer = Squeezer(editor_window)
+        squeezer.get_line_width = Mock(return_value=80)
+        return squeezer
+
+    def make_text_widget(self, root=None):
+        if root is None:
+            root = get_test_tk_root(self)
+        text_widget = Text(root)
+        text_widget["font"] = ('Courier', 10)
+        text_widget.mark_set("iomark", "1.0")
+        return text_widget
+
+    def set_idleconf_option_with_cleanup(self, configType, section, option, value):
+        prev_val = idleConf.GetOption(configType, section, option)
+        idleConf.SetOption(configType, section, option, value)
+        self.addCleanup(idleConf.SetOption,
+                        configType, section, option, prev_val)
 
     def test_count_lines(self):
-        """Test Squeezer.count_lines() with various inputs.
-
-        This checks that Squeezer.count_lines() calls the
-        count_lines_with_wrapping() function with the appropriate parameters.
-        """
-        for tabwidth, linewidth in [(4, 80), (1, 79), (8, 80), (3, 120)]:
-            self._test_count_lines_helper(linewidth=linewidth,
-                                          tabwidth=tabwidth)
-
-    def _prepare_mock_editwin_for_count_lines(self, editwin,
-                                              linewidth, tabwidth):
-        """Prepare a mock EditorWindow object for Squeezer.count_lines."""
-        CHAR_WIDTH = 10
-        BORDER_WIDTH = 2
-        PADDING_WIDTH = 1
-
-        # Prepare all the required functionality on the mock EditorWindow object
-        # so that the calculations in Squeezer.count_lines() can run.
-        editwin.get_tk_tabwidth.return_value = tabwidth
-        editwin.text.winfo_width.return_value = \
-            linewidth * CHAR_WIDTH + 2 * (BORDER_WIDTH + PADDING_WIDTH)
-        text_opts = {
-            'border': BORDER_WIDTH,
-            'padx': PADDING_WIDTH,
-            'font': None,
-        }
-        editwin.text.cget = lambda opt: text_opts[opt]
-
-        # monkey-path tkinter.font.Font with a mock object, so that
-        # Font.measure('0') returns CHAR_WIDTH
-        mock_font = Mock()
-        def measure(char):
-            if char == '0':
-                return CHAR_WIDTH
-            raise ValueError("measure should only be called on '0'!")
-        mock_font.return_value.measure = measure
-        patcher = patch('idlelib.squeezer.Font', mock_font)
-        patcher.start()
-        self.addCleanup(patcher.stop)
-
-    def _test_count_lines_helper(self, linewidth, tabwidth):
-        """Helper for test_count_lines."""
+        """Test Squeezer.count_lines() with various inputs."""
         editwin = self.make_mock_editor_window()
-        self._prepare_mock_editwin_for_count_lines(editwin, linewidth, tabwidth)
         squeezer = self.make_squeezer_instance(editwin)
 
-        mock_count_lines = Mock(return_value=SENTINEL_VALUE)
-        text = 'TEXT'
-        with patch('idlelib.squeezer.count_lines_with_wrapping',
-                   mock_count_lines):
-            self.assertIs(squeezer.count_lines(text), SENTINEL_VALUE)
-            mock_count_lines.assert_called_with(text, linewidth, tabwidth)
+        for text_code, line_width, expected in [
+            (r"'\n'", 80, 1),
+            (r"'\n' * 3", 80, 3),
+            (r"'a' * 40 + '\n'", 80, 1),
+            (r"'a' * 80 + '\n'", 80, 1),
+            (r"'a' * 200 + '\n'", 80, 3),
+            (r"'aa\t' * 20", 80, 2),
+            (r"'aa\t' * 21", 80, 3),
+            (r"'aa\t' * 20", 40, 4),
+        ]:
+            with self.subTest(text_code=text_code,
+                              line_width=line_width,
+                              expected=expected):
+                text = eval(text_code)
+                squeezer.get_line_width.return_value = line_width
+                self.assertEqual(squeezer.count_lines(text), expected)
 
     def test_init(self):
         """Test the creation of Squeezer instances."""
@@ -184,8 +182,6 @@ class SqueezerTest(unittest.TestCase):
     def test_write_stdout(self):
         """Test Squeezer's overriding of the EditorWindow's write() method."""
         editwin = self.make_mock_editor_window()
-        self._prepare_mock_editwin_for_count_lines(editwin,
-                                                   linewidth=80, tabwidth=8)
 
         for text in ['', 'TEXT']:
             editwin.write = orig_write = Mock(return_value=SENTINEL_VALUE)
@@ -209,12 +205,8 @@ class SqueezerTest(unittest.TestCase):
 
     def test_auto_squeeze(self):
         """Test that the auto-squeezing creates an ExpandingButton properly."""
-        root = get_test_tk_root(self)
-        text_widget = Text(root)
-        text_widget.mark_set("iomark", "1.0")
-
-        editwin = self.make_mock_editor_window()
-        editwin.text = text_widget
+        editwin = self.make_mock_editor_window(with_text_widget=True)
+        text_widget = editwin.text
         squeezer = self.make_squeezer_instance(editwin)
         squeezer.auto_squeeze_min_lines = 5
         squeezer.count_lines = Mock(return_value=6)
@@ -225,58 +217,48 @@ class SqueezerTest(unittest.TestCase):
 
     def test_squeeze_current_text_event(self):
         """Test the squeeze_current_text event."""
-        root = get_test_tk_root(self)
-
-        # squeezing text should work for both stdout and stderr
+        # Squeezing text should work for both stdout and stderr.
         for tag_name in ["stdout", "stderr"]:
-            text_widget = Text(root)
-            text_widget.mark_set("iomark", "1.0")
-
-            editwin = self.make_mock_editor_window()
-            editwin.text = editwin.per.bottom = text_widget
+            editwin = self.make_mock_editor_window(with_text_widget=True)
+            text_widget = editwin.text
             squeezer = self.make_squeezer_instance(editwin)
             squeezer.count_lines = Mock(return_value=6)
 
-            # prepare some text in the Text widget
+            # Prepare some text in the Text widget.
             text_widget.insert("1.0", "SOME\nTEXT\n", tag_name)
             text_widget.mark_set("insert", "1.0")
             self.assertEqual(text_widget.get('1.0', 'end'), 'SOME\nTEXT\n\n')
 
             self.assertEqual(len(squeezer.expandingbuttons), 0)
 
-            # test squeezing the current text
+            # Test squeezing the current text.
             retval = squeezer.squeeze_current_text_event(event=Mock())
             self.assertEqual(retval, "break")
             self.assertEqual(text_widget.get('1.0', 'end'), '\n\n')
             self.assertEqual(len(squeezer.expandingbuttons), 1)
             self.assertEqual(squeezer.expandingbuttons[0].s, 'SOME\nTEXT')
 
-            # test that expanding the squeezed text works and afterwards the
-            # Text widget contains the original text
+            # Test that expanding the squeezed text works and afterwards
+            # the Text widget contains the original text.
             squeezer.expandingbuttons[0].expand(event=Mock())
             self.assertEqual(text_widget.get('1.0', 'end'), 'SOME\nTEXT\n\n')
             self.assertEqual(len(squeezer.expandingbuttons), 0)
 
     def test_squeeze_current_text_event_no_allowed_tags(self):
         """Test that the event doesn't squeeze text without a relevant tag."""
-        root = get_test_tk_root(self)
-
-        text_widget = Text(root)
-        text_widget.mark_set("iomark", "1.0")
-
-        editwin = self.make_mock_editor_window()
-        editwin.text = editwin.per.bottom = text_widget
+        editwin = self.make_mock_editor_window(with_text_widget=True)
+        text_widget = editwin.text
         squeezer = self.make_squeezer_instance(editwin)
         squeezer.count_lines = Mock(return_value=6)
 
-        # prepare some text in the Text widget
+        # Prepare some text in the Text widget.
         text_widget.insert("1.0", "SOME\nTEXT\n", "TAG")
         text_widget.mark_set("insert", "1.0")
         self.assertEqual(text_widget.get('1.0', 'end'), 'SOME\nTEXT\n\n')
 
         self.assertEqual(len(squeezer.expandingbuttons), 0)
 
-        # test squeezing the current text
+        # Test squeezing the current text.
         retval = squeezer.squeeze_current_text_event(event=Mock())
         self.assertEqual(retval, "break")
         self.assertEqual(text_widget.get('1.0', 'end'), 'SOME\nTEXT\n\n')
@@ -284,23 +266,18 @@ class SqueezerTest(unittest.TestCase):
 
     def test_squeeze_text_before_existing_squeezed_text(self):
         """Test squeezing text before existing squeezed text."""
-        root = get_test_tk_root(self)
-
-        text_widget = Text(root)
-        text_widget.mark_set("iomark", "1.0")
-
-        editwin = self.make_mock_editor_window()
-        editwin.text = editwin.per.bottom = text_widget
+        editwin = self.make_mock_editor_window(with_text_widget=True)
+        text_widget = editwin.text
         squeezer = self.make_squeezer_instance(editwin)
         squeezer.count_lines = Mock(return_value=6)
 
-        # prepare some text in the Text widget and squeeze it
+        # Prepare some text in the Text widget and squeeze it.
         text_widget.insert("1.0", "SOME\nTEXT\n", "stdout")
         text_widget.mark_set("insert", "1.0")
         squeezer.squeeze_current_text_event(event=Mock())
         self.assertEqual(len(squeezer.expandingbuttons), 1)
 
-        # test squeezing the current text
+        # Test squeezing the current text.
         text_widget.insert("1.0", "MORE\nSTUFF\n", "stdout")
         text_widget.mark_set("insert", "1.0")
         retval = squeezer.squeeze_current_text_event(event=Mock())
@@ -313,27 +290,28 @@ class SqueezerTest(unittest.TestCase):
             squeezer.expandingbuttons[1],
         ))
 
-    GetOptionSignature = namedtuple('GetOptionSignature',
-        'configType section option default type warn_on_default raw')
-    @classmethod
-    def _make_sig(cls, configType, section, option, default=sentinel.NOT_GIVEN,
-                  type=sentinel.NOT_GIVEN,
-                  warn_on_default=sentinel.NOT_GIVEN,
-                  raw=sentinel.NOT_GIVEN):
-        return cls.GetOptionSignature(configType, section, option, default,
-                                      type, warn_on_default, raw)
-
-    @classmethod
-    def get_GetOption_signature(cls, mock_call_obj):
-        args, kwargs = mock_call_obj[-2:]
-        return cls._make_sig(*args, **kwargs)
-
     def test_reload(self):
         """Test the reload() class-method."""
-        self.assertIsInstance(Squeezer.auto_squeeze_min_lines, int)
-        idleConf.SetOption('main', 'PyShell', 'auto-squeeze-min-lines', '42')
+        editwin = self.make_mock_editor_window(with_text_widget=True)
+        squeezer = self.make_squeezer_instance(editwin)
+        squeezer.load_font = Mock()
+
+        orig_auto_squeeze_min_lines = squeezer.auto_squeeze_min_lines
+
+        # Increase auto-squeeze-min-lines.
+        new_auto_squeeze_min_lines = orig_auto_squeeze_min_lines + 10
+        self.set_idleconf_option_with_cleanup(
+            'main', 'PyShell', 'auto-squeeze-min-lines',
+            str(new_auto_squeeze_min_lines))
+
+        Squeezer.reload()
+        self.assertEqual(squeezer.auto_squeeze_min_lines,
+                         new_auto_squeeze_min_lines)
+        squeezer.load_font.assert_called()
+
+    def test_reload_no_squeezer_instances(self):
+        """Test that Squeezer.reload() runs without any instances existing."""
         Squeezer.reload()
-        self.assertEqual(Squeezer.auto_squeeze_min_lines, 42)
 
 
 class ExpandingButtonTest(unittest.TestCase):
@@ -346,7 +324,7 @@ class ExpandingButtonTest(unittest.TestCase):
         squeezer = Mock()
         squeezer.editwin.text = Text(root)
 
-        # Set default values for the configuration settings
+        # Set default values for the configuration settings.
         squeezer.auto_squeeze_min_lines = 50
         return squeezer
 
@@ -359,23 +337,23 @@ class ExpandingButtonTest(unittest.TestCase):
         expandingbutton = ExpandingButton('TEXT', 'TAGS', 50, squeezer)
         self.assertEqual(expandingbutton.s, 'TEXT')
 
-        # check that the underlying tkinter.Button is properly configured
+        # Check that the underlying tkinter.Button is properly configured.
         self.assertEqual(expandingbutton.master, text_widget)
         self.assertTrue('50 lines' in expandingbutton.cget('text'))
 
-        # check that the text widget still contains no text
+        # Check that the text widget still contains no text.
         self.assertEqual(text_widget.get('1.0', 'end'), '\n')
 
-        # check that the mouse events are bound
+        # Check that the mouse events are bound.
         self.assertIn('<Double-Button-1>', expandingbutton.bind())
         right_button_code = '<Button-%s>' % ('2' if macosx.isAquaTk() else '3')
         self.assertIn(right_button_code, expandingbutton.bind())
 
-        # check that ToolTip was called once, with appropriate values
+        # Check that ToolTip was called once, with appropriate values.
         self.assertEqual(MockHovertip.call_count, 1)
         MockHovertip.assert_called_with(expandingbutton, ANY, hover_delay=ANY)
 
-        # check that 'right-click' appears in the tooltip text
+        # Check that 'right-click' appears in the tooltip text.
         tooltip_text = MockHovertip.call_args[0][1]
         self.assertIn('right-click', tooltip_text.lower())
 
@@ -384,29 +362,30 @@ class ExpandingButtonTest(unittest.TestCase):
         squeezer = self.make_mock_squeezer()
         expandingbutton = ExpandingButton('TEXT', 'TAGS', 50, squeezer)
 
-        # insert the button into the text widget
-        # (this is normally done by the Squeezer class)
+        # Insert the button into the text widget
+        # (this is normally done by the Squeezer class).
         text_widget = expandingbutton.text
         text_widget.window_create("1.0", window=expandingbutton)
 
-        # set base_text to the text widget, so that changes are actually made
-        # to it (by ExpandingButton) and we can inspect these changes afterwards
+        # Set base_text to the text widget, so that changes are actually
+        # made to it (by ExpandingButton) and we can inspect these
+        # changes afterwards.
         expandingbutton.base_text = expandingbutton.text
 
         # trigger the expand event
         retval = expandingbutton.expand(event=Mock())
         self.assertEqual(retval, None)
 
-        # check that the text was inserted into the text widget
+        # Check that the text was inserted into the text widget.
         self.assertEqual(text_widget.get('1.0', 'end'), 'TEXT\n')
 
-        # check that the 'TAGS' tag was set on the inserted text
+        # Check that the 'TAGS' tag was set on the inserted text.
         text_end_index = text_widget.index('end-1c')
         self.assertEqual(text_widget.get('1.0', text_end_index), 'TEXT')
         self.assertEqual(text_widget.tag_nextrange('TAGS', '1.0'),
                           ('1.0', text_end_index))
 
-        # check that the button removed itself from squeezer.expandingbuttons
+        # Check that the button removed itself from squeezer.expandingbuttons.
         self.assertEqual(squeezer.expandingbuttons.remove.call_count, 1)
         squeezer.expandingbuttons.remove.assert_called_with(expandingbutton)
 
@@ -418,55 +397,54 @@ class ExpandingButtonTest(unittest.TestCase):
         expandingbutton.set_is_dangerous()
         self.assertTrue(expandingbutton.is_dangerous)
 
-        # insert the button into the text widget
-        # (this is normally done by the Squeezer class)
+        # Insert the button into the text widget
+        # (this is normally done by the Squeezer class).
         text_widget = expandingbutton.text
         text_widget.window_create("1.0", window=expandingbutton)
 
-        # set base_text to the text widget, so that changes are actually made
-        # to it (by ExpandingButton) and we can inspect these changes afterwards
+        # Set base_text to the text widget, so that changes are actually
+        # made to it (by ExpandingButton) and we can inspect these
+        # changes afterwards.
         expandingbutton.base_text = expandingbutton.text
 
-        # patch the message box module to always return False
+        # Patch the message box module to always return False.
         with patch('idlelib.squeezer.tkMessageBox') as mock_msgbox:
             mock_msgbox.askokcancel.return_value = False
             mock_msgbox.askyesno.return_value = False
-
-            # trigger the expand event
+            # Trigger the expand event.
             retval = expandingbutton.expand(event=Mock())
 
-        # check that the event chain was broken and no text was inserted
+        # Check that the event chain was broken and no text was inserted.
         self.assertEqual(retval, 'break')
         self.assertEqual(expandingbutton.text.get('1.0', 'end-1c'), '')
 
-        # patch the message box module to always return True
+        # Patch the message box module to always return True.
         with patch('idlelib.squeezer.tkMessageBox') as mock_msgbox:
             mock_msgbox.askokcancel.return_value = True
             mock_msgbox.askyesno.return_value = True
-
-            # trigger the expand event
+            # Trigger the expand event.
             retval = expandingbutton.expand(event=Mock())
 
-        # check that the event chain wasn't broken and the text was inserted
+        # Check that the event chain wasn't broken and the text was inserted.
         self.assertEqual(retval, None)
         self.assertEqual(expandingbutton.text.get('1.0', 'end-1c'), text)
 
     def test_copy(self):
         """Test the copy event."""
-        # testing with the actual clipboard proved problematic, so this test
-        # replaces the clipboard manipulation functions with mocks and checks
-        # that they are called appropriately
+        # Testing with the actual clipboard proved problematic, so this
+        # test replaces the clipboard manipulation functions with mocks
+        # and checks that they are called appropriately.
         squeezer = self.make_mock_squeezer()
         expandingbutton = ExpandingButton('TEXT', 'TAGS', 50, squeezer)
         expandingbutton.clipboard_clear = Mock()
         expandingbutton.clipboard_append = Mock()
 
-        # trigger the copy event
+        # Trigger the copy event.
         retval = expandingbutton.copy(event=Mock())
         self.assertEqual(retval, None)
 
-        # check that the expanding button called clipboard_clear() and
-        # clipboard_append('TEXT') once each
+        # Vheck that the expanding button called clipboard_clear() and
+        # clipboard_append('TEXT') once each.
         self.assertEqual(expandingbutton.clipboard_clear.call_count, 1)
         self.assertEqual(expandingbutton.clipboard_append.call_count, 1)
         expandingbutton.clipboard_append.assert_called_with('TEXT')
@@ -479,13 +457,13 @@ class ExpandingButtonTest(unittest.TestCase):
 
         with patch('idlelib.squeezer.view_text', autospec=view_text)\
                 as mock_view_text:
-            # trigger the view event
+            # Trigger the view event.
             expandingbutton.view(event=Mock())
 
-            # check that the expanding button called view_text
+            # Check that the expanding button called view_text.
             self.assertEqual(mock_view_text.call_count, 1)
 
-            # check that the proper text was passed
+            # Check that the proper text was passed.
             self.assertEqual(mock_view_text.call_args[0][2], 'TEXT')
 
     def test_rmenu(self):
index 9be4ed2ec411d557e9ca8bcda5e647b0bcee4ea9..eeaab59ae80295fbd6aef7d068f3dc460fd4b523 100644 (file)
@@ -178,7 +178,7 @@ def overrideRootMenu(root, flist):
     del mainmenu.menudefs[-1][1][0:2]
     # Remove the 'Configure Idle' entry from the options menu, it is in the
     # application menu as 'Preferences'
-    del mainmenu.menudefs[-2][1][0]
+    del mainmenu.menudefs[-3][1][0:2]
     menubar = Menu(root)
     root.configure(menu=menubar)
     menudict = {}
index 9fe6b5229446e3072744db46de8a3001f6adff47..f834220fc2bb7536831ab4a5c8ebfaf6908853af 100644 (file)
@@ -82,6 +82,9 @@ menudefs = [
    ('_View Last Restart', '<<view-restart>>'),
    ('_Restart Shell', '<<restart-shell>>'),
    None,
+   ('_Previous History', '<<history-previous>>'),
+   ('_Next History', '<<history-next>>'),
+   None,
    ('_Interrupt Execution', '<<interrupt-execution>>'),
    ]),
 
@@ -94,11 +97,12 @@ menudefs = [
 
  ('options', [
    ('Configure _IDLE', '<<open-config-dialog>>'),
-   ('_Code Context', '<<toggle-code-context>>'),
+   None,
+   ('Show _Code Context', '<<toggle-code-context>>'),
+   ('Zoom Height', '<<zoom-height>>'),
    ]),
 
  ('window', [
-   ('Zoom Height', '<<zoom-height>>'),
    ]),
 
  ('help', [
index e962142498dfd87308867298f6b25aaf069b8dae..ecc53ef0195dc644e8bdfde4d6d4121aef7a59e4 100644 (file)
@@ -78,6 +78,7 @@ class OutputWindow(EditorWindow):
         EditorWindow.__init__(self, *args)
         self.text.bind("<<goto-file-line>>", self.goto_file_line)
         self.text.unbind("<<toggle-code-context>>")
+        self.update_menu_state('options', '*Code Context', 'disabled')
 
     # Customize EditorWindow
     def ispythonsource(self, filename):
index 81a97ef6d6bcc511dc0a2d4b41d107a920d4cfc8..11bafdb49aaa57ff205a7b782077dcb548970d50 100755 (executable)
@@ -882,7 +882,7 @@ class PyShell(OutputWindow):
         self.usetabs = True
         # indentwidth must be 8 when using tabs.  See note in EditorWindow:
         self.indentwidth = 8
-
+        self.context_use_ps1 = True
         self.sys_ps1 = sys.ps1 if hasattr(sys, 'ps1') else '>>> '
         self.prompt_last_line = self.sys_ps1.split('\n')[-1]
         self.prompt = self.sys_ps1  # Changes when debug active
@@ -899,6 +899,9 @@ class PyShell(OutputWindow):
         if use_subprocess:
             text.bind("<<view-restart>>", self.view_restart_mark)
             text.bind("<<restart-shell>>", self.restart_shell)
+        squeezer = self.Squeezer(self)
+        text.bind("<<squeeze-current-text>>",
+                  squeezer.squeeze_current_text_event)
 
         self.save_stdout = sys.stdout
         self.save_stderr = sys.stderr
@@ -1492,7 +1495,7 @@ def main():
     if system() == 'Windows':
         iconfile = os.path.join(icondir, 'idle.ico')
         root.wm_iconbitmap(default=iconfile)
-    else:
+    elif not macosx.isAquaTk():
         ext = '.png' if TkVersion >= 8.6 else '.gif'
         iconfiles = [os.path.join(icondir, 'idle_%d%s' % (size, ext))
                      for size in (16, 32, 48)]
index c2628cceb739781a96cd17d61ada0a8f477e1e61..f0b72553db87f7a0abdfaf817bf35ad60f105678 100644 (file)
@@ -1,6 +1,5 @@
 """
 Dialogs that query users and verify the answer before accepting.
-Use ttk widgets, limiting use to tcl/tk 8.5+, as in IDLE 3.6+.
 
 Query is the generic base class for a popup dialog.
 The user must either enter a valid answer or close the dialog.
index 83cf98756bdf8127978b8818ffe5cdfc96ea68ed..4a834eb7901e61ff980c1d46e1f4126539b3e5fa 100644 (file)
@@ -205,12 +205,12 @@ class ReplaceDialog(SearchDialogBase):
 
 def _replace_dialog(parent):  # htest #
     from tkinter import Toplevel, Text, END, SEL
-    from tkinter.ttk import Button
+    from tkinter.ttk import Frame, Button
 
-    box = Toplevel(parent)
-    box.title("Test ReplaceDialog")
+    top = Toplevel(parent)
+    top.title("Test ReplaceDialog")
     x, y = map(int, parent.geometry().split('+')[1:])
-    box.geometry("+%d+%d" % (x, y + 175))
+    top.geometry("+%d+%d" % (x, y + 175))
 
     # mock undo delegator methods
     def undo_block_start():
@@ -219,7 +219,9 @@ def _replace_dialog(parent):  # htest #
     def undo_block_stop():
         pass
 
-    text = Text(box, inactiveselectbackground='gray')
+    frame = Frame(top)
+    frame.pack()
+    text = Text(frame, inactiveselectbackground='gray')
     text.undo_block_start = undo_block_start
     text.undo_block_stop = undo_block_stop
     text.pack()
@@ -231,7 +233,7 @@ def _replace_dialog(parent):  # htest #
         replace(text)
         text.tag_remove(SEL, "1.0", END)
 
-    button = Button(box, text="Replace", command=show_replace)
+    button = Button(frame, text="Replace", command=show_replace)
     button.pack()
 
 if __name__ == '__main__':
index 10229b63629293caa246ccc346edea7956a6db26..71fd18ab19ec8ae0e101bed1b3f77c41a28aaf7e 100644 (file)
@@ -1,5 +1,5 @@
 from tkinter import *
-from tkinter.ttk import Scrollbar
+from tkinter.ttk import Frame, Scrollbar
 
 from idlelib import macosx
 
index 6223661c8e080a9b583d8a9fa927dbbf442bfdf6..6e5a0c7973c728712e7638ba43e05244e065a20b 100644 (file)
@@ -75,13 +75,16 @@ class SearchDialog(SearchDialogBase):
 def _search_dialog(parent):  # htest #
     "Display search test box."
     from tkinter import Toplevel, Text
-    from tkinter.ttk import Button
+    from tkinter.ttk import Frame, Button
 
-    box = Toplevel(parent)
-    box.title("Test SearchDialog")
+    top = Toplevel(parent)
+    top.title("Test SearchDialog")
     x, y = map(int, parent.geometry().split('+')[1:])
-    box.geometry("+%d+%d" % (x, y + 175))
-    text = Text(box, inactiveselectbackground='gray')
+    top.geometry("+%d+%d" % (x, y + 175))
+
+    frame = Frame(top)
+    frame.pack()
+    text = Text(frame, inactiveselectbackground='gray')
     text.pack()
     text.insert("insert","This is a sample string.\n"*5)
 
@@ -90,7 +93,7 @@ def _search_dialog(parent):  # htest #
         _setup(text).open(text)
         text.tag_remove('sel', '1.0', 'end')
 
-    button = Button(box, text="Search (selection ignored)", command=show_find)
+    button = Button(frame, text="Search (selection ignored)", command=show_find)
     button.pack()
 
 if __name__ == '__main__':
index 9b03ff64c1e1a6635dbac4a129e2f218d577cad6..f0e3d6f14ba49b75243faa28b09a30c3d370e5d7 100644 (file)
@@ -1,7 +1,7 @@
 '''Define SearchDialogBase used by Search, Replace, and Grep dialogs.'''
 
-from tkinter import Toplevel, Frame
-from tkinter.ttk import Entry, Label, Button, Checkbutton, Radiobutton
+from tkinter import Toplevel
+from tkinter.ttk import Frame, Entry, Label, Button, Checkbutton, Radiobutton
 
 
 class SearchDialogBase:
@@ -42,6 +42,7 @@ class SearchDialogBase:
         icon (of dialog): ditto, use unclear if cannot minimize dialog.
         '''
         self.root = root
+        self.bell = root.bell
         self.engine = engine
         self.top = None
 
@@ -80,7 +81,6 @@ class SearchDialogBase:
         top.wm_title(self.title)
         top.wm_iconname(self.icon)
         self.top = top
-        self.bell = top.bell
 
         self.row = 0
         self.top.grid_columnconfigure(0, pad=2, weight=0)
index f5aac813a159334e30b88f5af05d6821485fc0f0..869498d753a2cd97476fbb759b6e3e676e1996fa 100644 (file)
@@ -15,6 +15,7 @@ output written to the standard error stream ("stderr"), such as exception
 messages and their tracebacks.
 """
 import re
+import weakref
 
 import tkinter as tk
 from tkinter.font import Font
@@ -26,7 +27,7 @@ from idlelib.tooltip import Hovertip
 from idlelib import macosx
 
 
-def count_lines_with_wrapping(s, linewidth=80, tabwidth=8):
+def count_lines_with_wrapping(s, linewidth=80):
     """Count the number of lines in a given string.
 
     Lines are counted as if the string was wrapped so that lines are never over
@@ -34,50 +35,49 @@ def count_lines_with_wrapping(s, linewidth=80, tabwidth=8):
 
     Tabs are considered tabwidth characters long.
     """
+    tabwidth = 8  # Currently always true in Shell.
     pos = 0
     linecount = 1
     current_column = 0
 
     for m in re.finditer(r"[\t\n]", s):
-        # process the normal chars up to tab or newline
+        # Process the normal chars up to tab or newline.
         numchars = m.start() - pos
         pos += numchars
         current_column += numchars
 
-        # deal with tab or newline
+        # Deal with tab or newline.
         if s[pos] == '\n':
+            # Avoid the `current_column == 0` edge-case, and while we're
+            # at it, don't bother adding 0.
+            if current_column > linewidth:
+                # If the current column was exactly linewidth, divmod
+                # would give (1,0), even though a new line hadn't yet
+                # been started. The same is true if length is any exact
+                # multiple of linewidth. Therefore, subtract 1 before
+                # dividing a non-empty line.
+                linecount += (current_column - 1) // linewidth
             linecount += 1
             current_column = 0
         else:
             assert s[pos] == '\t'
             current_column += tabwidth - (current_column % tabwidth)
 
-            # if a tab passes the end of the line, consider the entire tab as
-            # being on the next line
+            # If a tab passes the end of the line, consider the entire
+            # tab as being on the next line.
             if current_column > linewidth:
                 linecount += 1
                 current_column = tabwidth
 
-        pos += 1 # after the tab or newline
-
-        # avoid divmod(-1, linewidth)
-        if current_column > 0:
-            # If the length was exactly linewidth, divmod would give (1,0),
-            # even though a new line hadn't yet been started. The same is true
-            # if length is any exact multiple of linewidth. Therefore, subtract
-            # 1 before doing divmod, and later add 1 to the column to
-            # compensate.
-            lines, column = divmod(current_column - 1, linewidth)
-            linecount += lines
-            current_column = column + 1
+        pos += 1 # After the tab or newline.
 
-    # process remaining chars (no more tabs or newlines)
+    # Process remaining chars (no more tabs or newlines).
     current_column += len(s) - pos
-    # avoid divmod(-1, linewidth)
+    # Avoid divmod(-1, linewidth).
     if current_column > 0:
         linecount += (current_column - 1) // linewidth
     else:
-        # the text ended with a newline; don't count an extra line after it
+        # Text ended with newline; don't count an extra line after it.
         linecount -= 1
 
     return linecount
@@ -101,12 +101,11 @@ class ExpandingButton(tk.Button):
         self.squeezer = squeezer
         self.editwin = editwin = squeezer.editwin
         self.text = text = editwin.text
-
-        # the base Text widget of the PyShell object, used to change text
-        # before the iomark
+        # The base Text widget is needed to change text before iomark.
         self.base_text = editwin.per.bottom
 
-        button_text = "Squeezed text (%d lines)." % self.numoflines
+        line_plurality = "lines" if numoflines != 1 else "line"
+        button_text = f"Squeezed text ({numoflines} {line_plurality})."
         tk.Button.__init__(self, text, text=button_text,
                            background="#FFFFC0", activebackground="#FFFFE0")
 
@@ -121,7 +120,7 @@ class ExpandingButton(tk.Button):
             self.bind("<Button-2>", self.context_menu_event)
         else:
             self.bind("<Button-3>", self.context_menu_event)
-        self.selection_handle(
+        self.selection_handle(  # X windows only.
             lambda offset, length: s[int(offset):int(offset) + int(length)])
 
         self.is_dangerous = None
@@ -184,7 +183,7 @@ class ExpandingButton(tk.Button):
                   modal=False, wrap='none')
 
     rmenu_specs = (
-        # item structure: (label, method_name)
+        # Item structure: (label, method_name).
         ('copy', 'copy'),
         ('view', 'view'),
     )
@@ -204,6 +203,8 @@ class Squeezer:
     This avoids IDLE's shell slowing down considerably, and even becoming
     completely unresponsive, when very long outputs are written.
     """
+    _instance_weakref = None
+
     @classmethod
     def reload(cls):
         """Load class variables from config."""
@@ -212,6 +213,14 @@ class Squeezer:
             type="int", default=50,
         )
 
+        # Loading the font info requires a Tk root. IDLE doesn't rely
+        # on Tkinter's "default root", so the instance will reload
+        # font info using its editor windows's Tk root.
+        if cls._instance_weakref is not None:
+            instance = cls._instance_weakref()
+            if instance is not None:
+                instance.load_font()
+
     def __init__(self, editwin):
         """Initialize settings for Squeezer.
 
@@ -225,44 +234,58 @@ class Squeezer:
         self.editwin = editwin
         self.text = text = editwin.text
 
-        # Get the base Text widget of the PyShell object, used to change text
-        # before the iomark. PyShell deliberately disables changing text before
-        # the iomark via its 'text' attribute, which is actually a wrapper for
-        # the actual Text widget. Squeezer, however, needs to make such changes.
+        # Get the base Text widget of the PyShell object, used to change
+        # text before the iomark. PyShell deliberately disables changing
+        # text before the iomark via its 'text' attribute, which is
+        # actually a wrapper for the actual Text widget. Squeezer,
+        # however, needs to make such changes.
         self.base_text = editwin.per.bottom
 
+        Squeezer._instance_weakref = weakref.ref(self)
+        self.load_font()
+
+        # Twice the text widget's border width and internal padding;
+        # pre-calculated here for the get_line_width() method.
+        self.window_width_delta = 2 * (
+            int(text.cget('border')) +
+            int(text.cget('padx'))
+        )
+
         self.expandingbuttons = []
-        from idlelib.pyshell import PyShell  # done here to avoid import cycle
-        if isinstance(editwin, PyShell):
-            # If we get a PyShell instance, replace its write method with a
-            # wrapper, which inserts an ExpandingButton instead of a long text.
-            def mywrite(s, tags=(), write=editwin.write):
-                # only auto-squeeze text which has just the "stdout" tag
-                if tags != "stdout":
-                    return write(s, tags)
-
-                # only auto-squeeze text with at least the minimum
-                # configured number of lines
-                numoflines = self.count_lines(s)
-                if numoflines < self.auto_squeeze_min_lines:
-                    return write(s, tags)
-
-                # create an ExpandingButton instance
-                expandingbutton = ExpandingButton(s, tags, numoflines,
-                                                  self)
-
-                # insert the ExpandingButton into the Text widget
-                text.mark_gravity("iomark", tk.RIGHT)
-                text.window_create("iomark", window=expandingbutton,
-                                   padx=3, pady=5)
-                text.see("iomark")
-                text.update()
-                text.mark_gravity("iomark", tk.LEFT)
-
-                # add the ExpandingButton to the Squeezer's list
-                self.expandingbuttons.append(expandingbutton)
-
-            editwin.write = mywrite
+
+        # Replace the PyShell instance's write method with a wrapper,
+        # which inserts an ExpandingButton instead of a long text.
+        def mywrite(s, tags=(), write=editwin.write):
+            # Only auto-squeeze text which has just the "stdout" tag.
+            if tags != "stdout":
+                return write(s, tags)
+
+            # Only auto-squeeze text with at least the minimum
+            # configured number of lines.
+            auto_squeeze_min_lines = self.auto_squeeze_min_lines
+            # First, a very quick check to skip very short texts.
+            if len(s) < auto_squeeze_min_lines:
+                return write(s, tags)
+            # Now the full line-count check.
+            numoflines = self.count_lines(s)
+            if numoflines < auto_squeeze_min_lines:
+                return write(s, tags)
+
+            # Create an ExpandingButton instance.
+            expandingbutton = ExpandingButton(s, tags, numoflines, self)
+
+            # Insert the ExpandingButton into the Text widget.
+            text.mark_gravity("iomark", tk.RIGHT)
+            text.window_create("iomark", window=expandingbutton,
+                               padx=3, pady=5)
+            text.see("iomark")
+            text.update()
+            text.mark_gravity("iomark", tk.LEFT)
+
+            # Add the ExpandingButton to the Squeezer's list.
+            self.expandingbuttons.append(expandingbutton)
+
+        editwin.write = mywrite
 
     def count_lines(self, s):
         """Count the number of lines in a given text.
@@ -275,25 +298,24 @@ class Squeezer:
 
         Tabs are considered tabwidth characters long.
         """
-        # Tab width is configurable
-        tabwidth = self.editwin.get_tk_tabwidth()
-
-        # Get the Text widget's size
-        linewidth = self.editwin.text.winfo_width()
-        # Deduct the border and padding
-        linewidth -= 2*sum([int(self.editwin.text.cget(opt))
-                            for opt in ('border', 'padx')])
-
-        # Get the Text widget's font
-        font = Font(self.editwin.text, name=self.editwin.text.cget('font'))
-        # Divide the size of the Text widget by the font's width.
-        # According to Tk8.5 docs, the Text widget's width is set
-        # according to the width of its font's '0' (zero) character,
-        # so we will use this as an approximation.
-        # see: http://www.tcl.tk/man/tcl8.5/TkCmd/text.htm#M-width
-        linewidth //= font.measure('0')
-
-        return count_lines_with_wrapping(s, linewidth, tabwidth)
+        linewidth = self.get_line_width()
+        return count_lines_with_wrapping(s, linewidth)
+
+    def get_line_width(self):
+        # The maximum line length in pixels: The width of the text
+        # widget, minus twice the border width and internal padding.
+        linewidth_pixels = \
+            self.base_text.winfo_width() - self.window_width_delta
+
+        # Divide the width of the Text widget by the font width,
+        # which is taken to be the width of '0' (zero).
+        # http://www.tcl.tk/man/tcl8.6/TkCmd/text.htm#M21
+        return linewidth_pixels // self.zero_char_width
+
+    def load_font(self):
+        text = self.base_text
+        self.zero_char_width = \
+            Font(text, font=text.cget('font')).measure('0')
 
     def squeeze_current_text_event(self, event):
         """squeeze-current-text event handler
@@ -303,29 +325,29 @@ class Squeezer:
         If the insert cursor is not in a squeezable block of text, give the
         user a small warning and do nothing.
         """
-        # set tag_name to the first valid tag found on the "insert" cursor
+        # Set tag_name to the first valid tag found on the "insert" cursor.
         tag_names = self.text.tag_names(tk.INSERT)
         for tag_name in ("stdout", "stderr"):
             if tag_name in tag_names:
                 break
         else:
-            # the insert cursor doesn't have a "stdout" or "stderr" tag
+            # The insert cursor doesn't have a "stdout" or "stderr" tag.
             self.text.bell()
             return "break"
 
-        # find the range to squeeze
+        # Find the range to squeeze.
         start, end = self.text.tag_prevrange(tag_name, tk.INSERT + "+1c")
         s = self.text.get(start, end)
 
-        # if the last char is a newline, remove it from the range
+        # If the last char is a newline, remove it from the range.
         if len(s) > 0 and s[-1] == '\n':
             end = self.text.index("%s-1c" % end)
             s = s[:-1]
 
-        # delete the text
+        # Delete the text.
         self.base_text.delete(start, end)
 
-        # prepare an ExpandingButton
+        # Prepare an ExpandingButton.
         numoflines = self.count_lines(s)
         expandingbutton = ExpandingButton(s, tag_name, numoflines, self)
 
@@ -333,9 +355,9 @@ class Squeezer:
         self.text.window_create(start, window=expandingbutton,
                                 padx=3, pady=5)
 
-        # insert the ExpandingButton to the list of ExpandingButtons, while
-        # keeping the list ordered according to the position of the buttons in
-        # the Text widget
+        # Insert the ExpandingButton to the list of ExpandingButtons,
+        # while keeping the list ordered according to the position of
+        # the buttons in the Text widget.
         i = len(self.expandingbuttons)
         while i > 0 and self.text.compare(self.expandingbuttons[i-1],
                                           ">", expandingbutton):
index 05f864657fb827903acfaa694bd1d44f881e4e1b..21426cbb33e0da063915005e668f1d878d47b304 100644 (file)
@@ -17,7 +17,7 @@
 import os
 
 from tkinter import *
-from tkinter.ttk import Scrollbar
+from tkinter.ttk import Frame, Scrollbar
 
 from idlelib.config import idleConf
 from idlelib import zoomheight
index b2488b28cabe7ef363eafcf77f972e9af5458cf8..460d5b67948dde2e1eee32fa548fdd289e3512de 100644 (file)
@@ -1,4 +1,5 @@
-from tkinter import *
+from tkinter import Toplevel, TclError
+import sys
 
 
 class WindowList:
index 73f1df071bf3bf6aa9e4b43eaed6d2627702f941..35e285f0ba414bed91f4ef056f2484f697f2ffd0 100644 (file)
@@ -13,7 +13,10 @@ class ZoomHeight:
 
     def zoom_height_event(self, event=None):
         top = self.editwin.top
-        zoom_height(top)
+        zoomed = zoom_height(top)
+        menu_status = 'Restore' if zoomed else 'Zoom'
+        self.editwin.update_menu_label(menu='options', index='* Height',
+                                       label=f'{menu_status} Height')
         return "break"
 
 
@@ -46,6 +49,7 @@ def zoom_height(top):
     else:
         newgeom = "%dx%d+%d+%d" % (width, newheight, x, newy)
     top.wm_geometry(newgeom)
+    return newgeom != ""
 
 
 if __name__ == "__main__":
index dbed993a38d65af89dc086a631bb179c49e53e56..4ae8ddc77018648d69271ce2cedddd252e0e01a0 100644 (file)
@@ -1135,7 +1135,7 @@ class ListProxy(BaseListProxy):
 
 DictProxy = MakeProxyType('DictProxy', (
     '__contains__', '__delitem__', '__getitem__', '__iter__', '__len__',
-    '__setitem__', 'clear', 'copy', 'get', 'has_key', 'items',
+    '__setitem__', 'clear', 'copy', 'get', 'items',
     'keys', 'pop', 'popitem', 'setdefault', 'update', 'values'
     ))
 DictProxy._method_to_typeid_ = {
index 3e42e9c3387413a7afc70f19ee7dc55352ee22b2..e01953d32b7a426aad232a928dc6be050027ae60 100644 (file)
@@ -18,6 +18,19 @@ TERMINATE = 0x10000
 WINEXE = (sys.platform == 'win32' and getattr(sys, 'frozen', False))
 WINSERVICE = sys.executable.lower().endswith("pythonservice.exe")
 
+
+def _path_eq(p1, p2):
+    return p1 == p2 or os.path.normcase(p1) == os.path.normcase(p2)
+
+WINENV = (hasattr(sys, '_base_executable') and
+          not _path_eq(sys.executable, sys._base_executable))
+
+
+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.
@@ -40,12 +53,23 @@ class Popen(object):
                                      pipe_handle=rhandle)
         cmd = ' '.join('"%s"' % x for x in cmd)
 
+        python_exe = spawn.get_executable()
+
+        # bpo-35797: When running in a venv, we bypass the redirect
+        # executor and launch our base Python.
+        if WINENV and _path_eq(python_exe, sys.executable):
+            python_exe = sys._base_executable
+            env = os.environ.copy()
+            env["__PYVENV_LAUNCHER__"] = sys.executable
+        else:
+            env = None
+
         with open(wfd, 'wb', closefd=True) as to_child:
             # start process
             try:
                 hp, ht, pid, tid = _winapi.CreateProcess(
-                    spawn.get_executable(), cmd,
-                    None, None, False, 0, None, None, None)
+                    python_exe, cmd,
+                    env, None, False, 0, None, None, None)
                 _winapi.CloseHandle(ht)
             except:
                 _winapi.CloseHandle(rhandle)
index 1f4f3f496f51a26bee2382b4d3333a6e364f8b7a..6ed459074325d227d1270b6090dfd55db7b8f654 100644 (file)
@@ -30,7 +30,7 @@ if sys.platform != 'win32':
     WINEXE = False
     WINSERVICE = False
 else:
-    WINEXE = (sys.platform == 'win32' and getattr(sys, 'frozen', False))
+    WINEXE = getattr(sys, 'frozen', False)
     WINSERVICE = sys.executable.lower().endswith("pythonservice.exe")
 
 if WINSERVICE:
index c2986bd022d09457fdd3ef5e9badcc6376890f62..dd6a83f715f86e9ecbccd6a58d967eeca7f6a3f1 100644 (file)
@@ -37,6 +37,15 @@ __all__ = [
 # EBADF - guard agains macOS `stat` throwing EBADF
 _IGNORED_ERROS = (ENOENT, ENOTDIR, EBADF)
 
+_IGNORED_WINERRORS = (
+    21,  # ERROR_NOT_READY - drive exists but is not accessible
+)
+
+def _ignore_error(exception):
+    return (getattr(exception, 'errno', None) in _IGNORED_ERROS or
+            getattr(exception, 'winerror', None) in _IGNORED_WINERRORS)
+
+
 def _is_wildcard_pattern(pat):
     # Whether this pattern needs actual matching using fnmatch, or can
     # be looked up directly as a file.
@@ -535,7 +544,7 @@ class _RecursiveWildcardSelector(_Selector):
                 try:
                     entry_is_dir = entry.is_dir()
                 except OSError as e:
-                    if e.errno not in _IGNORED_ERROS:
+                    if not _ignore_error(e):
                         raise
                 if entry_is_dir and not entry.is_symlink():
                     path = parent_path._make_child_relpath(entry.name)
@@ -1081,7 +1090,7 @@ class Path(PurePath):
 
     def glob(self, pattern):
         """Iterate over this subtree and yield all existing files (of any
-        kind, including directories) matching the given pattern.
+        kind, including directories) matching the given relative pattern.
         """
         if not pattern:
             raise ValueError("Unacceptable pattern: {!r}".format(pattern))
@@ -1095,7 +1104,8 @@ class Path(PurePath):
 
     def rglob(self, pattern):
         """Recursively yield all existing files (of any kind, including
-        directories) matching the given pattern, anywhere in this subtree.
+        directories) matching the given relative pattern, anywhere in
+        this subtree.
         """
         pattern = self._flavour.casefold(pattern)
         drv, root, pattern_parts = self._flavour.parse_parts((pattern,))
@@ -1328,7 +1338,7 @@ class Path(PurePath):
         try:
             self.stat()
         except OSError as e:
-            if e.errno not in _IGNORED_ERROS:
+            if not _ignore_error(e):
                 raise
             return False
         return True
@@ -1340,7 +1350,7 @@ class Path(PurePath):
         try:
             return S_ISDIR(self.stat().st_mode)
         except OSError as e:
-            if e.errno not in _IGNORED_ERROS:
+            if not _ignore_error(e):
                 raise
             # Path doesn't exist or is a broken symlink
             # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
@@ -1354,7 +1364,7 @@ class Path(PurePath):
         try:
             return S_ISREG(self.stat().st_mode)
         except OSError as e:
-            if e.errno not in _IGNORED_ERROS:
+            if not _ignore_error(e):
                 raise
             # Path doesn't exist or is a broken symlink
             # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
@@ -1388,7 +1398,7 @@ class Path(PurePath):
         try:
             return S_ISLNK(self.lstat().st_mode)
         except OSError as e:
-            if e.errno not in _IGNORED_ERROS:
+            if not _ignore_error(e):
                 raise
             # Path doesn't exist
             return False
@@ -1400,7 +1410,7 @@ class Path(PurePath):
         try:
             return S_ISBLK(self.stat().st_mode)
         except OSError as e:
-            if e.errno not in _IGNORED_ERROS:
+            if not _ignore_error(e):
                 raise
             # Path doesn't exist or is a broken symlink
             # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
@@ -1413,7 +1423,7 @@ class Path(PurePath):
         try:
             return S_ISCHR(self.stat().st_mode)
         except OSError as e:
-            if e.errno not in _IGNORED_ERROS:
+            if not _ignore_error(e):
                 raise
             # Path doesn't exist or is a broken symlink
             # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
@@ -1426,7 +1436,7 @@ class Path(PurePath):
         try:
             return S_ISFIFO(self.stat().st_mode)
         except OSError as e:
-            if e.errno not in _IGNORED_ERROS:
+            if not _ignore_error(e):
                 raise
             # Path doesn't exist or is a broken symlink
             # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
@@ -1439,7 +1449,7 @@ class Path(PurePath):
         try:
             return S_ISSOCK(self.stat().st_mode)
         except OSError as e:
-            if e.errno not in _IGNORED_ERROS:
+            if not _ignore_error(e):
                 raise
             # Path doesn't exist or is a broken symlink
             # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
index 60bdb7675c8131660b2064150fa739911382c1d2..bf3219af3985da990b76b584a5c476c0e426d2c7 100755 (executable)
@@ -1096,7 +1096,11 @@ class Pdb(bdb.Bdb, cmd.Cmd):
         p = Pdb(self.completekey, self.stdin, self.stdout)
         p.prompt = "(%s) " % self.prompt.strip()
         self.message("ENTERING RECURSIVE DEBUGGER")
-        sys.call_tracing(p.run, (arg, globals, locals))
+        try:
+            sys.call_tracing(p.run, (arg, globals, locals))
+        except Exception:
+            exc_info = sys.exc_info()[:2]
+            self.error(traceback.format_exception_only(*exc_info)[-1].strip())
         self.message("LEAVING RECURSIVE DEBUGGER")
         sys.settrace(self.trace_dispatch)
         self.lastcmd = p.lastcmd
index bcf2eedebe6b546a9cab0442d68a8e4b3ae57195..f2a117864e5e159dacaef819739bcb015713aff5 100644 (file)
@@ -568,11 +568,11 @@ def _perfcheck(object=None):
     if object is None:
         object = [("string", (1, 2), [3, 4], {5: 6, 7: 8})] * 100000
     p = PrettyPrinter()
-    t1 = time.time()
+    t1 = time.perf_counter()
     _safe_repr(object, {}, None, 0)
-    t2 = time.time()
+    t2 = time.perf_counter()
     p.pformat(object)
-    t3 = time.time()
+    t3 = time.perf_counter()
     print("_safe_repr:", t2 - t1)
     print("pformat:", t3 - t2)
 
index 09992cd08245a290ebf0abf615ef5356c223f244..44df8c854ae9edba7087037dc7b520f4a5c5a4df 100644 (file)
@@ -2213,14 +2213,14 @@ def _start_server(urlhandler, hostname, port):
         Let the server do its thing. We just need to monitor its status.
         Use time.sleep so the loop doesn't hog the CPU.
 
-        >>> starttime = time.time()
+        >>> starttime = time.monotonic()
         >>> timeout = 1                    #seconds
 
         This is a short timeout for testing purposes.
 
         >>> while serverthread.serving:
         ...     time.sleep(.01)
-        ...     if serverthread.serving and time.time() - starttime > timeout:
+        ...     if serverthread.serving and time.monotonic() - starttime > timeout:
         ...          serverthread.stop()
         ...          break
 
index 55fb1199f896d68e35e00c45392381e556d5f5ed..d9cd501e755a04eb3a6c88cb977d8d3221ed11f4 100644 (file)
@@ -1,5 +1,5 @@
 # -*- coding: utf-8 -*-
-# Autogenerated by Sphinx on Sun Dec 23 16:24:58 2018
+# Autogenerated by Sphinx on Tue Mar 12 14:56:48 2019
 topics = {'assert': 'The "assert" statement\n'
            '**********************\n'
            '\n'
@@ -351,9 +351,9 @@ topics = {'assert': 'The "assert" statement\n'
                'Annotated assignment statements\n'
                '===============================\n'
                '\n'
-               'Annotation assignment is the combination, in a single '
-               'statement, of a\n'
-               'variable or attribute annotation and an optional assignment '
+               '*Annotation* assignment is the combination, in a single '
+               'statement, of\n'
+               'a variable or attribute annotation and an optional assignment\n'
                'statement:\n'
                '\n'
                '   annotated_assignment_stmt ::= augtarget ":" expression ["=" '
@@ -962,7 +962,8 @@ topics = {'assert': 'The "assert" statement\n'
                      'in a parent.)\n'
                      '\n'
                      'The space saved over using *__dict__* can be '
-                     'significant.\n'
+                     'significant. Attribute\n'
+                     'lookup speed can be significantly improved as well.\n'
                      '\n'
                      'object.__slots__\n'
                      '\n'
@@ -2667,30 +2668,31 @@ topics = {'assert': 'The "assert" statement\n'
              'passed\n'
              'used keyword arguments.\n'
              '\n'
-             'Parameters may have annotations of the form “": expression"” '
-             'following\n'
-             'the parameter name.  Any parameter may have an annotation even '
-             'those\n'
-             'of the form "*identifier" or "**identifier".  Functions may '
-             'have\n'
-             '“return” annotation of the form “"-> expression"” after the '
-             'parameter\n'
-             'list.  These annotations can be any valid Python expression.  '
-             'The\n'
-             'presence of annotations does not change the semantics of a '
-             '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'
-             'function object.  If the "annotations" import from "__future__" '
-             'is\n'
-             'used, annotations are preserved as strings at runtime which '
-             'enables\n'
-             'postponed evaluation.  Otherwise, they are evaluated when the '
-             'function\n'
-             'definition is executed.  In this case annotations may be '
-             'evaluated in\n'
-             'a different order than they appear in the source code.\n'
+             'Parameters may have an *annotation* of the form “": '
+             'expression"”\n'
+             'following the parameter name.  Any parameter may have an '
+             'annotation,\n'
+             'even those of the form "*identifier" or "**identifier".  '
+             'Functions may\n'
+             'have “return” annotation of the form “"-> expression"” after '
+             'the\n'
+             'parameter list.  These annotations can be any valid Python '
+             'expression.\n'
+             'The presence of annotations does not change the semantics of a\n'
+             'function.  The annotation values are available as values of a\n'
+             'dictionary keyed by the parameters’ names in the '
+             '"__annotations__"\n'
+             'attribute of the function object.  If the "annotations" import '
+             'from\n'
+             '"__future__" is used, annotations are preserved as strings at '
+             'runtime\n'
+             'which enables postponed evaluation.  Otherwise, they are '
+             'evaluated\n'
+             'when the function definition is executed.  In this case '
+             'annotations\n'
+             'may be evaluated in a different order than they appear in the '
+             'source\n'
+             'code.\n'
              '\n'
              'It is also possible to create anonymous functions (functions not '
              'bound\n'
@@ -3612,6 +3614,10 @@ topics = {'assert': 'The "assert" statement\n'
              'running\n'
              'without the debugger using the "continue" command.\n'
              '\n'
+             'New in version 3.7: The built-in "breakpoint()", when called '
+             'with\n'
+             'defaults, can be used instead of "import pdb; pdb.set_trace()".\n'
+             '\n'
              'The typical usage to inspect a crashed program is:\n'
              '\n'
              '   >>> import pdb\n'
@@ -5690,30 +5696,31 @@ topics = {'assert': 'The "assert" statement\n'
              'passed\n'
              'used keyword arguments.\n'
              '\n'
-             'Parameters may have annotations of the form “": expression"” '
-             'following\n'
-             'the parameter name.  Any parameter may have an annotation even '
-             'those\n'
-             'of the form "*identifier" or "**identifier".  Functions may '
-             'have\n'
-             '“return” annotation of the form “"-> expression"” after the '
-             'parameter\n'
-             'list.  These annotations can be any valid Python expression.  '
-             'The\n'
-             'presence of annotations does not change the semantics of a '
-             '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'
-             'function object.  If the "annotations" import from "__future__" '
-             'is\n'
-             'used, annotations are preserved as strings at runtime which '
-             'enables\n'
-             'postponed evaluation.  Otherwise, they are evaluated when the '
-             'function\n'
-             'definition is executed.  In this case annotations may be '
-             'evaluated in\n'
-             'a different order than they appear in the source code.\n'
+             'Parameters may have an *annotation* of the form “": '
+             'expression"”\n'
+             'following the parameter name.  Any parameter may have an '
+             'annotation,\n'
+             'even those of the form "*identifier" or "**identifier".  '
+             'Functions may\n'
+             'have “return” annotation of the form “"-> expression"” after '
+             'the\n'
+             'parameter list.  These annotations can be any valid Python '
+             'expression.\n'
+             'The presence of annotations does not change the semantics of a\n'
+             'function.  The annotation values are available as values of a\n'
+             'dictionary keyed by the parameters’ names in the '
+             '"__annotations__"\n'
+             'attribute of the function object.  If the "annotations" import '
+             'from\n'
+             '"__future__" is used, annotations are preserved as strings at '
+             'runtime\n'
+             'which enables postponed evaluation.  Otherwise, they are '
+             'evaluated\n'
+             'when the function definition is executed.  In this case '
+             'annotations\n'
+             'may be evaluated in a different order than they appear in the '
+             'source\n'
+             'code.\n'
              '\n'
              'It is also possible to create anonymous functions (functions not '
              'bound\n'
@@ -8566,7 +8573,9 @@ topics = {'assert': 'The "assert" statement\n'
                  '(unless explicitly declared in *__slots__* or available in a '
                  'parent.)\n'
                  '\n'
-                 'The space saved over using *__dict__* can be significant.\n'
+                 'The space saved over using *__dict__* can be significant. '
+                 'Attribute\n'
+                 'lookup speed can be significantly improved as well.\n'
                  '\n'
                  'object.__slots__\n'
                  '\n'
@@ -11555,7 +11564,7 @@ topics = {'assert': 'The "assert" statement\n'
           'Modules\n'
           '   Modules are a basic organizational unit of Python code, and are\n'
           '   created by the import system as invoked either by the "import"\n'
-          '   statement (see "import"), or by calling functions such as\n'
+          '   statement, or by calling functions such as\n'
           '   "importlib.import_module()" and built-in "__import__()".  A '
           'module\n'
           '   object has a namespace implemented by a dictionary object (this '
@@ -12147,11 +12156,11 @@ topics = {'assert': 'The "assert" statement\n'
                  '\n'
                  '      Return a shallow copy of the dictionary.\n'
                  '\n'
-                 '   classmethod fromkeys(seq[, value])\n'
+                 '   classmethod fromkeys(iterable[, value])\n'
                  '\n'
-                 '      Create a new dictionary with keys from *seq* and '
-                 'values set to\n'
-                 '      *value*.\n'
+                 '      Create a new dictionary with keys from *iterable* and '
+                 'values set\n'
+                 '      to *value*.\n'
                  '\n'
                  '      "fromkeys()" is a class method that returns a new '
                  'dictionary.\n'
index 8e94064c9c6123c5475a6c739e19d25244691411..bb6a05f26af68bdd1ae5165cbc1773bc0245836e 100644 (file)
@@ -706,14 +706,14 @@ def _test_generator(n, func, args):
     sqsum = 0.0
     smallest = 1e10
     largest = -1e10
-    t0 = time.time()
+    t0 = time.perf_counter()
     for i in range(n):
         x = func(*args)
         total += x
         sqsum = sqsum + x*x
         smallest = min(x, smallest)
         largest = max(x, largest)
-    t1 = time.time()
+    t1 = time.perf_counter()
     print(round(t1-t0, 3), 'sec,', end=' ')
     avg = total/n
     stddev = _sqrt(sqsum/n - avg*avg)
index ffd132b389e1b879df8ff7e8185508988de7c828..ad1146332b0ab7b65df640069bbeb4b6494bbad9 100644 (file)
@@ -457,7 +457,14 @@ def venv(known_paths):
 
     env = os.environ
     if sys.platform == 'darwin' and '__PYVENV_LAUNCHER__' in env:
-        executable = os.environ['__PYVENV_LAUNCHER__']
+        executable = sys._base_executable = os.environ['__PYVENV_LAUNCHER__']
+    elif sys.platform == 'win32' and '__PYVENV_LAUNCHER__' in env:
+        executable = sys.executable
+        import _winapi
+        sys._base_executable = _winapi.GetModuleFileName(0)
+        # bpo-35873: Clear the environment variable to avoid it being
+        # inherited by child processes.
+        del os.environ['__PYVENV_LAUNCHER__']
     else:
         executable = sys.executable
     exe_dir, _ = os.path.split(os.path.abspath(executable))
index f0377918e894365aa15be6efd891c1a21c584ad0..905df9319e2fa8d2baeb548df14318f58a0ba2a5 100644 (file)
@@ -594,7 +594,7 @@ if hasattr(os, "fork"):
         def service_actions(self):
             """Collect the zombie child processes regularly in the ForkingMixIn.
 
-            service_actions is called in the BaseServer's serve_forver loop.
+            service_actions is called in the BaseServer's serve_forever loop.
             """
             self.collect_children()
 
index 1c59a3cd31c625834a4dda5e282d86828bf888fc..865bd88f74f10a4947f7338b328d8fb372a316d0 100644 (file)
@@ -379,6 +379,10 @@ class RegressionTests(unittest.TestCase):
         del ref
         support.gc_collect()
 
+    def CheckDelIsolation_levelSegfault(self):
+        with self.assertRaises(AttributeError):
+            del self.con.isolation_level
+
 
 class UnhashableFunc:
     __hash__ = None
index 9ee4d3185a71276137a39481244846453a12f262..d15cec8dbfc9122c9b9f6b7b02212244c77c413d 100644 (file)
@@ -125,9 +125,16 @@ def _is_python_source_dir(d):
     return False
 
 _sys_home = getattr(sys, '_home', None)
-if (_sys_home and os.name == 'nt' and
-    _sys_home.lower().endswith(('\\pcbuild\\win32', '\\pcbuild\\amd64'))):
-    _sys_home = os.path.dirname(os.path.dirname(_sys_home))
+
+if os.name == 'nt':
+    def _fix_pcbuild(d):
+        if d and os.path.normcase(d).startswith(
+                os.path.normcase(os.path.join(_PREFIX, "PCbuild"))):
+            return _PREFIX
+        return d
+    _PROJECT_BASE = _fix_pcbuild(_PROJECT_BASE)
+    _sys_home = _fix_pcbuild(_sys_home)
+
 def is_python_build(check_home=False):
     if check_home and _sys_home:
         return _is_python_source_dir(_sys_home)
index abcb5d45e7ab7af4072feba2d4cbadde97b6ee5b..821bfa17830410637dce89f431175f4dd7eb8ae7 100644 (file)
@@ -157,11 +157,11 @@ class TimingWrapper(object):
         self.elapsed = None
 
     def __call__(self, *args, **kwds):
-        t = time.time()
+        t = time.monotonic()
         try:
             return self.func(*args, **kwds)
         finally:
-            self.elapsed = time.time() - t
+            self.elapsed = time.monotonic() - t
 
 #
 # Base class for test cases
@@ -1036,9 +1036,9 @@ class _TestQueue(BaseTestCase):
 
     def test_timeout(self):
         q = multiprocessing.Queue()
-        start = time.time()
+        start = time.monotonic()
         self.assertRaises(pyqueue.Empty, q.get, True, 0.200)
-        delta = time.time() - start
+        delta = time.monotonic() - start
         # bpo-30317: Tolerate a delta of 100 ms because of the bad clock
         # resolution on Windows (usually 15.6 ms). x86 Windows7 3.x once
         # failed because the delta was only 135.8 ms.
@@ -1434,9 +1434,9 @@ class _TestCondition(BaseTestCase):
         sem.release()
         with cond:
             expected = 0.1
-            dt = time.time()
+            dt = time.monotonic()
             result = cond.wait_for(lambda : state.value==4, timeout=expected)
-            dt = time.time() - dt
+            dt = time.monotonic() - dt
             # borrow logic in assertTimeout() from test/lock_tests.py
             if not result and expected * 0.6 < dt < expected * 10.0:
                 success.value = True
@@ -2527,7 +2527,7 @@ class _TestPool(BaseTestCase):
         # process would fill the result queue (after the result handler thread
         # terminated, hence not draining it anymore).
 
-        t_start = time.time()
+        t_start = time.monotonic()
 
         with self.assertRaises(ValueError):
             with self.Pool(2) as p:
@@ -2539,7 +2539,7 @@ class _TestPool(BaseTestCase):
                     p.join()
 
         # check that we indeed waited for all jobs
-        self.assertGreater(time.time() - t_start, 0.9)
+        self.assertGreater(time.monotonic() - t_start, 0.9)
 
     def test_release_task_refs(self):
         # Issue #29861: task arguments and results should not be kept
@@ -2779,6 +2779,7 @@ class _TestRemoteManager(BaseTestCase):
             address=(test.support.HOST, 0), authkey=authkey, serializer=SERIALIZER
             )
         manager.start()
+        self.addCleanup(manager.shutdown)
 
         p = self.Process(target=self._putter, args=(manager.address, authkey))
         p.daemon = True
@@ -2798,7 +2799,6 @@ class _TestRemoteManager(BaseTestCase):
 
         # Make queue finalizer run before the server is stopped
         del queue
-        manager.shutdown()
 
 class _TestManagerRestart(BaseTestCase):
 
@@ -2814,25 +2814,29 @@ class _TestManagerRestart(BaseTestCase):
         authkey = os.urandom(32)
         manager = QueueManager(
             address=(test.support.HOST, 0), authkey=authkey, serializer=SERIALIZER)
-        srvr = manager.get_server()
-        addr = srvr.address
-        # Close the connection.Listener socket which gets opened as a part
-        # of manager.get_server(). It's not needed for the test.
-        srvr.listener.close()
-        manager.start()
+        try:
+            srvr = manager.get_server()
+            addr = srvr.address
+            # Close the connection.Listener socket which gets opened as a part
+            # of manager.get_server(). It's not needed for the test.
+            srvr.listener.close()
+            manager.start()
 
-        p = self.Process(target=self._putter, args=(manager.address, authkey))
-        p.start()
-        p.join()
-        queue = manager.get_queue()
-        self.assertEqual(queue.get(), 'hello world')
-        del queue
-        manager.shutdown()
+            p = self.Process(target=self._putter, args=(manager.address, authkey))
+            p.start()
+            p.join()
+            queue = manager.get_queue()
+            self.assertEqual(queue.get(), 'hello world')
+            del queue
+        finally:
+            if hasattr(manager, "shutdown"):
+                manager.shutdown()
 
         manager = QueueManager(
             address=addr, authkey=authkey, serializer=SERIALIZER)
         try:
             manager.start()
+            self.addCleanup(manager.shutdown)
         except OSError as e:
             if e.errno != errno.EADDRINUSE:
                 raise
@@ -2841,7 +2845,8 @@ class _TestManagerRestart(BaseTestCase):
             time.sleep(1.0)
             manager = QueueManager(
                 address=addr, authkey=authkey, serializer=SERIALIZER)
-        manager.shutdown()
+            if hasattr(manager, "shutdown"):
+                self.addCleanup(manager.shutdown)
 
 #
 #
@@ -4051,9 +4056,9 @@ class TestWait(unittest.TestCase):
         expected = 5
         a, b = multiprocessing.Pipe()
 
-        start = time.time()
+        start = time.monotonic()
         res = wait([a, b], expected)
-        delta = time.time() - start
+        delta = time.monotonic() - start
 
         self.assertEqual(res, [])
         self.assertLess(delta, expected * 2)
@@ -4061,9 +4066,9 @@ class TestWait(unittest.TestCase):
 
         b.send(None)
 
-        start = time.time()
+        start = time.monotonic()
         res = wait([a, b], 20)
-        delta = time.time() - start
+        delta = time.monotonic() - start
 
         self.assertEqual(res, [a])
         self.assertLess(delta, 0.4)
@@ -4087,9 +4092,9 @@ class TestWait(unittest.TestCase):
         self.assertIsInstance(p.sentinel, int)
         self.assertTrue(sem.acquire(timeout=20))
 
-        start = time.time()
+        start = time.monotonic()
         res = wait([a, p.sentinel, b], expected + 20)
-        delta = time.time() - start
+        delta = time.monotonic() - start
 
         self.assertEqual(res, [p.sentinel])
         self.assertLess(delta, expected + 2)
@@ -4097,18 +4102,18 @@ class TestWait(unittest.TestCase):
 
         a.send(None)
 
-        start = time.time()
+        start = time.monotonic()
         res = wait([a, p.sentinel, b], 20)
-        delta = time.time() - start
+        delta = time.monotonic() - start
 
         self.assertEqual(sorted_(res), sorted_([p.sentinel, b]))
         self.assertLess(delta, 0.4)
 
         b.send(None)
 
-        start = time.time()
+        start = time.monotonic()
         res = wait([a, p.sentinel, b], 20)
-        delta = time.time() - start
+        delta = time.monotonic() - start
 
         self.assertEqual(sorted_(res), sorted_([a, p.sentinel, b]))
         self.assertLess(delta, 0.4)
@@ -4119,9 +4124,9 @@ class TestWait(unittest.TestCase):
     def test_neg_timeout(self):
         from multiprocessing.connection import wait
         a, b = multiprocessing.Pipe()
-        t = time.time()
+        t = time.monotonic()
         res = wait([a], timeout=-1)
-        t = time.time() - t
+        t = time.monotonic() - t
         self.assertEqual(res, [])
         self.assertLess(t, 1)
         a.close()
@@ -4575,6 +4580,242 @@ class TestSimpleQueue(unittest.TestCase):
 
         proc.join()
 
+
+class TestSyncManagerTypes(unittest.TestCase):
+    """Test all the types which can be shared between a parent and a
+    child process by using a manager which acts as an intermediary
+    between them.
+
+    In the following unit-tests the base type is created in the parent
+    process, the @classmethod represents the worker process and the
+    shared object is readable and editable between the two.
+
+    # The child.
+    @classmethod
+    def _test_list(cls, obj):
+        assert obj[0] == 5
+        assert obj.append(6)
+
+    # The parent.
+    def test_list(self):
+        o = self.manager.list()
+        o.append(5)
+        self.run_worker(self._test_list, o)
+        assert o[1] == 6
+    """
+    manager_class = multiprocessing.managers.SyncManager
+
+    def setUp(self):
+        self.manager = self.manager_class()
+        self.manager.start()
+        self.proc = None
+
+    def tearDown(self):
+        if self.proc is not None and self.proc.is_alive():
+            self.proc.terminate()
+            self.proc.join()
+        self.manager.shutdown()
+        self.manager = None
+        self.proc = None
+
+    @classmethod
+    def setUpClass(cls):
+        support.reap_children()
+
+    tearDownClass = setUpClass
+
+    def wait_proc_exit(self):
+        # Only the manager process should be returned by active_children()
+        # but this can take a bit on slow machines, so wait a few seconds
+        # if there are other children too (see #17395).
+        join_process(self.proc)
+        start_time = time.monotonic()
+        t = 0.01
+        while len(multiprocessing.active_children()) > 1:
+            time.sleep(t)
+            t *= 2
+            dt = time.monotonic() - start_time
+            if dt >= 5.0:
+                test.support.environment_altered = True
+                print("Warning -- multiprocessing.Manager still has %s active "
+                      "children after %s seconds"
+                      % (multiprocessing.active_children(), dt),
+                      file=sys.stderr)
+                break
+
+    def run_worker(self, worker, obj):
+        self.proc = multiprocessing.Process(target=worker, args=(obj, ))
+        self.proc.daemon = True
+        self.proc.start()
+        self.wait_proc_exit()
+        self.assertEqual(self.proc.exitcode, 0)
+
+    @classmethod
+    def _test_queue(cls, obj):
+        assert obj.qsize() == 2
+        assert obj.full()
+        assert not obj.empty()
+        assert obj.get() == 5
+        assert not obj.empty()
+        assert obj.get() == 6
+        assert obj.empty()
+
+    def test_queue(self, qname="Queue"):
+        o = getattr(self.manager, qname)(2)
+        o.put(5)
+        o.put(6)
+        self.run_worker(self._test_queue, o)
+        assert o.empty()
+        assert not o.full()
+
+    def test_joinable_queue(self):
+        self.test_queue("JoinableQueue")
+
+    @classmethod
+    def _test_event(cls, obj):
+        assert obj.is_set()
+        obj.wait()
+        obj.clear()
+        obj.wait(0.001)
+
+    def test_event(self):
+        o = self.manager.Event()
+        o.set()
+        self.run_worker(self._test_event, o)
+        assert not o.is_set()
+        o.wait(0.001)
+
+    @classmethod
+    def _test_lock(cls, obj):
+        obj.acquire()
+
+    def test_lock(self, lname="Lock"):
+        o = getattr(self.manager, lname)()
+        self.run_worker(self._test_lock, o)
+        o.release()
+        self.assertRaises(RuntimeError, o.release)  # already released
+
+    @classmethod
+    def _test_rlock(cls, obj):
+        obj.acquire()
+        obj.release()
+
+    def test_rlock(self, lname="Lock"):
+        o = getattr(self.manager, lname)()
+        self.run_worker(self._test_rlock, o)
+
+    @classmethod
+    def _test_semaphore(cls, obj):
+        obj.acquire()
+
+    def test_semaphore(self, sname="Semaphore"):
+        o = getattr(self.manager, sname)()
+        self.run_worker(self._test_semaphore, o)
+        o.release()
+
+    def test_bounded_semaphore(self):
+        self.test_semaphore(sname="BoundedSemaphore")
+
+    @classmethod
+    def _test_condition(cls, obj):
+        obj.acquire()
+        obj.release()
+
+    def test_condition(self):
+        o = self.manager.Condition()
+        self.run_worker(self._test_condition, o)
+
+    @classmethod
+    def _test_barrier(cls, obj):
+        assert obj.parties == 5
+        obj.reset()
+
+    def test_barrier(self):
+        o = self.manager.Barrier(5)
+        self.run_worker(self._test_barrier, o)
+
+    @classmethod
+    def _test_pool(cls, obj):
+        # TODO: fix https://bugs.python.org/issue35919
+        with obj:
+            pass
+
+    def test_pool(self):
+        o = self.manager.Pool(processes=4)
+        self.run_worker(self._test_pool, o)
+
+    @classmethod
+    def _test_list(cls, obj):
+        assert obj[0] == 5
+        assert obj.count(5) == 1
+        assert obj.index(5) == 0
+        obj.sort()
+        obj.reverse()
+        for x in obj:
+            pass
+        assert len(obj) == 1
+        assert obj.pop(0) == 5
+
+    def test_list(self):
+        o = self.manager.list()
+        o.append(5)
+        self.run_worker(self._test_list, o)
+        assert not o
+        self.assertEqual(len(o), 0)
+
+    @classmethod
+    def _test_dict(cls, obj):
+        assert len(obj) == 1
+        assert obj['foo'] == 5
+        assert obj.get('foo') == 5
+        assert list(obj.items()) == [('foo', 5)]
+        assert list(obj.keys()) == ['foo']
+        assert list(obj.values()) == [5]
+        assert obj.copy() == {'foo': 5}
+        assert obj.popitem() == ('foo', 5)
+
+    def test_dict(self):
+        o = self.manager.dict()
+        o['foo'] = 5
+        self.run_worker(self._test_dict, o)
+        assert not o
+        self.assertEqual(len(o), 0)
+
+    @classmethod
+    def _test_value(cls, obj):
+        assert obj.value == 1
+        assert obj.get() == 1
+        obj.set(2)
+
+    def test_value(self):
+        o = self.manager.Value('i', 1)
+        self.run_worker(self._test_value, o)
+        self.assertEqual(o.value, 2)
+        self.assertEqual(o.get(), 2)
+
+    @classmethod
+    def _test_array(cls, obj):
+        assert obj[0] == 0
+        assert obj[1] == 1
+        assert len(obj) == 2
+        assert list(obj) == [0, 1]
+
+    def test_array(self):
+        o = self.manager.Array('i', [0, 1])
+        self.run_worker(self._test_array, o)
+
+    @classmethod
+    def _test_namespace(cls, obj):
+        assert obj.x == 0
+        assert obj.y == 1
+
+    def test_namespace(self):
+        o = self.manager.Namespace()
+        o.x = 0
+        o.y = 1
+        self.run_worker(self._test_namespace, o)
+
+
 #
 # Mixins
 #
diff --git a/Lib/test/bisect.py b/Lib/test/bisect.py
deleted file mode 100755 (executable)
index 968537e..0000000
+++ /dev/null
@@ -1,167 +0,0 @@
-#!/usr/bin/env python3
-"""
-Command line tool to bisect failing CPython tests.
-
-Find the test_os test method which alters the environment:
-
-    ./python -m test.bisect --fail-env-changed test_os
-
-Find a reference leak in "test_os", write the list of failing tests into the
-"bisect" file:
-
-    ./python -m test.bisect -o bisect -R 3:3 test_os
-
-Load an existing list of tests from a file using -i option:
-
-    ./python -m test --list-cases -m FileTests test_os > tests
-    ./python -m test.bisect -i tests test_os
-"""
-
-import argparse
-import datetime
-import os.path
-import math
-import random
-import subprocess
-import sys
-import tempfile
-import time
-
-
-def write_tests(filename, tests):
-    with open(filename, "w") as fp:
-        for name in tests:
-            print(name, file=fp)
-        fp.flush()
-
-
-def write_output(filename, tests):
-    if not filename:
-        return
-    print("Writing %s tests into %s" % (len(tests), filename))
-    write_tests(filename, tests)
-    return filename
-
-
-def format_shell_args(args):
-    return ' '.join(args)
-
-
-def list_cases(args):
-    cmd = [sys.executable, '-m', 'test', '--list-cases']
-    cmd.extend(args.test_args)
-    proc = subprocess.run(cmd,
-                          stdout=subprocess.PIPE,
-                          universal_newlines=True)
-    exitcode = proc.returncode
-    if exitcode:
-        cmd = format_shell_args(cmd)
-        print("Failed to list tests: %s failed with exit code %s"
-              % (cmd, exitcode))
-        sys.exit(exitcode)
-    tests = proc.stdout.splitlines()
-    return tests
-
-
-def run_tests(args, tests, huntrleaks=None):
-    tmp = tempfile.mktemp()
-    try:
-        write_tests(tmp, tests)
-
-        cmd = [sys.executable, '-m', 'test', '--matchfile', tmp]
-        cmd.extend(args.test_args)
-        print("+ %s" % format_shell_args(cmd))
-        proc = subprocess.run(cmd)
-        return proc.returncode
-    finally:
-        if os.path.exists(tmp):
-            os.unlink(tmp)
-
-
-def parse_args():
-    parser = argparse.ArgumentParser()
-    parser.add_argument('-i', '--input',
-                        help='Test names produced by --list-tests written '
-                             'into a file. If not set, run --list-tests')
-    parser.add_argument('-o', '--output',
-                        help='Result of the bisection')
-    parser.add_argument('-n', '--max-tests', type=int, default=1,
-                        help='Maximum number of tests to stop the bisection '
-                             '(default: 1)')
-    parser.add_argument('-N', '--max-iter', type=int, default=100,
-                        help='Maximum number of bisection iterations '
-                             '(default: 100)')
-    # FIXME: document that following arguments are test arguments
-
-    args, test_args = parser.parse_known_args()
-    args.test_args = test_args
-    return args
-
-
-def main():
-    args = parse_args()
-
-    if args.input:
-        with open(args.input) as fp:
-            tests = [line.strip() for line in fp]
-    else:
-        tests = list_cases(args)
-
-    print("Start bisection with %s tests" % len(tests))
-    print("Test arguments: %s" % format_shell_args(args.test_args))
-    print("Bisection will stop when getting %s or less tests "
-          "(-n/--max-tests option), or after %s iterations "
-          "(-N/--max-iter option)"
-          % (args.max_tests, args.max_iter))
-    output = write_output(args.output, tests)
-    print()
-
-    start_time = time.monotonic()
-    iteration = 1
-    try:
-        while len(tests) > args.max_tests and iteration <= args.max_iter:
-            ntest = len(tests)
-            ntest = max(ntest // 2, 1)
-            subtests = random.sample(tests, ntest)
-
-            print("[+] Iteration %s: run %s tests/%s"
-                  % (iteration, len(subtests), len(tests)))
-            print()
-
-            exitcode = run_tests(args, subtests)
-
-            print("ran %s tests/%s" % (ntest, len(tests)))
-            print("exit", exitcode)
-            if exitcode:
-                print("Tests failed: continuing with this subtest")
-                tests = subtests
-                output = write_output(args.output, tests)
-            else:
-                print("Tests succeeded: skipping this subtest, trying a new subset")
-            print()
-            iteration += 1
-    except KeyboardInterrupt:
-        print()
-        print("Bisection interrupted!")
-        print()
-
-    print("Tests (%s):" % len(tests))
-    for test in tests:
-        print("* %s" % test)
-    print()
-
-    if output:
-        print("Output written into %s" % output)
-
-    dt = math.ceil(time.monotonic() - start_time)
-    if len(tests) <= args.max_tests:
-        print("Bisection completed in %s iterations and %s"
-              % (iteration, datetime.timedelta(seconds=dt)))
-        sys.exit(1)
-    else:
-        print("Bisection failed after %s iterations and %s"
-              % (iteration, datetime.timedelta(seconds=dt)))
-
-
-if __name__ == "__main__":
-    main()
diff --git a/Lib/test/bisect_cmd.py b/Lib/test/bisect_cmd.py
new file mode 100755 (executable)
index 0000000..968537e
--- /dev/null
@@ -0,0 +1,167 @@
+#!/usr/bin/env python3
+"""
+Command line tool to bisect failing CPython tests.
+
+Find the test_os test method which alters the environment:
+
+    ./python -m test.bisect --fail-env-changed test_os
+
+Find a reference leak in "test_os", write the list of failing tests into the
+"bisect" file:
+
+    ./python -m test.bisect -o bisect -R 3:3 test_os
+
+Load an existing list of tests from a file using -i option:
+
+    ./python -m test --list-cases -m FileTests test_os > tests
+    ./python -m test.bisect -i tests test_os
+"""
+
+import argparse
+import datetime
+import os.path
+import math
+import random
+import subprocess
+import sys
+import tempfile
+import time
+
+
+def write_tests(filename, tests):
+    with open(filename, "w") as fp:
+        for name in tests:
+            print(name, file=fp)
+        fp.flush()
+
+
+def write_output(filename, tests):
+    if not filename:
+        return
+    print("Writing %s tests into %s" % (len(tests), filename))
+    write_tests(filename, tests)
+    return filename
+
+
+def format_shell_args(args):
+    return ' '.join(args)
+
+
+def list_cases(args):
+    cmd = [sys.executable, '-m', 'test', '--list-cases']
+    cmd.extend(args.test_args)
+    proc = subprocess.run(cmd,
+                          stdout=subprocess.PIPE,
+                          universal_newlines=True)
+    exitcode = proc.returncode
+    if exitcode:
+        cmd = format_shell_args(cmd)
+        print("Failed to list tests: %s failed with exit code %s"
+              % (cmd, exitcode))
+        sys.exit(exitcode)
+    tests = proc.stdout.splitlines()
+    return tests
+
+
+def run_tests(args, tests, huntrleaks=None):
+    tmp = tempfile.mktemp()
+    try:
+        write_tests(tmp, tests)
+
+        cmd = [sys.executable, '-m', 'test', '--matchfile', tmp]
+        cmd.extend(args.test_args)
+        print("+ %s" % format_shell_args(cmd))
+        proc = subprocess.run(cmd)
+        return proc.returncode
+    finally:
+        if os.path.exists(tmp):
+            os.unlink(tmp)
+
+
+def parse_args():
+    parser = argparse.ArgumentParser()
+    parser.add_argument('-i', '--input',
+                        help='Test names produced by --list-tests written '
+                             'into a file. If not set, run --list-tests')
+    parser.add_argument('-o', '--output',
+                        help='Result of the bisection')
+    parser.add_argument('-n', '--max-tests', type=int, default=1,
+                        help='Maximum number of tests to stop the bisection '
+                             '(default: 1)')
+    parser.add_argument('-N', '--max-iter', type=int, default=100,
+                        help='Maximum number of bisection iterations '
+                             '(default: 100)')
+    # FIXME: document that following arguments are test arguments
+
+    args, test_args = parser.parse_known_args()
+    args.test_args = test_args
+    return args
+
+
+def main():
+    args = parse_args()
+
+    if args.input:
+        with open(args.input) as fp:
+            tests = [line.strip() for line in fp]
+    else:
+        tests = list_cases(args)
+
+    print("Start bisection with %s tests" % len(tests))
+    print("Test arguments: %s" % format_shell_args(args.test_args))
+    print("Bisection will stop when getting %s or less tests "
+          "(-n/--max-tests option), or after %s iterations "
+          "(-N/--max-iter option)"
+          % (args.max_tests, args.max_iter))
+    output = write_output(args.output, tests)
+    print()
+
+    start_time = time.monotonic()
+    iteration = 1
+    try:
+        while len(tests) > args.max_tests and iteration <= args.max_iter:
+            ntest = len(tests)
+            ntest = max(ntest // 2, 1)
+            subtests = random.sample(tests, ntest)
+
+            print("[+] Iteration %s: run %s tests/%s"
+                  % (iteration, len(subtests), len(tests)))
+            print()
+
+            exitcode = run_tests(args, subtests)
+
+            print("ran %s tests/%s" % (ntest, len(tests)))
+            print("exit", exitcode)
+            if exitcode:
+                print("Tests failed: continuing with this subtest")
+                tests = subtests
+                output = write_output(args.output, tests)
+            else:
+                print("Tests succeeded: skipping this subtest, trying a new subset")
+            print()
+            iteration += 1
+    except KeyboardInterrupt:
+        print()
+        print("Bisection interrupted!")
+        print()
+
+    print("Tests (%s):" % len(tests))
+    for test in tests:
+        print("* %s" % test)
+    print()
+
+    if output:
+        print("Output written into %s" % output)
+
+    dt = math.ceil(time.monotonic() - start_time)
+    if len(tests) <= args.max_tests:
+        print("Bisection completed in %s iterations and %s"
+              % (iteration, datetime.timedelta(seconds=dt)))
+        sys.exit(1)
+    else:
+        print("Bisection failed after %s iterations and %s"
+              % (iteration, datetime.timedelta(seconds=dt)))
+
+
+if __name__ == "__main__":
+    main()
diff --git a/Lib/test/clinic.test b/Lib/test/clinic.test
new file mode 100644 (file)
index 0000000..a113b94
--- /dev/null
@@ -0,0 +1,1205 @@
+/*[clinic input]
+output preset block
+[clinic start generated code]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3c81ac2402d06a8b]*/
+
+/*[clinic input]
+test_object_converter
+
+    a: object
+    b: object(converter="PyUnicode_FSConverter")
+    c: object(subclass_of="&PyUnicode_Type")
+    d: object(type="PyUnicode_Object *")
+    /
+
+[clinic start generated code]*/
+
+PyDoc_STRVAR(test_object_converter__doc__,
+"test_object_converter($module, a, b, c, d, /)\n"
+"--\n"
+"\n");
+
+#define TEST_OBJECT_CONVERTER_METHODDEF    \
+    {"test_object_converter", (PyCFunction)test_object_converter, METH_FASTCALL, test_object_converter__doc__},
+
+static PyObject *
+test_object_converter_impl(PyObject *module, PyObject *a, PyObject *b,
+                           PyObject *c, PyUnicode_Object *d);
+
+static PyObject *
+test_object_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    PyObject *a;
+    PyObject *b;
+    PyObject *c;
+    PyUnicode_Object *d;
+
+    if (!_PyArg_ParseStack(args, nargs, "OO&O!O:test_object_converter",
+        &a, PyUnicode_FSConverter, &b, &PyUnicode_Type, &c, &d)) {
+        goto exit;
+    }
+    return_value = test_object_converter_impl(module, a, b, c, d);
+
+exit:
+    return return_value;
+}
+
+static PyObject *
+test_object_converter_impl(PyObject *module, PyObject *a, PyObject *b,
+                           PyObject *c, PyUnicode_Object *d)
+/*[clinic end generated code: output=a82a013247de5d81 input=005e6a8a711a869b]*/
+
+/*[clinic input]
+test_object_converter_one_arg
+
+    a: object
+    /
+
+[clinic start generated code]*/
+
+PyDoc_STRVAR(test_object_converter_one_arg__doc__,
+"test_object_converter_one_arg($module, a, /)\n"
+"--\n"
+"\n");
+
+#define TEST_OBJECT_CONVERTER_ONE_ARG_METHODDEF    \
+    {"test_object_converter_one_arg", (PyCFunction)test_object_converter_one_arg, METH_O, test_object_converter_one_arg__doc__},
+
+static PyObject *
+test_object_converter_one_arg(PyObject *module, PyObject *a)
+/*[clinic end generated code: output=6da755f8502139df input=d635d92a421f1ca3]*/
+
+/*[clinic input]
+test_objects_converter
+
+    a: object
+    b: object = NULL
+    /
+
+[clinic start generated code]*/
+
+PyDoc_STRVAR(test_objects_converter__doc__,
+"test_objects_converter($module, a, b=None, /)\n"
+"--\n"
+"\n");
+
+#define TEST_OBJECTS_CONVERTER_METHODDEF    \
+    {"test_objects_converter", (PyCFunction)test_objects_converter, METH_FASTCALL, test_objects_converter__doc__},
+
+static PyObject *
+test_objects_converter_impl(PyObject *module, PyObject *a, PyObject *b);
+
+static PyObject *
+test_objects_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    PyObject *a;
+    PyObject *b = NULL;
+
+    if (!_PyArg_UnpackStack(args, nargs, "test_objects_converter",
+        1, 2,
+        &a, &b)) {
+        goto exit;
+    }
+    return_value = test_objects_converter_impl(module, a, b);
+
+exit:
+    return return_value;
+}
+
+static PyObject *
+test_objects_converter_impl(PyObject *module, PyObject *a, PyObject *b)
+/*[clinic end generated code: output=4bf98d3729b7bae7 input=4cbb3d9edd2a36f3]*/
+
+/*[clinic input]
+test_object_converter_subclass_of
+
+    a: object(subclass_of="&PyLong_Type")
+    b: object(subclass_of="&PyTuple_Type")
+    c: object(subclass_of="&PyList_Type")
+    d: object(subclass_of="&PySet_Type")
+    e: object(subclass_of="&PyFrozenSet_Type")
+    f: object(subclass_of="&PyDict_Type")
+    g: object(subclass_of="&PyUnicode_Type")
+    h: object(subclass_of="&PyBytes_Type")
+    i: object(subclass_of="&PyByteArray_Type")
+    j: object(subclass_of="&MyType")
+    /
+
+[clinic start generated code]*/
+
+PyDoc_STRVAR(test_object_converter_subclass_of__doc__,
+"test_object_converter_subclass_of($module, a, b, c, d, e, f, g, h, i,\n"
+"                                  j, /)\n"
+"--\n"
+"\n");
+
+#define TEST_OBJECT_CONVERTER_SUBCLASS_OF_METHODDEF    \
+    {"test_object_converter_subclass_of", (PyCFunction)test_object_converter_subclass_of, METH_FASTCALL, test_object_converter_subclass_of__doc__},
+
+static PyObject *
+test_object_converter_subclass_of_impl(PyObject *module, PyObject *a,
+                                       PyObject *b, PyObject *c, PyObject *d,
+                                       PyObject *e, PyObject *f, PyObject *g,
+                                       PyObject *h, PyObject *i, PyObject *j);
+
+static PyObject *
+test_object_converter_subclass_of(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    PyObject *a;
+    PyObject *b;
+    PyObject *c;
+    PyObject *d;
+    PyObject *e;
+    PyObject *f;
+    PyObject *g;
+    PyObject *h;
+    PyObject *i;
+    PyObject *j;
+
+    if (!_PyArg_ParseStack(args, nargs, "O!O!O!O!O!O!O!O!O!O!:test_object_converter_subclass_of",
+        &PyLong_Type, &a, &PyTuple_Type, &b, &PyList_Type, &c, &PySet_Type, &d, &PyFrozenSet_Type, &e, &PyDict_Type, &f, &PyUnicode_Type, &g, &PyBytes_Type, &h, &PyByteArray_Type, &i, &MyType, &j)) {
+        goto exit;
+    }
+    return_value = test_object_converter_subclass_of_impl(module, a, b, c, d, e, f, g, h, i, j);
+
+exit:
+    return return_value;
+}
+
+static PyObject *
+test_object_converter_subclass_of_impl(PyObject *module, PyObject *a,
+                                       PyObject *b, PyObject *c, PyObject *d,
+                                       PyObject *e, PyObject *f, PyObject *g,
+                                       PyObject *h, PyObject *i, PyObject *j)
+/*[clinic end generated code: output=811bcace8eca7f92 input=31b06b772d5f983e]*/
+
+/*[clinic input]
+test_PyBytesObject_converter
+
+    a: PyBytesObject
+    /
+
+[clinic start generated code]*/
+
+PyDoc_STRVAR(test_PyBytesObject_converter__doc__,
+"test_PyBytesObject_converter($module, a, /)\n"
+"--\n"
+"\n");
+
+#define TEST_PYBYTESOBJECT_CONVERTER_METHODDEF    \
+    {"test_PyBytesObject_converter", (PyCFunction)test_PyBytesObject_converter, METH_O, test_PyBytesObject_converter__doc__},
+
+static PyObject *
+test_PyBytesObject_converter_impl(PyObject *module, PyBytesObject *a);
+
+static PyObject *
+test_PyBytesObject_converter(PyObject *module, PyObject *arg)
+{
+    PyObject *return_value = NULL;
+    PyBytesObject *a;
+
+    if (!PyArg_Parse(arg, "S:test_PyBytesObject_converter", &a)) {
+        goto exit;
+    }
+    return_value = test_PyBytesObject_converter_impl(module, a);
+
+exit:
+    return return_value;
+}
+
+static PyObject *
+test_PyBytesObject_converter_impl(PyObject *module, PyBytesObject *a)
+/*[clinic end generated code: output=8dbf43c604ced031 input=12b10c7cb5750400]*/
+
+/*[clinic input]
+test_PyByteArrayObject_converter
+
+    a: PyByteArrayObject
+    /
+
+[clinic start generated code]*/
+
+PyDoc_STRVAR(test_PyByteArrayObject_converter__doc__,
+"test_PyByteArrayObject_converter($module, a, /)\n"
+"--\n"
+"\n");
+
+#define TEST_PYBYTEARRAYOBJECT_CONVERTER_METHODDEF    \
+    {"test_PyByteArrayObject_converter", (PyCFunction)test_PyByteArrayObject_converter, METH_O, test_PyByteArrayObject_converter__doc__},
+
+static PyObject *
+test_PyByteArrayObject_converter_impl(PyObject *module, PyByteArrayObject *a);
+
+static PyObject *
+test_PyByteArrayObject_converter(PyObject *module, PyObject *arg)
+{
+    PyObject *return_value = NULL;
+    PyByteArrayObject *a;
+
+    if (!PyArg_Parse(arg, "Y:test_PyByteArrayObject_converter", &a)) {
+        goto exit;
+    }
+    return_value = test_PyByteArrayObject_converter_impl(module, a);
+
+exit:
+    return return_value;
+}
+
+static PyObject *
+test_PyByteArrayObject_converter_impl(PyObject *module, PyByteArrayObject *a)
+/*[clinic end generated code: output=ade99fc6705e7d6e input=5a657da535d194ae]*/
+
+/*[clinic input]
+test_unicode_converter
+
+    a: unicode
+    /
+
+[clinic start generated code]*/
+
+PyDoc_STRVAR(test_unicode_converter__doc__,
+"test_unicode_converter($module, a, /)\n"
+"--\n"
+"\n");
+
+#define TEST_UNICODE_CONVERTER_METHODDEF    \
+    {"test_unicode_converter", (PyCFunction)test_unicode_converter, METH_O, test_unicode_converter__doc__},
+
+static PyObject *
+test_unicode_converter_impl(PyObject *module, PyObject *a);
+
+static PyObject *
+test_unicode_converter(PyObject *module, PyObject *arg)
+{
+    PyObject *return_value = NULL;
+    PyObject *a;
+
+    if (!PyArg_Parse(arg, "U:test_unicode_converter", &a)) {
+        goto exit;
+    }
+    return_value = test_unicode_converter_impl(module, a);
+
+exit:
+    return return_value;
+}
+
+static PyObject *
+test_unicode_converter_impl(PyObject *module, PyObject *a)
+/*[clinic end generated code: output=504a2c8d00370adf input=aa33612df92aa9c5]*/
+
+/*[clinic input]
+test_bool_converter
+
+    a: bool = True
+    b: bool(accept={object}) = True
+    c: bool(accept={int}) = True
+    /
+
+[clinic start generated code]*/
+
+PyDoc_STRVAR(test_bool_converter__doc__,
+"test_bool_converter($module, a=True, b=True, c=True, /)\n"
+"--\n"
+"\n");
+
+#define TEST_BOOL_CONVERTER_METHODDEF    \
+    {"test_bool_converter", (PyCFunction)test_bool_converter, METH_FASTCALL, test_bool_converter__doc__},
+
+static PyObject *
+test_bool_converter_impl(PyObject *module, int a, int b, int c);
+
+static PyObject *
+test_bool_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    int a = 1;
+    int b = 1;
+    int c = 1;
+
+    if (!_PyArg_ParseStack(args, nargs, "|ppi:test_bool_converter",
+        &a, &b, &c)) {
+        goto exit;
+    }
+    return_value = test_bool_converter_impl(module, a, b, c);
+
+exit:
+    return return_value;
+}
+
+static PyObject *
+test_bool_converter_impl(PyObject *module, int a, int b, int c)
+/*[clinic end generated code: output=a3e8bc2f49647d1b input=939854fa9f248c60]*/
+
+/*[clinic input]
+test_char_converter
+
+    a: char
+    /
+
+[clinic start generated code]*/
+
+PyDoc_STRVAR(test_char_converter__doc__,
+"test_char_converter($module, a, /)\n"
+"--\n"
+"\n");
+
+#define TEST_CHAR_CONVERTER_METHODDEF    \
+    {"test_char_converter", (PyCFunction)test_char_converter, METH_O, test_char_converter__doc__},
+
+static PyObject *
+test_char_converter_impl(PyObject *module, char a);
+
+static PyObject *
+test_char_converter(PyObject *module, PyObject *arg)
+{
+    PyObject *return_value = NULL;
+    char a;
+
+    if (!PyArg_Parse(arg, "c:test_char_converter", &a)) {
+        goto exit;
+    }
+    return_value = test_char_converter_impl(module, a);
+
+exit:
+    return return_value;
+}
+
+static PyObject *
+test_char_converter_impl(PyObject *module, char a)
+/*[clinic end generated code: output=900f0c5a82453471 input=e802e90b9deadd17]*/
+
+/*[clinic input]
+test_unsigned_char_converter
+
+    c: unsigned_char(bitwise=True) = 56
+    /
+
+[clinic start generated code]*/
+
+PyDoc_STRVAR(test_unsigned_char_converter__doc__,
+"test_unsigned_char_converter($module, c=56, /)\n"
+"--\n"
+"\n");
+
+#define TEST_UNSIGNED_CHAR_CONVERTER_METHODDEF    \
+    {"test_unsigned_char_converter", (PyCFunction)test_unsigned_char_converter, METH_FASTCALL, test_unsigned_char_converter__doc__},
+
+static PyObject *
+test_unsigned_char_converter_impl(PyObject *module, unsigned char c);
+
+static PyObject *
+test_unsigned_char_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    unsigned char c = 56;
+
+    if (!_PyArg_ParseStack(args, nargs, "|B:test_unsigned_char_converter",
+        &c)) {
+        goto exit;
+    }
+    return_value = test_unsigned_char_converter_impl(module, c);
+
+exit:
+    return return_value;
+}
+
+static PyObject *
+test_unsigned_char_converter_impl(PyObject *module, unsigned char c)
+/*[clinic end generated code: output=48eb2d10bdc8aa08 input=c761000cf94b2df3]*/
+
+/*[clinic input]
+test_short_converter
+
+    a: short = 12
+    /
+
+[clinic start generated code]*/
+
+PyDoc_STRVAR(test_short_converter__doc__,
+"test_short_converter($module, a=12, /)\n"
+"--\n"
+"\n");
+
+#define TEST_SHORT_CONVERTER_METHODDEF    \
+    {"test_short_converter", (PyCFunction)test_short_converter, METH_FASTCALL, test_short_converter__doc__},
+
+static PyObject *
+test_short_converter_impl(PyObject *module, short a);
+
+static PyObject *
+test_short_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    short a = 12;
+
+    if (!_PyArg_ParseStack(args, nargs, "|h:test_short_converter",
+        &a)) {
+        goto exit;
+    }
+    return_value = test_short_converter_impl(module, a);
+
+exit:
+    return return_value;
+}
+
+static PyObject *
+test_short_converter_impl(PyObject *module, short a)
+/*[clinic end generated code: output=ce5b137b7baae608 input=6a8a7a509a498ff4]*/
+
+/*[clinic input]
+test_unsigned_short_converter
+
+    c: unsigned_short(bitwise=True) = 56
+    /
+
+[clinic start generated code]*/
+
+PyDoc_STRVAR(test_unsigned_short_converter__doc__,
+"test_unsigned_short_converter($module, c=56, /)\n"
+"--\n"
+"\n");
+
+#define TEST_UNSIGNED_SHORT_CONVERTER_METHODDEF    \
+    {"test_unsigned_short_converter", (PyCFunction)test_unsigned_short_converter, METH_FASTCALL, test_unsigned_short_converter__doc__},
+
+static PyObject *
+test_unsigned_short_converter_impl(PyObject *module, unsigned short c);
+
+static PyObject *
+test_unsigned_short_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    unsigned short c = 56;
+
+    if (!_PyArg_ParseStack(args, nargs, "|H:test_unsigned_short_converter",
+        &c)) {
+        goto exit;
+    }
+    return_value = test_unsigned_short_converter_impl(module, c);
+
+exit:
+    return return_value;
+}
+
+static PyObject *
+test_unsigned_short_converter_impl(PyObject *module, unsigned short c)
+/*[clinic end generated code: output=1efab48251e8ac53 input=bdfdc5236f5eb7f8]*/
+
+/*[clinic input]
+test_int_converter
+
+    a: int = 12
+    b: int(accept={int}) = 34
+    c: int(accept={str}) = 45
+    d: int(type='myenum') = 67
+    /
+
+[clinic start generated code]*/
+
+PyDoc_STRVAR(test_int_converter__doc__,
+"test_int_converter($module, a=12, b=34, c=45, d=67, /)\n"
+"--\n"
+"\n");
+
+#define TEST_INT_CONVERTER_METHODDEF    \
+    {"test_int_converter", (PyCFunction)test_int_converter, METH_FASTCALL, test_int_converter__doc__},
+
+static PyObject *
+test_int_converter_impl(PyObject *module, int a, int b, int c, myenum d);
+
+static PyObject *
+test_int_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    int a = 12;
+    int b = 34;
+    int c = 45;
+    myenum d = 67;
+
+    if (!_PyArg_ParseStack(args, nargs, "|iiCi:test_int_converter",
+        &a, &b, &c, &d)) {
+        goto exit;
+    }
+    return_value = test_int_converter_impl(module, a, b, c, d);
+
+exit:
+    return return_value;
+}
+
+static PyObject *
+test_int_converter_impl(PyObject *module, int a, int b, int c, myenum d)
+/*[clinic end generated code: output=601e88039fdfa60a input=d20541fc1ca0553e]*/
+
+/*[clinic input]
+test_unsigned_int_converter
+
+    c: unsigned_int(bitwise=True) = 56
+    /
+
+[clinic start generated code]*/
+
+PyDoc_STRVAR(test_unsigned_int_converter__doc__,
+"test_unsigned_int_converter($module, c=56, /)\n"
+"--\n"
+"\n");
+
+#define TEST_UNSIGNED_INT_CONVERTER_METHODDEF    \
+    {"test_unsigned_int_converter", (PyCFunction)test_unsigned_int_converter, METH_FASTCALL, test_unsigned_int_converter__doc__},
+
+static PyObject *
+test_unsigned_int_converter_impl(PyObject *module, unsigned int c);
+
+static PyObject *
+test_unsigned_int_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    unsigned int c = 56;
+
+    if (!_PyArg_ParseStack(args, nargs, "|I:test_unsigned_int_converter",
+        &c)) {
+        goto exit;
+    }
+    return_value = test_unsigned_int_converter_impl(module, c);
+
+exit:
+    return return_value;
+}
+
+static PyObject *
+test_unsigned_int_converter_impl(PyObject *module, unsigned int c)
+/*[clinic end generated code: output=cc53589104965088 input=378cd89bcaa7d54a]*/
+
+/*[clinic input]
+test_long_converter
+
+    a: long = 12
+    /
+
+[clinic start generated code]*/
+
+PyDoc_STRVAR(test_long_converter__doc__,
+"test_long_converter($module, a=12, /)\n"
+"--\n"
+"\n");
+
+#define TEST_LONG_CONVERTER_METHODDEF    \
+    {"test_long_converter", (PyCFunction)test_long_converter, METH_FASTCALL, test_long_converter__doc__},
+
+static PyObject *
+test_long_converter_impl(PyObject *module, long a);
+
+static PyObject *
+test_long_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    long a = 12;
+
+    if (!_PyArg_ParseStack(args, nargs, "|l:test_long_converter",
+        &a)) {
+        goto exit;
+    }
+    return_value = test_long_converter_impl(module, a);
+
+exit:
+    return return_value;
+}
+
+static PyObject *
+test_long_converter_impl(PyObject *module, long a)
+/*[clinic end generated code: output=a9de1d6b8993931c input=d2179e3c9cdcde89]*/
+
+/*[clinic input]
+test_unsigned_long_converter
+
+    c: unsigned_long(bitwise=True) = 56
+    /
+
+[clinic start generated code]*/
+
+PyDoc_STRVAR(test_unsigned_long_converter__doc__,
+"test_unsigned_long_converter($module, c=56, /)\n"
+"--\n"
+"\n");
+
+#define TEST_UNSIGNED_LONG_CONVERTER_METHODDEF    \
+    {"test_unsigned_long_converter", (PyCFunction)test_unsigned_long_converter, METH_FASTCALL, test_unsigned_long_converter__doc__},
+
+static PyObject *
+test_unsigned_long_converter_impl(PyObject *module, unsigned long c);
+
+static PyObject *
+test_unsigned_long_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    unsigned long c = 56;
+
+    if (!_PyArg_ParseStack(args, nargs, "|k:test_unsigned_long_converter",
+        &c)) {
+        goto exit;
+    }
+    return_value = test_unsigned_long_converter_impl(module, c);
+
+exit:
+    return return_value;
+}
+
+static PyObject *
+test_unsigned_long_converter_impl(PyObject *module, unsigned long c)
+/*[clinic end generated code: output=484caa61090cd6f4 input=c69803655925e29c]*/
+
+/*[clinic input]
+test_long_long_converter
+
+    a: long_long = 12
+    /
+
+[clinic start generated code]*/
+
+PyDoc_STRVAR(test_long_long_converter__doc__,
+"test_long_long_converter($module, a=12, /)\n"
+"--\n"
+"\n");
+
+#define TEST_LONG_LONG_CONVERTER_METHODDEF    \
+    {"test_long_long_converter", (PyCFunction)test_long_long_converter, METH_FASTCALL, test_long_long_converter__doc__},
+
+static PyObject *
+test_long_long_converter_impl(PyObject *module, long long a);
+
+static PyObject *
+test_long_long_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    long long a = 12;
+
+    if (!_PyArg_ParseStack(args, nargs, "|L:test_long_long_converter",
+        &a)) {
+        goto exit;
+    }
+    return_value = test_long_long_converter_impl(module, a);
+
+exit:
+    return return_value;
+}
+
+static PyObject *
+test_long_long_converter_impl(PyObject *module, long long a)
+/*[clinic end generated code: output=7741ab7cfffae072 input=d5fc81577ff4dd02]*/
+
+/*[clinic input]
+test_unsigned_long_long_converter
+
+    c: unsigned_long_long(bitwise=True) = 56
+    /
+
+[clinic start generated code]*/
+
+PyDoc_STRVAR(test_unsigned_long_long_converter__doc__,
+"test_unsigned_long_long_converter($module, c=56, /)\n"
+"--\n"
+"\n");
+
+#define TEST_UNSIGNED_LONG_LONG_CONVERTER_METHODDEF    \
+    {"test_unsigned_long_long_converter", (PyCFunction)test_unsigned_long_long_converter, METH_FASTCALL, test_unsigned_long_long_converter__doc__},
+
+static PyObject *
+test_unsigned_long_long_converter_impl(PyObject *module,
+                                       unsigned long long c);
+
+static PyObject *
+test_unsigned_long_long_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    unsigned long long c = 56;
+
+    if (!_PyArg_ParseStack(args, nargs, "|K:test_unsigned_long_long_converter",
+        &c)) {
+        goto exit;
+    }
+    return_value = test_unsigned_long_long_converter_impl(module, c);
+
+exit:
+    return return_value;
+}
+
+static PyObject *
+test_unsigned_long_long_converter_impl(PyObject *module,
+                                       unsigned long long c)
+/*[clinic end generated code: output=e07b58db59674c80 input=75cfdbbadef34439]*/
+
+/*[clinic input]
+test_Py_ssize_t_converter
+
+    a: Py_ssize_t = 12
+    b: Py_ssize_t(accept={int}) = 34
+    c: Py_ssize_t(accept={int, NoneType}) = 56
+    /
+
+[clinic start generated code]*/
+
+PyDoc_STRVAR(test_Py_ssize_t_converter__doc__,
+"test_Py_ssize_t_converter($module, a=12, b=34, c=56, /)\n"
+"--\n"
+"\n");
+
+#define TEST_PY_SSIZE_T_CONVERTER_METHODDEF    \
+    {"test_Py_ssize_t_converter", (PyCFunction)test_Py_ssize_t_converter, METH_FASTCALL, test_Py_ssize_t_converter__doc__},
+
+static PyObject *
+test_Py_ssize_t_converter_impl(PyObject *module, Py_ssize_t a, Py_ssize_t b,
+                               Py_ssize_t c);
+
+static PyObject *
+test_Py_ssize_t_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    Py_ssize_t a = 12;
+    Py_ssize_t b = 34;
+    Py_ssize_t c = 56;
+
+    if (!_PyArg_ParseStack(args, nargs, "|nnO&:test_Py_ssize_t_converter",
+        &a, &b, _Py_convert_optional_to_ssize_t, &c)) {
+        goto exit;
+    }
+    return_value = test_Py_ssize_t_converter_impl(module, a, b, c);
+
+exit:
+    return return_value;
+}
+
+static PyObject *
+test_Py_ssize_t_converter_impl(PyObject *module, Py_ssize_t a, Py_ssize_t b,
+                               Py_ssize_t c)
+/*[clinic end generated code: output=504a11df58a5a277 input=3855f184bb3f299d]*/
+
+/*[clinic input]
+test_slice_index_converter
+
+    a: slice_index = 12
+    b: slice_index(accept={int}) = 34
+    c: slice_index(accept={int, NoneType}) = 56
+    /
+
+[clinic start generated code]*/
+
+PyDoc_STRVAR(test_slice_index_converter__doc__,
+"test_slice_index_converter($module, a=12, b=34, c=56, /)\n"
+"--\n"
+"\n");
+
+#define TEST_SLICE_INDEX_CONVERTER_METHODDEF    \
+    {"test_slice_index_converter", (PyCFunction)test_slice_index_converter, METH_FASTCALL, test_slice_index_converter__doc__},
+
+static PyObject *
+test_slice_index_converter_impl(PyObject *module, Py_ssize_t a, Py_ssize_t b,
+                                Py_ssize_t c);
+
+static PyObject *
+test_slice_index_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    Py_ssize_t a = 12;
+    Py_ssize_t b = 34;
+    Py_ssize_t c = 56;
+
+    if (!_PyArg_ParseStack(args, nargs, "|O&O&O&:test_slice_index_converter",
+        _PyEval_SliceIndex, &a, _PyEval_SliceIndexNotNone, &b, _PyEval_SliceIndex, &c)) {
+        goto exit;
+    }
+    return_value = test_slice_index_converter_impl(module, a, b, c);
+
+exit:
+    return return_value;
+}
+
+static PyObject *
+test_slice_index_converter_impl(PyObject *module, Py_ssize_t a, Py_ssize_t b,
+                                Py_ssize_t c)
+/*[clinic end generated code: output=b156931c01c9508a input=edeadb0ee126f531]*/
+
+/*[clinic input]
+test_float_converter
+
+    a: float = 12.5
+    /
+
+[clinic start generated code]*/
+
+PyDoc_STRVAR(test_float_converter__doc__,
+"test_float_converter($module, a=12.5, /)\n"
+"--\n"
+"\n");
+
+#define TEST_FLOAT_CONVERTER_METHODDEF    \
+    {"test_float_converter", (PyCFunction)test_float_converter, METH_FASTCALL, test_float_converter__doc__},
+
+static PyObject *
+test_float_converter_impl(PyObject *module, float a);
+
+static PyObject *
+test_float_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    float a = 12.5;
+
+    if (!_PyArg_ParseStack(args, nargs, "|f:test_float_converter",
+        &a)) {
+        goto exit;
+    }
+    return_value = test_float_converter_impl(module, a);
+
+exit:
+    return return_value;
+}
+
+static PyObject *
+test_float_converter_impl(PyObject *module, float a)
+/*[clinic end generated code: output=d37bb4f773ffac06 input=259c0d98eca35034]*/
+
+/*[clinic input]
+test_double_converter
+
+    a: double = 12.5
+    /
+
+[clinic start generated code]*/
+
+PyDoc_STRVAR(test_double_converter__doc__,
+"test_double_converter($module, a=12.5, /)\n"
+"--\n"
+"\n");
+
+#define TEST_DOUBLE_CONVERTER_METHODDEF    \
+    {"test_double_converter", (PyCFunction)test_double_converter, METH_FASTCALL, test_double_converter__doc__},
+
+static PyObject *
+test_double_converter_impl(PyObject *module, double a);
+
+static PyObject *
+test_double_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    double a = 12.5;
+
+    if (!_PyArg_ParseStack(args, nargs, "|d:test_double_converter",
+        &a)) {
+        goto exit;
+    }
+    return_value = test_double_converter_impl(module, a);
+
+exit:
+    return return_value;
+}
+
+static PyObject *
+test_double_converter_impl(PyObject *module, double a)
+/*[clinic end generated code: output=863371b11f7e55fd input=c6a9945706a41c27]*/
+
+/*[clinic input]
+test_Py_complex_converter
+
+    a: Py_complex
+    /
+
+[clinic start generated code]*/
+
+PyDoc_STRVAR(test_Py_complex_converter__doc__,
+"test_Py_complex_converter($module, a, /)\n"
+"--\n"
+"\n");
+
+#define TEST_PY_COMPLEX_CONVERTER_METHODDEF    \
+    {"test_Py_complex_converter", (PyCFunction)test_Py_complex_converter, METH_O, test_Py_complex_converter__doc__},
+
+static PyObject *
+test_Py_complex_converter_impl(PyObject *module, Py_complex a);
+
+static PyObject *
+test_Py_complex_converter(PyObject *module, PyObject *arg)
+{
+    PyObject *return_value = NULL;
+    Py_complex a;
+
+    if (!PyArg_Parse(arg, "D:test_Py_complex_converter", &a)) {
+        goto exit;
+    }
+    return_value = test_Py_complex_converter_impl(module, a);
+
+exit:
+    return return_value;
+}
+
+static PyObject *
+test_Py_complex_converter_impl(PyObject *module, Py_complex a)
+/*[clinic end generated code: output=27efb4ff772d6170 input=070f216a515beb79]*/
+
+/*[clinic input]
+test_str_converter
+
+    a: str = NULL
+    b: str = "ab"
+    c: str(accept={str}) = "cd"
+    d: str(accept={robuffer}) = "cef"
+    e: str(accept={str, NoneType}) = "gh"
+    f: str(accept={robuffer}, zeroes=True) = "ij"
+    g: str(accept={robuffer, str}, zeroes=True) = "kl"
+    h: str(accept={robuffer, str, NoneType}, zeroes=True) = "mn"
+    /
+
+[clinic start generated code]*/
+
+PyDoc_STRVAR(test_str_converter__doc__,
+"test_str_converter($module, a=None, b=\'ab\', c=\'cd\', d=\'cef\', e=\'gh\',\n"
+"                   f=\'ij\', g=\'kl\', h=\'mn\', /)\n"
+"--\n"
+"\n");
+
+#define TEST_STR_CONVERTER_METHODDEF    \
+    {"test_str_converter", (PyCFunction)test_str_converter, METH_FASTCALL, test_str_converter__doc__},
+
+static PyObject *
+test_str_converter_impl(PyObject *module, const char *a, const char *b,
+                        const char *c, const char *d, const char *e,
+                        const char *f, Py_ssize_clean_t f_length,
+                        const char *g, Py_ssize_clean_t g_length,
+                        const char *h, Py_ssize_clean_t h_length);
+
+static PyObject *
+test_str_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    const char *a = NULL;
+    const char *b = "ab";
+    const char *c = "cd";
+    const char *d = "cef";
+    const char *e = "gh";
+    const char *f = "ij";
+    Py_ssize_clean_t f_length;
+    const char *g = "kl";
+    Py_ssize_clean_t g_length;
+    const char *h = "mn";
+    Py_ssize_clean_t h_length;
+
+    if (!_PyArg_ParseStack(args, nargs, "|sssyzy#s#z#:test_str_converter",
+        &a, &b, &c, &d, &e, &f, &f_length, &g, &g_length, &h, &h_length)) {
+        goto exit;
+    }
+    return_value = test_str_converter_impl(module, a, b, c, d, e, f, f_length, g, g_length, h, h_length);
+
+exit:
+    return return_value;
+}
+
+static PyObject *
+test_str_converter_impl(PyObject *module, const char *a, const char *b,
+                        const char *c, const char *d, const char *e,
+                        const char *f, Py_ssize_clean_t f_length,
+                        const char *g, Py_ssize_clean_t g_length,
+                        const char *h, Py_ssize_clean_t h_length)
+/*[clinic end generated code: output=94988a5346fd888e input=8afe9da8185cd38c]*/
+
+/*[clinic input]
+test_str_converter_encoding
+
+    a: str(encoding="idna")
+    b: str(encoding="idna", accept={str})
+    c: str(encoding="idna", accept={bytes, bytearray, str})
+    d: str(encoding="idna", zeroes=True)
+    e: str(encoding="idna", accept={bytes, bytearray, str}, zeroes=True)
+    /
+
+[clinic start generated code]*/
+
+PyDoc_STRVAR(test_str_converter_encoding__doc__,
+"test_str_converter_encoding($module, a, b, c, d, e, /)\n"
+"--\n"
+"\n");
+
+#define TEST_STR_CONVERTER_ENCODING_METHODDEF    \
+    {"test_str_converter_encoding", (PyCFunction)test_str_converter_encoding, METH_FASTCALL, test_str_converter_encoding__doc__},
+
+static PyObject *
+test_str_converter_encoding_impl(PyObject *module, char *a, char *b, char *c,
+                                 char *d, Py_ssize_clean_t d_length, char *e,
+                                 Py_ssize_clean_t e_length);
+
+static PyObject *
+test_str_converter_encoding(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    char *a = NULL;
+    char *b = NULL;
+    char *c = NULL;
+    char *d = NULL;
+    Py_ssize_clean_t d_length;
+    char *e = NULL;
+    Py_ssize_clean_t e_length;
+
+    if (!_PyArg_ParseStack(args, nargs, "esesetes#et#:test_str_converter_encoding",
+        "idna", &a, "idna", &b, "idna", &c, "idna", &d, &d_length, "idna", &e, &e_length)) {
+        goto exit;
+    }
+    return_value = test_str_converter_encoding_impl(module, a, b, c, d, d_length, e, e_length);
+
+exit:
+    /* Cleanup for a */
+    if (a) {
+       PyMem_FREE(a);
+    }
+    /* Cleanup for b */
+    if (b) {
+       PyMem_FREE(b);
+    }
+    /* Cleanup for c */
+    if (c) {
+       PyMem_FREE(c);
+    }
+    /* Cleanup for d */
+    if (d) {
+       PyMem_FREE(d);
+    }
+    /* Cleanup for e */
+    if (e) {
+       PyMem_FREE(e);
+    }
+
+    return return_value;
+}
+
+static PyObject *
+test_str_converter_encoding_impl(PyObject *module, char *a, char *b, char *c,
+                                 char *d, Py_ssize_clean_t d_length, char *e,
+                                 Py_ssize_clean_t e_length)
+/*[clinic end generated code: output=1a63c67528fe9e74 input=eb4c38e1f898f402]*/
+
+/*[clinic input]
+test_Py_UNICODE_converter
+
+    a: Py_UNICODE
+    b: Py_UNICODE(accept={str})
+    c: Py_UNICODE(accept={str, NoneType})
+    d: Py_UNICODE(zeroes=True)
+    e: Py_UNICODE(accept={str, NoneType}, zeroes=True)
+    /
+
+[clinic start generated code]*/
+
+PyDoc_STRVAR(test_Py_UNICODE_converter__doc__,
+"test_Py_UNICODE_converter($module, a, b, c, d, e, /)\n"
+"--\n"
+"\n");
+
+#define TEST_PY_UNICODE_CONVERTER_METHODDEF    \
+    {"test_Py_UNICODE_converter", (PyCFunction)test_Py_UNICODE_converter, METH_FASTCALL, test_Py_UNICODE_converter__doc__},
+
+static PyObject *
+test_Py_UNICODE_converter_impl(PyObject *module, const Py_UNICODE *a,
+                               const Py_UNICODE *b, const Py_UNICODE *c,
+                               const Py_UNICODE *d,
+                               Py_ssize_clean_t d_length,
+                               const Py_UNICODE *e,
+                               Py_ssize_clean_t e_length);
+
+static PyObject *
+test_Py_UNICODE_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    const Py_UNICODE *a;
+    const Py_UNICODE *b;
+    const Py_UNICODE *c;
+    const Py_UNICODE *d;
+    Py_ssize_clean_t d_length;
+    const Py_UNICODE *e;
+    Py_ssize_clean_t e_length;
+
+    if (!_PyArg_ParseStack(args, nargs, "uuZu#Z#:test_Py_UNICODE_converter",
+        &a, &b, &c, &d, &d_length, &e, &e_length)) {
+        goto exit;
+    }
+    return_value = test_Py_UNICODE_converter_impl(module, a, b, c, d, d_length, e, e_length);
+
+exit:
+    return return_value;
+}
+
+static PyObject *
+test_Py_UNICODE_converter_impl(PyObject *module, const Py_UNICODE *a,
+                               const Py_UNICODE *b, const Py_UNICODE *c,
+                               const Py_UNICODE *d,
+                               Py_ssize_clean_t d_length,
+                               const Py_UNICODE *e,
+                               Py_ssize_clean_t e_length)
+/*[clinic end generated code: output=98f7ebc3ce76aff3 input=064a3b68ad7f04b0]*/
+
+/*[clinic input]
+test_Py_buffer_converter
+
+    a: Py_buffer
+    b: Py_buffer(accept={buffer})
+    c: Py_buffer(accept={str, buffer})
+    d: Py_buffer(accept={str, buffer, NoneType})
+    e: Py_buffer(accept={rwbuffer})
+    /
+
+[clinic start generated code]*/
+
+PyDoc_STRVAR(test_Py_buffer_converter__doc__,
+"test_Py_buffer_converter($module, a, b, c, d, e, /)\n"
+"--\n"
+"\n");
+
+#define TEST_PY_BUFFER_CONVERTER_METHODDEF    \
+    {"test_Py_buffer_converter", (PyCFunction)test_Py_buffer_converter, METH_FASTCALL, test_Py_buffer_converter__doc__},
+
+static PyObject *
+test_Py_buffer_converter_impl(PyObject *module, Py_buffer *a, Py_buffer *b,
+                              Py_buffer *c, Py_buffer *d, Py_buffer *e);
+
+static PyObject *
+test_Py_buffer_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    Py_buffer a = {NULL, NULL};
+    Py_buffer b = {NULL, NULL};
+    Py_buffer c = {NULL, NULL};
+    Py_buffer d = {NULL, NULL};
+    Py_buffer e = {NULL, NULL};
+
+    if (!_PyArg_ParseStack(args, nargs, "y*y*s*z*w*:test_Py_buffer_converter",
+        &a, &b, &c, &d, &e)) {
+        goto exit;
+    }
+    return_value = test_Py_buffer_converter_impl(module, &a, &b, &c, &d, &e);
+
+exit:
+    /* Cleanup for a */
+    if (a.obj) {
+       PyBuffer_Release(&a);
+    }
+    /* Cleanup for b */
+    if (b.obj) {
+       PyBuffer_Release(&b);
+    }
+    /* Cleanup for c */
+    if (c.obj) {
+       PyBuffer_Release(&c);
+    }
+    /* Cleanup for d */
+    if (d.obj) {
+       PyBuffer_Release(&d);
+    }
+    /* Cleanup for e */
+    if (e.obj) {
+       PyBuffer_Release(&e);
+    }
+
+    return return_value;
+}
+
+static PyObject *
+test_Py_buffer_converter_impl(PyObject *module, Py_buffer *a, Py_buffer *b,
+                              Py_buffer *c, Py_buffer *d, Py_buffer *e)
+/*[clinic end generated code: output=92937215f10bc937 input=6a9da0f56f9525fd]*/
index 2f838c445555dd0874991ab81c970bef105ea902..d729c7efd52fde3ccb5fc12a74497f66ea253b96 100644 (file)
@@ -1351,6 +1351,17 @@ class TestDate(HarmlessMixedComparison, unittest.TestCase):
         #check that this standard extension works
         t.strftime("%f")
 
+    def test_strftime_trailing_percent(self):
+        # bpo-35066: make sure trailing '%' doesn't cause
+        # datetime's strftime to complain
+        t = self.theclass(2005, 3, 2)
+        try:
+            _time.strftime('%')
+        except ValueError:
+            self.skipTest('time module does not support trailing %')
+        self.assertEqual(t.strftime('%'), '%')
+        self.assertEqual(t.strftime("m:%m d:%d y:%y %"), "m:03 d:02 y:05 %")
+
     def test_format(self):
         dt = self.theclass(2007, 9, 10)
         self.assertEqual(dt.__format__(''), str(dt))
index 25c169bde5005f5287a9c26a0c90e4c7b603b1bb..5f956b548fc40aa4e757b3cdea0ef405651d86a0 100644 (file)
@@ -12,6 +12,7 @@ import contextlib
 import faulthandler
 import fcntl
 import os
+import platform
 import select
 import signal
 import socket
@@ -518,6 +519,9 @@ class FNTLEINTRTest(EINTRBaseTest):
                 self.stop_alarm()
             proc.wait()
 
+    # Issue 35633: See https://bugs.python.org/issue35633#msg333662
+    # skip test rather than accept PermissionError from all platforms
+    @unittest.skipIf(platform.system() == "AIX", "AIX returns PermissionError")
     def test_lockf(self):
         self._lock(fcntl.lockf, "lockf")
 
index 09270323611f4ec7f2bae5cd9a513b26df71d9ab..7cd85bf2803aa1f4ef005d6498db5078d601a364 100644 (file)
@@ -68,7 +68,7 @@ typically try to ascertain containers keep working when containing more than
 2 billion objects, which only works on 64-bit systems. There are also some
 tests that try to exhaust the address space of the process, which only makes
 sense on 32-bit systems with at least 2Gb of memory. The passed-in memlimit,
-which is a string in the form of '2.5Gb', determines howmuch memory the
+which is a string in the form of '2.5Gb', determines how much memory the
 tests will limit themselves to (but they may go slightly over.) The number
 shouldn't be more memory than the machine has (including swap memory). You
 should also keep in mind that swap memory is generally much, much slower
index 8d44caf2999a026a5f0f349fab7eb763f4f50efd..32ac44029bc3a4016dacd64c5896d7f7c77e47e6 100644 (file)
@@ -1,5 +1,6 @@
 import datetime
 import faulthandler
+import json
 import locale
 import os
 import platform
@@ -565,6 +566,9 @@ class Regrtest:
 
         if self.ns.tempdir:
             TEMPDIR = self.ns.tempdir
+        elif self.ns.worker_args:
+            ns_dict, _ = json.loads(self.ns.worker_args)
+            TEMPDIR = ns_dict.get("tempdir") or TEMPDIR
 
         os.makedirs(TEMPDIR, exist_ok=True)
 
index 466b522db9ed0d5ab2f5700d2bcc55ccaabb0d35..dc2abf237bc01037434f069bf2a9e261b65626dd 100644 (file)
@@ -162,7 +162,7 @@ def runtest_inner(ns, test, display_failure=True):
         abstest = get_abs_module(ns, test)
         clear_caches()
         with saved_test_environment(test, ns.verbose, ns.quiet, pgo=ns.pgo) as environment:
-            start_time = time.time()
+            start_time = time.perf_counter()
             the_module = importlib.import_module(abstest)
             # If the test has a test_main, that will run the appropriate
             # tests.  If not, use normal unittest test loading.
@@ -180,7 +180,7 @@ def runtest_inner(ns, test, display_failure=True):
                 refleak = dash_R(the_module, test, test_runner, ns.huntrleaks)
             else:
                 test_runner()
-            test_time = time.time() - start_time
+            test_time = time.perf_counter() - start_time
         post_test_cleanup()
     except support.ResourceDenied as msg:
         if not ns.quiet and not ns.pgo:
index ed63fda20c1b7a751204d792b592a70e014fbe4e..40316de220fac2ca2e976f2f60fa686a440c8d6b 100644 (file)
@@ -31,9 +31,15 @@ class CommonTest(seq_tests.CommonTest):
         self.assertEqual(a, b)
 
     def test_getitem_error(self):
+        a = []
+        msg = "list indices must be integers or slices"
+        with self.assertRaisesRegex(TypeError, msg):
+            a['a']
+
+    def test_setitem_error(self):
+        a = []
         msg = "list indices must be integers or slices"
         with self.assertRaisesRegex(TypeError, msg):
-            a = []
             a['a'] = "python"
 
     def test_repr(self):
index 65fa4d87d4ce38a4cfbf3fbd9158aa6c1e15e0c0..23a02e0b4eb246dec304e527e1e4f33cfa0221fa 100644 (file)
@@ -74,7 +74,7 @@ class BaseTestCase(unittest.TestCase):
         support.reap_children()
 
     def assertTimeout(self, actual, expected):
-        # The waiting and/or time.time() can be imprecise, which
+        # The waiting and/or time.monotonic() can be imprecise, which
         # is why comparing to the expected value would sometimes fail
         # (especially under Windows).
         self.assertGreaterEqual(actual, expected * 0.6)
@@ -190,16 +190,16 @@ class BaseLockTests(BaseTestCase):
         # TIMEOUT_MAX is ok
         lock.acquire(timeout=TIMEOUT_MAX)
         lock.release()
-        t1 = time.time()
+        t1 = time.monotonic()
         self.assertTrue(lock.acquire(timeout=5))
-        t2 = time.time()
+        t2 = time.monotonic()
         # Just a sanity test that it didn't actually wait for the timeout.
         self.assertLess(t2 - t1, 5)
         results = []
         def f():
-            t1 = time.time()
+            t1 = time.monotonic()
             results.append(lock.acquire(timeout=0.5))
-            t2 = time.time()
+            t2 = time.monotonic()
             results.append(t2 - t1)
         Bunch(f, 1).wait_for_finished()
         self.assertFalse(results[0])
@@ -382,9 +382,9 @@ class EventTests(BaseTestCase):
         N = 5
         def f():
             results1.append(evt.wait(0.0))
-            t1 = time.time()
+            t1 = time.monotonic()
             r = evt.wait(0.5)
-            t2 = time.time()
+            t2 = time.monotonic()
             results2.append((r, t2 - t1))
         Bunch(f, N).wait_for_finished()
         self.assertEqual(results1, [False] * N)
@@ -545,9 +545,9 @@ class ConditionTests(BaseTestCase):
         N = 5
         def f():
             cond.acquire()
-            t1 = time.time()
+            t1 = time.monotonic()
             result = cond.wait(0.5)
-            t2 = time.time()
+            t2 = time.monotonic()
             cond.release()
             results.append((t2 - t1, result))
         Bunch(f, N).wait_for_finished()
@@ -584,9 +584,9 @@ class ConditionTests(BaseTestCase):
         success = []
         def f():
             with cond:
-                dt = time.time()
+                dt = time.monotonic()
                 result = cond.wait_for(lambda : state==4, timeout=0.1)
-                dt = time.time() - dt
+                dt = time.monotonic() - dt
                 self.assertFalse(result)
                 self.assertTimeout(dt, 0.1)
                 success.append(None)
@@ -692,9 +692,9 @@ class BaseSemaphoreTests(BaseTestCase):
         self.assertFalse(sem.acquire(timeout=0.005))
         sem.release()
         self.assertTrue(sem.acquire(timeout=0.005))
-        t = time.time()
+        t = time.monotonic()
         self.assertFalse(sem.acquire(timeout=0.5))
-        dt = time.time() - t
+        dt = time.monotonic() - t
         self.assertTimeout(dt, 0.5)
 
     def test_default_value(self):
index 813b7aa1bd2dd88b47e3edd418e0a9eea937cb7c..cca8af67d6d1d6cc65f586517981b3a04aaf865d 100644 (file)
@@ -277,6 +277,11 @@ class TestBase:
         writer = self.writer(stream)
         writer.reset()
 
+    def test_incrementalencoder_del_segfault(self):
+        e = self.incrementalencoder()
+        with self.assertRaises(AttributeError):
+            del e.errors
+
 
 class TestBase_Mapping(unittest.TestCase):
     pass_enctest = []
index 71c2feadb613d2450adcc5276f2c3fcf500fd208..293393fe37135ae5688d268d8eeecfcb6558b84b 100644 (file)
@@ -3,18 +3,22 @@ import copyreg
 import dbm
 import io
 import functools
+import os
 import pickle
 import pickletools
+import shutil
 import struct
 import sys
+import threading
 import unittest
 import weakref
+from textwrap import dedent
 from http.cookies import SimpleCookie
 
 from test import support
 from test.support import (
     TestFailed, TESTFN, run_with_locale, no_tracing,
-    _2G, _4G, bigmemtest,
+    _2G, _4G, bigmemtest, reap_threads, forget,
     )
 
 from pickle import bytes_types
@@ -1174,6 +1178,67 @@ class AbstractUnpickleTests(unittest.TestCase):
         for p in badpickles:
             self.check_unpickling_error(self.truncated_errors, p)
 
+    @reap_threads
+    def test_unpickle_module_race(self):
+        # https://bugs.python.org/issue34572
+        locker_module = dedent("""
+        import threading
+        barrier = threading.Barrier(2)
+        """)
+        locking_import_module = dedent("""
+        import locker
+        locker.barrier.wait()
+        class ToBeUnpickled(object):
+            pass
+        """)
+
+        os.mkdir(TESTFN)
+        self.addCleanup(shutil.rmtree, TESTFN)
+        sys.path.insert(0, TESTFN)
+        self.addCleanup(sys.path.remove, TESTFN)
+        with open(os.path.join(TESTFN, "locker.py"), "wb") as f:
+            f.write(locker_module.encode('utf-8'))
+        with open(os.path.join(TESTFN, "locking_import.py"), "wb") as f:
+            f.write(locking_import_module.encode('utf-8'))
+        self.addCleanup(forget, "locker")
+        self.addCleanup(forget, "locking_import")
+
+        import locker
+
+        pickle_bytes = (
+            b'\x80\x03clocking_import\nToBeUnpickled\nq\x00)\x81q\x01.')
+
+        # Then try to unpickle two of these simultaneously
+        # One of them will cause the module import, and we want it to block
+        # until the other one either:
+        #   - fails (before the patch for this issue)
+        #   - blocks on the import lock for the module, as it should
+        results = []
+        barrier = threading.Barrier(3)
+        def t():
+            # This ensures the threads have all started
+            # presumably barrier release is faster than thread startup
+            barrier.wait()
+            results.append(pickle.loads(pickle_bytes))
+
+        t1 = threading.Thread(target=t)
+        t2 = threading.Thread(target=t)
+        t1.start()
+        t2.start()
+
+        barrier.wait()
+        # could have delay here
+        locker.barrier.wait()
+
+        t1.join()
+        t2.join()
+
+        from locking_import import ToBeUnpickled
+        self.assertEqual(
+            [type(x) for x in results],
+            [ToBeUnpickled] * 2)
+
+
 
 class AbstractPickleTests(unittest.TestCase):
     # Subclass must define self.dumps, self.loads.
index 085c45d9cc04737789507b05973d7bb0bc7aaa6c..94abfdd86ca2b146e70c11cd8772392e4ff3fcd3 100644 (file)
@@ -516,6 +516,8 @@ def collect_resource(info_add):
         value = resource.getrlimit(key)
         info_add('resource.%s' % name, value)
 
+    call_func(info_add, 'resource.pagesize', resource, 'getpagesize')
+
 
 def collect_test_socket(info_add):
     try:
index 512e354fabc89f36622ebcc041daa39323b035ed..9d6fd44cbc1035ed5a4cb5a94bf9d0ce0ea0dd9c 100644 (file)
@@ -815,6 +815,10 @@ else:
 # module name.
 TESTFN = "{}_{}_tmp".format(TESTFN, os.getpid())
 
+# Define the URL of a dedicated HTTP server for the network tests.
+# The URL must use clear-text HTTP: no redirection to encrypted HTTPS.
+TEST_HTTP_URL = "http://www.pythontest.net"
+
 # FS_NONASCII: non-ASCII character encodable by os.fsencode(),
 # or None if there is no such character.
 FS_NONASCII = None
@@ -1897,7 +1901,7 @@ def _run_suite(suite):
     if junit_xml_list is not None:
         junit_xml_list.append(result.get_xml_element())
 
-    if not result.testsRun:
+    if not result.testsRun and not result.skipped:
         raise TestDidNotRun
     if not result.wasSuccessful():
         if len(result.errors) == 1 and not result.failures:
@@ -1946,7 +1950,7 @@ def set_match_tests(patterns):
         patterns = ()
     elif all(map(_is_full_match_test, patterns)):
         # Simple case: all patterns are full test identifier.
-        # The test.bisect utility only uses such full test identifiers.
+        # The test.bisect_cmd utility only uses such full test identifiers.
         func = set(patterns).__contains__
     else:
         regex = '|'.join(map(fnmatch.translate, patterns))
@@ -2219,19 +2223,19 @@ def start_threads(threads, unlock=None):
         try:
             if unlock:
                 unlock()
-            endtime = starttime = time.time()
+            endtime = starttime = time.monotonic()
             for timeout in range(1, 16):
                 endtime += 60
                 for t in started:
-                    t.join(max(endtime - time.time(), 0.01))
-                started = [t for t in started if t.isAlive()]
+                    t.join(max(endtime - time.monotonic(), 0.01))
+                started = [t for t in started if t.is_alive()]
                 if not started:
                     break
                 if verbose:
                     print('Unable to join %d threads during a period of '
                           '%d minutes' % (len(started), timeout))
         finally:
-            started = [t for t in started if t.isAlive()]
+            started = [t for t in started if t.is_alive()]
             if started:
                 faulthandler.dump_traceback(sys.stdout)
                 raise AssertionError('Unable to join %d threads' % len(started))
diff --git a/Lib/test/talos-2019-0758.pem b/Lib/test/talos-2019-0758.pem
new file mode 100644 (file)
index 0000000..13b95a7
--- /dev/null
@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDqDCCApKgAwIBAgIBAjALBgkqhkiG9w0BAQswHzELMAkGA1UEBhMCVUsxEDAO
+BgNVBAMTB2NvZHktY2EwHhcNMTgwNjE4MTgwMDU4WhcNMjgwNjE0MTgwMDU4WjA7
+MQswCQYDVQQGEwJVSzEsMCoGA1UEAxMjY29kZW5vbWljb24tdm0tMi50ZXN0Lmxh
+bC5jaXNjby5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC63fGB
+J80A9Av1GB0bptslKRIUtJm8EeEu34HkDWbL6AJY0P8WfDtlXjlPaLqFa6sqH6ES
+V48prSm1ZUbDSVL8R6BYVYpOlK8/48xk4pGTgRzv69gf5SGtQLwHy8UPBKgjSZoD
+5a5k5wJXGswhKFFNqyyxqCvWmMnJWxXTt2XDCiWc4g4YAWi4O4+6SeeHVAV9rV7C
+1wxqjzKovVe2uZOHjKEzJbbIU6JBPb6TRfMdRdYOw98n1VXDcKVgdX2DuuqjCzHP
+WhU4Tw050M9NaK3eXp4Mh69VuiKoBGOLSOcS8reqHIU46Reg0hqeL8LIL6OhFHIF
+j7HR6V1X6F+BfRS/AgMBAAGjgdYwgdMwCQYDVR0TBAIwADAdBgNVHQ4EFgQUOktp
+HQjxDXXUg8prleY9jeLKeQ4wTwYDVR0jBEgwRoAUx6zgPygZ0ZErF9sPC4+5e2Io
+UU+hI6QhMB8xCzAJBgNVBAYTAlVLMRAwDgYDVQQDEwdjb2R5LWNhggkA1QEAuwb7
+2s0wCQYDVR0SBAIwADAuBgNVHREEJzAlgiNjb2Rlbm9taWNvbi12bS0yLnRlc3Qu
+bGFsLmNpc2NvLmNvbTAOBgNVHQ8BAf8EBAMCBaAwCwYDVR0fBAQwAjAAMAsGCSqG
+SIb3DQEBCwOCAQEAvqantx2yBlM11RoFiCfi+AfSblXPdrIrHvccepV4pYc/yO6p
+t1f2dxHQb8rWH3i6cWag/EgIZx+HJQvo0rgPY1BFJsX1WnYf1/znZpkUBGbVmlJr
+t/dW1gSkNS6sPsM0Q+7HPgEv8CPDNK5eo7vU2seE0iWOkxSyVUuiCEY9ZVGaLVit
+p0C78nZ35Pdv4I+1cosmHl28+es1WI22rrnmdBpH8J1eY6WvUw2xuZHLeNVN0TzV
+Q3qq53AaCWuLOD1AjESWuUCxMZTK9DPS4JKXTK8RLyDeqOvJGjsSWp3kL0y3GaQ+
+10T1rfkKJub2+m9A9duin1fn6tHc2wSvB7m3DA==
+-----END CERTIFICATE-----
index 66b06034900703a18bcc8011cf5c4b875f258133..9466111b8ef780d4b9e791d7d6d45c816b9b3e01 100644 (file)
@@ -574,6 +574,7 @@ class EventLoopTestsMixin:
         self.loop.add_signal_handler(signal.SIGALRM, my_handler)
 
         signal.setitimer(signal.ITIMER_REAL, 0.01, 0)  # Send SIGALRM once.
+        self.loop.call_later(60, self.loop.stop)
         self.loop.run_forever()
         self.assertEqual(caught, 1)
 
@@ -586,11 +587,12 @@ class EventLoopTestsMixin:
             nonlocal caught
             caught += 1
             self.assertEqual(args, some_args)
+            self.loop.stop()
 
         self.loop.add_signal_handler(signal.SIGALRM, my_handler, *some_args)
 
         signal.setitimer(signal.ITIMER_REAL, 0.1, 0)  # Send SIGALRM once.
-        self.loop.call_later(0.5, self.loop.stop)
+        self.loop.call_later(60, self.loop.stop)
         self.loop.run_forever()
         self.assertEqual(caught, 1)
 
index 8c837ad6b620b6380d4c5ca06494b68f9bc1882d..9608a3a81cc334fc01635668822bdc0afa046265 100644 (file)
@@ -566,6 +566,13 @@ class CFutureTests(BaseFutureTests, test_utils.TestCase):
     except AttributeError:
         cls = None
 
+    def test_future_del_segfault(self):
+        fut = self._new_future(loop=self.loop)
+        with self.assertRaises(AttributeError):
+            del fut._asyncio_future_blocking
+        with self.assertRaises(AttributeError):
+            del fut._log_traceback
+
 
 @unittest.skipUnless(hasattr(futures, '_CFuture'),
                      'requires the C _asyncio module')
index 12c6ef4f619ebc3d50f3980844ea314c49c556f5..d92ed32bc99f606f7af656912c251dd1b37e25f2 100644 (file)
@@ -2512,6 +2512,15 @@ class CTask_CFuture_Tests(BaseTaskTests, SetMethodsTest,
             self.loop.run_until_complete(task)
         self.assertAlmostEqual(gettotalrefcount() - refs_before, 0, delta=10)
 
+    def test_del__log_destroy_pending_segfault(self):
+        @asyncio.coroutine
+        def coro():
+            pass
+        task = self.new_task(self.loop, coro())
+        self.loop.run_until_complete(task)
+        with self.assertRaises(AttributeError):
+            del task._log_destroy_pending
+
 
 @unittest.skipUnless(hasattr(futures, '_CFuture') and
                      hasattr(tasks, '_CTask'),
index 104f995937972e60672029919547aa77a8a22b35..5d16b95456f0cb7ec3f44dba22504290ccf02d8a 100644 (file)
@@ -433,10 +433,12 @@ class SelectorEventLoopUnixSockSendfileTests(test_utils.TestCase):
             self.data = bytearray()
             self.fut = loop.create_future()
             self.transport = None
+            self._ready = loop.create_future()
 
         def connection_made(self, transport):
             self.started = True
             self.transport = transport
+            self._ready.set_result(None)
 
         def data_received(self, data):
             self.data.extend(data)
@@ -487,13 +489,11 @@ class SelectorEventLoopUnixSockSendfileTests(test_utils.TestCase):
         server = self.run_loop(self.loop.create_server(
             lambda: proto, sock=srv_sock))
         self.run_loop(self.loop.sock_connect(sock, (support.HOST, port)))
+        self.run_loop(proto._ready)
 
         def cleanup():
-            if proto.transport is not None:
-                # can be None if the task was cancelled before
-                # connection_made callback
-                proto.transport.close()
-                self.run_loop(proto.wait_closed())
+            proto.transport.close()
+            self.run_loop(proto.wait_closed())
 
             server.close()
             self.run_loop(server.wait_closed())
index a148f1639eccb2f5815bc9c7e028540b383da7a3..d25d2cd5405c3946586ed903b02732409d3e252e 100644 (file)
@@ -107,10 +107,10 @@ def run_briefly(loop):
 
 
 def run_until(loop, pred, timeout=30):
-    deadline = time.time() + timeout
+    deadline = time.monotonic() + timeout
     while not pred():
         if timeout is not None:
-            timeout = deadline - time.time()
+            timeout = deadline - time.monotonic()
             if timeout <= 0:
                 raise futures.TimeoutError()
         loop.run_until_complete(tasks.sleep(0.001, loop=loop))
index 694ddffd6879ebb6f0dc83ab0fc68eaeb17c0e4f..3fcedb58ec18a62ba3b97cc1768e87cb668135bd 100644 (file)
@@ -70,8 +70,8 @@ def capture_server(evt, buf, serv):
         pass
     else:
         n = 200
-        start = time.time()
-        while n > 0 and time.time() - start < 3.0:
+        start = time.monotonic()
+        while n > 0 and time.monotonic() - start < 3.0:
             r, w, e = select.select([conn], [], [], 0.1)
             if r:
                 n -= 1
index 6133bbcac52afbfb096ed477e5a5c98e05fcd804..6a244dd8c94800b2e7a1e80eb9c39939d9b8dc87 100644 (file)
@@ -64,6 +64,7 @@ import sys
 ascii_char_size = 1
 ucs2_char_size = 2
 ucs4_char_size = 4
+pointer_size = 4 if sys.maxsize < 2**32 else 8
 
 
 class BaseStrTest:
@@ -372,7 +373,7 @@ class BaseStrTest:
     # suffer for the list size. (Otherwise, it'd cost another 48 times
     # size in bytes!) Nevertheless, a list of size takes
     # 8*size bytes.
-    @bigmemtest(size=_2G + 5, memuse=2 * ascii_char_size + 8)
+    @bigmemtest(size=_2G + 5, memuse=ascii_char_size * 2 + pointer_size)
     def test_split_large(self, size):
         _ = self.from_latin1
         s = _(' a') * size + _(' ')
@@ -604,15 +605,15 @@ class StrTest(unittest.TestCase, BaseStrTest):
         for name, memuse in self._adjusted.items():
             getattr(type(self), name).memuse = memuse
 
-    @bigmemtest(size=_2G, memuse=ucs4_char_size * 3)
+    @bigmemtest(size=_2G, memuse=ucs4_char_size * 3 + ascii_char_size * 2)
     def test_capitalize(self, size):
         self._test_capitalize(size)
 
-    @bigmemtest(size=_2G, memuse=ucs4_char_size * 3)
+    @bigmemtest(size=_2G, memuse=ucs4_char_size * 3 + ascii_char_size * 2)
     def test_title(self, size):
         self._test_title(size)
 
-    @bigmemtest(size=_2G, memuse=ucs4_char_size * 3)
+    @bigmemtest(size=_2G, memuse=ucs4_char_size * 3 + ascii_char_size * 2)
     def test_swapcase(self, size):
         self._test_swapcase(size)
 
@@ -630,7 +631,7 @@ class StrTest(unittest.TestCase, BaseStrTest):
         except MemoryError:
             pass # acceptable on 32-bit
 
-    @bigmemtest(size=_4G // 5 + 70, memuse=ascii_char_size + ucs4_char_size + 1)
+    @bigmemtest(size=_4G // 5 + 70, memuse=ascii_char_size + 8 + 1)
     def test_encode_utf7(self, size):
         try:
             return self.basic_encode_test(size, 'utf7')
@@ -820,7 +821,7 @@ class TupleTest(unittest.TestCase):
     # having more than 2<<31 references to any given object. Hence the
     # use of different types of objects as contents in different tests.
 
-    @bigmemtest(size=_2G + 2, memuse=16)
+    @bigmemtest(size=_2G + 2, memuse=pointer_size * 2)
     def test_compare(self, size):
         t1 = ('',) * size
         t2 = ('',) * size
@@ -843,15 +844,15 @@ class TupleTest(unittest.TestCase):
         t = t + t
         self.assertEqual(len(t), size * 2)
 
-    @bigmemtest(size=_2G // 2 + 2, memuse=24)
+    @bigmemtest(size=_2G // 2 + 2, memuse=pointer_size * 3)
     def test_concat_small(self, size):
         return self.basic_concat_test(size)
 
-    @bigmemtest(size=_2G + 2, memuse=24)
+    @bigmemtest(size=_2G + 2, memuse=pointer_size * 3)
     def test_concat_large(self, size):
         return self.basic_concat_test(size)
 
-    @bigmemtest(size=_2G // 5 + 10, memuse=8 * 5)
+    @bigmemtest(size=_2G // 5 + 10, memuse=pointer_size * 5)
     def test_contains(self, size):
         t = (1, 2, 3, 4, 5) * size
         self.assertEqual(len(t), size * 5)
@@ -859,7 +860,7 @@ class TupleTest(unittest.TestCase):
         self.assertFalse((1, 2, 3, 4, 5) in t)
         self.assertFalse(0 in t)
 
-    @bigmemtest(size=_2G + 10, memuse=8)
+    @bigmemtest(size=_2G + 10, memuse=pointer_size)
     def test_hash(self, size):
         t1 = (0,) * size
         h1 = hash(t1)
@@ -867,7 +868,7 @@ class TupleTest(unittest.TestCase):
         t2 = (0,) * (size + 1)
         self.assertFalse(h1 == hash(t2))
 
-    @bigmemtest(size=_2G + 10, memuse=8)
+    @bigmemtest(size=_2G + 10, memuse=pointer_size)
     def test_index_and_slice(self, size):
         t = (None,) * size
         self.assertEqual(len(t), size)
@@ -892,11 +893,11 @@ class TupleTest(unittest.TestCase):
         t = t * 2
         self.assertEqual(len(t), size * 2)
 
-    @bigmemtest(size=_2G // 2 + 2, memuse=24)
+    @bigmemtest(size=_2G // 2 + 2, memuse=pointer_size * 3)
     def test_repeat_small(self, size):
         return self.basic_test_repeat(size)
 
-    @bigmemtest(size=_2G + 2, memuse=24)
+    @bigmemtest(size=_2G + 2, memuse=pointer_size * 3)
     def test_repeat_large(self, size):
         return self.basic_test_repeat(size)
 
@@ -904,48 +905,42 @@ class TupleTest(unittest.TestCase):
     def test_repeat_large_2(self, size):
         return self.basic_test_repeat(size)
 
-    @bigmemtest(size=_1G - 1, memuse=9)
+    @bigmemtest(size=_1G - 1, memuse=pointer_size * 2)
     def test_from_2G_generator(self, size):
-        self.skipTest("test needs much more memory than advertised, see issue5438")
         try:
-            t = tuple(range(size))
+            t = tuple(iter([42]*size))
         except MemoryError:
             pass # acceptable on 32-bit
         else:
-            count = 0
-            for item in t:
-                self.assertEqual(item, count)
-                count += 1
-            self.assertEqual(count, size)
+            self.assertEqual(len(t), size)
+            self.assertEqual(t[:10], (42,) * 10)
+            self.assertEqual(t[-10:], (42,) * 10)
 
-    @bigmemtest(size=_1G - 25, memuse=9)
+    @bigmemtest(size=_1G - 25, memuse=pointer_size * 2)
     def test_from_almost_2G_generator(self, size):
-        self.skipTest("test needs much more memory than advertised, see issue5438")
         try:
-            t = tuple(range(size))
-            count = 0
-            for item in t:
-                self.assertEqual(item, count)
-                count += 1
-            self.assertEqual(count, size)
+            t = tuple(iter([42]*size))
         except MemoryError:
-            pass # acceptable, expected on 32-bit
+            pass # acceptable on 32-bit
+        else:
+            self.assertEqual(len(t), size)
+            self.assertEqual(t[:10], (42,) * 10)
+            self.assertEqual(t[-10:], (42,) * 10)
 
     # Like test_concat, split in two.
     def basic_test_repr(self, size):
-        t = (0,) * size
+        t = (False,) * size
         s = repr(t)
-        # The repr of a tuple of 0's is exactly three times the tuple length.
-        self.assertEqual(len(s), size * 3)
-        self.assertEqual(s[:5], '(0, 0')
-        self.assertEqual(s[-5:], '0, 0)')
-        self.assertEqual(s.count('0'), size)
+        # The repr of a tuple of Falses is exactly 7 times the tuple length.
+        self.assertEqual(len(s), size * 7)
+        self.assertEqual(s[:10], '(False, Fa')
+        self.assertEqual(s[-10:], 'se, False)')
 
-    @bigmemtest(size=_2G // 3 + 2, memuse=8 + 3 * ascii_char_size)
+    @bigmemtest(size=_2G // 7 + 2, memuse=pointer_size + ascii_char_size * 7)
     def test_repr_small(self, size):
         return self.basic_test_repr(size)
 
-    @bigmemtest(size=_2G + 2, memuse=8 + 3 * ascii_char_size)
+    @bigmemtest(size=_2G + 2, memuse=pointer_size + ascii_char_size * 7)
     def test_repr_large(self, size):
         return self.basic_test_repr(size)
 
@@ -956,7 +951,7 @@ class ListTest(unittest.TestCase):
     # lists hold references to various objects to test their refcount
     # limits.
 
-    @bigmemtest(size=_2G + 2, memuse=16)
+    @bigmemtest(size=_2G + 2, memuse=pointer_size * 2)
     def test_compare(self, size):
         l1 = [''] * size
         l2 = [''] * size
@@ -979,14 +974,16 @@ class ListTest(unittest.TestCase):
         l = l + l
         self.assertEqual(len(l), size * 2)
 
-    @bigmemtest(size=_2G // 2 + 2, memuse=24)
+    @bigmemtest(size=_2G // 2 + 2, memuse=pointer_size * 3)
     def test_concat_small(self, size):
         return self.basic_test_concat(size)
 
-    @bigmemtest(size=_2G + 2, memuse=24)
+    @bigmemtest(size=_2G + 2, memuse=pointer_size * 3)
     def test_concat_large(self, size):
         return self.basic_test_concat(size)
 
+    # XXX This tests suffers from overallocation, just like test_append.
+    # This should be fixed in future.
     def basic_test_inplace_concat(self, size):
         l = [sys.stdout] * size
         l += l
@@ -994,15 +991,15 @@ class ListTest(unittest.TestCase):
         self.assertTrue(l[0] is l[-1])
         self.assertTrue(l[size - 1] is l[size + 1])
 
-    @bigmemtest(size=_2G // 2 + 2, memuse=24)
+    @bigmemtest(size=_2G // 2 + 2, memuse=pointer_size * 2 * 9/8)
     def test_inplace_concat_small(self, size):
         return self.basic_test_inplace_concat(size)
 
-    @bigmemtest(size=_2G + 2, memuse=24)
+    @bigmemtest(size=_2G + 2, memuse=pointer_size * 2 * 9/8)
     def test_inplace_concat_large(self, size):
         return self.basic_test_inplace_concat(size)
 
-    @bigmemtest(size=_2G // 5 + 10, memuse=8 * 5)
+    @bigmemtest(size=_2G // 5 + 10, memuse=pointer_size * 5)
     def test_contains(self, size):
         l = [1, 2, 3, 4, 5] * size
         self.assertEqual(len(l), size * 5)
@@ -1010,12 +1007,12 @@ class ListTest(unittest.TestCase):
         self.assertFalse([1, 2, 3, 4, 5] in l)
         self.assertFalse(0 in l)
 
-    @bigmemtest(size=_2G + 10, memuse=8)
+    @bigmemtest(size=_2G + 10, memuse=pointer_size)
     def test_hash(self, size):
         l = [0] * size
         self.assertRaises(TypeError, hash, l)
 
-    @bigmemtest(size=_2G + 10, memuse=8)
+    @bigmemtest(size=_2G + 10, memuse=pointer_size)
     def test_index_and_slice(self, size):
         l = [None] * size
         self.assertEqual(len(l), size)
@@ -1079,14 +1076,16 @@ class ListTest(unittest.TestCase):
         l = l * 2
         self.assertEqual(len(l), size * 2)
 
-    @bigmemtest(size=_2G // 2 + 2, memuse=24)
+    @bigmemtest(size=_2G // 2 + 2, memuse=pointer_size * 3)
     def test_repeat_small(self, size):
         return self.basic_test_repeat(size)
 
-    @bigmemtest(size=_2G + 2, memuse=24)
+    @bigmemtest(size=_2G + 2, memuse=pointer_size * 3)
     def test_repeat_large(self, size):
         return self.basic_test_repeat(size)
 
+    # XXX This tests suffers from overallocation, just like test_append.
+    # This should be fixed in future.
     def basic_test_inplace_repeat(self, size):
         l = ['']
         l *= size
@@ -1099,34 +1098,34 @@ class ListTest(unittest.TestCase):
         self.assertEqual(len(l), size * 2)
         self.assertTrue(l[size - 1] is l[-1])
 
-    @bigmemtest(size=_2G // 2 + 2, memuse=16)
+    @bigmemtest(size=_2G // 2 + 2, memuse=pointer_size * 2 * 9/8)
     def test_inplace_repeat_small(self, size):
         return self.basic_test_inplace_repeat(size)
 
-    @bigmemtest(size=_2G + 2, memuse=16)
+    @bigmemtest(size=_2G + 2, memuse=pointer_size * 2 * 9/8)
     def test_inplace_repeat_large(self, size):
         return self.basic_test_inplace_repeat(size)
 
     def basic_test_repr(self, size):
-        l = [0] * size
+        l = [False] * size
         s = repr(l)
-        # The repr of a list of 0's is exactly three times the list length.
-        self.assertEqual(len(s), size * 3)
-        self.assertEqual(s[:5], '[0, 0')
-        self.assertEqual(s[-5:], '0, 0]')
-        self.assertEqual(s.count('0'), size)
+        # The repr of a list of Falses is exactly 7 times the list length.
+        self.assertEqual(len(s), size * 7)
+        self.assertEqual(s[:10], '[False, Fa')
+        self.assertEqual(s[-10:], 'se, False]')
+        self.assertEqual(s.count('F'), size)
 
-    @bigmemtest(size=_2G // 3 + 2, memuse=8 + 3 * ascii_char_size)
+    @bigmemtest(size=_2G // 7 + 2, memuse=pointer_size + ascii_char_size * 7)
     def test_repr_small(self, size):
         return self.basic_test_repr(size)
 
-    @bigmemtest(size=_2G + 2, memuse=8 + 3 * ascii_char_size)
+    @bigmemtest(size=_2G + 2, memuse=pointer_size + ascii_char_size * 7)
     def test_repr_large(self, size):
         return self.basic_test_repr(size)
 
     # list overallocates ~1/8th of the total size (on first expansion) so
     # the single list.append call puts memuse at 9 bytes per size.
-    @bigmemtest(size=_2G, memuse=9)
+    @bigmemtest(size=_2G, memuse=pointer_size * 9/8)
     def test_append(self, size):
         l = [object()] * size
         l.append(object())
@@ -1134,12 +1133,14 @@ class ListTest(unittest.TestCase):
         self.assertTrue(l[-3] is l[-2])
         self.assertFalse(l[-2] is l[-1])
 
-    @bigmemtest(size=_2G // 5 + 2, memuse=8 * 5)
+    @bigmemtest(size=_2G // 5 + 2, memuse=pointer_size * 5)
     def test_count(self, size):
         l = [1, 2, 3, 4, 5] * size
         self.assertEqual(l.count(1), size)
         self.assertEqual(l.count("1"), 0)
 
+    # XXX This tests suffers from overallocation, just like test_append.
+    # This should be fixed in future.
     def basic_test_extend(self, size):
         l = [object] * size
         l.extend(l)
@@ -1147,15 +1148,15 @@ class ListTest(unittest.TestCase):
         self.assertTrue(l[0] is l[-1])
         self.assertTrue(l[size - 1] is l[size + 1])
 
-    @bigmemtest(size=_2G // 2 + 2, memuse=16)
+    @bigmemtest(size=_2G // 2 + 2, memuse=pointer_size * 2 * 9/8)
     def test_extend_small(self, size):
         return self.basic_test_extend(size)
 
-    @bigmemtest(size=_2G + 2, memuse=16)
+    @bigmemtest(size=_2G + 2, memuse=pointer_size * 2 * 9/8)
     def test_extend_large(self, size):
         return self.basic_test_extend(size)
 
-    @bigmemtest(size=_2G // 5 + 2, memuse=8 * 5)
+    @bigmemtest(size=_2G // 5 + 2, memuse=pointer_size * 5)
     def test_index(self, size):
         l = [1, 2, 3, 4, 5] * size
         size *= 5
@@ -1166,7 +1167,7 @@ class ListTest(unittest.TestCase):
         self.assertRaises(ValueError, l.index, 6)
 
     # This tests suffers from overallocation, just like test_append.
-    @bigmemtest(size=_2G + 10, memuse=9)
+    @bigmemtest(size=_2G + 10, memuse=pointer_size * 9/8)
     def test_insert(self, size):
         l = [1.0] * size
         l.insert(size - 1, "A")
@@ -1185,7 +1186,7 @@ class ListTest(unittest.TestCase):
         self.assertEqual(l[:3], [1.0, "C", 1.0])
         self.assertEqual(l[size - 3:], ["A", 1.0, "B"])
 
-    @bigmemtest(size=_2G // 5 + 4, memuse=8 * 5)
+    @bigmemtest(size=_2G // 5 + 4, memuse=pointer_size * 5)
     def test_pop(self, size):
         l = ["a", "b", "c", "d", "e"] * size
         size *= 5
@@ -1209,7 +1210,7 @@ class ListTest(unittest.TestCase):
         self.assertEqual(item, "c")
         self.assertEqual(l[-2:], ["b", "d"])
 
-    @bigmemtest(size=_2G + 10, memuse=8)
+    @bigmemtest(size=_2G + 10, memuse=pointer_size)
     def test_remove(self, size):
         l = [10] * size
         self.assertEqual(len(l), size)
@@ -1229,7 +1230,7 @@ class ListTest(unittest.TestCase):
         self.assertEqual(len(l), size)
         self.assertEqual(l[-2:], [10, 10])
 
-    @bigmemtest(size=_2G // 5 + 2, memuse=8 * 5)
+    @bigmemtest(size=_2G // 5 + 2, memuse=pointer_size * 5)
     def test_reverse(self, size):
         l = [1, 2, 3, 4, 5] * size
         l.reverse()
@@ -1237,7 +1238,7 @@ class ListTest(unittest.TestCase):
         self.assertEqual(l[-5:], [5, 4, 3, 2, 1])
         self.assertEqual(l[:5], [5, 4, 3, 2, 1])
 
-    @bigmemtest(size=_2G // 5 + 2, memuse=8 * 5)
+    @bigmemtest(size=_2G // 5 + 2, memuse=pointer_size * 5 * 1.5)
     def test_sort(self, size):
         l = [1, 2, 3, 4, 5] * size
         l.sort()
index 7c9768a337bbb022379a6c2682f82241d7c10abc..c3f04ec7447c6ede04cca98ebecfa2bd7cee141a 100644 (file)
@@ -1601,6 +1601,7 @@ class TestBreakpoint(unittest.TestCase):
     def test_envar_unimportable(self):
         for envar in (
                 '.', '..', '.foo', 'foo.', '.int', 'int.',
+                '.foo.bar', '..foo.bar', '/./',
                 'nosuchbuiltin',
                 'nosuchmodule.nosuchcallable',
                 ):
index 145411efbb9d0cadcc6afe815eac5ee232dfa8cd..274616bf998dbc41b82b3cf37281e2a0f7447c60 100644 (file)
@@ -999,6 +999,12 @@ class BytesTest(BaseBytesTest, unittest.TestCase):
         self.assertRaises(OverflowError,
                           PyBytes_FromFormat, b'%c', c_int(256))
 
+        # Issue #33817: empty strings
+        self.assertEqual(PyBytes_FromFormat(b''),
+                         b'')
+        self.assertEqual(PyBytes_FromFormat(b'%s', b''),
+                         b'')
+
     def test_bytes_blocking(self):
         class IterationBlocked(list):
             __bytes__ = None
index 841cac9171cca07c533c488d1de19660cf8e0b2c..dcaedf43fa90672cd7c85e7ccd4db2fed4aeaaae 100644 (file)
@@ -602,19 +602,21 @@ class ClassTests(unittest.TestCase):
         class C:
             pass
 
+        error_msg = r'C.__init__\(\) takes exactly one argument \(the instance to initialize\)'
+
         with self.assertRaisesRegex(TypeError, r'C\(\) takes no arguments'):
             C(42)
 
         with self.assertRaisesRegex(TypeError, r'C\(\) takes no arguments'):
             C.__new__(C, 42)
 
-        with self.assertRaisesRegex(TypeError, r'C\(\).__init__\(\) takes no arguments'):
+        with self.assertRaisesRegex(TypeError, error_msg):
             C().__init__(42)
 
         with self.assertRaisesRegex(TypeError, r'C\(\) takes no arguments'):
             object.__new__(C, 42)
 
-        with self.assertRaisesRegex(TypeError, r'C\(\).__init__\(\) takes no arguments'):
+        with self.assertRaisesRegex(TypeError, error_msg):
             object.__init__(C(), 42)
 
         # Class with both `__init__` & `__new__` method overridden
@@ -624,13 +626,15 @@ class ClassTests(unittest.TestCase):
             def __init__(self, *args, **kwargs):
                 super().__init__(*args, **kwargs)
 
-        with self.assertRaisesRegex(TypeError, r'object.__new__\(\) takes no argument'):
+        error_msg =  r'object.__new__\(\) takes exactly one argument \(the type to instantiate\)'
+
+        with self.assertRaisesRegex(TypeError, error_msg):
             D(42)
 
-        with self.assertRaisesRegex(TypeError, r'object.__new__\(\) takes no argument'):
+        with self.assertRaisesRegex(TypeError, error_msg):
             D.__new__(D, 42)
 
-        with self.assertRaisesRegex(TypeError, r'object.__new__\(\) takes no argument'):
+        with self.assertRaisesRegex(TypeError, error_msg):
             object.__new__(D, 42)
 
         # Class that only overrides __init__
@@ -638,10 +642,12 @@ class ClassTests(unittest.TestCase):
             def __init__(self, *args, **kwargs):
                 super().__init__(*args, **kwargs)
 
-        with self.assertRaisesRegex(TypeError, r'object.__init__\(\) takes no argument'):
+        error_msg = r'object.__init__\(\) takes exactly one argument \(the instance to initialize\)'
+
+        with self.assertRaisesRegex(TypeError, error_msg):
             E().__init__(42)
 
-        with self.assertRaisesRegex(TypeError, r'object.__init__\(\) takes no argument'):
+        with self.assertRaisesRegex(TypeError, error_msg):
             object.__init__(E(), 42)
 
 if __name__ == '__main__':
index ba4ae3401056f48ba73acf198b809a69fb658cc5..244c5fecd3491562e723b653e772660df62b6eff 100644 (file)
@@ -44,7 +44,6 @@ class FakeConvertersDict:
     def get(self, name, default):
         return self.used_converters.setdefault(name, FakeConverterFactory(name))
 
-clinic.Clinic.presets_text = ''
 c = clinic.Clinic(language='C', filename = "file")
 
 class FakeClinic:
@@ -798,5 +797,22 @@ Not at column 0!
         self.assertEqual(stdout.getvalue(), 'Error in file "clown.txt" on line 69:\nThe igloos are melting!\n')
 
 
+class ClinicExternalTest(TestCase):
+    maxDiff = None
+
+    def test_external(self):
+        source = support.findfile('clinic.test')
+        with open(source, 'r', encoding='utf-8') as f:
+            original = f.read()
+        with support.temp_dir() as testdir:
+            testfile = os.path.join(testdir, 'clinic.test.c')
+            with open(testfile, 'w', encoding='utf-8') as f:
+                f.write(original)
+            clinic.parse_file(testfile, force=True)
+            with open(testfile, 'r', encoding='utf-8') as f:
+                result = f.read()
+            self.assertEqual(result, original)
+
+
 if __name__ == "__main__":
     unittest.main()
index 2099d236d0c4a1f299023407e5c6bb39fd167645..2e7c1996d118ba4201ff5f0b5ddea6d1fe370288 100644 (file)
@@ -114,6 +114,20 @@ class TestChainMap(unittest.TestCase):
         self.assertEqual(f['b'], 5)                                    # find first in chain
         self.assertEqual(f.parents['b'], 2)                            # look beyond maps[0]
 
+    def test_ordering(self):
+        # Combined order matches a series of dict updates from last to first.
+        # This test relies on the ordering of the underlying dicts.
+
+        baseline = {'music': 'bach', 'art': 'rembrandt'}
+        adjustments = {'art': 'van gogh', 'opera': 'carmen'}
+
+        cm = ChainMap(adjustments, baseline)
+
+        combined = baseline.copy()
+        combined.update(adjustments)
+
+        self.assertEqual(list(combined.items()), list(cm.items()))
+
     def test_constructor(self):
         self.assertEqual(ChainMap().maps, [{}])                        # no-args --> one new dict
         self.assertEqual(ChainMap({1:2}).maps, [{1:2}])                # 1 arg --> list
index ff6060c6d2838acf09e3a0519104a920aadf924a..9c83459f09e79714238b1415df0c15ebe818c0db 100755 (executable)
@@ -1737,23 +1737,33 @@ class TestCase(unittest.TestCase):
                 i: int = field(metadata=0)
 
         # Make sure an empty dict works.
+        d = {}
         @dataclass
         class C:
-            i: int = field(metadata={})
+            i: int = field(metadata=d)
         self.assertFalse(fields(C)[0].metadata)
         self.assertEqual(len(fields(C)[0].metadata), 0)
+        # Update should work (see bpo-35960).
+        d['foo'] = 1
+        self.assertEqual(len(fields(C)[0].metadata), 1)
+        self.assertEqual(fields(C)[0].metadata['foo'], 1)
         with self.assertRaisesRegex(TypeError,
                                     'does not support item assignment'):
             fields(C)[0].metadata['test'] = 3
 
         # Make sure a non-empty dict works.
+        d = {'test': 10, 'bar': '42', 3: 'three'}
         @dataclass
         class C:
-            i: int = field(metadata={'test': 10, 'bar': '42', 3: 'three'})
+            i: int = field(metadata=d)
         self.assertEqual(len(fields(C)[0].metadata), 3)
         self.assertEqual(fields(C)[0].metadata['test'], 10)
         self.assertEqual(fields(C)[0].metadata['bar'], '42')
         self.assertEqual(fields(C)[0].metadata[3], 'three')
+        # Update should work.
+        d['foo'] = 1
+        self.assertEqual(len(fields(C)[0].metadata), 4)
+        self.assertEqual(fields(C)[0].metadata['foo'], 1)
         with self.assertRaises(KeyError):
             # Non-existent key.
             fields(C)[0].metadata['baz']
index 83941c129f44630e1b73df8ed5c3439d1f745252..4a3c488738d39f40da337a669f28fd40e8681448 100644 (file)
@@ -2450,6 +2450,10 @@ def test_unittest_reportflags():
     Then the default eporting options are ignored:
 
       >>> result = suite.run(unittest.TestResult())
+
+    *NOTE*: These doctest are intentionally not placed in raw string to depict
+    the trailing whitespace using `\x20` in the diff below.
+
       >>> print(result.failures[0][1]) # doctest: +ELLIPSIS
       Traceback ...
       Failed example:
@@ -2463,7 +2467,7 @@ def test_unittest_reportflags():
       Differences (ndiff with -expected +actual):
             a
           - <BLANKLINE>
-          +
+          +\x20
             b
       <BLANKLINE>
       <BLANKLINE>
@@ -2952,6 +2956,47 @@ Invalid doctest option:
 
 """
 
+def test_no_trailing_whitespace_stripping():
+    r"""
+    The fancy reports had a bug for a long time where any trailing whitespace on
+    the reported diff lines was stripped, making it impossible to see the
+    differences in line reported as different that differed only in the amount of
+    trailing whitespace.  The whitespace still isn't particularly visible unless
+    you use NDIFF, but at least it is now there to be found.
+
+    *NOTE*: This snippet was intentionally put inside a raw string to get rid of
+    leading whitespace error in executing the example below
+
+    >>> def f(x):
+    ...     r'''
+    ...     >>> print('\n'.join(['a    ', 'b']))
+    ...     a
+    ...     b
+    ...     '''
+    """
+    """
+    *NOTE*: These doctest are not placed in raw string to depict the trailing whitespace
+    using `\x20`
+
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> flags = doctest.REPORT_NDIFF
+    >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test)
+    ... # doctest: +ELLIPSIS
+    **********************************************************************
+    File ..., line 3, in f
+    Failed example:
+        print('\n'.join(['a    ', 'b']))
+    Differences (ndiff with -expected +actual):
+        - a
+        + a
+          b
+    TestResults(failed=1, attempted=1)
+
+    *NOTE*: `\x20` is for checking the trailing whitespace on the +a line above.
+    We cannot use actual spaces there, as a commit hook prevents from committing
+    patches that contain trailing whitespace. More info on Issue 24746.
+    """
+
 ######################################################################
 ## Main
 ######################################################################
index 0840be67d562db5ee7c06e57c685d93c76853182..da512167834f7f0cb8c337160acc8485885fa58f 100644 (file)
@@ -70,14 +70,14 @@ class LockTests(unittest.TestCase):
             to_unlock.release()
 
         self.lock.acquire()
-        start_time = int(time.time())
+        start_time = int(time.monotonic())
         _thread.start_new_thread(delay_unlock,(self.lock, DELAY))
         if support.verbose:
             print()
             print("*** Waiting for thread to release the lock "\
             "(approx. %s sec.) ***" % DELAY)
         self.lock.acquire()
-        end_time = int(time.time())
+        end_time = int(time.monotonic())
         if support.verbose:
             print("done")
         self.assertGreaterEqual(end_time - start_time, DELAY,
index b221045328dbd3509906cd2ad24fc337afa2668a..29a429ccd998f2c1d9c361826bc8b58d2fbced37 100644 (file)
@@ -1866,6 +1866,15 @@ class TestEnum(unittest.TestCase):
             REVERT_ALL = "REVERT_ALL"
             RETRY = "RETRY"
 
+    def test_empty_globals(self):
+        # bpo-35717: sys._getframe(2).f_globals['__name__'] fails with KeyError
+        # when using compile and exec because f_globals is empty
+        code = "from enum import Enum; Enum('Animal', 'ANT BEE CAT DOG')"
+        code = compile(code, "<string>", "exec")
+        global_ns = {}
+        local_ls = {}
+        exec(code, global_ns, local_ls)
+
 
 class TestOrder(unittest.TestCase):
 
@@ -2729,6 +2738,23 @@ class TestIntFlag(unittest.TestCase):
         self.assertEqual(256, len(seen), 'too many composite members created')
 
 
+class TestEmptyAndNonLatinStrings(unittest.TestCase):
+
+    def test_empty_string(self):
+        with self.assertRaises(ValueError):
+            empty_abc = Enum('empty_abc', ('', 'B', 'C'))
+
+    def test_non_latin_character_string(self):
+        greek_abc = Enum('greek_abc', ('\u03B1', 'B', 'C'))
+        item = getattr(greek_abc, '\u03B1')
+        self.assertEqual(item.value, 1)
+
+    def test_non_latin_number_string(self):
+        hebrew_123 = Enum('hebrew_123', ('\u05D0', '2', '3'))
+        item = getattr(hebrew_123, '\u05D0')
+        self.assertEqual(item.value, 1)
+
+
 class TestUnique(unittest.TestCase):
 
     def test_unique_clean(self):
index d6dc4ba55d9b3e89a8602ac3d3beb34fccbe41d7..700b7ad6b8852b02da2ed572932fd3b63bcf3f4e 100644 (file)
@@ -5,6 +5,7 @@ import os
 import signal
 import subprocess
 import sys
+import sysconfig
 from test import support
 from test.support import script_helper, is_android
 import tempfile
@@ -19,6 +20,17 @@ except ImportError:
 
 TIMEOUT = 0.5
 MS_WINDOWS = (os.name == 'nt')
+_cflags = sysconfig.get_config_var('CFLAGS') or ''
+_config_args = sysconfig.get_config_var('CONFIG_ARGS') or ''
+UB_SANITIZER = (
+    '-fsanitize=undefined' in _cflags or
+    '--with-undefined-behavior-sanitizer' in _config_args
+)
+MEMORY_SANITIZER = (
+    '-fsanitize=memory' in _cflags or
+    '--with-memory-sanitizer' in _config_args
+)
+
 
 def expected_traceback(lineno1, lineno2, header, min_count=1):
     regex = header
@@ -94,7 +106,7 @@ class FaultHandlerTests(unittest.TestCase):
         else:
             header = 'Stack'
         regex = r"""
-            ^{fatal_error}
+            (?m)^{fatal_error}
 
             {header} \(most recent call first\):
               File "<string>", line {lineno} in <module>
@@ -252,6 +264,8 @@ class FaultHandlerTests(unittest.TestCase):
             3,
             'Segmentation fault')
 
+    @unittest.skipIf(UB_SANITIZER or MEMORY_SANITIZER,
+                     "sanitizer builds change crashing process output.")
     @skip_segfault_on_android
     def test_enable_file(self):
         with temporary_filename() as filename:
@@ -267,6 +281,8 @@ class FaultHandlerTests(unittest.TestCase):
 
     @unittest.skipIf(sys.platform == "win32",
                      "subprocess doesn't support pass_fds on Windows")
+    @unittest.skipIf(UB_SANITIZER or MEMORY_SANITIZER,
+                     "sanitizer builds change crashing process output.")
     @skip_segfault_on_android
     def test_enable_fd(self):
         with tempfile.TemporaryFile('wb+') as fp:
index 06ea90c207f56c98c0b0bd6c5389b0ca5f25c72f..49c1fbcd4ef8d377c0812088a1ab858929abfd0a 100644 (file)
@@ -701,6 +701,25 @@ class FormatTestCase(unittest.TestCase):
         self.assertEqual(format(1234.56, '.4'), '1.235e+03')
         self.assertEqual(format(12345.6, '.4'), '1.235e+04')
 
+    def test_issue35560(self):
+        self.assertEqual(format(123.0, '00'), '123.0')
+        self.assertEqual(format(123.34, '00f'), '123.340000')
+        self.assertEqual(format(123.34, '00e'), '1.233400e+02')
+        self.assertEqual(format(123.34, '00g'), '123.34')
+        self.assertEqual(format(123.34, '00.10f'), '123.3400000000')
+        self.assertEqual(format(123.34, '00.10e'), '1.2334000000e+02')
+        self.assertEqual(format(123.34, '00.10g'), '123.34')
+        self.assertEqual(format(123.34, '01f'), '123.340000')
+
+        self.assertEqual(format(-123.0, '00'), '-123.0')
+        self.assertEqual(format(-123.34, '00f'), '-123.340000')
+        self.assertEqual(format(-123.34, '00e'), '-1.233400e+02')
+        self.assertEqual(format(-123.34, '00g'), '-123.34')
+        self.assertEqual(format(-123.34, '00.10f'), '-123.3400000000')
+        self.assertEqual(format(-123.34, '00.10f'), '-123.3400000000')
+        self.assertEqual(format(-123.34, '00.10e'), '-1.2334000000e+02')
+        self.assertEqual(format(-123.34, '00.10g'), '-123.34')
+
 class ReprTestCase(unittest.TestCase):
     def test_repr(self):
         floats_file = open(os.path.join(os.path.split(__file__)[0],
index fd795085a5cd400e9fda91facd355166904e0053..d6aa2834cbc28b749b32f7daa412be296d5f68ca 100644 (file)
@@ -109,10 +109,7 @@ class ClearTest(unittest.TestCase):
             self.assertIs(None, wr())
 
 
-class FrameLocalsTest(unittest.TestCase):
-    """
-    Tests for the .f_locals attribute.
-    """
+class FrameAttrsTest(unittest.TestCase):
 
     def make_frames(self):
         def outer():
@@ -159,6 +156,11 @@ class FrameLocalsTest(unittest.TestCase):
         self.assertEqual(outer.f_locals, {})
         self.assertEqual(inner.f_locals, {})
 
+    def test_f_lineno_del_segfault(self):
+        f, _, _ = self.make_frames()
+        with self.assertRaises(AttributeError):
+            del f.f_lineno
+
 
 class ReprTest(unittest.TestCase):
     """
index 7a0757f7e17b10414d7864c6109c5b5d529d45ef..a91c6348e709d73df9c81f47b059fa6d82962cbb 100644 (file)
@@ -1226,6 +1226,33 @@ class TestLRU:
         self.assertEqual(misses, 4)
         self.assertEqual(currsize, 2)
 
+    def test_lru_bug_35780(self):
+        # C version of the lru_cache was not checking to see if
+        # the user function call has already modified the cache
+        # (this arises in recursive calls and in multi-threading).
+        # This cause the cache to have orphan links not referenced
+        # by the cache dictionary.
+
+        once = True                 # Modified by f(x) below
+
+        @self.module.lru_cache(maxsize=10)
+        def f(x):
+            nonlocal once
+            rv = f'.{x}.'
+            if x == 20 and once:
+                once = False
+                rv = f(x)
+            return rv
+
+        # Fill the cache
+        for x in range(15):
+            self.assertEqual(f(x), f'.{x}.')
+        self.assertEqual(f.cache_info().currsize, 10)
+
+        # Make a recursive call and make sure the cache remains full
+        self.assertEqual(f(20), '.20.')
+        self.assertEqual(f.cache_info().currsize, 10)
+
     def test_lru_hash_only_once(self):
         # To protect against weird reentrancy bugs and to improve
         # efficiency when faced with slow __hash__ methods, the
@@ -1322,7 +1349,7 @@ class TestLRU:
         for i in (0, 1):
             self.assertEqual([eq(n) for n in range(150)], list(range(150)))
         self.assertEqual(eq.cache_info(),
-            self.module._CacheInfo(hits=0, misses=300, maxsize=-10, currsize=1))
+            self.module._CacheInfo(hits=0, misses=300, maxsize=0, currsize=0))
 
     def test_lru_with_exceptions(self):
         # Verify that user_function exceptions get passed through without
index 413dd4d96b0367cc0572b2333359039c5ebd6266..b27ca40d2eaeb3eab1a873f5909f83374b0e20c7 100644 (file)
@@ -1,6 +1,11 @@
 from __future__ import unicode_literals
-
 import unittest
 
+
+class Tests(unittest.TestCase):
+    def test_unicode_literals(self):
+        self.assertIsInstance("literal", str)
+
+
 if __name__ == "__main__":
     unittest.main()
index 37e755b1167e83529c377975f6a0b889b75efc02..37a87bc6815ec2fb414f392db36a9ddd32dcdbd3 100644 (file)
@@ -248,7 +248,14 @@ class TestClassGetitem(unittest.TestCase):
                 return f'{cls.__name__}[{item.__name__}]'
         self.assertEqual(Meta[int], 'Meta[int]')
 
-    def test_class_getitem_metaclass_2(self):
+    def test_class_getitem_with_metaclass(self):
+        class Meta(type): pass
+        class C(metaclass=Meta):
+            def __class_getitem__(cls, item):
+                return f'{cls.__name__}[{item.__name__}]'
+        self.assertEqual(C[int], 'C[int]')
+
+    def test_class_getitem_metaclass_first(self):
         class Meta(type):
             def __getitem__(cls, item):
                 return 'from metaclass'
index abc625d672a784826c8de8fb8e0e6292181eca28..16edf34a99259f64a8dec005c58505e831d3833c 100644 (file)
@@ -415,6 +415,7 @@ class CookieTests(unittest.TestCase):
             ("http://foo.bar.com/", ".foo.bar.com", True),
             ("http://foo.bar.com/", "foo.bar.com", True),
             ("http://foo.bar.com/", ".bar.com", True),
+            ("http://foo.bar.com/", "bar.com", True),
             ("http://foo.bar.com/", "com", True),
             ("http://foo.com/", "rhubarb.foo.com", False),
             ("http://foo.com/", ".foo.com", True),
@@ -425,6 +426,8 @@ class CookieTests(unittest.TestCase):
             ("http://foo/", "foo", True),
             ("http://foo/", "foo.local", True),
             ("http://foo/", ".local", True),
+            ("http://barfoo.com", ".foo.com", False),
+            ("http://barfoo.com", "foo.com", False),
             ]:
             request = urllib.request.Request(url)
             r = pol.domain_return_ok(domain, request)
@@ -692,6 +695,30 @@ class CookieTests(unittest.TestCase):
         req = urllib.request.Request("http://www.example.com")
         self.assertEqual(request_path(req), "/")
 
+    def test_path_prefix_match(self):
+        pol = DefaultCookiePolicy()
+        strict_ns_path_pol = DefaultCookiePolicy(strict_ns_set_path=True)
+
+        c = CookieJar(pol)
+        base_url = "http://bar.com"
+        interact_netscape(c, base_url, 'spam=eggs; Path=/foo')
+        cookie = c._cookies['bar.com']['/foo']['spam']
+
+        for path, ok in [('/foo', True),
+                         ('/foo/', True),
+                         ('/foo/bar', True),
+                         ('/', False),
+                         ('/foobad/foo', False)]:
+            url = f'{base_url}{path}'
+            req = urllib.request.Request(url)
+            h = interact_netscape(c, url)
+            if ok:
+                self.assertIn('spam=eggs', h, f"cookie not set for {path}")
+                self.assertTrue(strict_ns_path_pol.set_ok_path(cookie, req))
+            else:
+                self.assertNotIn('spam=eggs', h, f"cookie set for {path}")
+                self.assertFalse(strict_ns_path_pol.set_ok_path(cookie, req))
+
     def test_request_port(self):
         req = urllib.request.Request("http://www.acme.com:1234/",
                                      headers={"Host": "www.acme.com:4321"})
@@ -959,6 +986,33 @@ class CookieTests(unittest.TestCase):
         c.add_cookie_header(req)
         self.assertFalse(req.has_header("Cookie"))
 
+        c.clear()
+
+        pol.set_blocked_domains([])
+        req = urllib.request.Request("http://acme.com/")
+        res = FakeResponse(headers, "http://acme.com/")
+        cookies = c.make_cookies(res, req)
+        c.extract_cookies(res, req)
+        self.assertEqual(len(c), 1)
+
+        req = urllib.request.Request("http://acme.com/")
+        c.add_cookie_header(req)
+        self.assertTrue(req.has_header("Cookie"))
+
+        req = urllib.request.Request("http://badacme.com/")
+        c.add_cookie_header(req)
+        self.assertFalse(pol.return_ok(cookies[0], req))
+        self.assertFalse(req.has_header("Cookie"))
+
+        p = pol.set_blocked_domains(["acme.com"])
+        req = urllib.request.Request("http://acme.com/")
+        c.add_cookie_header(req)
+        self.assertFalse(req.has_header("Cookie"))
+
+        req = urllib.request.Request("http://badacme.com/")
+        c.add_cookie_header(req)
+        self.assertFalse(req.has_header("Cookie"))
+
     def test_secure(self):
         for ns in True, False:
             for whitespace in " ", "":
index a0b598d0c7840926a4aeba5458b411021ee1b5aa..a060143e1f6be4327d342a06bd26ac41f0d559a4 100644 (file)
@@ -8,6 +8,7 @@ import socketserver
 import time
 import calendar
 import threading
+import socket
 
 from test.support import (reap_threads, verbose, transient_internet,
                           run_with_tz, run_with_locale, cpython_only)
@@ -71,6 +72,15 @@ class TestImaplib(unittest.TestCase):
             imaplib.Time2Internaldate(t)
 
     def test_imap4_host_default_value(self):
+        # Check whether the IMAP4_PORT is truly unavailable.
+        with socket.socket() as s:
+            try:
+                s.connect(('', imaplib.IMAP4_PORT))
+                self.skipTest(
+                    "Cannot run the test with local IMAP server running.")
+            except socket.error:
+                pass
+
         expected_errnos = [
             # This is the exception that should be raised.
             errno.ECONNREFUSED,
index b41141e28adbad31ef0a1b118546f0c93d063966..6655576b6d4b89eac30f3fe2bf17323cb907402a 100644 (file)
@@ -28,6 +28,7 @@ import pickle
 import random
 import signal
 import sys
+import sysconfig
 import threading
 import time
 import unittest
@@ -59,6 +60,13 @@ else:
     class EmptyStruct(ctypes.Structure):
         pass
 
+_cflags = sysconfig.get_config_var('CFLAGS') or ''
+_config_args = sysconfig.get_config_var('CONFIG_ARGS') or ''
+MEMORY_SANITIZER = (
+    '-fsanitize=memory' in _cflags or
+    '--with-memory-sanitizer' in _config_args
+)
+
 def _default_chunk_size():
     """Get the default TextIOWrapper chunk size"""
     with open(__file__, "r", encoding="latin-1") as f:
@@ -1496,6 +1504,8 @@ class BufferedReaderTest(unittest.TestCase, CommonBufferedTests):
 class CBufferedReaderTest(BufferedReaderTest, SizeofTest):
     tp = io.BufferedReader
 
+    @unittest.skipIf(MEMORY_SANITIZER, "MSan defaults to crashing "
+                     "instead of returning NULL for malloc failure.")
     def test_constructor(self):
         BufferedReaderTest.test_constructor(self)
         # The allocation can succeed on 32-bit builds, e.g. with more
@@ -1840,6 +1850,8 @@ class BufferedWriterTest(unittest.TestCase, CommonBufferedTests):
 class CBufferedWriterTest(BufferedWriterTest, SizeofTest):
     tp = io.BufferedWriter
 
+    @unittest.skipIf(MEMORY_SANITIZER, "MSan defaults to crashing "
+                     "instead of returning NULL for malloc failure.")
     def test_constructor(self):
         BufferedWriterTest.test_constructor(self)
         # The allocation can succeed on 32-bit builds, e.g. with more
@@ -2314,6 +2326,8 @@ class BufferedRandomTest(BufferedReaderTest, BufferedWriterTest):
 class CBufferedRandomTest(BufferedRandomTest, SizeofTest):
     tp = io.BufferedRandom
 
+    @unittest.skipIf(MEMORY_SANITIZER, "MSan defaults to crashing "
+                     "instead of returning NULL for malloc failure.")
     def test_constructor(self):
         BufferedRandomTest.test_constructor(self)
         # The allocation can succeed on 32-bit builds, e.g. with more
@@ -3635,6 +3649,11 @@ class CTextIOWrapperTest(TextIOWrapperTest):
             t2.buddy = t1
         support.gc_collect()
 
+    def test_del__CHUNK_SIZE_SystemError(self):
+        t = self.TextIOWrapper(self.BytesIO(), encoding='ascii')
+        with self.assertRaises(AttributeError):
+            del t._CHUNK_SIZE
+
 
 class PyTextIOWrapperTest(TextIOWrapperTest):
     io = pyio
@@ -4116,10 +4135,9 @@ class SignalsTest(unittest.TestCase):
         in the latter."""
         read_results = []
         def _read():
-            if hasattr(signal, 'pthread_sigmask'):
-                signal.pthread_sigmask(signal.SIG_BLOCK, [signal.SIGALRM])
             s = os.read(r, 1)
             read_results.append(s)
+
         t = threading.Thread(target=_read)
         t.daemon = True
         r, w = os.pipe()
@@ -4127,7 +4145,14 @@ class SignalsTest(unittest.TestCase):
         large_data = item * (support.PIPE_MAX_SIZE // len(item) + 1)
         try:
             wio = self.io.open(w, **fdopen_kwargs)
-            t.start()
+            if hasattr(signal, 'pthread_sigmask'):
+                # create the thread with SIGALRM signal blocked
+                signal.pthread_sigmask(signal.SIG_BLOCK, [signal.SIGALRM])
+                t.start()
+                signal.pthread_sigmask(signal.SIG_UNBLOCK, [signal.SIGALRM])
+            else:
+                t.start()
+
             # Fill the pipe enough that the write will be blocking.
             # It will be interrupted by the timer armed above.  Since the
             # other thread has read one byte, the low-level write will
index 6d89ca4b77321eb0d29a7967449463f8e186d1fb..4aa4753fc2a6db445b06db5c6acab516d436b955 100644 (file)
@@ -1,5 +1,5 @@
 """ Test suite for the code in msilib """
-import os.path
+import os
 import unittest
 from test.support import TESTFN, import_module, unlink
 msilib = import_module('msilib')
@@ -42,6 +42,29 @@ class MsiDatabaseTestCase(unittest.TestCase):
         )
         self.addCleanup(unlink, db_path)
 
+    def test_summaryinfo_getproperty_issue1104(self):
+        db, db_path = init_database()
+        try:
+            sum_info = db.GetSummaryInformation(99)
+            title = sum_info.GetProperty(msilib.PID_TITLE)
+            self.assertEqual(title, b"Installation Database")
+
+            sum_info.SetProperty(msilib.PID_TITLE, "a" * 999)
+            title = sum_info.GetProperty(msilib.PID_TITLE)
+            self.assertEqual(title, b"a" * 999)
+
+            sum_info.SetProperty(msilib.PID_TITLE, "a" * 1000)
+            title = sum_info.GetProperty(msilib.PID_TITLE)
+            self.assertEqual(title, b"a" * 1000)
+
+            sum_info.SetProperty(msilib.PID_TITLE, "a" * 1001)
+            title = sum_info.GetProperty(msilib.PID_TITLE)
+            self.assertEqual(title, b"a" * 1001)
+        finally:
+            db = None
+            sum_info = None
+            os.unlink(db_path)
+
     def test_database_open_failed(self):
         with self.assertRaises(msilib.MSIError) as cm:
             msilib.OpenDatabase('non-existent.msi', msilib.MSIDBOPEN_READONLY)
@@ -92,7 +115,7 @@ class Test_make_id(unittest.TestCase):
     def test_invalid_any_char(self):
         self.assertEqual(
             msilib.make_id(".s\x82ort"), "_.s_ort")
-        self.assertEqual    (
+        self.assertEqual(
             msilib.make_id(".s\x82o?*+rt"), "_.s_o___rt")
 
 
index 9fd5c9fcd91fa698525ebff56b67b32a4935ade1..b6abfcc7e283d5e53225ffc9dbbe6b7bff822841 100644 (file)
@@ -54,18 +54,21 @@ if "check_sibling" in __file__:
 if __name__ == '__main__':
     start_method = sys.argv[1]
     set_start_method(start_method)
-    p = Pool(5)
     results = []
-    p.map_async(f, [1, 2, 3], callback=results.extend)
-    start_time = time.monotonic()
-    while not results:
-        time.sleep(0.05)
-        # 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)
+    with Pool(5) as pool:
+        pool.map_async(f, [1, 2, 3], callback=results.extend)
+        start_time = time.monotonic()
+        while not results:
+            time.sleep(0.05)
+            # 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)
+
+    pool.join()
 """
 
 test_source_main_skipped_in_children = """\
@@ -84,18 +87,21 @@ from multiprocessing import Pool, set_start_method
 
 start_method = sys.argv[1]
 set_start_method(start_method)
-p = Pool(5)
 results = []
-p.map_async(int, [1, 4, 9], callback=results.extend)
-start_time = time.monotonic()
-while not results:
-    time.sleep(0.05)
-    # 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)
+with Pool(5) as pool:
+    pool.map_async(int, [1, 4, 9], callback=results.extend)
+    start_time = time.monotonic()
+    while not results:
+        time.sleep(0.05)
+        # 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)
+
+pool.join()
 """
 
 # These helpers were copied from test_cmd_line_script & tweaked a bit...
index fe7261dd76e98efad90d4da3ed8bc233b05c5144..fd9f70e30dba396f69461c19d9c0981dd136424c 100644 (file)
@@ -923,7 +923,7 @@ class WalkTests(unittest.TestCase):
                               ["broken_link", "broken_link2", "broken_link3",
                                "tmp3"])
         else:
-            self.sub2_tree = (sub2_path, [], ["tmp3"])
+            self.sub2_tree = (sub2_path, ["SUB21"], ["tmp3"])
 
         os.chmod(sub21_path, 0)
         try:
@@ -1798,36 +1798,46 @@ class LinkTests(unittest.TestCase):
 
 @unittest.skipIf(sys.platform == "win32", "Posix specific tests")
 class PosixUidGidTests(unittest.TestCase):
+    # uid_t and gid_t are 32-bit unsigned integers on Linux
+    UID_OVERFLOW = (1 << 32)
+    GID_OVERFLOW = (1 << 32)
+
     @unittest.skipUnless(hasattr(os, 'setuid'), 'test needs os.setuid()')
     def test_setuid(self):
         if os.getuid() != 0:
             self.assertRaises(OSError, os.setuid, 0)
-        self.assertRaises(OverflowError, os.setuid, 1<<32)
+        self.assertRaises(TypeError, os.setuid, 'not an int')
+        self.assertRaises(OverflowError, os.setuid, self.UID_OVERFLOW)
 
     @unittest.skipUnless(hasattr(os, 'setgid'), 'test needs os.setgid()')
     def test_setgid(self):
         if os.getuid() != 0 and not HAVE_WHEEL_GROUP:
             self.assertRaises(OSError, os.setgid, 0)
-        self.assertRaises(OverflowError, os.setgid, 1<<32)
+        self.assertRaises(TypeError, os.setgid, 'not an int')
+        self.assertRaises(OverflowError, os.setgid, self.GID_OVERFLOW)
 
     @unittest.skipUnless(hasattr(os, 'seteuid'), 'test needs os.seteuid()')
     def test_seteuid(self):
         if os.getuid() != 0:
             self.assertRaises(OSError, os.seteuid, 0)
-        self.assertRaises(OverflowError, os.seteuid, 1<<32)
+        self.assertRaises(TypeError, os.setegid, 'not an int')
+        self.assertRaises(OverflowError, os.seteuid, self.UID_OVERFLOW)
 
     @unittest.skipUnless(hasattr(os, 'setegid'), 'test needs os.setegid()')
     def test_setegid(self):
         if os.getuid() != 0 and not HAVE_WHEEL_GROUP:
             self.assertRaises(OSError, os.setegid, 0)
-        self.assertRaises(OverflowError, os.setegid, 1<<32)
+        self.assertRaises(TypeError, os.setegid, 'not an int')
+        self.assertRaises(OverflowError, os.setegid, self.GID_OVERFLOW)
 
     @unittest.skipUnless(hasattr(os, 'setreuid'), 'test needs os.setreuid()')
     def test_setreuid(self):
         if os.getuid() != 0:
             self.assertRaises(OSError, os.setreuid, 0, 0)
-        self.assertRaises(OverflowError, os.setreuid, 1<<32, 0)
-        self.assertRaises(OverflowError, os.setreuid, 0, 1<<32)
+        self.assertRaises(TypeError, os.setreuid, 'not an int', 0)
+        self.assertRaises(TypeError, os.setreuid, 0, 'not an int')
+        self.assertRaises(OverflowError, os.setreuid, self.UID_OVERFLOW, 0)
+        self.assertRaises(OverflowError, os.setreuid, 0, self.UID_OVERFLOW)
 
     @unittest.skipUnless(hasattr(os, 'setreuid'), 'test needs os.setreuid()')
     def test_setreuid_neg1(self):
@@ -1841,8 +1851,10 @@ class PosixUidGidTests(unittest.TestCase):
     def test_setregid(self):
         if os.getuid() != 0 and not HAVE_WHEEL_GROUP:
             self.assertRaises(OSError, os.setregid, 0, 0)
-        self.assertRaises(OverflowError, os.setregid, 1<<32, 0)
-        self.assertRaises(OverflowError, os.setregid, 0, 1<<32)
+        self.assertRaises(TypeError, os.setregid, 'not an int', 0)
+        self.assertRaises(TypeError, os.setregid, 0, 'not an int')
+        self.assertRaises(OverflowError, os.setregid, self.GID_OVERFLOW, 0)
+        self.assertRaises(OverflowError, os.setregid, 0, self.GID_OVERFLOW)
 
     @unittest.skipUnless(hasattr(os, 'setregid'), 'test needs os.setregid()')
     def test_setregid_neg1(self):
@@ -2278,6 +2290,62 @@ class Win32JunctionTests(unittest.TestCase):
         os.unlink(self.junction)
         self.assertFalse(os.path.exists(self.junction))
 
+@unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
+class Win32NtTests(unittest.TestCase):
+    def setUp(self):
+        from test import support
+        self.nt = support.import_module('nt')
+        pass
+
+    def tearDown(self):
+        pass
+
+    def test_getfinalpathname_handles(self):
+        try:
+            import ctypes, ctypes.wintypes
+        except ImportError:
+            raise unittest.SkipTest('ctypes module is required for this test')
+
+        kernel = ctypes.WinDLL('Kernel32.dll', use_last_error=True)
+        kernel.GetCurrentProcess.restype = ctypes.wintypes.HANDLE
+
+        kernel.GetProcessHandleCount.restype = ctypes.wintypes.BOOL
+        kernel.GetProcessHandleCount.argtypes = (ctypes.wintypes.HANDLE,
+                                                 ctypes.wintypes.LPDWORD)
+
+        # This is a pseudo-handle that doesn't need to be closed
+        hproc = kernel.GetCurrentProcess()
+
+        handle_count = ctypes.wintypes.DWORD()
+        ok = kernel.GetProcessHandleCount(hproc, ctypes.byref(handle_count))
+        self.assertEqual(1, ok)
+
+        before_count = handle_count.value
+
+        # The first two test the error path, __file__ tests the success path
+        filenames = [ r'\\?\C:',
+                      r'\\?\NUL',
+                      r'\\?\CONIN',
+                      __file__ ]
+
+        for i in range(10):
+            for name in filenames:
+                try:
+                    tmp = self.nt._getfinalpathname(name)
+                except:
+                    # Failure is expected
+                    pass
+                try:
+                    tmp = os.stat(name)
+                except:
+                    pass
+
+        ok = kernel.GetProcessHandleCount(hproc, ctypes.byref(handle_count))
+        self.assertEqual(1, ok)
+
+        handle_delta = handle_count.value - before_count
+
+        self.assertEqual(0, handle_delta)
 
 @support.skip_unless_symlink
 class NonLocalSymlinkTests(unittest.TestCase):
@@ -3241,7 +3309,7 @@ class PathTConverterTests(unittest.TestCase):
                             cleanup_fn(result)
 
                 with self.assertRaisesRegex(
-                        TypeError, 'should be string, bytes'):
+                        TypeError, 'to return str or bytes'):
                     fn(int_fspath, *extra_args)
 
                 if allow_fd:
@@ -3254,6 +3322,15 @@ class PathTConverterTests(unittest.TestCase):
                             'os.PathLike'):
                         fn(fd, *extra_args)
 
+    def test_path_t_converter_and_custom_class(self):
+        msg = r'__fspath__\(\) to return str or bytes, not %s'
+        with self.assertRaisesRegex(TypeError, msg % r'int'):
+            os.stat(FakePath(2))
+        with self.assertRaisesRegex(TypeError, msg % r'float'):
+            os.stat(FakePath(2.34))
+        with self.assertRaisesRegex(TypeError, msg % r'object'):
+            os.stat(FakePath(object()))
+
 
 @unittest.skipUnless(hasattr(os, 'get_blocking'),
                      'needs os.get_blocking() and os.set_blocking()')
index c9e2a24767792eb95015bfac7341fa924ef6b71f..624fbf21ba7d88f7f3a485c5fdd201c0b3567d8e 100644 (file)
@@ -77,10 +77,10 @@ class OSSAudioDevTests(unittest.TestCase):
         # set parameters based on .au file headers
         dsp.setparameters(AFMT_S16_NE, nchannels, rate)
         self.assertTrue(abs(expected_time - 3.51) < 1e-2, expected_time)
-        t1 = time.time()
+        t1 = time.monotonic()
         dsp.write(data)
         dsp.close()
-        t2 = time.time()
+        t2 = time.monotonic()
         elapsed_time = t2 - t1
 
         percent_diff = (abs(elapsed_time - expected_time) / expected_time) * 100
index 9aa38e08dd6e6c204a9585d25adf0ed6d3a15823..f573f5f54b0fe205bcc15831303fcc10dcad92c9 100644 (file)
@@ -1482,6 +1482,28 @@ class PdbTestCase(unittest.TestCase):
         stdout, _ = self._run_pdb(['-m', self.module_name + '.runme'], commands)
         self.assertTrue(any("VAR from module" in l for l in stdout.splitlines()), stdout)
 
+    def test_errors_in_command(self):
+        commands = "\n".join([
+            'print(',
+            'debug print(',
+            'debug doesnotexist',
+            'c',
+        ])
+        stdout, _ = self.run_pdb_script('', commands + '\n')
+
+        self.assertEqual(stdout.splitlines()[1:], [
+            '(Pdb) *** SyntaxError: unexpected EOF while parsing',
+
+            '(Pdb) ENTERING RECURSIVE DEBUGGER',
+            '*** SyntaxError: unexpected EOF while parsing',
+            'LEAVING RECURSIVE DEBUGGER',
+
+            '(Pdb) ENTERING RECURSIVE DEBUGGER',
+            '> <string>(1)<module>()',
+            "((Pdb)) *** NameError: name 'doesnotexist' is not defined",
+            'LEAVING RECURSIVE DEBUGGER',
+            '(Pdb) ',
+        ])
 
 def load_tests(*args):
     from test import test_pdb
index 9bf365ed4b95a9777e0766cfd349d58fa8118e1e..198cea93eb52d7a74fe8dd83ae643f5e294b1870 100644 (file)
@@ -1013,12 +1013,12 @@ class PydocServerTest(unittest.TestCase):
         serverthread = pydoc._start_server(my_url_handler, hostname='0.0.0.0', port=0)
         self.assertIn('0.0.0.0', serverthread.docserver.address)
 
-        starttime = time.time()
+        starttime = time.monotonic()
         timeout = 1  #seconds
 
         while serverthread.serving:
             time.sleep(.01)
-            if serverthread.serving and time.time() - starttime > timeout:
+            if serverthread.serving and time.monotonic() - starttime > timeout:
                 serverthread.stop()
                 break
 
index 9fed4bef8809fcc2029a76842ec10277a4f01266..5ef6d7b12c50a3baf17e4a8375571a612f07e5d8 100644 (file)
@@ -1516,8 +1516,18 @@ class ReTests(unittest.TestCase):
         self.assertRaises(re.error, re.compile, r'(?au)\w')
 
     def test_locale_flag(self):
-        import locale
-        _, enc = locale.getlocale(locale.LC_CTYPE)
+        # On Windows, Python 3.7 doesn't call setlocale(LC_CTYPE, "") at
+        # startup and so the LC_CTYPE locale uses Latin1 encoding by default,
+        # whereas getpreferredencoding() returns the ANSI code page. Set
+        # temporarily the LC_CTYPE locale to the user preferred encoding to
+        # ensure that it uses the ANSI code page.
+        oldloc = locale.setlocale(locale.LC_CTYPE, None)
+        locale.setlocale(locale.LC_CTYPE, "")
+        self.addCleanup(locale.setlocale, locale.LC_CTYPE, oldloc)
+
+        # Get the current locale encoding
+        enc = locale.getpreferredencoding(False)
+
         # Search non-ASCII letter
         for i in range(128, 256):
             try:
@@ -2031,6 +2041,40 @@ ELSE
         self.assertEqual(m.group(), b'xyz')
         self.assertEqual(m2.group(), b'')
 
+    def test_bug_34294(self):
+        # Issue 34294: wrong capturing groups
+
+        # exists since Python 2
+        s = "a\tx"
+        p = r"\b(?=(\t)|(x))x"
+        self.assertEqual(re.search(p, s).groups(), (None, 'x'))
+
+        # introduced in Python 3.7.0
+        s = "ab"
+        p = r"(?=(.)(.)?)"
+        self.assertEqual(re.findall(p, s),
+                         [('a', 'b'), ('b', '')])
+        self.assertEqual([m.groups() for m in re.finditer(p, s)],
+                         [('a', 'b'), ('b', None)])
+
+        # test-cases provided by issue34294, introduced in Python 3.7.0
+        p = r"(?=<(?P<tag>\w+)/?>(?:(?P<text>.+?)</(?P=tag)>)?)"
+        s = "<test><foo2/></test>"
+        self.assertEqual(re.findall(p, s),
+                         [('test', '<foo2/>'), ('foo2', '')])
+        self.assertEqual([m.groupdict() for m in re.finditer(p, s)],
+                         [{'tag': 'test', 'text': '<foo2/>'},
+                          {'tag': 'foo2', 'text': None}])
+        s = "<test>Hello</test><foo/>"
+        self.assertEqual([m.groupdict() for m in re.finditer(p, s)],
+                         [{'tag': 'test', 'text': 'Hello'},
+                          {'tag': 'foo', 'text': None}])
+        s = "<test>Hello</test><foo/><foo/>"
+        self.assertEqual([m.groupdict() for m in re.finditer(p, s)],
+                         [{'tag': 'test', 'text': 'Hello'},
+                          {'tag': 'foo', 'text': None},
+                          {'tag': 'foo', 'text': None}])
+
 
 class PatternReprTests(unittest.TestCase):
     def check(self, pattern, expected):
index db9bd6dfc04359179cd23ebfa029ec06d9d207c1..a67458313addb2b5999afc35c6ec7325c5bfbe82 100644 (file)
@@ -1004,6 +1004,7 @@ class ArgsTestCase(BaseTestCase):
         output = self.run_tests("-w", testname, exitcode=2)
         self.check_executed_tests(output, [testname],
                                   failed=testname, rerun=testname)
+
     def test_no_tests_ran(self):
         code = textwrap.dedent("""
             import unittest
@@ -1017,6 +1018,19 @@ class ArgsTestCase(BaseTestCase):
         output = self.run_tests(testname, "-m", "nosuchtest", exitcode=0)
         self.check_executed_tests(output, [testname], no_test_ran=testname)
 
+    def test_no_tests_ran_skip(self):
+        code = textwrap.dedent("""
+            import unittest
+
+            class Tests(unittest.TestCase):
+                def test_skipped(self):
+                    self.skipTest("because")
+        """)
+        testname = self.create_test(code=code)
+
+        output = self.run_tests(testname, exitcode=0)
+        self.check_executed_tests(output, [testname])
+
     def test_no_tests_ran_multiple_tests_nonexistent(self):
         code = textwrap.dedent("""
             import unittest
index 24cab0f89ee7a3936e0dc3fa5c6080a136329b07..406684bdbec796e66e67db8ab035b60a7770c843 100644 (file)
@@ -1122,18 +1122,18 @@ class StressTest(unittest.TestCase):
         self.setsig(signal.SIGALRM, second_handler)  # for ITIMER_REAL
 
         expected_sigs = 0
-        deadline = time.time() + 15.0
+        deadline = time.monotonic() + 15.0
 
         while expected_sigs < N:
             os.kill(os.getpid(), signal.SIGPROF)
             expected_sigs += 1
             # Wait for handlers to run to avoid signal coalescing
-            while len(sigs) < expected_sigs and time.time() < deadline:
+            while len(sigs) < expected_sigs and time.monotonic() < deadline:
                 time.sleep(1e-5)
 
             os.kill(os.getpid(), signal.SIGUSR1)
             expected_sigs += 1
-            while len(sigs) < expected_sigs and time.time() < deadline:
+            while len(sigs) < expected_sigs and time.monotonic() < deadline:
                 time.sleep(1e-5)
 
         # All ITIMER_REAL signals should have been delivered to the
@@ -1156,7 +1156,7 @@ class StressTest(unittest.TestCase):
         self.setsig(signal.SIGALRM, handler)  # for ITIMER_REAL
 
         expected_sigs = 0
-        deadline = time.time() + 15.0
+        deadline = time.monotonic() + 15.0
 
         while expected_sigs < N:
             # Hopefully the SIGALRM will be received somewhere during
@@ -1166,7 +1166,7 @@ class StressTest(unittest.TestCase):
 
             expected_sigs += 2
             # Wait for handlers to run to avoid signal coalescing
-            while len(sigs) < expected_sigs and time.time() < deadline:
+            while len(sigs) < expected_sigs and time.monotonic() < deadline:
                 time.sleep(1e-5)
 
         # All ITIMER_REAL signals should have been delivered to the
index a30bd2f0067ff51158cd49ba33fe4605c0f90e82..655a12ddd1654c1acb11a7c5e64b6f02b819a9f2 100644 (file)
@@ -183,7 +183,9 @@ class HelperFunctionsTests(unittest.TestCase):
         finally:
             pth_file.cleanup()
 
-    def test_getuserbase(self):
+    # This tests _getuserbase, hence the double underline
+    # to distinguish from a test for getuserbase
+    def test__getuserbase(self):
         self.assertEqual(site._getuserbase(), sysconfig._getuserbase())
 
     def test_get_path(self):
index 9b9d11368cb7f64e1c0b216f0027080fdc2d1ce7..381965289615d5508d04c3c5c560f4aadeaf1350 100644 (file)
@@ -5533,7 +5533,7 @@ class SendfileUsingSendTest(ThreadedTCPSocketTest):
         support.unlink(support.TESTFN)
 
     def accept_conn(self):
-        self.serv.settimeout(self.TIMEOUT)
+        self.serv.settimeout(MAIN_TIMEOUT)
         conn, addr = self.serv.accept()
         conn.settimeout(self.TIMEOUT)
         self.addCleanup(conn.close)
@@ -5717,11 +5717,11 @@ class SendfileUsingSendTest(ThreadedTCPSocketTest):
 
     def _testWithTimeoutTriggeredSend(self):
         address = self.serv.getsockname()
-        file = open(support.TESTFN, 'rb')
-        with socket.create_connection(address, timeout=0.01) as sock, \
-                file as file:
-            meth = self.meth_from_sock(sock)
-            self.assertRaises(socket.timeout, meth, file)
+        with open(support.TESTFN, 'rb') as file:
+            with socket.create_connection(address) as sock:
+                sock.settimeout(0.01)
+                meth = self.meth_from_sock(sock)
+                self.assertRaises(socket.timeout, meth, file)
 
     def testWithTimeoutTriggeredSend(self):
         conn = self.accept_conn()
index f1b9565c8d91a52bf0d2b15bdb107b1fe3201640..8eab447415f79106814b1a87db70fd11828944ae 100644 (file)
@@ -34,6 +34,19 @@ IS_OPENSSL_1_1_0 = not IS_LIBRESSL and ssl.OPENSSL_VERSION_INFO >= (1, 1, 0)
 IS_OPENSSL_1_1_1 = not IS_LIBRESSL and ssl.OPENSSL_VERSION_INFO >= (1, 1, 1)
 PY_SSL_DEFAULT_CIPHERS = sysconfig.get_config_var('PY_SSL_DEFAULT_CIPHERS')
 
+PROTOCOL_TO_TLS_VERSION = {}
+for proto, ver in (
+    ("PROTOCOL_SSLv23", "SSLv3"),
+    ("PROTOCOL_TLSv1", "TLSv1"),
+    ("PROTOCOL_TLSv1_1", "TLSv1_1"),
+):
+    try:
+        proto = getattr(ssl, proto)
+        ver = getattr(ssl.TLSVersion, ver)
+    except AttributeError:
+        continue
+    PROTOCOL_TO_TLS_VERSION[proto] = ver
+
 def data_file(*name):
     return os.path.join(os.path.dirname(__file__), *name)
 
@@ -116,6 +129,7 @@ NONEXISTINGCERT = data_file("XXXnonexisting.pem")
 BADKEY = data_file("badkey.pem")
 NOKIACERT = data_file("nokia.pem")
 NULLBYTECERT = data_file("nullbytecert.pem")
+TALOS_INVALID_CRLDP = data_file("talos-2019-0758.pem")
 
 DHFILE = data_file("ffdh3072.pem")
 BYTES_DHFILE = os.fsencode(DHFILE)
@@ -365,6 +379,27 @@ class BasicSocketTests(unittest.TestCase):
         self.assertEqual(p['crlDistributionPoints'],
                          ('http://SVRIntl-G3-crl.verisign.com/SVRIntlG3.crl',))
 
+    def test_parse_cert_CVE_2019_5010(self):
+        p = ssl._ssl._test_decode_cert(TALOS_INVALID_CRLDP)
+        if support.verbose:
+            sys.stdout.write("\n" + pprint.pformat(p) + "\n")
+        self.assertEqual(
+            p,
+            {
+                'issuer': (
+                    (('countryName', 'UK'),), (('commonName', 'cody-ca'),)),
+                'notAfter': 'Jun 14 18:00:58 2028 GMT',
+                'notBefore': 'Jun 18 18:00:58 2018 GMT',
+                'serialNumber': '02',
+                'subject': ((('countryName', 'UK'),),
+                            (('commonName',
+                              'codenomicon-vm-2.test.lal.cisco.com'),)),
+                'subjectAltName': (
+                    ('DNS', 'codenomicon-vm-2.test.lal.cisco.com'),),
+                'version': 3
+            }
+        )
+
     def test_parse_cert_CVE_2013_4238(self):
         p = ssl._ssl._test_decode_cert(NULLBYTECERT)
         if support.verbose:
@@ -1086,8 +1121,15 @@ class ContextTests(unittest.TestCase):
                          "required OpenSSL 1.1.0g")
     def test_min_max_version(self):
         ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
-        self.assertEqual(
-            ctx.minimum_version, ssl.TLSVersion.MINIMUM_SUPPORTED
+        # OpenSSL default is MINIMUM_SUPPORTED, however some vendors like
+        # Fedora override the setting to TLS 1.0.
+        self.assertIn(
+            ctx.minimum_version,
+            {ssl.TLSVersion.MINIMUM_SUPPORTED,
+             # Fedora 29 uses TLS 1.0 by default
+             ssl.TLSVersion.TLSv1,
+             # RHEL 8 uses TLS 1.2 by default
+             ssl.TLSVersion.TLSv1_2}
         )
         self.assertEqual(
             ctx.maximum_version, ssl.TLSVersion.MAXIMUM_SUPPORTED
@@ -2605,6 +2647,17 @@ def try_protocol_combo(server_protocol, client_protocol, expect_success,
     server_context = ssl.SSLContext(server_protocol)
     server_context.options |= server_options
 
+    min_version = PROTOCOL_TO_TLS_VERSION.get(client_protocol, None)
+    if (min_version is not None
+    # SSLContext.minimum_version is only available on recent OpenSSL
+    # (setter added in OpenSSL 1.1.0, getter added in OpenSSL 1.1.1)
+    and hasattr(server_context, 'minimum_version')
+    and server_protocol == ssl.PROTOCOL_TLS
+    and server_context.minimum_version > min_version):
+        # If OpenSSL configuration is strict and requires more recent TLS
+        # version, we have to change the minimum to test old TLS versions.
+        server_context.minimum_version = min_version
+
     # NOTE: we must enable "ALL" ciphers on the client, otherwise an
     # SSLv23 client will send an SSLv3 hello (rather than SSLv2)
     # starting from OpenSSL 1.0.0 (see issue #8322).
index c1306f54327f4e10c213228355b59dc088ef7441..32564f3df214ca2295bf520058e841714abc13a0 100644 (file)
@@ -2,6 +2,7 @@ import unittest
 from test import support
 import os
 import sys
+import sysconfig
 import subprocess
 
 
@@ -35,8 +36,8 @@ class TestSymbolGeneration(unittest.TestCase):
             lines2 = fp.readlines()
         self.assertEqual(lines1, lines2)
 
-    @unittest.skipIf(not os.path.exists(GRAMMAR_FILE),
-                     'test only works from source build directory')
+    @unittest.skipUnless(sysconfig.is_python_build(),
+                         'test only works from source build directory')
     def test_real_grammar_and_symbol_file(self):
         output = support.TESTFN
         self.addCleanup(support.unlink, output)
index 7d2eec8a7ccfaa7a0d475e3461e775c8b02ca6eb..5e4d75ecfce1af384c47417343d3e3224389ee36 100644 (file)
@@ -973,16 +973,21 @@ class GNUReadTest(LongnameTest, ReadTest, unittest.TestCase):
     def _fs_supports_holes():
         # Return True if the platform knows the st_blocks stat attribute and
         # uses st_blocks units of 512 bytes, and if the filesystem is able to
-        # store holes in files.
+        # store holes of 4 KiB in files.
+        #
+        # The function returns False if page size is larger than 4 KiB.
+        # For example, ppc64 uses pages of 64 KiB.
         if sys.platform.startswith("linux"):
             # Linux evidentially has 512 byte st_blocks units.
             name = os.path.join(TEMPDIR, "sparse-test")
             with open(name, "wb") as fobj:
+                # Seek to "punch a hole" of 4 KiB
                 fobj.seek(4096)
+                fobj.write(b'x' * 4096)
                 fobj.truncate()
             s = os.stat(name)
             support.unlink(name)
-            return s.st_blocks == 0
+            return (s.st_blocks * 512 < s.st_size)
         else:
             return False
 
index 8160a5af0064475e7bab524c5e74d85d595b3204..27f328dbe63c298d5c2534d6ccb26deaecf0f0c8 100644 (file)
@@ -415,7 +415,8 @@ class ThreadTests(BaseTestCase):
         t.setDaemon(True)
         t.getName()
         t.setName("name")
-        t.isAlive()
+        with self.assertWarnsRegex(PendingDeprecationWarning, 'use is_alive()'):
+            t.isAlive()
         e = threading.Event()
         e.isSet()
         threading.activeCount()
index 984f8dda37438433b4ad17ca62d7a3f62f60ebf9..2fd14ae2e16f3d0b506237bb009e7d7f9c355b58 100644 (file)
@@ -1,3 +1,4 @@
+import sys
 import unittest
 from doctest import DocTestSuite
 from test import support
index 7e13b1720f91e9b890fe3e3df8295d0084b432fd..eeacd3698cb138c480ab935bbda74896ff6e4215 100644 (file)
@@ -95,9 +95,9 @@ class ThreadSignals(unittest.TestCase):
             lock = thread.allocate_lock()
             lock.acquire()
             signal.alarm(1)
-            t1 = time.time()
+            t1 = time.monotonic()
             self.assertRaises(KeyboardInterrupt, lock.acquire, timeout=5)
-            dt = time.time() - t1
+            dt = time.monotonic() - t1
             # Checking that KeyboardInterrupt was raised is not sufficient.
             # We want to assert that lock.acquire() was interrupted because
             # of the signal, not that the signal handler was called immediately
@@ -136,9 +136,9 @@ class ThreadSignals(unittest.TestCase):
                     rlock.release()
                     time.sleep(0.01)
                 signal.alarm(1)
-                t1 = time.time()
+                t1 = time.monotonic()
                 self.assertRaises(KeyboardInterrupt, rlock.acquire, timeout=5)
-                dt = time.time() - t1
+                dt = time.monotonic() - t1
                 # See rationale above in test_lock_acquire_interruption
                 self.assertLess(dt, 3.0)
         finally:
@@ -203,9 +203,9 @@ class ThreadSignals(unittest.TestCase):
         old_handler = signal.signal(signal.SIGUSR1, my_handler)
         try:
             def timed_acquire():
-                self.start = time.time()
+                self.start = time.monotonic()
                 lock.acquire(timeout=0.5)
-                self.end = time.time()
+                self.end = time.monotonic()
             def send_signals():
                 for _ in range(40):
                     time.sleep(0.02)
index 3c75dcc6f922cc12b4dd58989355f272273d1749..b54fc826ae0aa70c7875ca67e3f52cc43f14f1f4 100644 (file)
@@ -127,11 +127,11 @@ class TimeoutTestCase(unittest.TestCase):
         self.sock.settimeout(timeout)
         method = getattr(self.sock, method)
         for i in range(count):
-            t1 = time.time()
+            t1 = time.monotonic()
             try:
                 method(*args)
             except socket.timeout as e:
-                delta = time.time() - t1
+                delta = time.monotonic() - t1
                 break
         else:
             self.fail('socket.timeout was not raised')
index 3cc018c0cc2caa8c3125233fde2a4d314dc4e0d9..1aad9334074c5cc22af16414826d8db67292e0f5 100644 (file)
@@ -2676,6 +2676,12 @@ class CAPITest(unittest.TestCase):
         check_format('%.%s',
                      b'%.%s', b'abc')
 
+        # Issue #33817: empty strings
+        check_format('',
+                     b'')
+        check_format('',
+                     b'%s', b'')
+
     # Test PyUnicode_AsWideChar()
     @support.cpython_only
     def test_aswidechar(self):
index c292d74f84a93c12fadc03c99beb09d7c76f3b9f..2ac73b58d832064f8328d6d06eb90135056c7c59 100644 (file)
@@ -712,7 +712,7 @@ FF
 
         with self.assertRaises(urllib.error.ContentTooShortError):
             try:
-                urllib.request.urlretrieve('http://example.com/',
+                urllib.request.urlretrieve(support.TEST_HTTP_URL,
                                            reporthook=_reporthook)
             finally:
                 self.unfakehttp()
@@ -729,7 +729,7 @@ FF
 ''')
         with self.assertRaises(urllib.error.ContentTooShortError):
             try:
-                urllib.request.urlretrieve('http://example.com/')
+                urllib.request.urlretrieve(support.TEST_HTTP_URL)
             finally:
                 self.unfakehttp()
 
index 1aa64cbee1ca4b562dc78642522b4b32f1669939..0f43d71ea67b55078a547db02f9424190f545acf 100644 (file)
@@ -84,7 +84,7 @@ class CloseSocketTest(unittest.TestCase):
     def test_close(self):
         # calling .close() on urllib2's response objects should close the
         # underlying socket
-        url = "http://www.example.com/"
+        url = support.TEST_HTTP_URL
         with support.transient_internet(url):
             response = _urlopen_with_retry(url)
             sock = response.fp
@@ -173,7 +173,7 @@ class OtherNetworkTests(unittest.TestCase):
                     "http://www.pythontest.net/elsewhere/#frag")
 
     def test_custom_headers(self):
-        url = "http://www.example.com"
+        url = support.TEST_HTTP_URL
         with support.transient_internet(url):
             opener = urllib.request.build_opener()
             request = urllib.request.Request(url)
@@ -259,7 +259,7 @@ class OtherNetworkTests(unittest.TestCase):
 class TimeoutTest(unittest.TestCase):
     def test_http_basic(self):
         self.assertIsNone(socket.getdefaulttimeout())
-        url = "http://www.example.com"
+        url = support.TEST_HTTP_URL
         with support.transient_internet(url, timeout=None):
             u = _urlopen_with_retry(url)
             self.addCleanup(u.close)
@@ -267,7 +267,7 @@ class TimeoutTest(unittest.TestCase):
 
     def test_http_default_timeout(self):
         self.assertIsNone(socket.getdefaulttimeout())
-        url = "http://www.example.com"
+        url = support.TEST_HTTP_URL
         with support.transient_internet(url):
             socket.setdefaulttimeout(60)
             try:
@@ -279,7 +279,7 @@ class TimeoutTest(unittest.TestCase):
 
     def test_http_no_timeout(self):
         self.assertIsNone(socket.getdefaulttimeout())
-        url = "http://www.example.com"
+        url = support.TEST_HTTP_URL
         with support.transient_internet(url):
             socket.setdefaulttimeout(60)
             try:
@@ -290,7 +290,7 @@ class TimeoutTest(unittest.TestCase):
             self.assertIsNone(u.fp.raw._sock.gettimeout())
 
     def test_http_timeout(self):
-        url = "http://www.example.com"
+        url = support.TEST_HTTP_URL
         with support.transient_internet(url):
             u = _urlopen_with_retry(url, timeout=120)
             self.addCleanup(u.close)
index 4103b6c07505d53bd88db487508dba9f207d75a7..d394ceddd080e7d4ef696df397b3a5950fa1f644 100644 (file)
@@ -3,6 +3,7 @@ from test import support
 
 import contextlib
 import socket
+import urllib.parse
 import urllib.request
 import os
 import email.message
@@ -24,8 +25,9 @@ class URLTimeoutTest(unittest.TestCase):
         socket.setdefaulttimeout(None)
 
     def testURLread(self):
-        with support.transient_internet("www.example.com"):
-            f = urllib.request.urlopen("http://www.example.com/")
+        domain = urllib.parse.urlparse(support.TEST_HTTP_URL).netloc
+        with support.transient_internet(domain):
+            f = urllib.request.urlopen(support.TEST_HTTP_URL)
             f.read()
 
 
index be50b47603aa5b899d18584a64a77cc61bf6d855..e6638aee2244a86189e4d20252074ccdea5ccccf 100644 (file)
@@ -1,3 +1,5 @@
+import sys
+import unicodedata
 import unittest
 import urllib.parse
 
@@ -984,6 +986,27 @@ class UrlParseTestCase(unittest.TestCase):
                 expected.append(name)
         self.assertCountEqual(urllib.parse.__all__, expected)
 
+    def test_urlsplit_normalization(self):
+        # Certain characters should never occur in the netloc,
+        # including under normalization.
+        # Ensure that ALL of them are detected and cause an error
+        illegal_chars = '/:#?@'
+        hex_chars = {'{:04X}'.format(ord(c)) for c in illegal_chars}
+        denorm_chars = [
+            c for c in map(chr, range(128, sys.maxunicode))
+            if (hex_chars & set(unicodedata.decomposition(c).split()))
+            and c not in illegal_chars
+        ]
+        # Sanity check that we found at least one such character
+        self.assertIn('\u2100', denorm_chars)
+        self.assertIn('\uFF03', denorm_chars)
+
+        for scheme in ["http", "https", "ftp"]:
+            for c in denorm_chars:
+                url = "{}://netloc{}false.netloc/path".format(scheme, c)
+                with self.subTest(url=url, char='{:04X}'.format(ord(c))):
+                    with self.assertRaises(ValueError):
+                        urllib.parse.urlsplit(url)
 
 class Utility_Tests(unittest.TestCase):
     """Testcase to test the various utility functions in the urllib."""
index 1147205a3b533045107012847da9b834dcf49fea..c9f05e5b760d922cfaddf4a509d2fbc317b8b97f 100644 (file)
@@ -6,6 +6,8 @@ Nick Mathewson
 import unittest
 from test import support
 
+import os
+import stat
 import sys
 import uu
 import io
@@ -218,6 +220,23 @@ class UUFileTest(unittest.TestCase):
         with open(self.tmpin, 'rb') as f:
             self.assertRaises(uu.Error, uu.decode, f)
 
+    def test_decode_mode(self):
+        # Verify that decode() will set the given mode for the out_file
+        expected_mode = 0o444
+        with open(self.tmpin, 'wb') as f:
+            f.write(encodedtextwrapped(expected_mode, self.tmpout))
+
+        # make file writable again, so it can be removed (Windows only)
+        self.addCleanup(os.chmod, self.tmpout, expected_mode | stat.S_IWRITE)
+
+        with open(self.tmpin, 'rb') as f:
+            uu.decode(f)
+
+        self.assertEqual(
+            stat.S_IMODE(os.stat(self.tmpout).st_mode),
+            expected_mode
+        )
+
 
 if __name__=="__main__":
     unittest.main()
index 22a3b78852f8c093b6239db565f38ae3f25642dc..347544a67722780ad3f5fec48bb5449bf62c2257 100644 (file)
@@ -52,10 +52,7 @@ class BaseTest(unittest.TestCase):
             self.bindir = 'bin'
             self.lib = ('lib', 'python%d.%d' % sys.version_info[:2])
             self.include = 'include'
-        if sys.platform == 'darwin' and '__PYVENV_LAUNCHER__' in os.environ:
-            executable = os.environ['__PYVENV_LAUNCHER__']
-        else:
-            executable = sys.executable
+        executable = getattr(sys, '_base_executable', sys.executable)
         self.exe = os.path.split(executable)[-1]
 
     def tearDown(self):
@@ -100,11 +97,7 @@ class BasicTest(BaseTest):
         else:
             self.assertFalse(os.path.exists(p))
         data = self.get_text_file_contents('pyvenv.cfg')
-        if sys.platform == 'darwin' and ('__PYVENV_LAUNCHER__'
-                                         in os.environ):
-            executable =  os.environ['__PYVENV_LAUNCHER__']
-        else:
-            executable = sys.executable
+        executable = getattr(sys, '_base_executable', sys.executable)
         path = os.path.dirname(executable)
         self.assertIn('home = %s' % path, data)
         fn = self.get_env_file(self.bindir, self.exe)
@@ -243,7 +236,6 @@ class BasicTest(BaseTest):
             self.assertIn('include-system-site-packages = %s\n' % s, data)
 
     @unittest.skipUnless(can_symlink(), 'Needs symlinks')
-    @unittest.skipIf(os.name == 'nt', 'Symlinks are never used on Windows')
     def test_symlinking(self):
         """
         Test symlinking works as expected
@@ -306,6 +298,19 @@ class BasicTest(BaseTest):
         )
         self.assertEqual(out.strip(), '0')
 
+    def test_multiprocessing(self):
+        """
+        Test that the multiprocessing is able to spawn.
+        """
+        rmtree(self.env_dir)
+        self.run_with_capture(venv.create, self.env_dir)
+        envpy = os.path.join(os.path.realpath(self.env_dir),
+                             self.bindir, self.exe)
+        out, err = check_output([envpy, '-c',
+            'from multiprocessing import Pool; ' +
+            'print(Pool(1).apply_async("Python".lower).get(3))'])
+        self.assertEqual(out.strip(), "python".encode())
+
 @skipInVenv
 class EnsurePipTest(BaseTest):
     """Test venv module installation of pip."""
index a40a9a297c82eed87b38d9e0ed5cdb83a93aad5c..87cc3a7e36ae698bef42e74803c3997d96a6ccff 100644 (file)
@@ -940,6 +940,25 @@ class WarningsDisplayTests(BaseTest):
                                 file_object, expected_file_line)
         self.assertEqual(expect, file_object.getvalue())
 
+    def test_formatwarning_override(self):
+        # bpo-35178: Test that a custom formatwarning function gets the 'line'
+        # argument as a positional argument, and not only as a keyword argument
+        def myformatwarning(message, category, filename, lineno, text):
+            return f'm={message}:c={category}:f={filename}:l={lineno}:t={text}'
+
+        file_name = os.path.splitext(warning_tests.__file__)[0] + '.py'
+        line_num = 3
+        file_line = linecache.getline(file_name, line_num).strip()
+        message = 'msg'
+        category = Warning
+        file_object = StringIO()
+        expected = f'm={message}:c={category}:f={file_name}:l={line_num}' + \
+                   f':t={file_line}'
+        with support.swap_attr(self.module, 'formatwarning', myformatwarning):
+            self.module.showwarning(message, category, file_name, line_num,
+                                    file_object, file_line)
+            self.assertEqual(file_object.getvalue(), expected)
+
 
 class CWarningsDisplayTests(WarningsDisplayTests, unittest.TestCase):
     module = c_warnings
index 9fa0bbd7808766d487d0dbb242a6b9e3d4a20603..1fac08dafc7d980471da0290c46c804942448a2a 100644 (file)
@@ -8,6 +8,7 @@ import contextlib
 import copy
 import threading
 import time
+import random
 
 from test import support
 from test.support import script_helper
@@ -1688,6 +1689,87 @@ class MappingTestCase(TestBase):
                 self.assertEqual(len(d), 1)
                 o = None  # lose ref
 
+    def check_threaded_weak_dict_copy(self, type_, deepcopy):
+        # `type_` should be either WeakKeyDictionary or WeakValueDictionary.
+        # `deepcopy` should be either True or False.
+        exc = []
+
+        class DummyKey:
+            def __init__(self, ctr):
+                self.ctr = ctr
+
+        class DummyValue:
+            def __init__(self, ctr):
+                self.ctr = ctr
+
+        def dict_copy(d, exc):
+            try:
+                if deepcopy is True:
+                    _ = copy.deepcopy(d)
+                else:
+                    _ = d.copy()
+            except Exception as ex:
+                exc.append(ex)
+
+        def pop_and_collect(lst):
+            gc_ctr = 0
+            while lst:
+                i = random.randint(0, len(lst) - 1)
+                gc_ctr += 1
+                lst.pop(i)
+                if gc_ctr % 10000 == 0:
+                    gc.collect()  # just in case
+
+        self.assertIn(type_, (weakref.WeakKeyDictionary, weakref.WeakValueDictionary))
+
+        d = type_()
+        keys = []
+        values = []
+        # Initialize d with many entries
+        for i in range(70000):
+            k, v = DummyKey(i), DummyValue(i)
+            keys.append(k)
+            values.append(v)
+            d[k] = v
+            del k
+            del v
+
+        t_copy = threading.Thread(target=dict_copy, args=(d, exc,))
+        if type_ is weakref.WeakKeyDictionary:
+            t_collect = threading.Thread(target=pop_and_collect, args=(keys,))
+        else:  # weakref.WeakValueDictionary
+            t_collect = threading.Thread(target=pop_and_collect, args=(values,))
+
+        t_copy.start()
+        t_collect.start()
+
+        t_copy.join()
+        t_collect.join()
+
+        # Test exceptions
+        if exc:
+            raise exc[0]
+
+    def test_threaded_weak_key_dict_copy(self):
+        # Issue #35615: Weakref keys or values getting GC'ed during dict
+        # copying should not result in a crash.
+        self.check_threaded_weak_dict_copy(weakref.WeakKeyDictionary, False)
+
+    def test_threaded_weak_key_dict_deepcopy(self):
+        # Issue #35615: Weakref keys or values getting GC'ed during dict
+        # copying should not result in a crash.
+        self.check_threaded_weak_dict_copy(weakref.WeakKeyDictionary, True)
+
+    def test_threaded_weak_value_dict_copy(self):
+        # Issue #35615: Weakref keys or values getting GC'ed during dict
+        # copying should not result in a crash.
+        self.check_threaded_weak_dict_copy(weakref.WeakValueDictionary, False)
+
+    def test_threaded_weak_value_dict_deepcopy(self):
+        # Issue #35615: Weakref keys or values getting GC'ed during dict
+        # copying should not result in a crash.
+        self.check_threaded_weak_dict_copy(weakref.WeakValueDictionary, True)
+
 
 from test import mapping_tests
 
index e87de6094441e1333702d114b997ee5ecf537b24..2144d203e1e95ce1cc8716154c1ca76830546580 100644 (file)
@@ -1,4 +1,5 @@
 # xml.etree test for cElementTree
+import io
 import struct
 from test import support
 from test.support import import_fresh_module
@@ -133,6 +134,26 @@ class MiscTests(unittest.TestCase):
         self.assertEqual(len(elem), 1)
         self.assertEqual(elem[0].tag, 'child')
 
+    def test_iterparse_leaks(self):
+        # Test reference leaks in TreeBuilder (issue #35502).
+        # The test is written to be executed in the hunting reference leaks
+        # mode.
+        XML = '<a></a></b>'
+        parser = cET.iterparse(io.StringIO(XML))
+        next(parser)
+        del parser
+        support.gc_collect()
+
+    def test_xmlpullparser_leaks(self):
+        # Test reference leaks in TreeBuilder (issue #35502).
+        # The test is written to be executed in the hunting reference leaks
+        # mode.
+        XML = '<a></a></b>'
+        parser = cET.XMLPullParser()
+        parser.feed(XML)
+        del parser
+        support.gc_collect()
+
 
 @unittest.skipUnless(cET, 'requires _elementtree')
 class TestAliasWorking(unittest.TestCase):
index 5f780d88002e9ee912cdaeb9299ab630008b9cc7..32263f7f0b3b06ee8b096543762a974ce4702d5b 100644 (file)
@@ -818,11 +818,10 @@ class SimpleServerTestCase(BaseServerTestCase):
                 # protocol error; provide additional information in test output
                 self.fail("%s\n%s" % (e, getattr(e, "headers", "")))
 
-    # [ch] The test 404 is causing lots of false alarms.
-    def XXXtest_404(self):
+    def test_404(self):
         # send POST with http.client, it should return 404 header and
         # 'Not Found' message.
-        conn = httplib.client.HTTPConnection(ADDR, PORT)
+        conn = http.client.HTTPConnection(ADDR, PORT)
         conn.request('POST', '/this-is-not-valid')
         response = conn.getresponse()
         conn.close()
index cba909f6bce2772430b09643c4239440d3f44540..524dcf021324aa2509a736c9a31b0c9e3e3e3dae 100644 (file)
@@ -22,7 +22,7 @@ from test.support import TESTFN, requires_zlib
 TESTFN2 = TESTFN + "2"
 
 # How much time in seconds can pass before we print a 'Still working' message.
-_PRINT_WORKING_MSG_INTERVAL = 5 * 60
+_PRINT_WORKING_MSG_INTERVAL = 60
 
 class TestsWithSourceFile(unittest.TestCase):
     def setUp(self):
@@ -43,12 +43,12 @@ class TestsWithSourceFile(unittest.TestCase):
         # raw data to store.
         filecount = 6*1024**3 // len(self.data)
 
-        next_time = time.time() + _PRINT_WORKING_MSG_INTERVAL
+        next_time = time.monotonic() + _PRINT_WORKING_MSG_INTERVAL
         for num in range(filecount):
             zipfp.writestr("testfn%d" % num, self.data)
             # Print still working message since this test can be really slow
-            if next_time <= time.time():
-                next_time = time.time() + _PRINT_WORKING_MSG_INTERVAL
+            if next_time <= time.monotonic():
+                next_time = time.monotonic() + _PRINT_WORKING_MSG_INTERVAL
                 print((
                    '  zipTest still writing %d of %d, be patient...' %
                    (num, filecount)), file=sys.__stdout__)
@@ -60,8 +60,8 @@ class TestsWithSourceFile(unittest.TestCase):
         for num in range(filecount):
             self.assertEqual(zipfp.read("testfn%d" % num), self.data)
             # Print still working message since this test can be really slow
-            if next_time <= time.time():
-                next_time = time.time() + _PRINT_WORKING_MSG_INTERVAL
+            if next_time <= time.monotonic():
+                next_time = time.monotonic() + _PRINT_WORKING_MSG_INTERVAL
                 print((
                    '  zipTest still reading %d of %d, be patient...' %
                    (num, filecount)), file=sys.__stdout__)
index 2585ecb7820711daf1eb97b4a7dfc4d13bacb517..55ebac62912fe1dd744fe58bdfca0617c8e1fdac 100644 (file)
@@ -14,26 +14,26 @@ def test_scaled_msg(scale, name):
     longStr = b'Z'*scale
 
     localCF = creatorFunc
-    start = time.time()
+    start = time.perf_counter()
     for f in range(iterations):
         x = localCF(longStr).digest()
-    end = time.time()
+    end = time.perf_counter()
 
     print(('%2.2f' % (end-start)), "seconds", iterations, "x", len(longStr), "bytes", name)
 
 def test_create():
-    start = time.time()
+    start = time.perf_counter()
     for f in range(20000):
         d = creatorFunc()
-    end = time.time()
+    end = time.perf_counter()
 
     print(('%2.2f' % (end-start)), "seconds", '[20000 creations]')
 
 def test_zero():
-    start = time.time()
+    start = time.perf_counter()
     for f in range(20000):
         x = creatorFunc().digest()
-    end = time.time()
+    end = time.perf_counter()
 
     print(('%2.2f' % (end-start)), "seconds", '[20000 "" digests]')
 
index bb41456fb1410c228fff19667f5351c04304eb22..318b3301126ac26439987daa60d5777bfe24a902 100644 (file)
@@ -568,8 +568,8 @@ class Barrier:
     """Implements a Barrier.
 
     Useful for synchronizing a fixed number of threads at known synchronization
-    points.  Threads block on 'wait()' and are simultaneously once they have all
-    made that call.
+    points.  Threads block on 'wait()' and are simultaneously awoken once they
+    have all made that call.
 
     """
 
@@ -578,7 +578,7 @@ class Barrier:
 
         'action' is a callable which, when supplied, will be called by one of
         the threads after they have all entered the barrier and just prior to
-        releasing them all. If a 'timeout' is provided, it is uses as the
+        releasing them all. If a 'timeout' is provided, it is used as the
         default for all subsequent 'wait()' calls.
 
         """
@@ -1007,7 +1007,7 @@ class Thread:
         When the timeout argument is present and not None, it should be a
         floating point number specifying a timeout for the operation in seconds
         (or fractions thereof). As join() always returns None, you must call
-        isAlive() after join() to decide whether a timeout happened -- if the
+        is_alive() after join() to decide whether a timeout happened -- if the
         thread is still alive, the join() call timed out.
 
         When the timeout argument is not present or None, the operation will
@@ -1091,7 +1091,15 @@ class Thread:
         self._wait_for_tstate_lock(False)
         return not self._is_stopped
 
-    isAlive = is_alive
+    def isAlive(self):
+        """Return whether the thread is alive.
+
+        This method is deprecated, use is_alive() instead.
+        """
+        import warnings
+        warnings.warn('isAlive() is deprecated, use is_alive() instead',
+                      PendingDeprecationWarning, stacklevel=2)
+        return self.is_alive()
 
     @property
     def daemon(self):
index 06e3dfe70d5dc37d0f39929d729bc3622bbaa5cb..ba9e3b54f78e73c666b382a48883c41351f2f79e 100644 (file)
@@ -329,7 +329,12 @@ class EntryTest(AbstractWidgetTest, unittest.TestCase):
         self.entry.wait_visibility()
         self.entry.update_idletasks()
 
-        self.assertEqual(self.entry.identify(5, 5), "textarea")
+        # bpo-27313: macOS Cocoa widget differs from X, allow either
+        if sys.platform == 'darwin':
+            self.assertIn(self.entry.identify(5, 5),
+                ("textarea", "Combobox.button") )
+        else:
+            self.assertEqual(self.entry.identify(5, 5), "textarea")
         self.assertEqual(self.entry.identify(-1, -1), "")
 
         self.assertRaises(tkinter.TclError, self.entry.identify, None, 5)
index ce4652f37189763dbce5b3946d53b45d4e076493..2e0513ca1582d4d2150ef63d30d41e7fd7a0c2aa 100644 (file)
@@ -55,7 +55,7 @@ except TypeError:
 GetSetDescriptorType = type(FunctionType.__code__)
 MemberDescriptorType = type(FunctionType.__globals__)
 
-del sys, _f, _g, _C, _c,                           # Not for export
+del sys, _f, _g, _C, _c, _ag  # Not for export
 
 
 # Provide a PEP 3115 compliant mechanism for class creation
index d936a96e73fbc77a8e0e9108ce898010aae3aa6d..ba7105e1ad6039ffbd3f9ea61566d1e6e204954d 100644 (file)
@@ -229,7 +229,9 @@ class TestLoader(object):
             testFunc = getattr(testCaseClass, attrname)
             if not callable(testFunc):
                 return False
-            fullName = '%s.%s' % (testCaseClass.__module__, testFunc.__qualname__)
+            fullName = f'%s.%s.%s' % (
+                testCaseClass.__module__, testCaseClass.__qualname__, attrname
+            )
             return self.testNamePatterns is None or \
                 any(fnmatchcase(fullName, pattern) for pattern in self.testNamePatterns)
         testFnNames = list(filter(shouldIncludeMethod, dir(testCaseClass)))
index f641e38dc54bea132117cfe15d431775bd08060a..5b8e7441403538ca49bb17f7d63342666d888f9b 100644 (file)
@@ -102,6 +102,7 @@ def _check_signature(func, mock, skipfirst, instance=False):
         sig.bind(*args, **kwargs)
     _copy_func_details(func, checksig)
     type(mock)._mock_check_sig = checksig
+    type(mock).__signature__ = sig
 
 
 def _copy_func_details(func, funcopy):
@@ -171,11 +172,11 @@ def _set_signature(mock, original, instance=False):
     return mock(*args, **kwargs)""" % name
     exec (src, context)
     funcopy = context[name]
-    _setup_func(funcopy, mock)
+    _setup_func(funcopy, mock, sig)
     return funcopy
 
 
-def _setup_func(funcopy, mock):
+def _setup_func(funcopy, mock, sig):
     funcopy.mock = mock
 
     # can't use isinstance with mocks
@@ -223,6 +224,7 @@ def _setup_func(funcopy, mock):
     funcopy.assert_called = assert_called
     funcopy.assert_not_called = assert_not_called
     funcopy.assert_called_once = assert_called_once
+    funcopy.__signature__ = sig
 
     mock._mock_delegate = funcopy
 
@@ -318,6 +320,14 @@ class _CallList(list):
 
 
 def _check_and_set_parent(parent, value, name, new_name):
+    # function passed to create_autospec will have mock
+    # attribute attached to which parent must be set
+    if isinstance(value, FunctionTypes):
+        try:
+            value = value.mock
+        except AttributeError:
+            pass
+
     if not _is_instance_mock(value):
         return False
     if ((value._mock_name or value._mock_new_name) or
@@ -726,11 +736,10 @@ class NonCallableMock(Base):
                 # not set on the instance itself
                 return
 
-        if name in self.__dict__:
-            object.__delattr__(self, name)
-
         obj = self._mock_children.get(name, _missing)
-        if obj is _deleted:
+        if name in self.__dict__:
+            super().__delattr__(name)
+        elif obj is _deleted:
             raise AttributeError(name)
         if obj is not _missing:
             del self._mock_children[name]
@@ -1594,8 +1603,6 @@ class _patch_dict(object):
     """
 
     def __init__(self, in_dict, values=(), clear=False, **kwargs):
-        if isinstance(in_dict, str):
-            in_dict = _importer(in_dict)
         self.in_dict = in_dict
         # support any argument supported by dict(...) constructor
         self.values = dict(values)
@@ -1636,6 +1643,8 @@ class _patch_dict(object):
 
     def _patch_dict(self):
         values = self.values
+        if isinstance(self.in_dict, str):
+            self.in_dict = _importer(self.in_dict)
         in_dict = self.in_dict
         clear = self.clear
 
@@ -2350,7 +2359,7 @@ def mock_open(mock=None, read_data=''):
     default) then a `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 `read` methoddline`, and `readlines` of the
+    `read_data` is a string for the `read`, `readline` and `readlines` of the
     file handle to return.  This is an empty string by default.
     """
     def _readlines_side_effect(*args, **kwargs):
index 2c5ea4ab079d7e9d5ab8497933d2c4d416a965af..45e7e4c0458d4c86c29dab650b45c65317ffa7b0 100644 (file)
@@ -168,7 +168,7 @@ class TextTestRunner(object):
                     warnings.filterwarnings('module',
                             category=DeprecationWarning,
                             message=r'Please use assert\w+ instead.')
-            startTime = time.time()
+            startTime = time.perf_counter()
             startTestRun = getattr(result, 'startTestRun', None)
             if startTestRun is not None:
                 startTestRun()
@@ -178,7 +178,7 @@ class TextTestRunner(object):
                 stopTestRun = getattr(result, 'stopTestRun', None)
                 if stopTestRun is not None:
                     stopTestRun()
-            stopTime = time.time()
+            stopTime = time.perf_counter()
         timeTaken = stopTime - startTime
         result.printErrors()
         if hasattr(result, 'separator2'):
index bfd722940b5683f2990bcba38ad5740ae93429b2..bc54bf0553528d0ab239515cabb06b42a19a269c 100644 (file)
@@ -1,3 +1,4 @@
+import functools
 import sys
 import types
 import warnings
@@ -1575,5 +1576,20 @@ class Test_TestLoader(unittest.TestCase):
         self.assertIs(loader.suiteClass, unittest.TestSuite)
 
 
+    def test_partial_functions(self):
+        def noop(arg):
+            pass
+
+        class Foo(unittest.TestCase):
+            pass
+
+        setattr(Foo, 'test_partial', functools.partial(noop, None))
+
+        loader = unittest.TestLoader()
+
+        test_names = ['test_partial']
+        self.assertEqual(loader.getTestCaseNames(Foo), test_names)
+
+
 if __name__ == "__main__":
     unittest.main()
index 205431adcacc8919e0b01f9544d22034a1296064..73e406f0a86fd19645a00b9aca980c168bec4dd9 100644 (file)
@@ -1,3 +1,6 @@
+target = {'foo': 'FOO'}
+
+
 def is_instance(obj, klass):
     """Version of is_instance that doesn't access __class__"""
     return issubclass(type(obj), klass)
index 9388311e3e2517fd9c00df60c54e9f986597a252..745580ef79db9073008637a0096b72a593828033 100644 (file)
@@ -1,3 +1,4 @@
+import inspect
 import time
 import types
 import unittest
@@ -901,6 +902,35 @@ class SpecSignatureTest(unittest.TestCase):
         self.assertFalse(hasattr(autospec, '__name__'))
 
 
+    def test_spec_inspect_signature(self):
+
+        def myfunc(x, y):
+            pass
+
+        mock = create_autospec(myfunc)
+        mock(1, 2)
+        mock(x=1, y=2)
+
+        self.assertEqual(inspect.getfullargspec(mock), inspect.getfullargspec(myfunc))
+        self.assertEqual(mock.mock_calls, [call(1, 2), call(x=1, y=2)])
+        self.assertRaises(TypeError, mock, 1)
+
+
+    def test_spec_inspect_signature_annotations(self):
+
+        def foo(a: int, b: int=10, *, c:int) -> int:
+            return a + b + c
+
+        mock = create_autospec(foo)
+        mock(1, 2, c=3)
+        mock(1, c=3)
+
+        self.assertEqual(inspect.getfullargspec(mock), inspect.getfullargspec(foo))
+        self.assertEqual(mock.mock_calls, [call(1, 2, c=3), call(1, c=3)])
+        self.assertRaises(TypeError, mock, 1)
+        self.assertRaises(TypeError, mock, 1, 2, 3, c=4)
+
+
 class TestCallList(unittest.TestCase):
 
     def test_args_list_contains_call_list(self):
index 49ecbb446629c523373020aa4ec59b089cc10b88..447a502b57d6eb5845b50293cfc9c886016d9e18 100644 (file)
@@ -1739,6 +1739,33 @@ class MockTest(unittest.TestCase):
             self.assertRaises(AttributeError, getattr, mock, 'f')
 
 
+    def test_mock_does_not_raise_on_repeated_attribute_deletion(self):
+        # bpo-20239: Assigning and deleting twice an attribute raises.
+        for mock in (Mock(), MagicMock(), NonCallableMagicMock(),
+                     NonCallableMock()):
+            mock.foo = 3
+            self.assertTrue(hasattr(mock, 'foo'))
+            self.assertEqual(mock.foo, 3)
+
+            del mock.foo
+            self.assertFalse(hasattr(mock, 'foo'))
+
+            mock.foo = 4
+            self.assertTrue(hasattr(mock, 'foo'))
+            self.assertEqual(mock.foo, 4)
+
+            del mock.foo
+            self.assertFalse(hasattr(mock, 'foo'))
+
+
+    def test_mock_raises_when_deleting_nonexistent_attribute(self):
+        for mock in (Mock(), MagicMock(), NonCallableMagicMock(),
+                     NonCallableMock()):
+            del mock.foo
+            with self.assertRaises(AttributeError):
+                del mock.foo
+
+
     def test_reset_mock_does_not_raise_on_attr_deletion(self):
         # bpo-31177: reset_mock should not raise AttributeError when attributes
         # were deleted in a mock instance
@@ -1772,5 +1799,18 @@ class MockTest(unittest.TestCase):
         self.assertEqual(type(call.parent().parent), _Call)
 
 
+    def test_parent_propagation_with_create_autospec(self):
+
+        def foo(a, b):
+            pass
+
+        mock = Mock()
+        mock.child = create_autospec(foo)
+        mock.child(1, 2)
+
+        self.assertRaises(TypeError, mock.child, 1)
+        self.assertEqual(mock.mock_calls, [call.child(1, 2)])
+
+
 if __name__ == '__main__':
     unittest.main()
index f05225730dafb29e8b4264e3750cd40211b72647..c484adb605086a576b4bc84f802d0d9dddde540d 100644 (file)
@@ -664,6 +664,23 @@ class PatchTest(unittest.TestCase):
         test()
 
 
+    def test_patch_dict_decorator_resolution(self):
+        # bpo-35512: Ensure that patch with a string target resolves to
+        # the new dictionary during function call
+        original = support.target.copy()
+
+        @patch.dict('unittest.test.testmock.support.target', {'bar': 'BAR'})
+        def test():
+            self.assertEqual(support.target, {'foo': 'BAZ', 'bar': 'BAR'})
+
+        try:
+            support.target = {'foo': 'BAZ'}
+            test()
+            self.assertEqual(support.target, {'foo': 'BAZ'})
+        finally:
+            support.target = original
+
+
     def test_patch_descriptor(self):
         # would be some effort to fix this - we could special case the
         # builtin descriptors: classmethod, property, staticmethod
index 43b36a1199526122d2e252385fb35bac827f23a7..ec4e540dcfd941fe855d0b526a52fae24f88d53a 100644 (file)
@@ -126,6 +126,20 @@ class WithTest(unittest.TestCase):
 
         self.assertEqual(foo, {})
 
+    def test_double_patch_instance_method(self):
+        class C:
+            def f(self):
+                pass
+
+        c = C()
+
+        with patch.object(c, 'f', autospec=True) as patch1:
+            with patch.object(c, 'f', autospec=True) as patch2:
+                c.f()
+            self.assertEqual(patch2.call_count, 1)
+            self.assertEqual(patch1.call_count, 0)
+            c.f()
+        self.assertEqual(patch1.call_count, 1)
 
 
 class TestMockOpen(unittest.TestCase):
index f691ab74f87f7313f7886ade2357fa3ef02b21cc..39c5d6a808248e4fbf6573b2b2dea9e36b644a56 100644 (file)
@@ -391,6 +391,21 @@ def _splitnetloc(url, start=0):
             delim = min(delim, wdelim)     # use earliest delim position
     return url[start:delim], url[delim:]   # return (domain, rest)
 
+def _checknetloc(netloc):
+    if not netloc or netloc.isascii():
+        return
+    # looking for characters like \u2100 that expand to 'a/c'
+    # IDNA uses NFKC equivalence, so normalize for this check
+    import unicodedata
+    netloc2 = unicodedata.normalize('NFKC', netloc)
+    if netloc == netloc2:
+        return
+    _, _, netloc = netloc.rpartition('@') # anything to the left of '@' is okay
+    for c in '/?#@:':
+        if c in netloc2:
+            raise ValueError("netloc '" + netloc2 + "' contains invalid " +
+                             "characters under NFKC normalization")
+
 def urlsplit(url, scheme='', allow_fragments=True):
     """Parse a URL into 5 components:
     <scheme>://<netloc>/<path>?<query>#<fragment>
@@ -419,6 +434,7 @@ def urlsplit(url, scheme='', allow_fragments=True):
                 url, fragment = url.split('#', 1)
             if '?' in url:
                 url, query = url.split('?', 1)
+            _checknetloc(netloc)
             v = SplitResult('http', netloc, url, query, fragment)
             _parse_cache[key] = v
             return _coerce_result(v)
@@ -442,6 +458,7 @@ def urlsplit(url, scheme='', allow_fragments=True):
         url, fragment = url.split('#', 1)
     if '?' in url:
         url, query = url.split('?', 1)
+    _checknetloc(netloc)
     v = SplitResult(scheme, netloc, url, query, fragment)
     _parse_cache[key] = v
     return _coerce_result(v)
index 8333e864d8f95df6df1a8197b9fac2dd863ef5c0..9b1e5e607207f789deec21efa1a19fb8a5f7a788 100755 (executable)
--- a/Lib/uu.py
+++ b/Lib/uu.py
@@ -133,10 +133,7 @@ def decode(in_file, out_file=None, mode=None, quiet=False):
             out_file = sys.stdout.buffer
         elif isinstance(out_file, str):
             fp = open(out_file, 'wb')
-            try:
-                os.path.chmod(out_file, mode)
-            except AttributeError:
-                pass
+            os.chmod(out_file, mode)
             out_file = fp
             opened_files.append(out_file)
         #
index 5438b0d4e5082a665e24065b6b1c440634a31f2f..d5ab38958bb2f112af7977dad7d5519160866de1 100644 (file)
@@ -64,11 +64,10 @@ class EnvBuilder:
         self.system_site_packages = False
         self.create_configuration(context)
         self.setup_python(context)
-        if not self.upgrade:
-            self.setup_scripts(context)
         if self.with_pip:
             self._setup_pip(context)
         if not self.upgrade:
+            self.setup_scripts(context)
             self.post_setup(context)
         if true_system_site_packages:
             # We had set it to False before, now
@@ -107,10 +106,7 @@ class EnvBuilder:
         context.prompt = '(%s) ' % prompt
         create_if_needed(env_dir)
         env = os.environ
-        if sys.platform == 'darwin' and '__PYVENV_LAUNCHER__' in env:
-            executable = os.environ['__PYVENV_LAUNCHER__']
-        else:
-            executable = sys.executable
+        executable = getattr(sys, '_base_executable', sys.executable)
         dirname, exename = os.path.split(os.path.abspath(executable))
         context.executable = executable
         context.python_dir = dirname
@@ -176,6 +172,23 @@ class EnvBuilder:
                 logger.warning('Unable to symlink %r to %r', src, dst)
                 force_copy = True
         if force_copy:
+            if os.name == 'nt':
+                # On Windows, we rewrite symlinks to our base python.exe into
+                # copies of venvlauncher.exe
+                basename, ext = os.path.splitext(os.path.basename(src))
+                if basename.endswith('_d'):
+                    ext = '_d' + ext
+                    basename = basename[:-2]
+                if sysconfig.is_python_build(True):
+                    if basename == 'python':
+                        basename = 'venvlauncher'
+                    elif basename == 'pythonw':
+                        basename = 'venvwlauncher'
+                    scripts = os.path.dirname(src)
+                else:
+                    scripts = os.path.join(os.path.dirname(__file__), "scripts", "nt")
+                src = os.path.join(scripts, basename + ext)
+
             shutil.copyfile(src, dst)
 
     def setup_python(self, context):
@@ -202,23 +215,31 @@ class EnvBuilder:
                     if not os.path.islink(path):
                         os.chmod(path, 0o755)
         else:
-            # For normal cases, the venvlauncher will be copied from
-            # our scripts folder. For builds, we need to copy it
-            # manually.
-            if sysconfig.is_python_build(True):
-                suffix = '.exe'
-                if context.python_exe.lower().endswith('_d.exe'):
-                    suffix = '_d.exe'
-
-                src = os.path.join(dirname, "venvlauncher" + suffix)
-                dst = os.path.join(binpath, context.python_exe)
-                copier(src, dst)
+            if self.symlinks:
+                # For symlinking, we need a complete copy of the root directory
+                # If symlinks fail, you'll get unnecessary copies of files, but
+                # we assume that if you've opted into symlinks on Windows then
+                # you know what you're doing.
+                suffixes = [
+                    f for f in os.listdir(dirname) if
+                    os.path.normcase(os.path.splitext(f)[1]) in ('.exe', '.dll')
+                ]
+                if sysconfig.is_python_build(True):
+                    suffixes = [
+                        f for f in suffixes if
+                        os.path.normcase(f).startswith(('python', 'vcruntime'))
+                    ]
+            else:
+                suffixes = ['python.exe', 'python_d.exe', 'pythonw.exe',
+                            'pythonw_d.exe']
 
-                src = os.path.join(dirname, "venvwlauncher" + suffix)
-                dst = os.path.join(binpath, "pythonw" + suffix)
-                copier(src, dst)
+            for suffix in suffixes:
+                src = os.path.join(dirname, suffix)
+                if os.path.exists(src):
+                    copier(src, os.path.join(binpath, suffix))
 
-                # copy init.tcl over
+            if sysconfig.is_python_build(True):
+                # copy init.tcl
                 for root, dirs, files in os.walk(context.python_dir):
                     if 'init.tcl' in files:
                         tcldir = os.path.basename(root)
@@ -304,6 +325,9 @@ class EnvBuilder:
                         dirs.remove(d)
                 continue # ignore files in top level
             for f in files:
+                if (os.name == 'nt' and f.startswith('python')
+                        and f.endswith(('.exe', '.pdb'))):
+                    continue
                 srcfile = os.path.join(root, f)
                 suffix = root[plen:].split(os.sep)[2:]
                 if not suffix:
index ae4295e120f69fea805b4de8aac33e950d649ee5..9064f56827df3d22787fa583a0a3daf762ddc724 100644 (file)
@@ -124,7 +124,7 @@ def _formatwarnmsg(msg):
         if fw is not _formatwarning_orig:
             # warnings.formatwarning() was replaced
             return fw(msg.message, msg.category,
-                      msg.filename, msg.lineno, line=msg.line)
+                      msg.filename, msg.lineno, msg.line)
     return _formatwarnmsg_impl(msg)
 
 def filterwarnings(action, message="", category=Warning, module="", lineno=0,
index 99de2eab741439a5aa220d1ef49117bcc9ff3fc0..753f07291e20e8411d5d768ef94eac720af0f8a1 100644 (file)
@@ -171,10 +171,11 @@ class WeakValueDictionary(_collections_abc.MutableMapping):
         if self._pending_removals:
             self._commit_removals()
         new = WeakValueDictionary()
-        for key, wr in self.data.items():
-            o = wr()
-            if o is not None:
-                new[key] = o
+        with _IterationGuard(self):
+            for key, wr in self.data.items():
+                o = wr()
+                if o is not None:
+                    new[key] = o
         return new
 
     __copy__ = copy
@@ -184,10 +185,11 @@ class WeakValueDictionary(_collections_abc.MutableMapping):
         if self._pending_removals:
             self._commit_removals()
         new = self.__class__()
-        for key, wr in self.data.items():
-            o = wr()
-            if o is not None:
-                new[deepcopy(key, memo)] = o
+        with _IterationGuard(self):
+            for key, wr in self.data.items():
+                o = wr()
+                if o is not None:
+                    new[deepcopy(key, memo)] = o
         return new
 
     def get(self, key, default=None):
@@ -408,10 +410,11 @@ class WeakKeyDictionary(_collections_abc.MutableMapping):
 
     def copy(self):
         new = WeakKeyDictionary()
-        for key, value in self.data.items():
-            o = key()
-            if o is not None:
-                new[o] = value
+        with _IterationGuard(self):
+            for key, value in self.data.items():
+                o = key()
+                if o is not None:
+                    new[o] = value
         return new
 
     __copy__ = copy
@@ -419,10 +422,11 @@ class WeakKeyDictionary(_collections_abc.MutableMapping):
     def __deepcopy__(self, memo):
         from copy import deepcopy
         new = self.__class__()
-        for key, value in self.data.items():
-            o = key()
-            if o is not None:
-                new[o] = deepcopy(value, memo)
+        with _IterationGuard(self):
+            for key, value in self.data.items():
+                o = key()
+                if o is not None:
+                    new[o] = deepcopy(value, memo)
         return new
 
     def get(self, key, default=None):
index 5d11bbb10e60895a0329e19e60aa18078c0432f6..2e3a61ec71d1838182204c3d2e8e62447a588aa7 100755 (executable)
@@ -227,9 +227,9 @@ def library_recipes():
     if internalTk():
         result.extend([
           dict(
-              name="Tcl 8.6.9",
-              url="ftp://ftp.tcl.tk/pub/tcl//tcl8_6/tcl8.6.9-src.tar.gz",
-              checksum='aa0a121d95a0e7b73a036f26028538d4',
+              name="Tcl 8.6.8",
+              url="ftp://ftp.tcl.tk/pub/tcl//tcl8_6/tcl8.6.8-src.tar.gz",
+              checksum='81656d3367af032e0ae6157eff134f89',
               buildDir="unix",
               configure_pre=[
                     '--enable-shared',
@@ -243,9 +243,12 @@ def library_recipes():
                   },
               ),
           dict(
-              name="Tk 8.6.9.1",
-              url="ftp://ftp.tcl.tk/pub/tcl//tcl8_6/tk8.6.9.1-src.tar.gz",
-              checksum='9efe3976468352dc894dae0c4e785a8e',
+              name="Tk 8.6.8",
+              url="ftp://ftp.tcl.tk/pub/tcl//tcl8_6/tk8.6.8-src.tar.gz",
+              checksum='5e0faecba458ee1386078fb228d008ba',
+              patches=[
+                  "tk868_on_10_8_10_9.patch",
+                   ],
               buildDir="unix",
               configure_pre=[
                     '--enable-aqua',
@@ -706,7 +709,6 @@ def extractArchive(builddir, archiveName):
     work for current Tcl and Tk source releases where the basename of
     the archive ends with "-src" but the uncompressed directory does not.
     For now, just special case Tcl and Tk tar.gz downloads.
-    Another special case: the tk8.6.9.1 tarball extracts to tk8.6.9.
     """
     curdir = os.getcwd()
     try:
@@ -716,8 +718,6 @@ def extractArchive(builddir, archiveName):
             if ((retval.startswith('tcl') or retval.startswith('tk'))
                     and retval.endswith('-src')):
                 retval = retval[:-4]
-                if retval == 'tk8.6.9.1':
-                    retval = 'tk8.6.9'
             if os.path.exists(retval):
                 shutil.rmtree(retval)
             fp = os.popen("tar zxf %s 2>&1"%(shellQuote(archiveName),), 'r')
diff --git a/Mac/BuildScript/tk868_on_10_8_10_9.patch b/Mac/BuildScript/tk868_on_10_8_10_9.patch
new file mode 100644 (file)
index 0000000..8fe1060
--- /dev/null
@@ -0,0 +1,18 @@
+Fix build failure with +quartz variant on OS X 10.8 and 10.9.
+Even though Gestalt was deprecated in OS X 10.8, it should work fine
+through OS X 10.9, and its replacement NSOperatingSystemVersion was
+not introduced until OS X 10.10.
+
+Patch from MacPorts project and reported upstream:
+https://trac.macports.org/ticket/55649
+--- tk8.6.8/macosx/tkMacOSXXStubs.c.orig       2017-12-06 09:25:08.000000000 -0600
++++ tk8.6.8-patched/macosx/tkMacOSXXStubs.c    2018-01-06 19:34:17.000000000 -0600
+@@ -175,7 +175,7 @@
+     {
+       int major, minor, patch;
+-#if MAC_OS_X_VERSION_MIN_REQUIRED < 1080
++#if MAC_OS_X_VERSION_MIN_REQUIRED < 101000
+       Gestalt(gestaltSystemVersionMajor, (SInt32*)&major);
+       Gestalt(gestaltSystemVersionMinor, (SInt32*)&minor);
+       Gestalt(gestaltSystemVersionBugFix, (SInt32*)&patch);
index 826d3793f75a1b98e894a8dcb9d42fb7c5ca3f66..04a0a08c836395ddeeed0858c147af61fc29cc6d 100644 (file)
@@ -36,7 +36,7 @@
        <key>CFBundleExecutable</key>
        <string>IDLE</string>
        <key>CFBundleGetInfoString</key>
-       <string>%version%, © 2001-2018 Python Software Foundation</string>
+       <string>%version%, © 2001-2019 Python Software Foundation</string>
        <key>CFBundleIconFile</key>
        <string>IDLE.icns</string>
        <key>CFBundleIdentifier</key>
index 5fa346ed4d3d5ce6dd1ebff68497b809150ece48..9fb4e0affd9c43288af7a0403ab3dbba8715e0a7 100644 (file)
@@ -40,7 +40,7 @@
        <key>CFBundleExecutable</key>
        <string>Python Launcher</string>
        <key>CFBundleGetInfoString</key>
-       <string>%VERSION%, © 2001-2018 Python Software Foundation</string>
+       <string>%VERSION%, © 2001-2019 Python Software Foundation</string>
        <key>CFBundleIconFile</key>
        <string>PythonLauncher.icns</string>
        <key>CFBundleIdentifier</key>
index abe9ae23e341a766eb60a23f10c102781540534e..b7581984dd6764e5a86eb324d652ed185244de5c 100644 (file)
@@ -37,7 +37,7 @@
        <key>CFBundleInfoDictionaryVersion</key>
        <string>6.0</string>
        <key>CFBundleLongVersionString</key>
-       <string>%version%, (c) 2001-2018 Python Software Foundation.</string>
+       <string>%version%, (c) 2001-2019 Python Software Foundation.</string>
        <key>CFBundleName</key>
        <string>Python</string>
        <key>CFBundlePackageType</key>
index c1ea9f6889209b416fa552816832a5b1b668c72f..0dc2e17156f186377aaee09a87008c469ef9ff9c 100644 (file)
@@ -17,9 +17,9 @@
        <key>CFBundlePackageType</key>
        <string>FMWK</string>
        <key>CFBundleShortVersionString</key>
-       <string>%VERSION%, (c) 2001-2018 Python Software Foundation.</string>
+       <string>%VERSION%, (c) 2001-2019 Python Software Foundation.</string>
        <key>CFBundleLongVersionString</key>
-       <string>%VERSION%, (c) 2001-2018 Python Software Foundation.</string>
+       <string>%VERSION%, (c) 2001-2019 Python Software Foundation.</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
index c35ef1c0fa35b15e60e10253033e4cf2e6fed3f3..193592290f0e6234ea9d46c899e17e4e1c34886d 100644 (file)
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -60,6 +60,7 @@ Heidi Annexstad
 Ramchandra Apte
 Éric Araujo
 Alexandru Ardelean
+Emmanuel Arias
 Alicia Arlen
 Jeffrey Armstrong
 Jason Asbahr
@@ -894,6 +895,7 @@ Glenn Langford
 Andrew Langmead
 Wolfgang Langner
 Detlef Lannert
+Rémi Lapeyre
 Soren Larsen
 Amos Latteier
 Piers Lauder
@@ -1821,3 +1823,4 @@ Jelle Zijlstra
 Gennadiy Zlobin
 Doug Zongker
 Peter Åstrand
+Zheao Li
index bce9073bee53dccd6a12701991ff5c963f6a5d85..66cd43897c67c94682586d23c336170e0043f5c1 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -2,6 +2,443 @@
 Python News
 +++++++++++
 
+What's New in Python 3.7.3 final?
+=================================
+
+*Release date: 2019-03-25*
+
+There were no new changes in version 3.7.3.
+
+
+
+What's New in Python 3.7.3 release candidate 1?
+===============================================
+
+*Release date: 2019-03-12*
+
+Security
+--------
+
+- bpo-36216: Changes urlsplit() to raise ValueError when the URL contains
+  characters that decompose under IDNA encoding (NFKC-normalization) into
+  characters that affect how the URL is parsed.
+
+- bpo-35746: [CVE-2019-5010] Fix a NULL pointer deref in ssl module. The
+  cert parser did not handle CRL distribution points with empty DP or URI
+  correctly. A malicious or buggy certificate can result into segfault.
+  Vulnerability (TALOS-2018-0758) reported by Colin Read and Nicolas Edet of
+  Cisco.
+
+- bpo-35121: Don't send cookies of domain A without Domain attribute to
+  domain B when domain A is a suffix match of domain B while using a
+  cookiejar with :class:`http.cookiejar.DefaultCookiePolicy` policy. Patch
+  by Karthikeyan Singaravelan.
+
+Core and Builtins
+-----------------
+
+- bpo-35942: The error message emitted when returning invalid types from
+  ``__fspath__`` in interfaces that allow passing :class:`~os.PathLike`
+  objects has been improved and now it does explain the origin of the error.
+
+- bpo-35992: Fix ``__class_getitem__()`` not being called on a class with a
+  custom non-subscriptable metaclass.
+
+- bpo-35991: Fix a potential double free in Modules/_randommodule.c.
+
+- bpo-35961: Fix a crash in slice_richcompare(): use strong references
+  rather than stolen references for the two temporary internal tuples.
+
+- bpo-31506: Clarify the errors reported when ``object.__new__`` and
+  ``object.__init__`` receive more than one argument. Contributed by Sanyam
+  Khurana.
+
+- bpo-35720: Fixed a minor memory leak in pymain_parse_cmdline_impl function
+  in Modules/main.c
+
+- bpo-35623: Fix a crash when sorting very long lists. Patch by Stephan
+  Hohe.
+
+- bpo-35214: clang Memory Sanitizer build instrumentation was added to work
+  around false positives from posix, socket, time, test_io, and
+  test_faulthandler.
+
+- bpo-35560: Fix an assertion error in :func:`format` in debug build for
+  floating point formatting with "n" format, zero padding and small width.
+  Release build is not impacted. Patch by Karthikeyan Singaravelan.
+
+- bpo-35552: Format characters ``%s`` and ``%V`` in
+  :c:func:`PyUnicode_FromFormat` and ``%s`` in :c:func:`PyBytes_FromFormat`
+  no longer read memory past the limit if *precision* is specified.
+
+- bpo-35504: Fix segfaults and :exc:`SystemError`\ s when deleting certain
+  attributes. Patch by Zackery Spytz.
+
+- bpo-33989: Fix a possible crash in :meth:`list.sort` when sorting objects
+  with ``ob_type->tp_richcompare == NULL``.  Patch by Zackery Spytz.
+
+Library
+-------
+
+- bpo-35931: The :mod:`pdb` ``debug`` command now gracefully handles all
+  exceptions.
+
+- bpo-36251: Fix format strings used for stderrprinter and re.Match reprs.
+  Patch by Stephan Hohe.
+
+- bpo-35807: Update ensurepip to install pip 19.0.3 and setuptools 40.8.0.
+
+- bpo-36179: Fix two unlikely reference leaks in _hashopenssl. The leaks
+  only occur in out-of-memory cases.
+
+- bpo-35178: Ensure custom :func:`warnings.formatwarning` function can
+  receive `line` as positional argument. Based on patch by Tashrif Billah.
+
+- bpo-36106: Resolve potential name clash with libm's sinpi(). Patch by
+  Dmitrii Pasechnik.
+
+- bpo-35512: :func:`unittest.mock.patch.dict` used as a decorator with
+  string target resolves the target during function call instead of during
+  decorator construction. Patch by Karthikeyan Singaravelan.
+
+- bpo-36091: Clean up reference to async generator in Lib/types. Patch by
+  Henry Chen.
+
+- bpo-35899: Enum has been fixed to correctly handle empty strings and
+  strings with non-Latin characters (ie. 'α', 'א') without crashing.
+  Original patch contributed by Maxwell. Assisted by Stéphane Wirtel.
+
+- bpo-35918: Removed broken ``has_key`` method from
+  multiprocessing.managers.SyncManager.dict. Contributed by Rémi Lapeyre.
+
+- bpo-35960: Fix :func:`dataclasses.field` throwing away empty mapping
+  objects passed as metadata.
+
+- bpo-35847: RISC-V needed the CTYPES_PASS_BY_REF_HACK.  Fixes ctypes
+  Structure test_pass_by_value.
+
+- bpo-35780: Fix lru_cache() errors arising in recursive, reentrant, or
+  multi-threaded code. These errors could result in orphan links and in the
+  cache being trapped in a state with fewer than the specified maximum
+  number of links. Fix handling of negative maxsize which should have been
+  treated as zero. Fix errors in toggling the "full" status flag. Fix
+  misordering of links when errors are encountered.  Sync-up the C code and
+  pure Python code for the space saving path in functions with a single
+  positional argument. In this common case, the space overhead of an lru
+  cache entry is reduced by almost half.  Fix counting of cache misses. In
+  error cases, the miss count was out of sync with the actual number of
+  times the underlying user function was called.
+
+- bpo-23846: :class:`asyncio.ProactorEventLoop` now catches and logs send
+  errors when the self-pipe is full.
+
+- bpo-34323: :mod:`asyncio`: Enhance ``IocpProactor.close()`` log: wait 1
+  second before the first log, then log every second. Log also the number of
+  seconds since ``close()`` was called.
+
+- bpo-34294: re module, fix wrong capturing groups in rare cases.
+  :func:`re.search`, :func:`re.findall`, :func:`re.sub` and other functions
+  that scan through string looking for a match, should reset capturing
+  groups between two match attempts. Patch by Ma Lin.
+
+- bpo-35717: Fix KeyError exception raised when using enums and compile.
+  Patch contributed by Rémi Lapeyre.
+
+- bpo-35699: Fixed detection of Visual Studio Build Tools 2017 in distutils
+
+- bpo-32710: Fix memory leaks in asyncio ProactorEventLoop on overlapped
+  operation failure.
+
+- bpo-32710: Fix a memory leak in asyncio in the ProactorEventLoop when
+  ``ReadFile()`` or ``WSASend()`` overlapped operation fail immediately:
+  release the internal buffer.
+
+- bpo-35682: Fix ``asyncio.ProactorEventLoop.sendfile()``: don't attempt to
+  set the result of an internal future if it's already done.
+
+- bpo-35283: Add a pending deprecated warning for the
+  :meth:`threading.Thread.isAlive` method. Patch by Dong-hee Na.
+
+- bpo-35643: Fixed a SyntaxWarning: invalid escape sequence in
+  Modules/_sha3/cleanup.py. Patch by Mickaël Schoentgen.
+
+- bpo-35615: :mod:`weakref`: Fix a RuntimeError when copying a
+  WeakKeyDictionary or a WeakValueDictionary, due to some keys or values
+  disappearing while iterating.
+
+- bpo-28503: The `crypt` module now internally uses the `crypt_r()` library
+  function instead of `crypt()` when available.
+
+- bpo-35121: Don't set cookie for a request when the request path is a
+  prefix match of the cookie's path attribute but doesn't end with "/".
+  Patch by Karthikeyan Singaravelan.
+
+- bpo-35585: Speed-up building enums by value, e.g. http.HTTPStatus(200).
+
+- bpo-21478: Calls to a child function created with
+  :func:`unittest.mock.create_autospec` should propagate to the parent.
+  Patch by Karthikeyan Singaravelan.
+
+- bpo-35513: :class:`~unittest.runner.TextTestRunner` of
+  :mod:`unittest.runner` now uses :func:`time.perf_counter` rather than
+  :func:`time.time` to measure the execution time of a test:
+  :func:`time.time` can go backwards, whereas :func:`time.perf_counter` is
+  monotonic.
+
+- bpo-35502: Fixed reference leaks in
+  :class:`xml.etree.ElementTree.TreeBuilder` in case of unfinished building
+  of the tree (in particular when an error was raised during parsing XML).
+
+- bpo-31446: Copy command line that was passed to CreateProcessW since this
+  function can change the content of the input buffer.
+
+- bpo-20239: Allow repeated assignment deletion of
+  :class:`unittest.mock.Mock` attributes. Patch by Pablo Galindo.
+
+- bpo-17185: Set ``__signature__`` on mock for :mod:`inspect` to get
+  signature. Patch by Karthikeyan Singaravelan.
+
+- bpo-10496: :func:`~distutils.utils.check_environ` of
+  :mod:`distutils.utils` now catches :exc:`KeyError` on calling
+  :func:`pwd.getpwuid`: don't create the ``HOME`` environment variable in
+  this case.
+
+- bpo-35066: Previously, calling the strftime() method on a datetime object
+  with a trailing '%' in the format string would result in an exception.
+  However, this only occured when the datetime C module was being used; the
+  python implementation did not match this behavior. Datetime is now PEP-399
+  compliant, and will not throw an exception on a trailing '%'.
+
+- bpo-24746: Avoid stripping trailing whitespace in doctest fancy diff.
+  Orignial patch by R. David Murray & Jairo Trad. Enhanced by Sanyam
+  Khurana.
+
+- bpo-35198: Fix C++ extension compilation on AIX
+
+- bpo-28441: On Cygwin and MinGW, ensure that ``sys.executable`` always
+  includes the full filename in the path, including the ``.exe`` suffix
+  (unless it is a symbolic link).
+
+- bpo-34572: Fix C implementation of pickle.loads to use importlib's locking
+  mechanisms, and thereby avoid using partially-loaded modules. Patch by Tim
+  Burgess.
+
+- bpo-33687: Fix the call to ``os.chmod()`` for ``uu.decode()`` if a mode is
+  given or decoded. Patch by Timo Furrer.
+
+- bpo-32146: Document the interaction between frozen executables and the
+  spawn and forkserver start methods in multiprocessing.
+
+Documentation
+-------------
+
+- bpo-36083: Fix formatting of --check-hash-based-pycs options in the
+  manpage Synopsis.
+
+- bpo-34764: Improve example of iter() with 2nd sentinel argument.
+
+- bpo-21314: A new entry was added to the Core Language Section of the
+  Programming FAQ, which explaines the usage of slash(/) in the signature of
+  a function. Patch by Lysandros Nikolaou
+
+- bpo-22062: Update documentation and docstrings for pathlib. Original patch
+  by Mike Short.
+
+Tests
+-----
+
+- bpo-36234: test_posix.PosixUidGidTests: add tests for invalid uid/gid type
+  (str). Initial patch written by David Malcolm.
+
+- bpo-29571: Fix ``test_re.test_locale_flag()``:  use
+  ``locale.getpreferredencoding()`` rather than ``locale.getlocale()`` to
+  get the locale encoding. With some locales, ``locale.getlocale()`` returns
+  the wrong encoding. On Windows, set temporarily the ``LC_CTYPE`` locale to
+  the user preferred encoding to ensure that it uses the ANSI code page, to
+  be consistent with ``locale.getpreferredencoding()``.
+
+- bpo-36123: Fix race condition in test_socket.
+
+- bpo-27313: Avoid test_ttk_guionly ComboboxTest failure with macOS Cocoa
+  Tk.
+
+- bpo-36019: Add test.support.TEST_HTTP_URL and replace references of
+  http://www.example.com by this new constant. Contributed by Stéphane
+  Wirtel.
+
+- bpo-36037: Fix test_ssl for strict OpenSSL configuration like RHEL8 strict
+  crypto policy. Use older TLS version for minimum TLS version of the server
+  SSL context if needed, to test TLS version older than default minimum TLS
+  version.
+
+- bpo-35505: Make test_imap4_host_default_value independent on whether the
+  local IMAP server is running.
+
+- bpo-35917: multiprocessing: provide unit tests for SyncManager and
+  SharedMemoryManager classes + all the shareable types which are supposed
+  to be supported by them.  (patch by Giampaolo Rodola)
+
+- bpo-35772: Fix sparse file tests of test_tarfile on ppc64 with the tmpfs
+  filesystem. Fix the function testing if the filesystem supports sparse
+  files: create a file which contains data and "holes", instead of creating
+  a file which contains no data. tmpfs effective block size is a page size
+  (tmpfs lives in the page cache). RHEL uses 64 KiB pages on aarch64, ppc64,
+  ppc64le, only s390x and x86_64 use 4 KiB pages, whereas the test punch
+  holes of 4 KiB.
+
+- bpo-35045: Make ssl tests less strict and also accept TLSv1 as system
+  default. The changes unbreaks test_min_max_version on Fedora 29.
+
+- bpo-31731: Fix a race condition in ``check_interrupted_write()`` of
+  test_io: create directly the thread with SIGALRM signal blocked, rather
+  than blocking the signal later from the thread. Previously, it was
+  possible that the thread gets the signal before the signal is blocked.
+
+- bpo-35424: Fix test_multiprocessing_main_handling: use
+  :class:`multiprocessing.Pool` with a context manager and then explicitly
+  join the pool.
+
+- bpo-35519: Rename :mod:`test.bisect` module to :mod:`test.bisect_cmd` to
+  avoid conflict with :mod:`bisect` module when running directly a test like
+  ``./python Lib/test/test_xmlrpc.py``.
+
+- bpo-35513: Replace :func:`time.time` with :func:`time.monotonic` in tests
+  to measure time delta.
+
+- bpo-34279: :func:`test.support.run_unittest` no longer raise
+  :exc:`TestDidNotRun` if the test result contains skipped tests. The
+  exception is now only raised if no test have been run and no test have
+  been skipped.
+
+- bpo-35412: Add testcase to ``test_future4``: check unicode literal.
+
+- bpo-26704: Added test demonstrating double-patching of an instance method.
+  Patch by Anthony Sottile.
+
+Build
+-----
+
+- bpo-34691: The _contextvars module is now built into the core Python
+  library on Windows.
+
+- bpo-35683: Improved Azure Pipelines build steps and now verifying layouts
+  correctly
+
+- bpo-35642: Remove asynciomodule.c from pythoncore.vcxproj
+
+- bpo-35550: Fix incorrect Solaris #ifdef checks to look for __sun && __SVR4
+  instead of sun when compiling.
+
+Windows
+-------
+
+- bpo-24643: Fix name collisions due to ``#define timezone _timezone`` in
+  PC/pyconfig.h.
+
+- bpo-35692: ``pathlib`` no longer raises when checking file and directory
+  existence on drives that are not ready
+
+- bpo-35872: Uses the base Python executable when invoking venv in a virtual
+  environment
+
+- bpo-35873: Prevents venv paths being inherited by child processes
+
+- bpo-35299: Fix sysconfig detection of the source directory and distutils
+  handling of pyconfig.h during PGO profiling
+
+- bpo-32560: The ``py`` launcher now forwards its ``STARTUPINFO`` structure
+  to child processes.
+
+- bpo-35854: Fix EnvBuilder and --symlinks in venv on Windows
+
+- bpo-35811: Avoid propagating venv settings when launching via py.exe
+
+- bpo-35797: Fix default executable used by the multiprocessing module
+
+- bpo-29734: Fix handle leaks in os.stat on Windows.
+
+- bpo-35596: Use unchecked PYCs for the embeddable distro to avoid zipimport
+  restrictions.
+
+- bpo-35596: Fix vcruntime140.dll being added to embeddable distro multiple
+  times.
+
+- bpo-35402: Update Windows build to use Tcl and Tk 8.6.9
+
+- bpo-33316: PyThread_release_lock always fails
+
+- bpo-1104: Correctly handle string length in
+  ``msilib.SummaryInfo.GetProperty()`` to prevent it from truncating the
+  last character.
+
+IDLE
+----
+
+- bpo-36176: Fix IDLE autocomplete & calltip popup colors. Prevent conflicts
+  with Linux dark themes (and slightly darken calltip background).
+
+- bpo-36152: Remove colorizer.ColorDelegator.close_when_done and the
+  corresponding argument of .close().  In IDLE, both have always been None
+  or False since 2007.
+
+- bpo-32129: Avoid blurry IDLE application icon on macOS with Tk 8.6. Patch
+  by Kevin Walzer.
+
+- bpo-24310: IDLE -- Document settings dialog font tab sample.
+
+- bpo-36096: Refactor class variables to instance variables in colorizer.
+
+- bpo-35833: Revise IDLE doc for control codes sent to Shell. Add a code
+  example block.
+
+- bpo-35770: IDLE macosx deletes Options => Configure IDLE. It previously
+  deleted Window => Zoom Height by mistake. (Zoom Height is now on the
+  Options menu).  On Mac, the settings dialog is accessed via Preferences on
+  the IDLE menu.
+
+- bpo-35769: Change IDLE's new file name from 'Untitled' to 'untitled'
+
+- bpo-35689: Add docstrings and unittests for colorizer.py.
+
+- bpo-35660: Fix imports in idlelib.window.
+
+- bpo-35641: Proper format `calltip` when the function has no docstring.
+
+- bpo-33987: Use ttk Frame for ttk widgets.
+
+- bpo-34055: Fix erroneous 'smart' indents and newlines in IDLE Shell.
+
+- bpo-35591: Find Selection now works when selection not found.
+
+- bpo-35196: Speed up squeezer line counting.
+
+- bpo-35598: Update config_key: use PEP 8 names and ttk widgets, make some
+  objects global, and add tests.
+
+- bpo-28097: Add Previous/Next History entries to Shell menu.
+
+- bpo-35208: Squeezer now properly counts wrapped lines before newlines.
+
+- bpo-35555: Gray out Code Context menu entry when it's not applicable.
+
+- bpo-35521: Document the IDLE editor code context feature. Add some
+  internal references within the IDLE doc.
+
+- bpo-22703: The Code Context menu label now toggles between Show/Hide Code
+  Context. The Zoom Height menu now toggles between Zoom/Restore Height.
+  Zoom Height has moved from the Window menu to the Options menu.
+
+Tools/Demos
+-----------
+
+- bpo-35132: Fix py-list and py-bt commands of python-gdb.py on gdb7.
+
+C API
+-----
+
+- bpo-33817: Fixed :c:func:`_PyBytes_Resize` for empty bytes objects.
+
+
 What's New in Python 3.7.2 final?
 =================================
 
@@ -344,7 +781,10 @@ Windows
 macOS
 -----
 
-- bpo-35402: Update macOS installer to use Tcl/Tk 8.6.9.1.
+- bpo-35402: Update macOS installer to use Tcl/Tk 8.6.9.1.  [NOTE: This
+  change was reverted for the released python.org 3.7.2 macOS installers due
+  to regressions found in Tk 8.6.9.1.  For now, the installers provide
+  Tcl/Tk 8.6.8.]
 
 - bpo-35401: Update macOS installer to use OpenSSL 1.1.0j.
 
@@ -1008,11 +1448,11 @@ IDLE
 Tools/Demos
 -----------
 
-- bpo-32962: python-gdb now catchs ``UnicodeDecodeError`` exceptions when
+- bpo-32962: python-gdb now catches ``UnicodeDecodeError`` exceptions when
   calling ``string()``.
 
-- bpo-32962: python-gdb now catchs ValueError on read_var(): when Python has
-  no debug symbols for example.
+- bpo-32962: python-gdb now catches ValueError on read_var(): when Python
+  has no debug symbols for example.
 
 C API
 -----
index 3cdf8840d4d841818d699018f836a2709e5fa165..8d5ad8cd6ca87fd1a276ef80b1249afa5120c591 100644 (file)
@@ -75,7 +75,11 @@ python \- an interpreted, interactive, object-oriented programming language
 .br
        [
 .B \--check-hash-based-pycs
-\'default\'|\'always\'|\'never\'
+.I default
+|
+.I always
+|
+.I never
 ]
 .br
        [
index 36c1757b5fd3c8bedd9f0854d63b06f3673f8c97..1fbf3a831007bd677212f2f64c1ef063d5c8b11c 100644 (file)
@@ -66,7 +66,7 @@ PyDoc_STRVAR(abc_data_doc,
 "Internal state held by ABC machinery.");
 
 static PyTypeObject _abc_data_type = {
-    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    PyVarObject_HEAD_INIT(NULL, 0)
     "_abc_data",                        /*tp_name*/
     sizeof(_abc_data),                  /*tp_basicsize*/
     .tp_dealloc = (destructor)abc_data_dealloc,
index 5816a6748f66a3e35b3069f64d2e3ca9381ffd6e..35264f5815c3bce2ca37d184134f2e249a1ca433 100644 (file)
@@ -1110,6 +1110,10 @@ FutureObj_set_blocking(FutureObj *fut, PyObject *val, void *Py_UNUSED(ignored))
     if (future_ensure_alive(fut)) {
         return -1;
     }
+    if (val == NULL) {
+        PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
+        return -1;
+    }
 
     int is_true = PyObject_IsTrue(val);
     if (is_true < 0) {
@@ -1134,6 +1138,10 @@ FutureObj_get_log_traceback(FutureObj *fut, void *Py_UNUSED(ignored))
 static int
 FutureObj_set_log_traceback(FutureObj *fut, PyObject *val, void *Py_UNUSED(ignored))
 {
+    if (val == NULL) {
+        PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
+        return -1;
+    }
     int is_true = PyObject_IsTrue(val);
     if (is_true < 0) {
         return -1;
@@ -2008,6 +2016,10 @@ TaskObj_get_log_destroy_pending(TaskObj *task, void *Py_UNUSED(ignored))
 static int
 TaskObj_set_log_destroy_pending(TaskObj *task, PyObject *val, void *Py_UNUSED(ignored))
 {
+    if (val == NULL) {
+        PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
+        return -1;
+    }
     int is_true = PyObject_IsTrue(val);
     if (is_true < 0) {
         return -1;
index 58d179e6a3d2d15b3f4db5f098ba2af732e11fe0..5d03f45f643615315ddaf20758c0dcd659e6a6db 100644 (file)
@@ -34,7 +34,15 @@ static PyObject *
 crypt_crypt_impl(PyObject *module, const char *word, const char *salt)
 /*[clinic end generated code: output=0512284a03d2803c input=0e8edec9c364352b]*/
 {
-    return Py_BuildValue("s", crypt(word, salt));
+    char *crypt_result;
+#ifdef HAVE_CRYPT_R
+    struct crypt_data data;
+    memset(&data, 0, sizeof(data));
+    crypt_result = crypt_r(word, salt, &data);
+#else
+    crypt_result = crypt(word, salt);
+#endif
+    return Py_BuildValue("s", crypt_result);
 }
 
 
index c5fc811ad98e34cb88e5f20a36be81e3be2e1227..f98eabbb370b50a1d3373c35e3e6253f82c62dc8 100644 (file)
@@ -1171,6 +1171,10 @@ CharArray_set_raw(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored))
     Py_ssize_t size;
     Py_buffer view;
 
+    if (value == NULL) {
+        PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
+        return -1;
+    }
     if (PyObject_GetBuffer(value, &view, PyBUF_SIMPLE) < 0)
         return -1;
     size = view.len;
@@ -3405,20 +3409,23 @@ PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds)
         return NULL;
     }
 #endif
-    Py_INCREF(dll); /* for KeepRef */
-    Py_DECREF(ftuple);
-    if (!_validate_paramflags(type, paramflags))
+    if (!_validate_paramflags(type, paramflags)) {
+        Py_DECREF(ftuple);
         return NULL;
+    }
 
     self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds);
-    if (!self)
+    if (!self) {
+        Py_DECREF(ftuple);
         return NULL;
+    }
 
     Py_XINCREF(paramflags);
     self->paramflags = paramflags;
 
     *(void **)self->b_ptr = address;
-
+    Py_INCREF(dll);
+    Py_DECREF(ftuple);
     if (-1 == KeepRef((CDataObject *)self, 0, dll)) {
         Py_DECREF((PyObject *)self);
         return NULL;
index ec596b4de31d4066daed9b8be5817aa8343a1d74..e971388f69b92fb746c7cdd1860b3b0f972ab4c1 100644 (file)
@@ -1052,7 +1052,7 @@ GetComError(HRESULT errcode, GUID *riid, IUnknown *pIunk)
 #endif
 
 #if (defined(__x86_64__) && (defined(__MINGW64__) || defined(__CYGWIN__))) || \
-    defined(__aarch64__)
+    defined(__aarch64__) || defined(__riscv)
 #define CTYPES_PASS_BY_REF_HACK
 #define POW2(x) (((x & ~(x - 1)) == x) ? x : 0)
 #define IS_PASS_BY_REF(x) (x > 8 || !POW2(x))
index 5afeeea4881ddbcabc8a8dc742ea6ee0ae3c7a02..9405b4610dfcdb037ea4ca8595c38100ceeef7c1 100644 (file)
@@ -1514,10 +1514,13 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
             ntoappend = 1;
         }
         else if ((ch = *pin++) == '\0') {
-            /* There's a lone trailing %; doesn't make sense. */
-            PyErr_SetString(PyExc_ValueError, "strftime format "
-                            "ends with raw %");
-            goto Done;
+        /* Null byte follows %, copy only '%'. 
+         * 
+         * Back the pin up one char so that we catch the null check
+         * the next time through the loop.*/
+            pin--;
+            ptoappend = pin - 1;
+            ntoappend = 1;
         }
         /* A % has been seen and ch is the character after it. */
         else if (ch == 'z') {
@@ -1602,7 +1605,7 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
         usednew += ntoappend;
         assert(usednew <= totalnew);
     }  /* end while() */
-
+    
     if (_PyBytes_Resize(&newfmt, usednew) < 0)
         goto Done;
     {
index ff3a240f2ec311faaec9e50758410ac3ccea3b96..79f1ccd68565745e8b378dbdcb8baf2ba813dea6 100644 (file)
@@ -2429,6 +2429,11 @@ _elementtree_TreeBuilder___init___impl(TreeBuilderObject *self,
 static int
 treebuilder_gc_traverse(TreeBuilderObject *self, visitproc visit, void *arg)
 {
+    Py_VISIT(self->end_ns_event_obj);
+    Py_VISIT(self->start_ns_event_obj);
+    Py_VISIT(self->end_event_obj);
+    Py_VISIT(self->start_event_obj);
+    Py_VISIT(self->events_append);
     Py_VISIT(self->root);
     Py_VISIT(self->this);
     Py_VISIT(self->last);
index ff4172d663b65f115e68bb28262c156be2449990..c6a92ed1695965c643778f9ea887cb8dfc3874a0 100644 (file)
@@ -661,6 +661,26 @@ sequence is empty.");
 
 /* lru_cache object **********************************************************/
 
+/* There are four principal algorithmic differences from the pure python version:
+
+   1). The C version relies on the GIL instead of having its own reentrant lock.
+
+   2). The prev/next link fields use borrowed references.
+
+   3). For a full cache, the pure python version rotates the location of the
+       root entry so that it never has to move individual links and it can
+       limit updates to just the key and result fields.  However, in the C
+       version, links are temporarily removed while the cache dict updates are
+       occurring. Afterwards, they are appended or prepended back into the
+       doubly-linked lists.
+
+   4)  In the Python version, the _HashSeq class is used to prevent __hash__
+       from being called more than once.  In the C version, the "known hash"
+       variants of dictionary calls as used to the same effect.
+
+*/
+
+
 /* this object is used delimit args and keywords in the cache keys */
 static PyObject *kwd_mark = NULL;
 
@@ -711,16 +731,15 @@ typedef PyObject *(*lru_cache_ternaryfunc)(struct lru_cache_object *, PyObject *
 
 typedef struct lru_cache_object {
     lru_list_elem root;  /* includes PyObject_HEAD */
-    Py_ssize_t maxsize;
-    PyObject *maxsize_O;
-    PyObject *func;
     lru_cache_ternaryfunc wrapper;
+    int typed;
     PyObject *cache;
+    Py_ssize_t hits;
+    PyObject *func;
+    Py_ssize_t maxsize;
+    Py_ssize_t misses;
     PyObject *cache_info_type;
-    Py_ssize_t misses, hits;
-    int typed;
     PyObject *dict;
-    int full;
 } lru_cache_object;
 
 static PyTypeObject lru_cache_type;
@@ -733,6 +752,15 @@ lru_cache_make_key(PyObject *args, PyObject *kwds, int typed)
 
     /* short path, key will match args anyway, which is a tuple */
     if (!typed && !kwds) {
+        if (PyTuple_GET_SIZE(args) == 1) {
+            key = PyTuple_GET_ITEM(args, 0);
+            if (PyUnicode_CheckExact(key) || PyLong_CheckExact(key)) {
+                /* For common scalar keys, save space by
+                   dropping the enclosing args tuple  */
+                Py_INCREF(key);
+                return key;
+            }
+        }
         Py_INCREF(args);
         return args;
     }
@@ -788,10 +816,12 @@ lru_cache_make_key(PyObject *args, PyObject *kwds, int typed)
 static PyObject *
 uncached_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds)
 {
-    PyObject *result = PyObject_Call(self->func, args, kwds);
+    PyObject *result;
+
+    self->misses++;
+    result = PyObject_Call(self->func, args, kwds);
     if (!result)
         return NULL;
-    self->misses++;
     return result;
 }
 
@@ -819,6 +849,7 @@ infinite_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwd
         Py_DECREF(key);
         return NULL;
     }
+    self->misses++;
     result = PyObject_Call(self->func, args, kwds);
     if (!result) {
         Py_DECREF(key);
@@ -830,15 +861,16 @@ infinite_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwd
         return NULL;
     }
     Py_DECREF(key);
-    self->misses++;
     return result;
 }
 
 static void
-lru_cache_extricate_link(lru_list_elem *link)
+lru_cache_extract_link(lru_list_elem *link)
 {
-    link->prev->next = link->next;
-    link->next->prev = link->prev;
+    lru_list_elem *link_prev = link->prev;
+    lru_list_elem *link_next = link->next;
+    link_prev->next = link->next;
+    link_next->prev = link->prev;
 }
 
 static void
@@ -851,11 +883,52 @@ lru_cache_append_link(lru_cache_object *self, lru_list_elem *link)
     link->next = root;
 }
 
+static void
+lru_cache_prepend_link(lru_cache_object *self, lru_list_elem *link)
+{
+    lru_list_elem *root = &self->root;
+    lru_list_elem *first = root->next;
+    first->prev = root->next = link;
+    link->prev = root;
+    link->next = first;
+}
+
+/* General note on reentrancy:
+
+   There are four dictionary calls in the bounded_lru_cache_wrapper():
+   1) The initial check for a cache match.  2) The post user-function
+   check for a cache match.  3) The deletion of the oldest entry.
+   4) The addition of the newest entry.
+
+   In all four calls, we have a known hash which lets use avoid a call
+   to __hash__().  That leaves only __eq__ as a possible source of a
+   reentrant call.
+
+   The __eq__ method call is always made for a cache hit (dict access #1).
+   Accordingly, we have make sure not modify the cache state prior to
+   this call.
+
+   The __eq__ method call is never made for the deletion (dict access #3)
+   because it is an identity match.
+
+   For the other two accesses (#2 and #4), calls to __eq__ only occur
+   when some other entry happens to have an exactly matching hash (all
+   64-bits).  Though rare, this can happen, so we have to make sure to
+   either call it at the top of its code path before any cache
+   state modifications (dict access #2) or be prepared to restore
+   invariants at the end of the code path (dict access #4).
+
+   Another possible source of reentrancy is a decref which can trigger
+   arbitrary code execution.  To make the code easier to reason about,
+   the decrefs are deferred to the end of the each possible code path
+   so that we know the cache is a consistent state.
+ */
+
 static PyObject *
 bounded_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds)
 {
     lru_list_elem *link;
-    PyObject *key, *result;
+    PyObject *key, *result, *testresult;
     Py_hash_t hash;
 
     key = lru_cache_make_key(args, kwds, self->typed);
@@ -867,11 +940,11 @@ bounded_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds
         return NULL;
     }
     link  = (lru_list_elem *)_PyDict_GetItem_KnownHash(self->cache, key, hash);
-    if (link) {
-        lru_cache_extricate_link(link);
+    if (link != NULL) {
+        lru_cache_extract_link(link);
         lru_cache_append_link(self, link);
-        self->hits++;
         result = link->result;
+        self->hits++;
         Py_INCREF(result);
         Py_DECREF(key);
         return result;
@@ -880,65 +953,38 @@ bounded_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds
         Py_DECREF(key);
         return NULL;
     }
+    self->misses++;
     result = PyObject_Call(self->func, args, kwds);
     if (!result) {
         Py_DECREF(key);
         return NULL;
     }
-    if (self->full && self->root.next != &self->root) {
-        /* Use the oldest item to store the new key and result. */
-        PyObject *oldkey, *oldresult, *popresult;
-        /* Extricate the oldest item. */
-        link = self->root.next;
-        lru_cache_extricate_link(link);
-        /* Remove it from the cache.
-           The cache dict holds one reference to the link,
-           and the linked list holds yet one reference to it. */
-        popresult = _PyDict_Pop_KnownHash(self->cache,
-                                          link->key, link->hash,
-                                          Py_None);
-        if (popresult == Py_None) {
-            /* Getting here means that this same key was added to the
-               cache while the lock was released.  Since the link
-               update is already done, we need only return the
-               computed result and update the count of misses. */
-            Py_DECREF(popresult);
-            Py_DECREF(link);
-            Py_DECREF(key);
-        }
-        else if (popresult == NULL) {
-            lru_cache_append_link(self, link);
-            Py_DECREF(key);
-            Py_DECREF(result);
-            return NULL;
-        }
-        else {
-            Py_DECREF(popresult);
-            /* Keep a reference to the old key and old result to
-               prevent their ref counts from going to zero during the
-               update. That will prevent potentially arbitrary object
-               clean-up code (i.e. __del__) from running while we're
-               still adjusting the links. */
-            oldkey = link->key;
-            oldresult = link->result;
-
-            link->hash = hash;
-            link->key = key;
-            link->result = result;
-            if (_PyDict_SetItem_KnownHash(self->cache, key, (PyObject *)link,
-                                          hash) < 0) {
-                Py_DECREF(link);
-                Py_DECREF(oldkey);
-                Py_DECREF(oldresult);
-                return NULL;
-            }
-            lru_cache_append_link(self, link);
-            Py_INCREF(result); /* for return */
-            Py_DECREF(oldkey);
-            Py_DECREF(oldresult);
-        }
-    } else {
-        /* Put result in a new link at the front of the queue. */
+    testresult = _PyDict_GetItem_KnownHash(self->cache, key, hash);
+    if (testresult != NULL) {
+        /* Getting here means that this same key was added to the cache
+           during the PyObject_Call().  Since the link update is already
+           done, we need only return the computed result. */
+        Py_DECREF(key);
+        return result;
+    }
+    if (PyErr_Occurred()) {
+        /* This is an unusual case since this same lookup
+           did not previously trigger an error during lookup.
+           Treat it the same as an error in user function
+           and return with the error set. */
+        Py_DECREF(key);
+        Py_DECREF(result);
+        return NULL;
+    }
+    /* This is the normal case.  The new key wasn't found before
+       user function call and it is still not there.  So we
+       proceed normally and update the cache with the new result. */
+
+    assert(self->maxsize > 0);
+    if (PyDict_GET_SIZE(self->cache) < self->maxsize ||
+        self->root.next == &self->root)
+    {
+        /* Cache is not full, so put the result in a new link */
         link = (lru_list_elem *)PyObject_New(lru_list_elem,
                                              &lru_list_elem_type);
         if (link == NULL) {
@@ -950,6 +996,11 @@ bounded_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds
         link->hash = hash;
         link->key = key;
         link->result = result;
+        /* What is really needed here is a SetItem variant with a "no clobber"
+           option.  If the __eq__ call triggers a reentrant call that adds
+           this same key, then this setitem call will update the cache dict
+           with this new link, leaving the old link as an orphan (i.e. not
+           having a cache dict entry that refers to it). */
         if (_PyDict_SetItem_KnownHash(self->cache, key, (PyObject *)link,
                                       hash) < 0) {
             Py_DECREF(link);
@@ -957,9 +1008,84 @@ bounded_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds
         }
         lru_cache_append_link(self, link);
         Py_INCREF(result); /* for return */
-        self->full = (PyDict_GET_SIZE(self->cache) >= self->maxsize);
+        return result;
     }
-    self->misses++;
+    /* Since the cache is full, we need to evict an old key and add
+       a new key.  Rather than free the old link and allocate a new
+       one, we reuse the link for the new key and result and move it
+       to front of the cache to mark it as recently used.
+
+       We try to assure all code paths (including errors) leave all
+       of the links in place.  Either the link is successfully
+       updated and moved or it is restored to its old position.
+       However if an unrecoverable error is found, it doesn't
+       make sense to reinsert the link, so we leave it out
+       and the cache will no longer register as full.
+    */
+    PyObject *oldkey, *oldresult, *popresult;
+
+    /* Extract the oldest item. */
+    assert(self->root.next != &self->root);
+    link = self->root.next;
+    lru_cache_extract_link(link);
+    /* Remove it from the cache.
+       The cache dict holds one reference to the link.
+       We created one other reference when the link was created.
+       The linked list only has borrowed references. */
+    popresult = _PyDict_Pop_KnownHash(self->cache, link->key,
+                                      link->hash, Py_None);
+    if (popresult == Py_None) {
+        /* Getting here means that the user function call or another
+           thread has already removed the old key from the dictionary.
+           This link is now an orphan.  Since we don't want to leave the
+           cache in an inconsistent state, we don't restore the link. */
+        Py_DECREF(popresult);
+        Py_DECREF(link);
+        Py_DECREF(key);
+        return result;
+    }
+    if (popresult == NULL) {
+        /* An error arose while trying to remove the oldest key (the one
+           being evicted) from the cache.  We restore the link to its
+           original position as the oldest link.  Then we allow the
+           error propagate upward; treating it the same as an error
+           arising in the user function. */
+        lru_cache_prepend_link(self, link);
+        Py_DECREF(key);
+        Py_DECREF(result);
+        return NULL;
+    }
+    /* Keep a reference to the old key and old result to prevent their
+       ref counts from going to zero during the update. That will
+       prevent potentially arbitrary object clean-up code (i.e. __del__)
+       from running while we're still adjusting the links. */
+    oldkey = link->key;
+    oldresult = link->result;
+
+    link->hash = hash;
+    link->key = key;
+    link->result = result;
+    /* Note:  The link is being added to the cache dict without the
+       prev and next fields set to valid values.   We have to wait
+       for successful insertion in the cache dict before adding the
+       link to the linked list.  Otherwise, the potentially reentrant
+       __eq__ call could cause the then orphan link to be visited. */
+    if (_PyDict_SetItem_KnownHash(self->cache, key, (PyObject *)link,
+                                  hash) < 0) {
+        /* Somehow the cache dict update failed.  We no longer can
+           restore the old link.  Let the error propagate upward and
+           leave the cache short one link. */
+        Py_DECREF(popresult);
+        Py_DECREF(link);
+        Py_DECREF(oldkey);
+        Py_DECREF(oldresult);
+        return NULL;
+    }
+    lru_cache_append_link(self, link);
+    Py_INCREF(result); /* for return */
+    Py_DECREF(popresult);
+    Py_DECREF(oldkey);
+    Py_DECREF(oldresult);
     return result;
 }
 
@@ -995,6 +1121,9 @@ lru_cache_new(PyTypeObject *type, PyObject *args, PyObject *kw)
         maxsize = PyNumber_AsSsize_t(maxsize_O, PyExc_OverflowError);
         if (maxsize == -1 && PyErr_Occurred())
             return NULL;
+        if (maxsize < 0) {
+            maxsize = 0;
+        }
         if (maxsize == 0)
             wrapper = uncached_lru_cache_wrapper;
         else
@@ -1013,20 +1142,17 @@ lru_cache_new(PyTypeObject *type, PyObject *args, PyObject *kw)
         return NULL;
     }
 
-    obj->cache = cachedict;
     obj->root.prev = &obj->root;
     obj->root.next = &obj->root;
-    obj->maxsize = maxsize;
-    Py_INCREF(maxsize_O);
-    obj->maxsize_O = maxsize_O;
+    obj->wrapper = wrapper;
+    obj->typed = typed;
+    obj->cache = cachedict;
     Py_INCREF(func);
     obj->func = func;
-    obj->wrapper = wrapper;
     obj->misses = obj->hits = 0;
-    obj->typed = typed;
+    obj->maxsize = maxsize;
     Py_INCREF(cache_info_type);
     obj->cache_info_type = cache_info_type;
-
     return (PyObject *)obj;
 }
 
@@ -1060,11 +1186,10 @@ lru_cache_dealloc(lru_cache_object *obj)
     PyObject_GC_UnTrack(obj);
 
     list = lru_cache_unlink_list(obj);
-    Py_XDECREF(obj->maxsize_O);
-    Py_XDECREF(obj->func);
     Py_XDECREF(obj->cache);
-    Py_XDECREF(obj->dict);
+    Py_XDECREF(obj->func);
     Py_XDECREF(obj->cache_info_type);
+    Py_XDECREF(obj->dict);
     lru_cache_clear_list(list);
     Py_TYPE(obj)->tp_free(obj);
 }
@@ -1088,8 +1213,13 @@ lru_cache_descr_get(PyObject *self, PyObject *obj, PyObject *type)
 static PyObject *
 lru_cache_cache_info(lru_cache_object *self, PyObject *unused)
 {
-    return PyObject_CallFunction(self->cache_info_type, "nnOn",
-                                 self->hits, self->misses, self->maxsize_O,
+    if (self->maxsize == -1) {
+        return PyObject_CallFunction(self->cache_info_type, "nnOn",
+                                     self->hits, self->misses, Py_None,
+                                     PyDict_GET_SIZE(self->cache));
+    }
+    return PyObject_CallFunction(self->cache_info_type, "nnnn",
+                                 self->hits, self->misses, self->maxsize,
                                  PyDict_GET_SIZE(self->cache));
 }
 
@@ -1098,7 +1228,6 @@ lru_cache_cache_clear(lru_cache_object *self, PyObject *unused)
 {
     lru_list_elem *list = lru_cache_unlink_list(self);
     self->hits = self->misses = 0;
-    self->full = 0;
     PyDict_Clear(self->cache);
     lru_cache_clear_list(list);
     Py_RETURN_NONE;
@@ -1134,7 +1263,6 @@ lru_cache_tp_traverse(lru_cache_object *self, visitproc visit, void *arg)
         Py_VISIT(link->result);
         link = next;
     }
-    Py_VISIT(self->maxsize_O);
     Py_VISIT(self->func);
     Py_VISIT(self->cache);
     Py_VISIT(self->cache_info_type);
@@ -1146,7 +1274,6 @@ static int
 lru_cache_tp_clear(lru_cache_object *self)
 {
     lru_list_elem *list = lru_cache_unlink_list(self);
-    Py_CLEAR(self->maxsize_O);
     Py_CLEAR(self->func);
     Py_CLEAR(self->cache);
     Py_CLEAR(self->cache_info_type);
index 31d05409f2494e8ed91afbf8a5cc44e5856bebf2..b69f16c61a506b775dbc959abf1d89dd1393191a 100644 (file)
@@ -112,17 +112,18 @@ newEVPobject(PyObject *name)
         return NULL;
     }
 
+    /* save the name for .name to return */
+    Py_INCREF(name);
+    retval->name = name;
+    retval->lock = NULL;
+
     retval->ctx = EVP_MD_CTX_new();
     if (retval->ctx == NULL) {
+        Py_DECREF(retval);
         PyErr_NoMemory();
         return NULL;
     }
 
-    /* save the name for .name to return */
-    Py_INCREF(name);
-    retval->name = name;
-    retval->lock = NULL;
-
     return retval;
 }
 
@@ -181,6 +182,7 @@ EVP_copy(EVPobject *self, PyObject *unused)
         return NULL;
 
     if (!locked_EVP_MD_CTX_copy(newobj->ctx, self)) {
+        Py_DECREF(newobj);
         return _setException(PyExc_ValueError);
     }
     return (PyObject *)newobj;
@@ -824,7 +826,7 @@ _hashlib_scrypt_impl(PyObject *module, Py_buffer *password, Py_buffer *salt,
     if (!retval) {
         /* sorry, can't do much better */
         PyErr_SetString(PyExc_ValueError,
-                        "Invalid paramemter combination for n, r, p, maxmem.");
+                        "Invalid parameter combination for n, r, p, maxmem.");
         return NULL;
    }
 
index 9d0d9cac40dbcc5ead13d8c442c0dff45af7c060..49b545c4787fbf8158131a51258b7c0bfb4ceb35 100644 (file)
@@ -3049,6 +3049,10 @@ textiowrapper_chunk_size_set(textio *self, PyObject *arg, void *context)
 {
     Py_ssize_t n;
     CHECK_ATTACHED_INT(self);
+    if (arg == NULL) {
+        PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
+        return -1;
+    }
     n = PyNumber_AsSsize_t(arg, PyExc_ValueError);
     if (n == -1 && PyErr_Occurred())
         return -1;
index 60ef921521efbc53d3ab75dfc0d8d203629dedd6..15e15cdf45063d276553f1a3c384a5a7c8c6b68a 100644 (file)
@@ -6636,13 +6636,13 @@ _pickle_Unpickler_find_class_impl(UnpicklerObject *self,
         }
     }
 
-    module = PyImport_GetModule(module_name);
+    /*
+     * we don't use PyImport_GetModule here, because it can return partially-
+     * initialised modules, which then cause the getattribute to fail.
+     */
+    module = PyImport_Import(module_name);
     if (module == NULL) {
-        if (PyErr_Occurred())
-            return NULL;
-        module = PyImport_Import(module_name);
-        if (module == NULL)
-            return NULL;
+        return NULL;
     }
     global = getattribute(module, global_name, self->proto >= 4);
     Py_DECREF(module);
index 851aa9777168084d98c9f9f61f79214d110a5ceb..3cf0683ad98bba4022331da9e837d6082d7325ce 100644 (file)
@@ -30,7 +30,7 @@
 # define SYS_getdents64  __NR_getdents64
 #endif
 
-#if defined(sun)
+#if defined(__sun) && defined(__SVR4)
 /* readdir64 is used to work around Solaris 9 bug 6395699. */
 # define readdir readdir64
 # define dirent dirent64
index 51677f8b00a492e88eb2c0b458bd684506de04e5..1a76ba99ab25270d3ca4bcf2d4745486ccdc2728 100644 (file)
@@ -292,7 +292,6 @@ random_seed(RandomObject *self, PyObject *args)
                               PY_LITTLE_ENDIAN,
                               0); /* unsigned */
     if (res == -1) {
-        PyMem_Free(key);
         goto Done;
     }
 
index 17c56b34b261abd5d50869911e75af4145cd76c2..4f53681b49e67bc200efab1eee5cf9cf365b5fe7 100755 (executable)
@@ -8,7 +8,7 @@ import os
 import re
 
 CPP1 = re.compile("^//(.*)")
-CPP2 = re.compile("\ //(.*)")
+CPP2 = re.compile(r"\ //(.*)")
 
 STATICS = ("void ", "int ", "HashReturn ",
            "const UINT64 ", "UINT16 ", "    int prefix##")
index 351317e78db4fc285995a981b33799ad980e41e7..d43286a2d34d62f4f8b1dec90caa9fceb6e4e7a8 100644 (file)
@@ -1138,6 +1138,10 @@ static PyObject* pysqlite_connection_get_in_transaction(pysqlite_Connection* sel
 static int
 pysqlite_connection_set_isolation_level(pysqlite_Connection* self, PyObject* isolation_level, void *Py_UNUSED(ignored))
 {
+    if (isolation_level == NULL) {
+        PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
+        return -1;
+    }
     if (isolation_level == Py_None) {
         PyObject *res = pysqlite_connection_commit(self, NULL);
         if (!res) {
index d2ea62d55a81b31c3b41d91e7bba0f3cfd429982..4d2bdcc209679d1d5ce4c0c706db1a6d9b4660ee 100644 (file)
@@ -347,7 +347,7 @@ _sre_unicode_tolower_impl(PyObject *module, int character)
 LOCAL(void)
 state_reset(SRE_STATE* state)
 {
-    /* FIXME: dynamic! */
+    /* state->mark will be set to 0 in SRE_OP_MARK dynamically. */
     /*memset(state->mark, 0, sizeof(*state->mark) * SRE_MARK_SIZE);*/
 
     state->lastmark = -1;
@@ -2319,7 +2319,7 @@ match_repr(MatchObject *self)
     if (group0 == NULL)
         return NULL;
     result = PyUnicode_FromFormat(
-            "<%s object; span=(%d, %d), match=%.50R>",
+            "<%s object; span=(%zd, %zd), match=%.50R>",
             Py_TYPE(self)->tp_name,
             self->mark[0], self->mark[1], group0);
     Py_DECREF(group0);
index 310b38bf11f4578e23cfdf3d5c27cca6c39c5650..9baec8a9bc84e51aa855d3cc7343d8c2ad6d4468 100644 (file)
@@ -1516,6 +1516,10 @@ _get_crl_dp(X509 *certificate) {
         STACK_OF(GENERAL_NAME) *gns;
 
         dp = sk_DIST_POINT_value(dps, i);
+        if (dp->distpoint == NULL) {
+            /* Ignore empty DP value, CVE-2019-5010 */
+            continue;
+        }
         gns = dp->distpoint->name.fullname;
 
         for (j=0; j < sk_GENERAL_NAME_num(gns); j++) {
@@ -3626,6 +3630,10 @@ static int
 set_post_handshake_auth(PySSLContext *self, PyObject *arg, void *c) {
     int (*verify_cb)(int, X509_STORE_CTX *) = NULL;
     int mode = SSL_CTX_get_verify_mode(self->ctx);
+    if (arg == NULL) {
+        PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
+        return -1;
+    }
     int pha = PyObject_IsTrue(arg);
 
     if (pha == -1) {
index 9ea5a926629559e1c9cb8257d15149dfc78180ac..036464d9ab4a1a0b02c569775f2aef30516615d3 100644 (file)
@@ -974,7 +974,8 @@ cleanup:
 _winapi.CreateProcess
 
     application_name: Py_UNICODE(accept={str, NoneType})
-    command_line: Py_UNICODE(accept={str, NoneType})
+    command_line: object
+        Can be str or None
     proc_attrs: object
         Ignored internally, can be None.
     thread_attrs: object
@@ -993,13 +994,14 @@ process ID, and thread ID.
 [clinic start generated code]*/
 
 static PyObject *
-_winapi_CreateProcess_impl(PyObject *module, Py_UNICODE *application_name,
-                           Py_UNICODE *command_line, PyObject *proc_attrs,
+_winapi_CreateProcess_impl(PyObject *module,
+                           const Py_UNICODE *application_name,
+                           PyObject *command_line, PyObject *proc_attrs,
                            PyObject *thread_attrs, BOOL inherit_handles,
                            DWORD creation_flags, PyObject *env_mapping,
-                           Py_UNICODE *current_directory,
+                           const Py_UNICODE *current_directory,
                            PyObject *startup_info)
-/*[clinic end generated code: output=4652a33aff4b0ae1 input=4a43b05038d639bb]*/
+/*[clinic end generated code: output=9b2423a609230132 input=42ac293eaea03fc4]*/
 {
     PyObject *ret = NULL;
     BOOL result;
@@ -1007,6 +1009,7 @@ _winapi_CreateProcess_impl(PyObject *module, Py_UNICODE *application_name,
     STARTUPINFOEXW si;
     PyObject *environment = NULL;
     wchar_t *wenvironment;
+    wchar_t *command_line_copy = NULL;
     AttributeList attribute_list = {0};
 
     ZeroMemory(&si, sizeof(si));
@@ -1041,10 +1044,23 @@ _winapi_CreateProcess_impl(PyObject *module, Py_UNICODE *application_name,
         goto cleanup;
 
     si.lpAttributeList = attribute_list.attribute_list;
+    if (PyUnicode_Check(command_line)) {
+        command_line_copy = PyUnicode_AsWideCharString(command_line, NULL);
+        if (command_line_copy == NULL) {
+            goto cleanup;
+        }
+    }
+    else if (command_line != Py_None) {
+        PyErr_Format(PyExc_TypeError, 
+                     "CreateProcess() argument 2 must be str or None, not %s", 
+                     Py_TYPE(command_line)->tp_name);
+        goto cleanup;
+    }
+
 
     Py_BEGIN_ALLOW_THREADS
     result = CreateProcessW(application_name,
-                           command_line,
+                           command_line_copy,
                            NULL,
                            NULL,
                            inherit_handles,
@@ -1068,6 +1084,7 @@ _winapi_CreateProcess_impl(PyObject *module, Py_UNICODE *application_name,
                         pi.dwThreadId);
 
 cleanup:
+    PyMem_Free(command_line_copy);
     Py_XDECREF(environment);
     freeattributelist(&attribute_list);
 
index 7b4a4a3ad21660fca6165fd54b959dca4cca6620..ee7ae54661b3a52b3e2dcff6d46b42fc15737ae4 100644 (file)
@@ -1712,9 +1712,9 @@ some other type.
 [clinic start generated code]*/
 
 static PyObject *
-array_array_fromunicode_impl(arrayobject *self, Py_UNICODE *ustr,
+array_array_fromunicode_impl(arrayobject *self, const Py_UNICODE *ustr,
                              Py_ssize_clean_t ustr_length)
-/*[clinic end generated code: output=ebb72fc16975e06d input=150f00566ffbca6e]*/
+/*[clinic end generated code: output=cf2f662908e2befc input=150f00566ffbca6e]*/
 {
     char typecode;
 
index 4d0aaf3a336f9ca9a5797eaf44eb2e898ec8570c..5c91ada103d5a08e979bfce6ab5f48d3502a31db 100644 (file)
@@ -133,6 +133,10 @@ codecctx_errors_set(MultibyteStatefulCodecContext *self, PyObject *value,
     PyObject *cb;
     const char *str;
 
+    if (value == NULL) {
+        PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
+        return -1;
+    }
     if (!PyUnicode_Check(value)) {
         PyErr_SetString(PyExc_TypeError, "errors must be a string");
         return -1;
index c66522ebab6d6c7272b05d0be3cfb1c2c10e6e02..f4d884237b3f1af4422f72f9459c00a9c8e0f8e2 100644 (file)
@@ -286,6 +286,8 @@ PyDoc_STRVAR(_winapi_CreateProcess__doc__,
 "\n"
 "Create a new process and its primary thread.\n"
 "\n"
+"  command_line\n"
+"    Can be str or None\n"
 "  proc_attrs\n"
 "    Ignored internally, can be None.\n"
 "  thread_attrs\n"
@@ -298,28 +300,29 @@ PyDoc_STRVAR(_winapi_CreateProcess__doc__,
     {"CreateProcess", (PyCFunction)_winapi_CreateProcess, METH_FASTCALL, _winapi_CreateProcess__doc__},
 
 static PyObject *
-_winapi_CreateProcess_impl(PyObject *module, Py_UNICODE *application_name,
-                           Py_UNICODE *command_line, PyObject *proc_attrs,
+_winapi_CreateProcess_impl(PyObject *module,
+                           const Py_UNICODE *application_name,
+                           PyObject *command_line, PyObject *proc_attrs,
                            PyObject *thread_attrs, BOOL inherit_handles,
                            DWORD creation_flags, PyObject *env_mapping,
-                           Py_UNICODE *current_directory,
+                           const Py_UNICODE *current_directory,
                            PyObject *startup_info);
 
 static PyObject *
 _winapi_CreateProcess(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
 {
     PyObject *return_value = NULL;
-    Py_UNICODE *application_name;
-    Py_UNICODE *command_line;
+    const Py_UNICODE *application_name;
+    PyObject *command_line;
     PyObject *proc_attrs;
     PyObject *thread_attrs;
     BOOL inherit_handles;
     DWORD creation_flags;
     PyObject *env_mapping;
-    Py_UNICODE *current_directory;
+    const Py_UNICODE *current_directory;
     PyObject *startup_info;
 
-    if (!_PyArg_ParseStack(args, nargs, "ZZOOikOZO:CreateProcess",
+    if (!_PyArg_ParseStack(args, nargs, "ZOOOikOZO:CreateProcess",
         &application_name, &command_line, &proc_attrs, &thread_attrs, &inherit_handles, &creation_flags, &env_mapping, &current_directory, &startup_info)) {
         goto exit;
     }
@@ -941,4 +944,4 @@ _winapi_GetFileType(PyObject *module, PyObject *const *args, Py_ssize_t nargs, P
 exit:
     return return_value;
 }
-/*[clinic end generated code: output=baaf3d379b91be0a input=a9049054013a1b77]*/
+/*[clinic end generated code: output=896d06ce2290aa86 input=a9049054013a1b77]*/
index b03a507914a88f1b46444c524c3884b5e0aed48a..c85d0c6262e6c1e0b68e51c6c3e155065e51a434 100644 (file)
@@ -376,14 +376,14 @@ PyDoc_STRVAR(array_array_fromunicode__doc__,
     {"fromunicode", (PyCFunction)array_array_fromunicode, METH_O, array_array_fromunicode__doc__},
 
 static PyObject *
-array_array_fromunicode_impl(arrayobject *self, Py_UNICODE *ustr,
+array_array_fromunicode_impl(arrayobject *self, const Py_UNICODE *ustr,
                              Py_ssize_clean_t ustr_length);
 
 static PyObject *
 array_array_fromunicode(arrayobject *self, PyObject *arg)
 {
     PyObject *return_value = NULL;
-    Py_UNICODE *ustr;
+    const Py_UNICODE *ustr;
     Py_ssize_clean_t ustr_length;
 
     if (!PyArg_Parse(arg, "u#:fromunicode", &ustr, &ustr_length)) {
@@ -505,4 +505,4 @@ PyDoc_STRVAR(array_arrayiterator___setstate____doc__,
 
 #define ARRAY_ARRAYITERATOR___SETSTATE___METHODDEF    \
     {"__setstate__", (PyCFunction)array_arrayiterator___setstate__, METH_O, array_arrayiterator___setstate____doc__},
-/*[clinic end generated code: output=1289bde2a095a712 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=2d0fb1937dea02c2 input=a9049054013a1b77]*/
index 3230cd70097271d2baafd85f64884801af98f58f..caa1cacd3f0a9ee8f6b27fcae9d70a1e8b019f04 100644 (file)
@@ -1264,7 +1264,7 @@ PyDoc_STRVAR(os_replace__doc__,
 "  descriptor open to a directory, and the respective path string (src or dst)\n"
 "  should be relative; the path will then be relative to that directory.\n"
 "src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n"
-"  If they are unavailable, using them will raise a NotImplementedError.\"");
+"  If they are unavailable, using them will raise a NotImplementedError.");
 
 #define OS_REPLACE_METHODDEF    \
     {"replace", (PyCFunction)os_replace, METH_FASTCALL|METH_KEYWORDS, os_replace__doc__},
@@ -1350,7 +1350,7 @@ PyDoc_STRVAR(os_system__doc__,
     {"system", (PyCFunction)os_system, METH_FASTCALL|METH_KEYWORDS, os_system__doc__},
 
 static long
-os_system_impl(PyObject *module, Py_UNICODE *command);
+os_system_impl(PyObject *module, const Py_UNICODE *command);
 
 static PyObject *
 os_system(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
@@ -1358,7 +1358,7 @@ os_system(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k
     PyObject *return_value = NULL;
     static const char * const _keywords[] = {"command", NULL};
     static _PyArg_Parser _parser = {"u:system", _keywords, 0};
-    Py_UNICODE *command;
+    const Py_UNICODE *command;
     long _return_value;
 
     if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser,
@@ -5201,7 +5201,8 @@ PyDoc_STRVAR(os_startfile__doc__,
     {"startfile", (PyCFunction)os_startfile, METH_FASTCALL|METH_KEYWORDS, os_startfile__doc__},
 
 static PyObject *
-os_startfile_impl(PyObject *module, path_t *filepath, Py_UNICODE *operation);
+os_startfile_impl(PyObject *module, path_t *filepath,
+                  const Py_UNICODE *operation);
 
 static PyObject *
 os_startfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
@@ -5210,7 +5211,7 @@ os_startfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject
     static const char * const _keywords[] = {"filepath", "operation", NULL};
     static _PyArg_Parser _parser = {"O&|u:startfile", _keywords, 0};
     path_t filepath = PATH_T_INITIALIZE("startfile", "filepath", 0, 0);
-    Py_UNICODE *operation = NULL;
+    const Py_UNICODE *operation = NULL;
 
     if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser,
         path_converter, &filepath, &operation)) {
@@ -6537,4 +6538,4 @@ exit:
 #ifndef OS_GETRANDOM_METHODDEF
     #define OS_GETRANDOM_METHODDEF
 #endif /* !defined(OS_GETRANDOM_METHODDEF) */
-/*[clinic end generated code: output=c6ca6ad4afa64454 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=32c935671ee020d5 input=a9049054013a1b77]*/
index e6a3e8e78cd3ee83321e7f72196dc5faf1798f11..bfb33316d969b9728602990855b42bccb6c90345 100644 (file)
@@ -296,6 +296,41 @@ absolutize(wchar_t *path)
 }
 
 
+#if defined(__CYGWIN__) || defined(__MINGW32__)
+/* add_exe_suffix requires that progpath be allocated at least
+   MAXPATHLEN + 1 bytes.
+*/
+
+#ifndef EXE_SUFFIX
+#define EXE_SUFFIX L".exe"
+#endif
+
+static void
+add_exe_suffix(wchar_t *progpath)
+{
+    /* Check for already have an executable suffix */
+    size_t n = wcslen(progpath);
+    size_t s = wcslen(EXE_SUFFIX);
+    if (wcsncasecmp(EXE_SUFFIX, progpath+n-s, s) != 0) {
+        if (n + s > MAXPATHLEN) {
+            Py_FatalError("progpath overflow in getpath.c's add_exe_suffix()");
+        }
+        /* Save original path for revert */
+        wchar_t orig[MAXPATHLEN+1];
+        wcsncpy(orig, progpath, MAXPATHLEN);
+
+        wcsncpy(progpath+n, EXE_SUFFIX, s);
+        progpath[n+s] = '\0';
+
+        if (!isxfile(progpath)) {
+            /* Path that added suffix is invalid */
+            wcsncpy(progpath, orig, MAXPATHLEN);
+        }
+    }
+}
+#endif
+
+
 /* search_for_prefix requires that argv0_path be no more than MAXPATHLEN
    bytes long.
 */
@@ -605,6 +640,16 @@ calculate_program_full_path(const _PyCoreConfig *core_config,
     if (program_full_path[0] != SEP && program_full_path[0] != '\0') {
         absolutize(program_full_path);
     }
+#if defined(__CYGWIN__) || defined(__MINGW32__)
+    /* For these platforms it is necessary to ensure that the .exe suffix
+     * is appended to the filename, otherwise there is potential for
+     * sys.executable to return the name of a directory under the same
+     * path (bpo-28441).
+     */
+    if (program_full_path[0] != '\0') {
+        add_exe_suffix(program_full_path);
+    }
+#endif
 
     config->program_full_path = _PyMem_RawWcsdup(program_full_path);
     if (config->program_full_path == NULL) {
index af2c191b9b9b321abe79189200fb87909a297e70..a745381109d37775913779c975d81107c135d03f 100644 (file)
@@ -2165,6 +2165,7 @@ pymain_read_conf(_PyMain *pymain, _PyCoreConfig *config, _PyCmdline *cmdline)
             goto done;
         }
         pymain_clear_cmdline(pymain, cmdline);
+        pymain_clear_pymain(pymain);
         memset(cmdline, 0, sizeof(*cmdline));
 
         cmdline_get_global_config(cmdline);
index 5d9fe5aa71a6790c9e3354364e311304c3f370c3..9eaeff11597fd56545090edfef8d3f2adba3e7fa 100644 (file)
@@ -77,7 +77,7 @@ static const double sqrtpi = 1.772453850905516027298167483341145182798;
 #endif /* !defined(HAVE_ERF) || !defined(HAVE_ERFC) */
 
 static double
-sinpi(double x)
+m_sinpi(double x)
 {
     double y, r;
     int n;
@@ -305,7 +305,7 @@ m_tgamma(double x)
        integer. */
     if (absx > 200.0) {
         if (x < 0.0) {
-            return 0.0/sinpi(x);
+            return 0.0/m_sinpi(x);
         }
         else {
             errno = ERANGE;
@@ -329,7 +329,7 @@ m_tgamma(double x)
     }
     z = z * lanczos_g / y;
     if (x < 0.0) {
-        r = -pi / sinpi(absx) / absx * exp(y) / lanczos_sum(absx);
+        r = -pi / m_sinpi(absx) / absx * exp(y) / lanczos_sum(absx);
         r -= z * r;
         if (absx < 140.0) {
             r /= pow(y, absx - 0.5);
@@ -400,7 +400,7 @@ m_lgamma(double x)
     r += (absx - 0.5) * (log(absx + lanczos_g - 0.5) - 1);
     if (x < 0.0)
         /* Use reflection formula to get value for negative x. */
-        r = logpi - log(fabs(sinpi(absx))) - log(absx) - r;
+        r = logpi - log(fabs(m_sinpi(absx))) - log(absx) - r;
     if (Py_IS_INFINITY(r))
         errno = ERANGE;
     return r;
index ae7cddadd02df73648250fefe108a8bb3c3ec5c5..7798856bee7304d12051b06b96a4aaa823bb8320 100644 (file)
@@ -561,6 +561,28 @@ Overlapped_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
     return (PyObject *)self;
 }
 
+
+/* Note (bpo-32710): OverlappedType.tp_clear is not defined to not release
+   buffers while overlapped are still running, to prevent a crash. */
+static int
+Overlapped_clear(OverlappedObject *self)
+{
+    switch (self->type) {
+    case TYPE_READ:
+    case TYPE_ACCEPT:
+        Py_CLEAR(self->allocated_buffer);
+        break;
+    case TYPE_WRITE:
+    case TYPE_READINTO:
+        if (self->user_buffer.obj) {
+            PyBuffer_Release(&self->user_buffer);
+        }
+        break;
+    }
+    self->type = TYPE_NOT_STARTED;
+    return 0;
+}
+
 static void
 Overlapped_dealloc(OverlappedObject *self)
 {
@@ -594,20 +616,11 @@ Overlapped_dealloc(OverlappedObject *self)
         }
     }
 
-    if (self->overlapped.hEvent != NULL)
+    if (self->overlapped.hEvent != NULL) {
         CloseHandle(self->overlapped.hEvent);
-
-    switch (self->type) {
-    case TYPE_READ:
-    case TYPE_ACCEPT:
-        Py_CLEAR(self->allocated_buffer);
-        break;
-    case TYPE_WRITE:
-    case TYPE_READINTO:
-        if (self->user_buffer.obj)
-            PyBuffer_Release(&self->user_buffer);
-        break;
     }
+
+    Overlapped_clear(self);
     PyObject_Del(self);
     SetLastError(olderr);
 }
@@ -723,7 +736,7 @@ do_ReadFile(OverlappedObject *self, HANDLE handle,
         case ERROR_IO_PENDING:
             Py_RETURN_NONE;
         default:
-            self->type = TYPE_NOT_STARTED;
+            Overlapped_clear(self);
             return SetFromWindowsErr(err);
     }
 }
@@ -826,7 +839,7 @@ do_WSARecv(OverlappedObject *self, HANDLE handle,
         case ERROR_IO_PENDING:
             Py_RETURN_NONE;
         default:
-            self->type = TYPE_NOT_STARTED;
+            Overlapped_clear(self);
             return SetFromWindowsErr(err);
     }
 }
@@ -954,7 +967,7 @@ Overlapped_WriteFile(OverlappedObject *self, PyObject *args)
         case ERROR_IO_PENDING:
             Py_RETURN_NONE;
         default:
-            self->type = TYPE_NOT_STARTED;
+            Overlapped_clear(self);
             return SetFromWindowsErr(err);
     }
 }
@@ -1011,7 +1024,7 @@ Overlapped_WSASend(OverlappedObject *self, PyObject *args)
         case ERROR_IO_PENDING:
             Py_RETURN_NONE;
         default:
-            self->type = TYPE_NOT_STARTED;
+            Overlapped_clear(self);
             return SetFromWindowsErr(err);
     }
 }
@@ -1061,7 +1074,7 @@ Overlapped_AcceptEx(OverlappedObject *self, PyObject *args)
         case ERROR_IO_PENDING:
             Py_RETURN_NONE;
         default:
-            self->type = TYPE_NOT_STARTED;
+            Overlapped_clear(self);
             return SetFromWindowsErr(err);
     }
 }
@@ -1153,7 +1166,7 @@ Overlapped_ConnectEx(OverlappedObject *self, PyObject *args)
         case ERROR_IO_PENDING:
             Py_RETURN_NONE;
         default:
-            self->type = TYPE_NOT_STARTED;
+            Overlapped_clear(self);
             return SetFromWindowsErr(err);
     }
 }
@@ -1192,7 +1205,7 @@ Overlapped_DisconnectEx(OverlappedObject *self, PyObject *args)
         case ERROR_IO_PENDING:
             Py_RETURN_NONE;
         default:
-            self->type = TYPE_NOT_STARTED;
+            Overlapped_clear(self);
             return SetFromWindowsErr(err);
     }
 }
@@ -1247,7 +1260,7 @@ Overlapped_TransmitFile(OverlappedObject *self, PyObject *args)
         case ERROR_IO_PENDING:
             Py_RETURN_NONE;
         default:
-            self->type = TYPE_NOT_STARTED;
+            Overlapped_clear(self);
             return SetFromWindowsErr(err);
     }
 }
@@ -1288,7 +1301,7 @@ Overlapped_ConnectNamedPipe(OverlappedObject *self, PyObject *args)
         case ERROR_IO_PENDING:
             Py_RETURN_FALSE;
         default:
-            self->type = TYPE_NOT_STARTED;
+            Overlapped_clear(self);
             return SetFromWindowsErr(err);
     }
 }
@@ -1338,6 +1351,25 @@ Overlapped_getpending(OverlappedObject *self)
                            self->type != TYPE_NOT_STARTED);
 }
 
+static int
+Overlapped_traverse(OverlappedObject *self, visitproc visit, void *arg)
+{
+    switch (self->type) {
+    case TYPE_READ:
+    case TYPE_ACCEPT:
+        Py_VISIT(self->allocated_buffer);
+        break;
+    case TYPE_WRITE:
+    case TYPE_READINTO:
+        if (self->user_buffer.obj) {
+            Py_VISIT(&self->user_buffer.obj);
+        }
+        break;
+    }
+    return 0;
+}
+
+
 static PyMethodDef Overlapped_methods[] = {
     {"getresult", (PyCFunction) Overlapped_getresult,
      METH_VARARGS, Overlapped_getresult_doc},
@@ -1408,7 +1440,7 @@ PyTypeObject OverlappedType = {
     /* tp_as_buffer      */ 0,
     /* tp_flags          */ Py_TPFLAGS_DEFAULT,
     /* tp_doc            */ "OVERLAPPED structure wrapper",
-    /* tp_traverse       */ 0,
+    /* tp_traverse       */ (traverseproc)Overlapped_traverse,
     /* tp_clear          */ 0,
     /* tp_richcompare    */ 0,
     /* tp_weaklistoffset */ 0,
index 5403660ba45e98ca4255e393f4bd134f9131a5aa..e7a1f987def9a75e1063599033894ba831d39c54 100644 (file)
@@ -393,6 +393,10 @@ static int win32_can_symlink = 0;
 #define HAVE_STRUCT_STAT_ST_FSTYPE 1
 #endif
 
+#ifdef _Py_MEMORY_SANITIZER
+# include <sanitizer/msan_interface.h>
+#endif
+
 #ifdef HAVE_FORK
 static void
 run_at_forkers(PyObject *lst, int reverse)
@@ -975,28 +979,35 @@ path_converter(PyObject *o, void *p)
     if (!is_index && !is_buffer && !is_unicode && !is_bytes) {
         /* Inline PyOS_FSPath() for better error messages. */
         _Py_IDENTIFIER(__fspath__);
-        PyObject *func = NULL;
+        PyObject *func, *res;
 
         func = _PyObject_LookupSpecial(o, &PyId___fspath__);
         if (NULL == func) {
             goto error_format;
         }
-        /* still owns a reference to the original object */
-        Py_DECREF(o);
-        o = _PyObject_CallNoArg(func);
+        res = _PyObject_CallNoArg(func);
         Py_DECREF(func);
-        if (NULL == o) {
+        if (NULL == res) {
             goto error_exit;
         }
-        else if (PyUnicode_Check(o)) {
+        else if (PyUnicode_Check(res)) {
             is_unicode = 1;
         }
-        else if (PyBytes_Check(o)) {
+        else if (PyBytes_Check(res)) {
             is_bytes = 1;
         }
         else {
-            goto error_format;
+            PyErr_Format(PyExc_TypeError,
+                 "expected %.200s.__fspath__() to return str or bytes, "
+                 "not %.200s", Py_TYPE(o)->tp_name,
+                 Py_TYPE(res)->tp_name);
+            Py_DECREF(res);
+            goto error_exit;
         }
+
+        /* still owns a reference to the original object */
+        Py_DECREF(o);
+        o = res;
     }
 
     if (is_unicode) {
@@ -1612,11 +1623,6 @@ get_target_path(HANDLE hdl, wchar_t **target_path)
         return FALSE;
     }
 
-    if(!CloseHandle(hdl)) {
-        PyMem_RawFree(buf);
-        return FALSE;
-    }
-
     buf[result_length] = 0;
 
     *target_path = buf;
@@ -1674,9 +1680,10 @@ win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
             return -1;
         }
         if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
-            if (!win32_get_reparse_tag(hFile, &reparse_tag))
+            if (!win32_get_reparse_tag(hFile, &reparse_tag)) {
+                CloseHandle(hFile);
                 return -1;
-
+            }
             /* Close the outer open file handle now that we're about to
                reopen it with different flags. */
             if (!CloseHandle(hFile))
@@ -1693,8 +1700,14 @@ win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
                 if (hFile2 == INVALID_HANDLE_VALUE)
                     return -1;
 
-                if (!get_target_path(hFile2, &target_path))
+                if (!get_target_path(hFile2, &target_path)) {
+                    CloseHandle(hFile2);
+                    return -1;
+                }
+
+                if (!CloseHandle(hFile2)) {
                     return -1;
+                }
 
                 code = win32_xstat_impl(target_path, result, FALSE);
                 PyMem_RawFree(target_path);
@@ -4116,13 +4129,13 @@ If either src_dir_fd or dst_dir_fd is not None, it should be a file
   descriptor open to a directory, and the respective path string (src or dst)
   should be relative; the path will then be relative to that directory.
 src_dir_fd and dst_dir_fd, may not be implemented on your platform.
-  If they are unavailable, using them will raise a NotImplementedError."
+  If they are unavailable, using them will raise a NotImplementedError.
 [clinic start generated code]*/
 
 static PyObject *
 os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
                 int dst_dir_fd)
-/*[clinic end generated code: output=1968c02e7857422b input=25515dfb107c8421]*/
+/*[clinic end generated code: output=1968c02e7857422b input=c003f0def43378ef]*/
 {
     return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
 }
@@ -4181,8 +4194,8 @@ Execute the command in a subshell.
 [clinic start generated code]*/
 
 static long
-os_system_impl(PyObject *module, Py_UNICODE *command)
-/*[clinic end generated code: output=96c4dffee36dfb48 input=303f5ce97df606b0]*/
+os_system_impl(PyObject *module, const Py_UNICODE *command)
+/*[clinic end generated code: output=5b7c3599c068ca42 input=303f5ce97df606b0]*/
 {
     long result;
     Py_BEGIN_ALLOW_THREADS
@@ -5689,6 +5702,9 @@ os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
         posix_error();
         return -1.0;
     }
+#ifdef _Py_MEMORY_SANITIZER
+    __msan_unpoison(&interval, sizeof(interval));
+#endif
     return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
 }
 #endif /* HAVE_SCHED_RR_GET_INTERVAL */
@@ -5926,7 +5942,7 @@ os_openpty_impl(PyObject *module)
 #endif
 #if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
     PyOS_sighandler_t sig_saved;
-#ifdef sun
+#if defined(__sun) && defined(__SVR4)
     extern char *ptsname(int fildes);
 #endif
 #endif
@@ -6155,6 +6171,12 @@ posix_getgrouplist(PyObject *self, PyObject *args)
         return posix_error();
     }
 
+#ifdef _Py_MEMORY_SANITIZER
+    /* Clang memory sanitizer libc intercepts don't know getgrouplist. */
+    __msan_unpoison(&ngroups, sizeof(ngroups));
+    __msan_unpoison(groups, ngroups*sizeof(*groups));
+#endif
+
     list = PyList_New(ngroups);
     if (list == NULL) {
         PyMem_Del(groups);
@@ -10792,8 +10814,9 @@ the underlying Win32 ShellExecute function doesn't work if it is.
 [clinic start generated code]*/
 
 static PyObject *
-os_startfile_impl(PyObject *module, path_t *filepath, Py_UNICODE *operation)
-/*[clinic end generated code: output=912ceba79acfa1c9 input=63950bf2986380d0]*/
+os_startfile_impl(PyObject *module, path_t *filepath,
+                  const Py_UNICODE *operation)
+/*[clinic end generated code: output=66dc311c94d50797 input=63950bf2986380d0]*/
 {
     HINSTANCE rc;
 
index e6d3f8be6edeeaa67fbe142e41dc86dab9b663a5..988471e15fbe3025ce12867fd239766b85f4a0fb 100644 (file)
@@ -100,6 +100,10 @@ Local naming conventions:
 #include "Python.h"
 #include "structmember.h"
 
+#ifdef _Py_MEMORY_SANITIZER
+# include <sanitizer/msan_interface.h>
+#endif
+
 /* Socket object documentation */
 PyDoc_STRVAR(sock_doc,
 "socket(family=AF_INET, type=SOCK_STREAM, proto=0) -> socket object\n\
@@ -261,7 +265,7 @@ http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/net/getaddrinfo.c.diff?r1=1.82&
 #endif
 
 /* Solaris fails to define this variable at all. */
-#if defined(sun) && !defined(INET_ADDRSTRLEN)
+#if (defined(__sun) && defined(__SVR4)) && !defined(INET_ADDRSTRLEN)
 #define INET_ADDRSTRLEN 16
 #endif
 
@@ -6463,7 +6467,23 @@ socket_if_nameindex(PyObject *self, PyObject *arg)
         return NULL;
     }
 
+#ifdef _Py_MEMORY_SANITIZER
+    __msan_unpoison(ni, sizeof(ni));
+    __msan_unpoison(&ni[0], sizeof(ni[0]));
+#endif
     for (i = 0; ni[i].if_index != 0 && i < INT_MAX; i++) {
+#ifdef _Py_MEMORY_SANITIZER
+        /* This one isn't the end sentinel, the next one must exist. */
+        __msan_unpoison(&ni[i+1], sizeof(ni[0]));
+        /* Otherwise Py_BuildValue internals are flagged by MSan when
+           they access the not-msan-tracked if_name string data. */
+        {
+            char *to_sanitize = ni[i].if_name;
+            do {
+                __msan_unpoison(to_sanitize, 1);
+            } while (*to_sanitize++ != '\0');
+        }
+#endif
         PyObject *ni_tuple = Py_BuildValue("IO&",
                 ni[i].if_index, PyUnicode_DecodeFSDefault, ni[i].if_name);
 
index 44948e21ad9553af8514625ce952a9028b3c2085..437ab43f434a62ab5b3fdd892c52c1df24b40f32 100644 (file)
@@ -1363,6 +1363,10 @@ exit:
     return ret; /* should never get here */
 }
 
+/* need to reset capturing groups between two SRE(match) callings in loops */
+#define RESET_CAPTURE_GROUP() \
+    do { state->lastmark = state->lastindex = -1; } while (0)
+
 LOCAL(Py_ssize_t)
 SRE(search)(SRE_STATE* state, SRE_CODE* pattern)
 {
@@ -1440,6 +1444,7 @@ SRE(search)(SRE_STATE* state, SRE_CODE* pattern)
             if (status != 0)
                 return status;
             ++ptr;
+            RESET_CAPTURE_GROUP();
         }
         return 0;
     }
@@ -1487,6 +1492,7 @@ SRE(search)(SRE_STATE* state, SRE_CODE* pattern)
                     /* close but no cigar -- try again */
                     if (++ptr >= end)
                         return 0;
+                    RESET_CAPTURE_GROUP();
                 }
                 i = overlap[i];
             } while (i != 0);
@@ -1510,6 +1516,7 @@ SRE(search)(SRE_STATE* state, SRE_CODE* pattern)
             if (status != 0)
                 break;
             ptr++;
+            RESET_CAPTURE_GROUP();
         }
     } else {
         /* general case */
@@ -1520,6 +1527,7 @@ SRE(search)(SRE_STATE* state, SRE_CODE* pattern)
         state->must_advance = 0;
         while (status == 0 && ptr < end) {
             ptr++;
+            RESET_CAPTURE_GROUP();
             TRACE(("|%p|%p|SEARCH\n", pattern, ptr));
             state->start = state->ptr = ptr;
             status = SRE(match)(state, pattern, 0);
index 13a174a4ea87796098c5bdca5780f7ac8e0ba113..ae7de5b2c7664086c0782b925e7341bc9ada9618 100644 (file)
 #endif /* MS_WINDOWS */
 #endif /* !__WATCOMC__ || __QNX__ */
 
+#ifdef _Py_MEMORY_SANITIZER
+# include <sanitizer/msan_interface.h>
+#endif
+
+#ifdef _MSC_VER
+#define _Py_timezone _timezone
+#define _Py_daylight _daylight
+#define _Py_tzname _tzname
+#else
+#define _Py_timezone timezone
+#define _Py_daylight daylight
+#define _Py_tzname tzname
+#endif
+
 #define SEC_TO_NS (1000 * 1000 * 1000)
 
 /* Forward declarations */
@@ -331,6 +345,9 @@ time_pthread_getcpuclockid(PyObject *self, PyObject *args)
         PyErr_SetFromErrno(PyExc_OSError);
         return NULL;
     }
+#ifdef _Py_MEMORY_SANITIZER
+    __msan_unpoison(&clk_id, sizeof(clk_id));
+#endif
     return PyLong_FromLong(clk_id);
 }
 
@@ -718,7 +735,7 @@ time_strftime(PyObject *self, PyObject *args)
         return NULL;
     }
 
-#if defined(_MSC_VER) || defined(sun) || defined(_AIX)
+#if defined(_MSC_VER) || (defined(__sun) && defined(__SVR4)) || defined(_AIX)
     if (buf.tm_year + 1900 < 1 || 9999 < buf.tm_year + 1900) {
         PyErr_SetString(PyExc_ValueError,
                         "strftime() requires year in [1; 9999]");
@@ -764,7 +781,7 @@ time_strftime(PyObject *self, PyObject *args)
             return NULL;
         }
     }
-#elif (defined(_AIX) || defined(sun)) && defined(HAVE_WCSFTIME)
+#elif (defined(_AIX) || (defined(__sun) && defined(__SVR4))) && defined(HAVE_WCSFTIME)
     for (outbuf = wcschr(fmt, '%');
         outbuf != NULL;
         outbuf = wcschr(outbuf+2, '%'))
@@ -1547,18 +1564,18 @@ init_timezone(PyObject *m)
 #if defined(HAVE_TZNAME) && !defined(__GLIBC__) && !defined(__CYGWIN__)
     PyObject *otz0, *otz1;
     tzset();
-    PyModule_AddIntConstant(m, "timezone", timezone);
+    PyModule_AddIntConstant(m, "timezone", _Py_timezone);
 #ifdef HAVE_ALTZONE
     PyModule_AddIntConstant(m, "altzone", altzone);
 #else
-    PyModule_AddIntConstant(m, "altzone", timezone-3600);
+    PyModule_AddIntConstant(m, "altzone", _Py_timezone-3600);
 #endif
-    PyModule_AddIntConstant(m, "daylight", daylight);
-    otz0 = PyUnicode_DecodeLocale(tzname[0], "surrogateescape");
+    PyModule_AddIntConstant(m, "daylight", _Py_daylight);
+    otz0 = PyUnicode_DecodeLocale(_Py_tzname[0], "surrogateescape");
     if (otz0 == NULL) {
         return -1;
     }
-    otz1 = PyUnicode_DecodeLocale(tzname[1], "surrogateescape");
+    otz1 = PyUnicode_DecodeLocale(_Py_tzname[1], "surrogateescape");
     if (otz1 == NULL) {
         Py_DECREF(otz0);
         return -1;
index 2d48a112aabcec105b9c32bfbdc99634e94390a4..9416df4321f3f9e795797ad1a5210f22761b1c46 100644 (file)
@@ -143,6 +143,7 @@ PyObject *
 PyObject_GetItem(PyObject *o, PyObject *key)
 {
     PyMappingMethods *m;
+    PySequenceMethods *ms;
 
     if (o == NULL || key == NULL) {
         return null_error();
@@ -155,7 +156,8 @@ PyObject_GetItem(PyObject *o, PyObject *key)
         return item;
     }
 
-    if (o->ob_type->tp_as_sequence) {
+    ms = o->ob_type->tp_as_sequence;
+    if (ms && ms->sq_item) {
         if (PyIndex_Check(key)) {
             Py_ssize_t key_value;
             key_value = PyNumber_AsSsize_t(key, PyExc_IndexError);
@@ -163,9 +165,10 @@ PyObject_GetItem(PyObject *o, PyObject *key)
                 return NULL;
             return PySequence_GetItem(o, key_value);
         }
-        else if (o->ob_type->tp_as_sequence->sq_item)
+        else {
             return type_error("sequence index must "
                               "be integer, not '%.200s'", key);
+        }
     }
 
     if (PyType_Check(o)) {
index 711faba645488fd8b94c5ae1f8796b6d24ae0d5a..172c7f38b9e258a6db2c90e578571e78f817399d 100644 (file)
@@ -311,9 +311,15 @@ PyBytes_FromFormatV(const char *format, va_list vargs)
             Py_ssize_t i;
 
             p = va_arg(vargs, const char*);
-            i = strlen(p);
-            if (prec > 0 && i > prec)
-                i = prec;
+            if (prec <= 0) {
+                i = strlen(p);
+            }
+            else {
+                i = 0;
+                while (i < prec && p[i]) {
+                    i++;
+                }
+            }
             s = _PyBytesWriter_WriteBytes(&writer, s, p, i);
             if (s == NULL)
                 goto error;
@@ -2990,9 +2996,22 @@ _PyBytes_Resize(PyObject **pv, Py_ssize_t newsize)
         /* return early if newsize equals to v->ob_size */
         return 0;
     }
+    if (Py_SIZE(v) == 0) {
+        if (newsize == 0) {
+            return 0;
+        }
+        *pv = _PyBytes_FromSize(newsize, 0);
+        Py_DECREF(v);
+        return (*pv == NULL) ? -1 : 0;
+    }
     if (Py_REFCNT(v) != 1) {
         goto error;
     }
+    if (newsize == 0) {
+        *pv = _PyBytes_FromSize(0, 0);
+        Py_DECREF(v);
+        return (*pv == NULL) ? -1 : 0;
+    }
     /* XXX UNREF/NEWREF interface should be more symmetrical */
     _Py_DEC_REFTOTAL;
     _Py_ForgetReference(v);
index ed4e12ba8a8deedd2fb3447d85bd934824060b84..d886e96e0f9b78d56f662d7560fb9d5590cb1696 100644 (file)
@@ -407,7 +407,7 @@ stdprinter_fileno(PyStdPrinter_Object *self)
 static PyObject *
 stdprinter_repr(PyStdPrinter_Object *self)
 {
-    return PyUnicode_FromFormat("<stdprinter(fd=%d) object at 0x%x>",
+    return PyUnicode_FromFormat("<stdprinter(fd=%d) object at %p>",
                                 self->fd, self);
 }
 
index 4ef10d0eb7bcd6c4097f8029db11222f87fdff9d..4362615cb08986671c20a5540c20533403caf475 100644 (file)
@@ -90,6 +90,10 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore
     int blockstack_top = 0;             /* (ditto) */
     unsigned char setup_op = 0;         /* (ditto) */
 
+    if (p_new_lineno == NULL) {
+        PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
+        return -1;
+    }
     /* f_lineno must be an integer. */
     if (!PyLong_CheckExact(p_new_lineno)) {
         PyErr_SetString(PyExc_ValueError,
index c8ffeff09368de048b8837f7f5d4853da6f0231d..7dc68a73bdb626bc870db614b7d3d65753533f89 100644 (file)
@@ -2232,7 +2232,6 @@ list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse)
         int ints_are_bounded = 1;
 
         /* Prove that assumption by checking every key. */
-        int i;
         for (i=0; i < saved_ob_size; i++) {
 
             if (keys_are_in_tuples &&
@@ -2280,6 +2279,9 @@ list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse)
             else if ((ms.key_richcompare = key_type->tp_richcompare) != NULL) {
                 ms.key_compare = unsafe_object_compare;
             }
+            else {
+                ms.key_compare = safe_object_compare;
+            }
         }
         else {
             ms.key_compare = safe_object_compare;
index 59f084d1a612cc36c2fa4e63a913a9d9b1f89a96..4d5212f6f0cbc8a531f9f3c4340e0c4a87e6f7be 100644 (file)
@@ -564,14 +564,11 @@ static PyMethodDef slice_methods[] = {
 static PyObject *
 slice_richcompare(PyObject *v, PyObject *w, int op)
 {
-    PyObject *t1;
-    PyObject *t2;
-    PyObject *res;
-
     if (!PySlice_Check(v) || !PySlice_Check(w))
         Py_RETURN_NOTIMPLEMENTED;
 
     if (v == w) {
+        PyObject *res;
         /* XXX Do we really need this shortcut?
            There's a unit test for it, but is that fair? */
         switch (op) {
@@ -588,34 +585,27 @@ slice_richcompare(PyObject *v, PyObject *w, int op)
         return res;
     }
 
-    t1 = PyTuple_New(3);
-    if (t1 == NULL)
+
+    PyObject *t1 = PyTuple_Pack(3,
+                                ((PySliceObject *)v)->start,
+                                ((PySliceObject *)v)->stop,
+                                ((PySliceObject *)v)->step);
+    if (t1 == NULL) {
         return NULL;
-    t2 = PyTuple_New(3);
+    }
+
+    PyObject *t2 = PyTuple_Pack(3,
+                                ((PySliceObject *)w)->start,
+                                ((PySliceObject *)w)->stop,
+                                ((PySliceObject *)w)->step);
     if (t2 == NULL) {
         Py_DECREF(t1);
         return NULL;
     }
 
-    PyTuple_SET_ITEM(t1, 0, ((PySliceObject *)v)->start);
-    PyTuple_SET_ITEM(t1, 1, ((PySliceObject *)v)->stop);
-    PyTuple_SET_ITEM(t1, 2, ((PySliceObject *)v)->step);
-    PyTuple_SET_ITEM(t2, 0, ((PySliceObject *)w)->start);
-    PyTuple_SET_ITEM(t2, 1, ((PySliceObject *)w)->stop);
-    PyTuple_SET_ITEM(t2, 2, ((PySliceObject *)w)->step);
-
-    res = PyObject_RichCompare(t1, t2, op);
-
-    PyTuple_SET_ITEM(t1, 0, NULL);
-    PyTuple_SET_ITEM(t1, 1, NULL);
-    PyTuple_SET_ITEM(t1, 2, NULL);
-    PyTuple_SET_ITEM(t2, 0, NULL);
-    PyTuple_SET_ITEM(t2, 1, NULL);
-    PyTuple_SET_ITEM(t2, 2, NULL);
-
+    PyObject *res = PyObject_RichCompare(t1, t2, op);
     Py_DECREF(t1);
     Py_DECREF(t2);
-
     return res;
 }
 
index 468210574119732e8ae6f5f05d70643f6b2d95f6..c578d6e9354568ca591d90394dd956475f31665a 100644 (file)
@@ -3654,11 +3654,13 @@ object_init(PyObject *self, PyObject *args, PyObject *kwds)
     PyTypeObject *type = Py_TYPE(self);
     if (excess_args(args, kwds)) {
         if (type->tp_init != object_init) {
-            PyErr_SetString(PyExc_TypeError, "object.__init__() takes no arguments");
+            PyErr_SetString(PyExc_TypeError,
+                            "object.__init__() takes exactly one argument (the instance to initialize)");
             return -1;
         }
         if (type->tp_new == object_new) {
-            PyErr_Format(PyExc_TypeError, "%.200s().__init__() takes no arguments",
+            PyErr_Format(PyExc_TypeError,
+                         "%.200s.__init__() takes exactly one argument (the instance to initialize)",
                          type->tp_name);
             return -1;
         }
@@ -3671,7 +3673,8 @@ object_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 {
     if (excess_args(args, kwds)) {
         if (type->tp_new != object_new) {
-            PyErr_SetString(PyExc_TypeError, "object.__new__() takes no arguments");
+            PyErr_SetString(PyExc_TypeError,
+                            "object.__new__() takes exactly one argument (the type to instantiate)");
             return NULL;
         }
         if (type->tp_init == object_init) {
index d46ab2a1e2ab8d24a0c39488d69729ba6165792c..b67ffac4e9fb98466246df28baef948c0abd8e66 100644 (file)
@@ -2579,9 +2579,15 @@ unicode_fromformat_write_cstr(_PyUnicodeWriter *writer, const char *str,
     PyObject *unicode;
     int res;
 
-    length = strlen(str);
-    if (precision != -1)
-        length = Py_MIN(length, precision);
+    if (precision == -1) {
+        length = strlen(str);
+    }
+    else {
+        length = 0;
+        while (length < precision && str[length]) {
+            length++;
+        }
+    }
     unicode = PyUnicode_DecodeUTF8Stateful(str, length, "replace", NULL);
     if (unicode == NULL)
         return -1;
@@ -9356,6 +9362,7 @@ _PyUnicode_InsertThousandsGrouping(
     PyObject *thousands_sep,
     Py_UCS4 *maxchar)
 {
+    min_width = Py_MAX(0, min_width);
     if (writer) {
         assert(digits != NULL);
         assert(maxchar == NULL);
@@ -9366,7 +9373,6 @@ _PyUnicode_InsertThousandsGrouping(
     }
     assert(0 <= d_pos);
     assert(0 <= n_digits);
-    assert(0 <= min_width);
     assert(grouping != NULL);
 
     if (digits != NULL) {
index 024b2d3c9fd301ff5fcc26b45650b9c0cbc8ae83..ae30acbc9b48d4c07f99f57e6a8986c85883daa5 100644 (file)
--- a/PC/_msi.c
+++ b/PC/_msi.c
@@ -555,7 +555,7 @@ summary_getproperty(msiobj* si, PyObject *args)
     FILETIME fval;
     char sbuf[1000];
     char *sval = sbuf;
-    DWORD ssize = sizeof(sval);
+    DWORD ssize = sizeof(sbuf);
 
     if (!PyArg_ParseTuple(args, "i:GetProperty", &field))
         return NULL;
@@ -563,6 +563,7 @@ summary_getproperty(msiobj* si, PyObject *args)
     status = MsiSummaryInfoGetProperty(si->h, field, &type, &ival,
         &fval, sval, &ssize);
     if (status == ERROR_MORE_DATA) {
+        ssize++;
         sval = malloc(ssize);
         if (sval == NULL) {
             return PyErr_NoMemory();
@@ -572,21 +573,29 @@ summary_getproperty(msiobj* si, PyObject *args)
     }
 
     switch(type) {
-        case VT_I2: case VT_I4:
-            return PyLong_FromLong(ival);
+        case VT_I2:
+        case VT_I4:
+            result = PyLong_FromLong(ival);
+            break;
         case VT_FILETIME:
             PyErr_SetString(PyExc_NotImplementedError, "FILETIME result");
-            return NULL;
+            result = NULL;
+            break;
         case VT_LPSTR:
             result = PyBytes_FromStringAndSize(sval, ssize);
-            if (sval != sbuf)
-                free(sval);
-            return result;
+            break;
         case VT_EMPTY:
-            Py_RETURN_NONE;
+            Py_INCREF(Py_None);
+            result = Py_None;
+            break;
+        default:
+            PyErr_Format(PyExc_NotImplementedError, "result of type %d", type);
+            result = NULL;
+            break;
     }
-    PyErr_Format(PyExc_NotImplementedError, "result of type %d", type);
-    return NULL;
+    if (sval != sbuf)
+        free(sval);
+    return result;
 }
 
 static PyObject*
@@ -907,7 +916,7 @@ msidb_getsummaryinformation(msiobj *db, PyObject *args)
         return msierror(status);
 
     oresult = PyObject_NEW(struct msiobj, &summary_Type);
-    if (!result) {
+    if (!oresult) {
         MsiCloseHandle(result);
         return NULL;
     }
index 69781a9692854a8b607514bb7f7d9ba4981fba79..6a5f613808c2e7e8cc5a69d14b70554d8fe34ba7 100644 (file)
@@ -137,14 +137,14 @@ PyDoc_STRVAR(winreg_ConnectRegistry__doc__,
     {"ConnectRegistry", (PyCFunction)winreg_ConnectRegistry, METH_FASTCALL, winreg_ConnectRegistry__doc__},
 
 static HKEY
-winreg_ConnectRegistry_impl(PyObject *module, Py_UNICODE *computer_name,
-                            HKEY key);
+winreg_ConnectRegistry_impl(PyObject *module,
+                            const Py_UNICODE *computer_name, HKEY key);
 
 static PyObject *
 winreg_ConnectRegistry(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
 {
     PyObject *return_value = NULL;
-    Py_UNICODE *computer_name;
+    const Py_UNICODE *computer_name;
     HKEY key;
     HKEY _return_value;
 
@@ -185,14 +185,14 @@ PyDoc_STRVAR(winreg_CreateKey__doc__,
     {"CreateKey", (PyCFunction)winreg_CreateKey, METH_FASTCALL, winreg_CreateKey__doc__},
 
 static HKEY
-winreg_CreateKey_impl(PyObject *module, HKEY key, Py_UNICODE *sub_key);
+winreg_CreateKey_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key);
 
 static PyObject *
 winreg_CreateKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
 {
     PyObject *return_value = NULL;
     HKEY key;
-    Py_UNICODE *sub_key;
+    const Py_UNICODE *sub_key;
     HKEY _return_value;
 
     if (!_PyArg_ParseStack(args, nargs, "O&Z:CreateKey",
@@ -238,8 +238,9 @@ PyDoc_STRVAR(winreg_CreateKeyEx__doc__,
     {"CreateKeyEx", (PyCFunction)winreg_CreateKeyEx, METH_FASTCALL|METH_KEYWORDS, winreg_CreateKeyEx__doc__},
 
 static HKEY
-winreg_CreateKeyEx_impl(PyObject *module, HKEY key, Py_UNICODE *sub_key,
-                        int reserved, REGSAM access);
+winreg_CreateKeyEx_impl(PyObject *module, HKEY key,
+                        const Py_UNICODE *sub_key, int reserved,
+                        REGSAM access);
 
 static PyObject *
 winreg_CreateKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
@@ -248,7 +249,7 @@ winreg_CreateKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py
     static const char * const _keywords[] = {"key", "sub_key", "reserved", "access", NULL};
     static _PyArg_Parser _parser = {"O&Z|ii:CreateKeyEx", _keywords, 0};
     HKEY key;
-    Py_UNICODE *sub_key;
+    const Py_UNICODE *sub_key;
     int reserved = 0;
     REGSAM access = KEY_WRITE;
     HKEY _return_value;
@@ -289,14 +290,14 @@ PyDoc_STRVAR(winreg_DeleteKey__doc__,
     {"DeleteKey", (PyCFunction)winreg_DeleteKey, METH_FASTCALL, winreg_DeleteKey__doc__},
 
 static PyObject *
-winreg_DeleteKey_impl(PyObject *module, HKEY key, Py_UNICODE *sub_key);
+winreg_DeleteKey_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key);
 
 static PyObject *
 winreg_DeleteKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
 {
     PyObject *return_value = NULL;
     HKEY key;
-    Py_UNICODE *sub_key;
+    const Py_UNICODE *sub_key;
 
     if (!_PyArg_ParseStack(args, nargs, "O&u:DeleteKey",
         clinic_HKEY_converter, &key, &sub_key)) {
@@ -337,8 +338,9 @@ PyDoc_STRVAR(winreg_DeleteKeyEx__doc__,
     {"DeleteKeyEx", (PyCFunction)winreg_DeleteKeyEx, METH_FASTCALL|METH_KEYWORDS, winreg_DeleteKeyEx__doc__},
 
 static PyObject *
-winreg_DeleteKeyEx_impl(PyObject *module, HKEY key, Py_UNICODE *sub_key,
-                        REGSAM access, int reserved);
+winreg_DeleteKeyEx_impl(PyObject *module, HKEY key,
+                        const Py_UNICODE *sub_key, REGSAM access,
+                        int reserved);
 
 static PyObject *
 winreg_DeleteKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
@@ -347,7 +349,7 @@ winreg_DeleteKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py
     static const char * const _keywords[] = {"key", "sub_key", "access", "reserved", NULL};
     static _PyArg_Parser _parser = {"O&u|ii:DeleteKeyEx", _keywords, 0};
     HKEY key;
-    Py_UNICODE *sub_key;
+    const Py_UNICODE *sub_key;
     REGSAM access = KEY_WOW64_64KEY;
     int reserved = 0;
 
@@ -376,14 +378,14 @@ PyDoc_STRVAR(winreg_DeleteValue__doc__,
     {"DeleteValue", (PyCFunction)winreg_DeleteValue, METH_FASTCALL, winreg_DeleteValue__doc__},
 
 static PyObject *
-winreg_DeleteValue_impl(PyObject *module, HKEY key, Py_UNICODE *value);
+winreg_DeleteValue_impl(PyObject *module, HKEY key, const Py_UNICODE *value);
 
 static PyObject *
 winreg_DeleteValue(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
 {
     PyObject *return_value = NULL;
     HKEY key;
-    Py_UNICODE *value;
+    const Py_UNICODE *value;
 
     if (!_PyArg_ParseStack(args, nargs, "O&Z:DeleteValue",
         clinic_HKEY_converter, &key, &value)) {
@@ -490,13 +492,14 @@ PyDoc_STRVAR(winreg_ExpandEnvironmentStrings__doc__,
     {"ExpandEnvironmentStrings", (PyCFunction)winreg_ExpandEnvironmentStrings, METH_O, winreg_ExpandEnvironmentStrings__doc__},
 
 static PyObject *
-winreg_ExpandEnvironmentStrings_impl(PyObject *module, Py_UNICODE *string);
+winreg_ExpandEnvironmentStrings_impl(PyObject *module,
+                                     const Py_UNICODE *string);
 
 static PyObject *
 winreg_ExpandEnvironmentStrings(PyObject *module, PyObject *arg)
 {
     PyObject *return_value = NULL;
-    Py_UNICODE *string;
+    const Py_UNICODE *string;
 
     if (!PyArg_Parse(arg, "u:ExpandEnvironmentStrings", &string)) {
         goto exit;
@@ -579,16 +582,16 @@ PyDoc_STRVAR(winreg_LoadKey__doc__,
     {"LoadKey", (PyCFunction)winreg_LoadKey, METH_FASTCALL, winreg_LoadKey__doc__},
 
 static PyObject *
-winreg_LoadKey_impl(PyObject *module, HKEY key, Py_UNICODE *sub_key,
-                    Py_UNICODE *file_name);
+winreg_LoadKey_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key,
+                    const Py_UNICODE *file_name);
 
 static PyObject *
 winreg_LoadKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
 {
     PyObject *return_value = NULL;
     HKEY key;
-    Py_UNICODE *sub_key;
-    Py_UNICODE *file_name;
+    const Py_UNICODE *sub_key;
+    const Py_UNICODE *file_name;
 
     if (!_PyArg_ParseStack(args, nargs, "O&uu:LoadKey",
         clinic_HKEY_converter, &key, &sub_key, &file_name)) {
@@ -623,7 +626,7 @@ PyDoc_STRVAR(winreg_OpenKey__doc__,
     {"OpenKey", (PyCFunction)winreg_OpenKey, METH_FASTCALL|METH_KEYWORDS, winreg_OpenKey__doc__},
 
 static HKEY
-winreg_OpenKey_impl(PyObject *module, HKEY key, Py_UNICODE *sub_key,
+winreg_OpenKey_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key,
                     int reserved, REGSAM access);
 
 static PyObject *
@@ -633,7 +636,7 @@ winreg_OpenKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje
     static const char * const _keywords[] = {"key", "sub_key", "reserved", "access", NULL};
     static _PyArg_Parser _parser = {"O&Z|ii:OpenKey", _keywords, 0};
     HKEY key;
-    Py_UNICODE *sub_key;
+    const Py_UNICODE *sub_key;
     int reserved = 0;
     REGSAM access = KEY_READ;
     HKEY _return_value;
@@ -675,7 +678,7 @@ PyDoc_STRVAR(winreg_OpenKeyEx__doc__,
     {"OpenKeyEx", (PyCFunction)winreg_OpenKeyEx, METH_FASTCALL|METH_KEYWORDS, winreg_OpenKeyEx__doc__},
 
 static HKEY
-winreg_OpenKeyEx_impl(PyObject *module, HKEY key, Py_UNICODE *sub_key,
+winreg_OpenKeyEx_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key,
                       int reserved, REGSAM access);
 
 static PyObject *
@@ -685,7 +688,7 @@ winreg_OpenKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb
     static const char * const _keywords[] = {"key", "sub_key", "reserved", "access", NULL};
     static _PyArg_Parser _parser = {"O&Z|ii:OpenKeyEx", _keywords, 0};
     HKEY key;
-    Py_UNICODE *sub_key;
+    const Py_UNICODE *sub_key;
     int reserved = 0;
     REGSAM access = KEY_READ;
     HKEY _return_value;
@@ -764,14 +767,14 @@ PyDoc_STRVAR(winreg_QueryValue__doc__,
     {"QueryValue", (PyCFunction)winreg_QueryValue, METH_FASTCALL, winreg_QueryValue__doc__},
 
 static PyObject *
-winreg_QueryValue_impl(PyObject *module, HKEY key, Py_UNICODE *sub_key);
+winreg_QueryValue_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key);
 
 static PyObject *
 winreg_QueryValue(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
 {
     PyObject *return_value = NULL;
     HKEY key;
-    Py_UNICODE *sub_key;
+    const Py_UNICODE *sub_key;
 
     if (!_PyArg_ParseStack(args, nargs, "O&Z:QueryValue",
         clinic_HKEY_converter, &key, &sub_key)) {
@@ -803,14 +806,14 @@ PyDoc_STRVAR(winreg_QueryValueEx__doc__,
     {"QueryValueEx", (PyCFunction)winreg_QueryValueEx, METH_FASTCALL, winreg_QueryValueEx__doc__},
 
 static PyObject *
-winreg_QueryValueEx_impl(PyObject *module, HKEY key, Py_UNICODE *name);
+winreg_QueryValueEx_impl(PyObject *module, HKEY key, const Py_UNICODE *name);
 
 static PyObject *
 winreg_QueryValueEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
 {
     PyObject *return_value = NULL;
     HKEY key;
-    Py_UNICODE *name;
+    const Py_UNICODE *name;
 
     if (!_PyArg_ParseStack(args, nargs, "O&Z:QueryValueEx",
         clinic_HKEY_converter, &key, &name)) {
@@ -847,14 +850,14 @@ PyDoc_STRVAR(winreg_SaveKey__doc__,
     {"SaveKey", (PyCFunction)winreg_SaveKey, METH_FASTCALL, winreg_SaveKey__doc__},
 
 static PyObject *
-winreg_SaveKey_impl(PyObject *module, HKEY key, Py_UNICODE *file_name);
+winreg_SaveKey_impl(PyObject *module, HKEY key, const Py_UNICODE *file_name);
 
 static PyObject *
 winreg_SaveKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
 {
     PyObject *return_value = NULL;
     HKEY key;
-    Py_UNICODE *file_name;
+    const Py_UNICODE *file_name;
 
     if (!_PyArg_ParseStack(args, nargs, "O&u:SaveKey",
         clinic_HKEY_converter, &key, &file_name)) {
@@ -896,8 +899,8 @@ PyDoc_STRVAR(winreg_SetValue__doc__,
     {"SetValue", (PyCFunction)winreg_SetValue, METH_FASTCALL, winreg_SetValue__doc__},
 
 static PyObject *
-winreg_SetValue_impl(PyObject *module, HKEY key, Py_UNICODE *sub_key,
-                     DWORD type, Py_UNICODE *value,
+winreg_SetValue_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key,
+                     DWORD type, const Py_UNICODE *value,
                      Py_ssize_clean_t value_length);
 
 static PyObject *
@@ -905,9 +908,9 @@ winreg_SetValue(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
 {
     PyObject *return_value = NULL;
     HKEY key;
-    Py_UNICODE *sub_key;
+    const Py_UNICODE *sub_key;
     DWORD type;
-    Py_UNICODE *value;
+    const Py_UNICODE *value;
     Py_ssize_clean_t value_length;
 
     if (!_PyArg_ParseStack(args, nargs, "O&Zku#:SetValue",
@@ -967,15 +970,16 @@ PyDoc_STRVAR(winreg_SetValueEx__doc__,
     {"SetValueEx", (PyCFunction)winreg_SetValueEx, METH_FASTCALL, winreg_SetValueEx__doc__},
 
 static PyObject *
-winreg_SetValueEx_impl(PyObject *module, HKEY key, Py_UNICODE *value_name,
-                       PyObject *reserved, DWORD type, PyObject *value);
+winreg_SetValueEx_impl(PyObject *module, HKEY key,
+                       const Py_UNICODE *value_name, PyObject *reserved,
+                       DWORD type, PyObject *value);
 
 static PyObject *
 winreg_SetValueEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
 {
     PyObject *return_value = NULL;
     HKEY key;
-    Py_UNICODE *value_name;
+    const Py_UNICODE *value_name;
     PyObject *reserved;
     DWORD type;
     PyObject *value;
@@ -1091,4 +1095,4 @@ winreg_QueryReflectionKey(PyObject *module, PyObject *arg)
 exit:
     return return_value;
 }
-/*[clinic end generated code: output=d1c8e2678015dd7d input=a9049054013a1b77]*/
+/*[clinic end generated code: output=60c92ffc7438f8cf input=a9049054013a1b77]*/
index 2037b3db64ba4b7454f60ba078e5bc3666c28e69..c4922ccd623f6d23ff7795a3c3ffb9880f15f5a5 100644 (file)
@@ -72,6 +72,8 @@ extern PyObject* PyInit__string(void);
 extern PyObject* PyInit__stat(void);
 extern PyObject* PyInit__opcode(void);
 
+extern PyObject* PyInit__contextvars(void);
+
 /* tools/freeze/makeconfig.py marker for additional "extern" */
 /* -- ADDMODULE MARKER 1 -- */
 
@@ -164,6 +166,8 @@ struct _inittab _PyImport_Inittab[] = {
     {"_stat", PyInit__stat},
     {"_opcode", PyInit__opcode},
 
+    {"_contextvars", PyInit__contextvars},
+
     /* Sentinel */
     {0, 0}
 };
index 4c620dab7c096447f122d432a8cc33aaff627b4d..a4e678115f3470c0bd9393e9369a4c79f65e44ca 100644 (file)
@@ -666,7 +666,7 @@ run_child(wchar_t * cmdline)
     if (!ok)
         error(RC_CREATE_PROCESS, L"Job information setting failed");
     memset(&si, 0, sizeof(si));
-    si.cb = sizeof(si);
+    GetStartupInfoW(&si);
     ok = safe_duplicate_handle(GetStdHandle(STD_INPUT_HANDLE), &si.hStdInput);
     if (!ok)
         error(RC_NO_STD_HANDLES, L"stdin duplication failed");
@@ -1707,6 +1707,17 @@ process(int argc, wchar_t ** argv)
     command = skip_me(GetCommandLineW());
     debug(L"Called with command line: %ls\n", command);
 
+#if !defined(VENV_REDIRECT)
+    /* bpo-35811: The __PYVENV_LAUNCHER__ variable is used to
+     * override sys.executable and locate the original prefix path. 
+     * However, if it is silently inherited by a non-venv Python
+     * process, that process will believe it is running in the venv
+     * still. This is the only place where *we* can clear it (that is,
+     * when py.exe is being used to launch Python), so we do.
+     */
+    SetEnvironmentVariableW(L"__PYVENV_LAUNCHER__", NULL);
+#endif
+
 #if defined(SCRIPT_WRAPPER)
     /* The launcher is being used in "script wrapper" mode.
      * There should therefore be a Python script named <exename>-script.py in
index 217b2b096e07685254171a0cf80a37bfb41dd05a..910085c01bb2efe0f121364cd8cf1d192e301a35 100644 (file)
@@ -46,7 +46,7 @@ TCLTK_FILES_ONLY = FileNameSet("turtle.py")
 
 VENV_DIRS_ONLY = FileNameSet("venv", "ensurepip")
 
-EXCLUDE_FROM_PYDS = FileStemSet("python*", "pyshellext")
+EXCLUDE_FROM_PYDS = FileStemSet("python*", "pyshellext", "vcruntime*")
 EXCLUDE_FROM_LIB = FileNameSet("*.pyc", "__pycache__", "*.pickle")
 EXCLUDE_FROM_PACKAGED_LIB = FileNameSet("readme.txt")
 EXCLUDE_FROM_COMPILE = FileNameSet("badsyntax_*", "bad_*")
@@ -156,6 +156,8 @@ def get_layout(ns):
     for dest, src in rglob(ns.build, "vcruntime*.dll"):
         yield dest, src
 
+    yield "LICENSE.txt", ns.source / "LICENSE"
+
     for dest, src in rglob(ns.build, ("*.pyd", "*.dll")):
         if src.stem.endswith("_d") != bool(ns.debug) and src not in REQUIRED_DLLS:
             continue
@@ -240,12 +242,18 @@ def get_layout(ns):
             yield "DLLs/{}".format(ns.include_cat.name), ns.include_cat
 
 
-def _compile_one_py(src, dest, name, optimize):
+def _compile_one_py(src, dest, name, optimize, checked=True):
     import py_compile
 
     if dest is not None:
         dest = str(dest)
 
+    mode = (
+        py_compile.PycInvalidationMode.CHECKED_HASH
+        if checked
+        else py_compile.PycInvalidationMode.UNCHECKED_HASH
+    )
+
     try:
         return Path(
             py_compile.compile(
@@ -254,7 +262,7 @@ def _compile_one_py(src, dest, name, optimize):
                 str(name),
                 doraise=True,
                 optimize=optimize,
-                invalidation_mode=py_compile.PycInvalidationMode.CHECKED_HASH,
+                invalidation_mode=mode,
             )
         )
     except py_compile.PyCompileError:
@@ -262,16 +270,16 @@ def _compile_one_py(src, dest, name, optimize):
         return None
 
 
-def _py_temp_compile(src, ns, dest_dir=None):
+def _py_temp_compile(src, ns, dest_dir=None, checked=True):
     if not ns.precompile or src not in PY_FILES or src.parent in DATA_DIRS:
         return None
 
     dest = (dest_dir or ns.temp) / (src.stem + ".py")
-    return _compile_one_py(src, dest.with_suffix(".pyc"), dest, optimize=2)
+    return _compile_one_py(src, dest.with_suffix(".pyc"), dest, optimize=2, checked=checked)
 
 
-def _write_to_zip(zf, dest, src, ns):
-    pyc = _py_temp_compile(src, ns)
+def _write_to_zip(zf, dest, src, ns, checked=True):
+    pyc = _py_temp_compile(src, ns, checked=checked)
     if pyc:
         try:
             zf.write(str(pyc), dest.with_suffix(".pyc"))
@@ -321,7 +329,7 @@ def generate_source_files(ns):
         ns.temp.mkdir(parents=True, exist_ok=True)
         with zipfile.ZipFile(zip_path, "w", zipfile.ZIP_DEFLATED) as zf:
             for dest, src in get_lib_layout(ns):
-                _write_to_zip(zf, dest, src, ns)
+                _write_to_zip(zf, dest, src, ns, checked=False)
 
     if ns.include_underpth:
         log_info("Generating {} in {}", PYTHON_PTH_NAME, ns.temp)
index d2a3f5dd39bb7f509d2cadde140a352f9c69dc67..46fc84e92f29ec2bee62f01124c6f34ae947e997 100644 (file)
@@ -192,18 +192,6 @@ typedef int pid_t;
 #define Py_IS_FINITE(X) _finite(X)
 #define copysign _copysign
 
-/* VS 2010 and above already defines hypot as _hypot */
-#if _MSC_VER < 1600
-#define hypot _hypot
-#endif
-
-/* VS 2015 defines these names with a leading underscore */
-#if _MSC_VER >= 1900
-#define timezone _timezone
-#define daylight _daylight
-#define tzname _tzname
-#endif
-
 /* Side by Side assemblies supported in VS 2005 and VS 2008 but not 2010*/
 #if _MSC_VER >= 1400 && _MSC_VER < 1600
 #define HAVE_SXS 1
@@ -231,7 +219,6 @@ typedef int pid_t;
 #endif
 
 #define COMPILER "[gcc]"
-#define hypot _hypot
 #define PY_LONG_LONG long long
 #define PY_LLONG_MIN LLONG_MIN
 #define PY_LLONG_MAX LLONG_MAX
index 6f3106644b2c5d63ec8b9e3eeac6008be8e164a2..e3801b257b071e74285bb2fd006c0dfc49f2f8ee 100644 (file)
@@ -826,9 +826,9 @@ If the function fails, an OSError exception is raised.
 [clinic start generated code]*/
 
 static HKEY
-winreg_ConnectRegistry_impl(PyObject *module, Py_UNICODE *computer_name,
-                            HKEY key)
-/*[clinic end generated code: output=5ab79d02aa3167b4 input=5f98a891a347e68e]*/
+winreg_ConnectRegistry_impl(PyObject *module,
+                            const Py_UNICODE *computer_name, HKEY key)
+/*[clinic end generated code: output=cd4f70fb9ec901fb input=5f98a891a347e68e]*/
 {
     HKEY retKey;
     long rc;
@@ -863,8 +863,8 @@ If the function fails, an OSError exception is raised.
 [clinic start generated code]*/
 
 static HKEY
-winreg_CreateKey_impl(PyObject *module, HKEY key, Py_UNICODE *sub_key)
-/*[clinic end generated code: output=9c81d4095527c927 input=3cdd1622488acea2]*/
+winreg_CreateKey_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key)
+/*[clinic end generated code: output=2af13910d56eae26 input=3cdd1622488acea2]*/
 {
     HKEY retKey;
     long rc;
@@ -902,9 +902,10 @@ If the function fails, an OSError exception is raised.
 [clinic start generated code]*/
 
 static HKEY
-winreg_CreateKeyEx_impl(PyObject *module, HKEY key, Py_UNICODE *sub_key,
-                        int reserved, REGSAM access)
-/*[clinic end generated code: output=b9fce6dc5c4e39b1 input=42c2b03f98406b66]*/
+winreg_CreateKeyEx_impl(PyObject *module, HKEY key,
+                        const Py_UNICODE *sub_key, int reserved,
+                        REGSAM access)
+/*[clinic end generated code: output=643a70ad6a361a97 input=42c2b03f98406b66]*/
 {
     HKEY retKey;
     long rc;
@@ -937,8 +938,8 @@ is removed.  If the function fails, an OSError exception is raised.
 [clinic start generated code]*/
 
 static PyObject *
-winreg_DeleteKey_impl(PyObject *module, HKEY key, Py_UNICODE *sub_key)
-/*[clinic end generated code: output=7734b1e431991ae4 input=b31d225b935e4211]*/
+winreg_DeleteKey_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key)
+/*[clinic end generated code: output=d2652a84f70e0862 input=b31d225b935e4211]*/
 {
     long rc;
     rc = RegDeleteKeyW(key, sub_key );
@@ -972,9 +973,10 @@ On unsupported Windows versions, NotImplementedError is raised.
 [clinic start generated code]*/
 
 static PyObject *
-winreg_DeleteKeyEx_impl(PyObject *module, HKEY key, Py_UNICODE *sub_key,
-                        REGSAM access, int reserved)
-/*[clinic end generated code: output=01378d86ad3eb936 input=711d9d89e7ecbed7]*/
+winreg_DeleteKeyEx_impl(PyObject *module, HKEY key,
+                        const Py_UNICODE *sub_key, REGSAM access,
+                        int reserved)
+/*[clinic end generated code: output=52a1c8b374ebc003 input=711d9d89e7ecbed7]*/
 {
     HMODULE hMod;
     typedef LONG (WINAPI *RDKEFunc)(HKEY, const wchar_t*, REGSAM, int);
@@ -1014,8 +1016,8 @@ Removes a named value from a registry key.
 [clinic start generated code]*/
 
 static PyObject *
-winreg_DeleteValue_impl(PyObject *module, HKEY key, Py_UNICODE *value)
-/*[clinic end generated code: output=67e7e9a514f84951 input=a78d3407a4197b21]*/
+winreg_DeleteValue_impl(PyObject *module, HKEY key, const Py_UNICODE *value)
+/*[clinic end generated code: output=56fa9d21f3a54371 input=a78d3407a4197b21]*/
 {
     long rc;
     Py_BEGIN_ALLOW_THREADS
@@ -1182,8 +1184,9 @@ Expand environment vars.
 [clinic start generated code]*/
 
 static PyObject *
-winreg_ExpandEnvironmentStrings_impl(PyObject *module, Py_UNICODE *string)
-/*[clinic end generated code: output=cba46ac293a8af1a input=b2a9714d2b751aa6]*/
+winreg_ExpandEnvironmentStrings_impl(PyObject *module,
+                                     const Py_UNICODE *string)
+/*[clinic end generated code: output=8fa4e959747a7312 input=b2a9714d2b751aa6]*/
 {
     wchar_t *retValue = NULL;
     DWORD retValueSize;
@@ -1275,9 +1278,9 @@ tree.
 [clinic start generated code]*/
 
 static PyObject *
-winreg_LoadKey_impl(PyObject *module, HKEY key, Py_UNICODE *sub_key,
-                    Py_UNICODE *file_name)
-/*[clinic end generated code: output=87344005c5905cde input=e3b5b45ade311582]*/
+winreg_LoadKey_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key,
+                    const Py_UNICODE *file_name)
+/*[clinic end generated code: output=65f89f2548cb27c7 input=e3b5b45ade311582]*/
 {
     long rc;
 
@@ -1309,9 +1312,9 @@ If the function fails, an OSError exception is raised.
 [clinic start generated code]*/
 
 static HKEY
-winreg_OpenKey_impl(PyObject *module, HKEY key, Py_UNICODE *sub_key,
+winreg_OpenKey_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key,
                     int reserved, REGSAM access)
-/*[clinic end generated code: output=a905f1b947f3ce85 input=098505ac36a9ae28]*/
+/*[clinic end generated code: output=8849bff2c30104ad input=098505ac36a9ae28]*/
 {
     HKEY retKey;
     long rc;
@@ -1336,9 +1339,9 @@ If the function fails, an OSError exception is raised.
 [clinic start generated code]*/
 
 static HKEY
-winreg_OpenKeyEx_impl(PyObject *module, HKEY key, Py_UNICODE *sub_key,
+winreg_OpenKeyEx_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key,
                       int reserved, REGSAM access)
-/*[clinic end generated code: output=226042593b37e940 input=c6c4972af8622959]*/
+/*[clinic end generated code: output=81bc2bd684bc77ae input=c6c4972af8622959]*/
 {
     return winreg_OpenKey_impl(module, key, sub_key, reserved, access);
 }
@@ -1406,8 +1409,8 @@ completeness.
 [clinic start generated code]*/
 
 static PyObject *
-winreg_QueryValue_impl(PyObject *module, HKEY key, Py_UNICODE *sub_key)
-/*[clinic end generated code: output=2bb8d1e02c10d0b6 input=41cafbbf423b21d6]*/
+winreg_QueryValue_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key)
+/*[clinic end generated code: output=c655810ae50c63a9 input=41cafbbf423b21d6]*/
 {
     long rc;
     PyObject *retStr;
@@ -1473,8 +1476,8 @@ The return value is a tuple of the value and the type_id.
 [clinic start generated code]*/
 
 static PyObject *
-winreg_QueryValueEx_impl(PyObject *module, HKEY key, Py_UNICODE *name)
-/*[clinic end generated code: output=5b4fa3e33d6d3e8f input=cf366cada4836891]*/
+winreg_QueryValueEx_impl(PyObject *module, HKEY key, const Py_UNICODE *name)
+/*[clinic end generated code: output=f1b85b1c3d887ec7 input=cf366cada4836891]*/
 {
     long rc;
     BYTE *retBuf, *tmp;
@@ -1546,8 +1549,8 @@ to the API.
 [clinic start generated code]*/
 
 static PyObject *
-winreg_SaveKey_impl(PyObject *module, HKEY key, Py_UNICODE *file_name)
-/*[clinic end generated code: output=1dda1502bd4c30d8 input=da735241f91ac7a2]*/
+winreg_SaveKey_impl(PyObject *module, HKEY key, const Py_UNICODE *file_name)
+/*[clinic end generated code: output=ca94b835c88f112b input=da735241f91ac7a2]*/
 {
     LPSECURITY_ATTRIBUTES pSA = NULL;
 
@@ -1592,10 +1595,10 @@ KEY_SET_VALUE access.
 [clinic start generated code]*/
 
 static PyObject *
-winreg_SetValue_impl(PyObject *module, HKEY key, Py_UNICODE *sub_key,
-                     DWORD type, Py_UNICODE *value,
+winreg_SetValue_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key,
+                     DWORD type, const Py_UNICODE *value,
                      Py_ssize_clean_t value_length)
-/*[clinic end generated code: output=1e31931174820631 input=2cd2adab79339c53]*/
+/*[clinic end generated code: output=686bedb1cbb4367b input=2cd2adab79339c53]*/
 {
     long rc;
 
@@ -1658,9 +1661,10 @@ the configuration registry to help the registry perform efficiently.
 [clinic start generated code]*/
 
 static PyObject *
-winreg_SetValueEx_impl(PyObject *module, HKEY key, Py_UNICODE *value_name,
-                       PyObject *reserved, DWORD type, PyObject *value)
-/*[clinic end generated code: output=c88c8426b6c00ec7 input=900a9e3990bfb196]*/
+winreg_SetValueEx_impl(PyObject *module, HKEY key,
+                       const Py_UNICODE *value_name, PyObject *reserved,
+                       DWORD type, PyObject *value)
+/*[clinic end generated code: output=811b769a66ae11b7 input=900a9e3990bfb196]*/
 {
     BYTE *data;
     DWORD len;
diff --git a/PCbuild/_contextvars.vcxproj b/PCbuild/_contextvars.vcxproj
deleted file mode 100644 (file)
index cf266f3..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>\r
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
-  <ItemGroup Label="ProjectConfigurations">\r
-    <ProjectConfiguration Include="Debug|Win32">\r
-      <Configuration>Debug</Configuration>\r
-      <Platform>Win32</Platform>\r
-    </ProjectConfiguration>\r
-    <ProjectConfiguration Include="Debug|x64">\r
-      <Configuration>Debug</Configuration>\r
-      <Platform>x64</Platform>\r
-    </ProjectConfiguration>\r
-    <ProjectConfiguration Include="PGInstrument|Win32">\r
-      <Configuration>PGInstrument</Configuration>\r
-      <Platform>Win32</Platform>\r
-    </ProjectConfiguration>\r
-    <ProjectConfiguration Include="PGInstrument|x64">\r
-      <Configuration>PGInstrument</Configuration>\r
-      <Platform>x64</Platform>\r
-    </ProjectConfiguration>\r
-    <ProjectConfiguration Include="PGUpdate|Win32">\r
-      <Configuration>PGUpdate</Configuration>\r
-      <Platform>Win32</Platform>\r
-    </ProjectConfiguration>\r
-    <ProjectConfiguration Include="PGUpdate|x64">\r
-      <Configuration>PGUpdate</Configuration>\r
-      <Platform>x64</Platform>\r
-    </ProjectConfiguration>\r
-    <ProjectConfiguration Include="Release|Win32">\r
-      <Configuration>Release</Configuration>\r
-      <Platform>Win32</Platform>\r
-    </ProjectConfiguration>\r
-    <ProjectConfiguration Include="Release|x64">\r
-      <Configuration>Release</Configuration>\r
-      <Platform>x64</Platform>\r
-    </ProjectConfiguration>\r
-  </ItemGroup>\r
-  <PropertyGroup Label="Globals">\r
-    <ProjectGuid>{B8BF1D81-09DC-42D4-B406-4F868B33A89E}</ProjectGuid>\r
-    <RootNamespace>_contextvars</RootNamespace>\r
-    <Keyword>Win32Proj</Keyword>\r
-  </PropertyGroup>\r
-  <Import Project="python.props" />\r
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />\r
-  <PropertyGroup Label="Configuration">\r
-    <ConfigurationType>DynamicLibrary</ConfigurationType>\r
-    <CharacterSet>NotSet</CharacterSet>\r
-  </PropertyGroup>\r
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />\r
-  <PropertyGroup>\r
-    <TargetExt>.pyd</TargetExt>\r
-  </PropertyGroup>\r
-  <ImportGroup Label="ExtensionSettings">\r
-  </ImportGroup>\r
-  <ImportGroup Label="PropertySheets">\r
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
-    <Import Project="pyproject.props" />\r
-  </ImportGroup>\r
-  <PropertyGroup Label="UserMacros" />\r
-  <PropertyGroup>\r
-    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\r
-  </PropertyGroup>\r
-  <ItemGroup>\r
-    <ClCompile Include="..\Modules\_contextvarsmodule.c" />\r
-  </ItemGroup>\r
-  <ItemGroup>\r
-    <ResourceCompile Include="..\PC\python_nt.rc" />\r
-  </ItemGroup>\r
-  <ItemGroup>\r
-    <ProjectReference Include="pythoncore.vcxproj">\r
-      <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project>\r
-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>\r
-    </ProjectReference>\r
-  </ItemGroup>\r
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
-  <ImportGroup Label="ExtensionTargets">\r
-  </ImportGroup>\r
-</Project>\r
diff --git a/PCbuild/_contextvars.vcxproj.filters b/PCbuild/_contextvars.vcxproj.filters
deleted file mode 100644 (file)
index 06200c3..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>\r
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
-  <ItemGroup>\r
-    <ResourceCompile Include="..\PC\python_nt.rc" />\r
-  </ItemGroup>\r
-  <ItemGroup>\r
-    <Filter Include="Source Files">\r
-      <UniqueIdentifier>{7CBD8910-233D-4E9A-9164-9BA66C1F0E6D}</UniqueIdentifier>\r
-    </Filter>\r
-  </ItemGroup>\r
-  <ItemGroup>\r
-    <ClCompile Include="..\Modules\_contextvarsmodule.c">\r
-      <Filter>Source Files</Filter>\r
-    </ClCompile>\r
-  </ItemGroup>\r
-</Project>\r
index df69a195b80a1f410156f54bd74f91a8d43813b7..7f90fca26706c6947a089d7fc1bd188bc7b337a2 100644 (file)
@@ -24,7 +24,7 @@
 :begin_search\r
 @set PYTHON=\r
 \r
-@set _Py_EXTERNALS_DIR=%EXTERNAL_DIR%\r
+@set _Py_EXTERNALS_DIR=%EXTERNALS_DIR%\r
 @if "%_Py_EXTERNALS_DIR%"=="" (set _Py_EXTERNALS_DIR=%~dp0\..\externals)\r
 \r
 @rem If we have Python in externals, use that one\r
index dfbc924d3b6c562ee0685003ba917ebeb2a3ef0e..ddeb962699ba15ef946a8b240c86efcbe4c54a6e 100644 (file)
@@ -51,8 +51,8 @@ set libraries=
 set libraries=%libraries%                                       bzip2-1.0.6\r
 if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries%     openssl-1.1.0j\r
 set libraries=%libraries%                                       sqlite-3.21.0.0\r
-if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tcl-core-8.6.8.0\r
-if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tk-8.6.8.0\r
+if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tcl-core-8.6.9.0\r
+if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tk-8.6.9.0\r
 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tix-8.4.3.6\r
 set libraries=%libraries%                                       xz-5.2.2\r
 set libraries=%libraries%                                       zlib-1.2.11\r
@@ -73,7 +73,7 @@ echo.Fetching external binaries...
 \r
 set binaries=\r
 if NOT "%IncludeSSL%"=="false"     set binaries=%binaries% openssl-bin-1.1.0j\r
-if NOT "%IncludeTkinter%"=="false" set binaries=%binaries% tcltk-8.6.8.0\r
+if NOT "%IncludeTkinter%"=="false" set binaries=%binaries% tcltk-8.6.9.0\r
 if NOT "%IncludeSSLSrc%"=="false"  set binaries=%binaries% nasm-2.11.06\r
 \r
 for %%b in (%binaries%) do (\r
index 001dc45d841a021974005790446d0e4e061655ea..4b8d5df8c69ffaf98fdc41f803415b9bb3778025 100644 (file)
@@ -23,6 +23,6 @@
     <Copy SourceFiles="@(_SSLDLL)" DestinationFolder="$(OutDir)" />\r
   </Target>\r
   <Target Name="_CleanSSLDLL" BeforeTargets="Clean">\r
-    <Delete Files="@(_SSLDLL->'$(OutDir)%(Filename)%(Extension)')" />\r
+    <Delete Files="@(_SSLDLL->'$(OutDir)%(Filename)%(Extension)')" TreatErrorsAsWarnings="true" />\r
   </Target>\r
 </Project>
\ No newline at end of file
index 19d8d2f70ae20f1732ac2dac860250da9ce67520..b13abb7dc2108ff0d8812b537055190a1f71ed05 100644 (file)
@@ -50,7 +50,7 @@
     <!-- pyshellext.dll -->\r
     <Projects Include="pyshellext.vcxproj" />\r
     <!-- Extension modules -->\r
-    <ExtensionModules Include="_asyncio;_contextvars;_ctypes;_decimal;_elementtree;_msi;_multiprocessing;_overlapped;pyexpat;_queue;select;unicodedata;winsound" />\r
+    <ExtensionModules Include="_asyncio;_ctypes;_decimal;_elementtree;_msi;_multiprocessing;_overlapped;pyexpat;_queue;select;unicodedata;winsound" />\r
     <!-- Extension modules that require external sources -->\r
     <ExternalModules Include="_bz2;_lzma;_sqlite3" />\r
     <!-- venv launchers -->\r
index 2b36835bd52c9926e7ce5a92f66f67db017c179b..eaeb8b0d9975c441c591d12cdd04c6f6b4da38b2 100644 (file)
@@ -185,10 +185,11 @@ public override bool Execute() {
     <SdkBinPath Condition="!Exists($(SdkBinPath))">$(registry:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows Kits\Installed Roots@KitsRoot)\bin\x86</SdkBinPath>\r
     <SdkBinPath Condition="!Exists($(SdkBinPath))">$(registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.1A@InstallationFolder)\Bin\</SdkBinPath>\r
     <_SignCommand Condition="Exists($(SdkBinPath)) and '$(SigningCertificate)' != '' and $(SupportSigning)">"$(SdkBinPath)\signtool.exe" sign /q /a /n "$(SigningCertificate)" /fd sha256 /t http://timestamp.verisign.com/scripts/timestamp.dll /d "Python $(PythonVersion)"</_SignCommand>\r
+    <_SignCommand Condition="Exists($(SdkBinPath)) and '$(SigningCertificateSha1)' != '' and $(SupportSigning)">"$(SdkBinPath)\signtool.exe" sign /q /a /sha1 "$(SigningCertificateSha1)" /fd sha256 /t http://timestamp.verisign.com/scripts/timestamp.dll /d "Python $(PythonVersion)"</_SignCommand>\r
     <_MakeCatCommand Condition="Exists($(SdkBinPath))">"$(SdkBinPath)\makecat.exe"</_MakeCatCommand>\r
   </PropertyGroup>\r
-  \r
-  <Target Name="_SignBuild" AfterTargets="AfterBuild" Condition="'$(SigningCertificate)' != '' and $(SupportSigning)">\r
+\r
+  <Target Name="_SignBuild" AfterTargets="AfterBuild" Condition="'$(_SignCommand)' != '' and $(SupportSigning)">\r
     <Error Text="Unable to locate signtool.exe. Set /p:SignToolPath and rebuild" Condition="'$(_SignCommand)' == ''" />\r
     <Exec Command='$(_SignCommand) "$(TargetPath)" || $(_SignCommand) "$(TargetPath)" || $(_SignCommand) "$(TargetPath)"' ContinueOnError="false" />\r
   </Target>\r
index 3e60cddff8f4213044d6857a43194959f782ed5b..66533b696700b0daa08535f6b6960640d844aa33 100644 (file)
@@ -76,7 +76,7 @@
     matter which WinSDK version we use.\r
     -->\r
     <_RegistryVersion>$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0@ProductVersion)</_RegistryVersion>\r
-    <_RegistryVersion Condition="$(_RegistryVersion) == ''">$(Registry:HKEY_LOCAL_MACHINE\WOW6432Node\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0@ProductVersion)</_RegistryVersion>\r
+    <_RegistryVersion Condition="$(_RegistryVersion) == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Microsoft SDKs\Windows\v10.0@ProductVersion)</_RegistryVersion>\r
     <!-- Sometimes the version in the registry has to .0 suffix, and sometimes it doesn't. Check and add it -->\r
     <_RegistryVersion Condition="$(_RegistryVersion) != '' and !$(_RegistryVersion.EndsWith('.0'))">$(_RegistryVersion).0</_RegistryVersion>\r
 \r
index a10a521943bad14eabe216c45c806d4099ea9014..e9947473720ae0d02d5afc58180242195e9f90af 100644 (file)
   </ItemGroup>\r
   <ItemGroup>\r
     <ClCompile Include="..\Modules\_abc.c" />\r
-    <ClCompile Include="..\Modules\_asynciomodule.c" />\r
     <ClCompile Include="..\Modules\_bisectmodule.c" />\r
     <ClCompile Include="..\Modules\_blake2\blake2module.c" />\r
     <ClCompile Include="..\Modules\_blake2\blake2b_impl.c" />\r
index 34ce5930e5565f873c835ced664575786b4b904d..a0978e0f6bfa7d75f74dceade3b95469aecd6848 100644 (file)
     <ClCompile Include="..\PC\_findvs.cpp">\r
       <Filter>PC</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="..\Modules\_asynciomodule.c">\r
-      <Filter>Modules</Filter>\r
-    </ClCompile>\r
     <ClCompile Include="..\Modules\_contextvarsmodule.c">\r
       <Filter>Modules</Filter>\r
     </ClCompile>\r
index 6e0ec0e074c3709fbf659d736bdeb7cb8fd45399..7dc31c393f2001efc4d8b28e73e8c96f623bed26 100644 (file)
@@ -4,7 +4,7 @@
   <PropertyGroup>\r
     <TclMajorVersion>8</TclMajorVersion>\r
     <TclMinorVersion>6</TclMinorVersion>\r
-    <TclPatchLevel>8</TclPatchLevel>\r
+    <TclPatchLevel>9</TclPatchLevel>\r
     <TclRevision>0</TclRevision>\r
     <TkMajorVersion>$(TclMajorVersion)</TkMajorVersion>\r
     <TkMinorVersion>$(TclMinorVersion)</TkMinorVersion>\r
index e2afba2b2e33a82776160902bdeb976288234b15..58b0802f4668878269245742fef02a29bece3fb5 100644 (file)
@@ -116,7 +116,7 @@ py_getrandom(void *buffer, Py_ssize_t size, int blocking, int raise)
     flags = blocking ? 0 : GRND_NONBLOCK;
     dest = buffer;
     while (0 < size) {
-#ifdef sun
+#if defined(__sun) && defined(__SVR4)
         /* Issue #26735: On Solaris, getrandom() is limited to returning up
            to 1024 bytes. Call it multiple times if more bytes are
            requested. */
@@ -266,7 +266,7 @@ py_getentropy(char *buffer, Py_ssize_t size, int raise)
     }
     return 1;
 }
-#endif /* defined(HAVE_GETENTROPY) && !defined(sun) */
+#endif /* defined(HAVE_GETENTROPY) && !(defined(__sun) && defined(__SVR4)) */
 
 
 static struct {
index 51772ecef31797e68cd8d2b2732b4db516c5624f..27a1731f46ded490c47b1dbf0120e92643c36d8e 100644 (file)
@@ -4,7 +4,7 @@
 
 static const char cprt[] =
 "\
-Copyright (c) 2001-2018 Python Software Foundation.\n\
+Copyright (c) 2001-2019 Python Software Foundation.\n\
 All Rights Reserved.\n\
 \n\
 Copyright (c) 2000 BeOpen.com.\n\
index 5f5d135c7a2ed29c621796b9add5ffff82d1ac3c..ccdd5993050543200fbc52ede8cc26660613acfc 100644 (file)
@@ -743,7 +743,6 @@ _PyImport_FindExtensionObjectEx(PyObject *name, PyObject *filename,
     }
     if (_PyState_AddModule(mod, def) < 0) {
         PyMapping_DelItem(modules, name);
-        Py_DECREF(mod);
         return NULL;
     }
     if (Py_VerboseFlag)
index efe5b29ef33c8103cfdae0bca9a9c6ffdeb99c1a..cdc2edf038a13967705f824e25f1291d3cc28a42 100644 (file)
@@ -134,11 +134,14 @@ sys_breakpointhook(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyOb
         modulepath = PyUnicode_FromString("builtins");
         attrname = envar;
     }
-    else {
+    else if (last_dot != envar) {
         /* Split on the last dot; */
         modulepath = PyUnicode_FromStringAndSize(envar, last_dot - envar);
         attrname = last_dot + 1;
     }
+    else {
+        goto warn;
+    }
     if (modulepath == NULL) {
         PyMem_RawFree(envar);
         return NULL;
@@ -156,21 +159,29 @@ sys_breakpointhook(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyOb
     Py_DECREF(fromlist);
 
     if (module == NULL) {
-        goto error;
+        if (PyErr_ExceptionMatches(PyExc_ImportError)) {
+            goto warn;
+        }
+        PyMem_RawFree(envar);
+        return NULL;
     }
 
     PyObject *hook = PyObject_GetAttrString(module, attrname);
     Py_DECREF(module);
 
     if (hook == NULL) {
-        goto error;
+        if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
+            goto warn;
+        }
+        PyMem_RawFree(envar);
+        return NULL;
     }
     PyMem_RawFree(envar);
     PyObject *retval = _PyObject_FastCallKeywords(hook, args, nargs, keywords);
     Py_DECREF(hook);
     return retval;
 
-  error:
+  warn:
     /* If any of the imports went wrong, then warn and ignore. */
     PyErr_Clear();
     int status = PyErr_WarnFormat(
index 61fa8619bc1742f8562a55878a45443e971cf07b..56295d0e8c0f4ebae803eeca3155a646c2de66a3 100644 (file)
@@ -104,8 +104,9 @@ LeaveNonRecursiveMutex(PNRMUTEX mutex)
     if (PyMUTEX_LOCK(&mutex->cs))
         return FALSE;
     mutex->locked = 0;
-    result = PyCOND_SIGNAL(&mutex->cv);
-    result &= PyMUTEX_UNLOCK(&mutex->cs);
+    /* condvar APIs return 0 on success. We need to return TRUE on success. */
+    result = !PyCOND_SIGNAL(&mutex->cv);
+    PyMUTEX_UNLOCK(&mutex->cs);
     return result;
 }
 
index 43ded3e4c7ea148b8bd7cb49d67c96374e33952f..96d05f931d5675490f686c94dc2ee76f211a6ce1 100644 (file)
@@ -1,4 +1,4 @@
-This is Python version 3.7.2
+This is Python version 3.7.3
 ============================
 
 .. image:: https://travis-ci.org/python/cpython.svg?branch=master
@@ -18,8 +18,8 @@ This is Python version 3.7.2
    :target: https://codecov.io/gh/python/cpython
 
 Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
-2012, 2013, 2014, 2015, 2016, 2017, 2018 Python Software Foundation.  All rights
-reserved.
+2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 Python Software Foundation.  All
+rights reserved.
 
 See the end of this file for further copyright and license information.
 
@@ -60,7 +60,7 @@ On Unix, Linux, BSD, macOS, and Cygwin::
     make test
     sudo make install
 
-This will install Python as python3.
+This will install Python as ``python3``.
 
 You can pass many options to the configure script; run ``./configure --help``
 to find out more.  On macOS and Cygwin, the executable is called ``python.exe``;
@@ -247,8 +247,8 @@ Copyright and License Information
 ---------------------------------
 
 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.
+2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 Python Software Foundation.  All
+rights reserved.
 
 Copyright (c) 2000 BeOpen.com.  All rights reserved.
 
index b704b5a669fbd235e93ec490278341458a1bbffc..0ba8caba9e7975fd73c3064f88c3667b2670d63a 100755 (executable)
@@ -2824,7 +2824,7 @@ class unicode_converter(CConverter):
 @add_legacy_c_converter('Z', accept={str, NoneType})
 @add_legacy_c_converter('Z#', accept={str, NoneType}, zeroes=True)
 class Py_UNICODE_converter(CConverter):
-    type = 'Py_UNICODE *'
+    type = 'const Py_UNICODE *'
     default_type = (str, Null, NoneType)
     format_unit = 'u'
 
index bfaa9403b7876461b7a732d14050fffac2867537..d744cab7642a75106dcc3b316cac69ce231e35b3 100755 (executable)
@@ -1178,7 +1178,7 @@ class PyUnicodeObjectPtr(PyObjectPtr):
     def proxyval(self, visited):
         global _is_pep393
         if _is_pep393 is None:
-            fields = gdb.lookup_type('PyUnicodeObject').target().fields()
+            fields = gdb.lookup_type('PyUnicodeObject').fields()
             _is_pep393 = 'data' in [f.name for f in fields]
         if _is_pep393:
             # Python 3.3 and newer
index bc3a19ce33ca38c875ac2ef4228fd985ab060323..4a56cec35722cf016b51da13d59a5c1cad43dd3e 100644 (file)
@@ -21,7 +21,8 @@
         <EmbeddedResource Include="*.wxl" />
     </ItemGroup>
     <ItemGroup>
-        <InstallFiles Include="$(PySourcePath)include\**\*.h">
+        <InstallFiles Include="$(PySourcePath)include\**\*.h"
+                      Exclude="$(PySourcePath)include\pyconfig.h">
             <SourceBase>$(PySourcePath)</SourceBase>
             <Source>!(bindpath.src)</Source>
             <TargetBase>$(PySourcePath)</TargetBase>
index 4bd0c57e3229db035672ff51876bb77a9d9a2032..a9952bdac4db9164b4911a63d8f61054fb2224ea 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
-    <?define exts=pyexpat;select;unicodedata;winsound;_bz2;_elementtree;_socket;_ssl;_msi;_ctypes;_hashlib;_multiprocessing;_lzma;_decimal;_overlapped;_sqlite3;_asyncio;_queue;_contextvars ?>
+    <?define exts=pyexpat;select;unicodedata;winsound;_bz2;_elementtree;_socket;_ssl;_msi;_ctypes;_hashlib;_multiprocessing;_lzma;_decimal;_overlapped;_sqlite3;_asyncio;_queue ?>
     <Fragment>
         <DirectoryRef Id="Lib_venv_scripts_nt" />
 
index 81a74d3679d78e91c987100dbb0af5eedac9a720..61edb3411760c13d96fbb89845794d3c8a71d03a 100644 (file)
@@ -21,6 +21,9 @@ function Sign-File {
             $description = "Python";
         }
     }
+    if (-not $certsha1) {
+        $certsha1 = $env:SigningCertificateSha1;
+    }
     if (-not $certname) {
         $certname = $env:SigningCertificate;
     }
@@ -32,7 +35,7 @@ function Sign-File {
         if ($certsha1) {
             SignTool sign /sha1 $certsha1 /fd sha256 /t http://timestamp.verisign.com/scripts/timestamp.dll /d $description $a
         } elseif ($certname) {
-            SignTool sign /n $certname /fd sha256 /t http://timestamp.verisign.com/scripts/timestamp.dll /d $description $a
+            SignTool sign /a /n $certname /fd sha256 /t http://timestamp.verisign.com/scripts/timestamp.dll /d $description $a
         } elseif ($certfile) {
             SignTool sign /f $certfile /fd sha256 /t http://timestamp.verisign.com/scripts/timestamp.dll /d $description $a
         } else {
index d5f3e6324236724e306404b47fb906127703818b..8f98e808916a3203f9e018ea7fcee2449088f321 100644 (file)
@@ -5,9 +5,8 @@
     <title>Python</title>
     <version>0.0.0.0</version>
     <authors>Python Software Foundation</authors>
-    <licenseUrl>https://docs.python.org/3/license.html</licenseUrl>
+    <license type="file">tools\LICENSE.txt</license>
     <projectUrl>https://www.python.org/</projectUrl>
-    <requireLicenseAcceptance>false</requireLicenseAcceptance>
     <description>Installs 64-bit Python for use in build scenarios.</description>
     <iconUrl>https://www.python.org/static/favicon.ico</iconUrl>
     <tags>python</tags>
index ee3343bbb7b324832db08d7323f5cc3ec08d1315..5cf55806ddfb39c413cdf7f6966eea078d14b01c 100644 (file)
@@ -3,11 +3,10 @@
   <metadata>
     <id>pythondaily</id>
     <title>Python (Daily build)</title>
-    <version>0.0.0.0</version>
     <authors>Python Software Foundation</authors>
-    <licenseUrl>https://docs.python.org/3/license.html</licenseUrl>
+    <version>0.0.0.0</version>
+    <license type="file">tools\LICENSE.txt</license>
     <projectUrl>https://www.python.org/</projectUrl>
-    <requireLicenseAcceptance>false</requireLicenseAcceptance>
     <description>Installs an unsigned, untested build of Python for test purposes only.</description>
     <iconUrl>https://www.python.org/static/favicon.ico</iconUrl>
     <tags>python</tags>
index b89717a1afe3b87e06f1e15d6c8cfe788e8bb734..608e15c50e02d2d7fb5a12dcd6091c589d6bd815 100644 (file)
@@ -5,9 +5,7 @@
     <title>Python (Daily build)</title>
     <version>0.0.0.0</version>
     <authors>Python Software Foundation</authors>
-    <licenseUrl>https://docs.python.org/3/license.html</licenseUrl>
     <projectUrl>https://www.python.org/</projectUrl>
-    <requireLicenseAcceptance>false</requireLicenseAcceptance>
     <description>Contains symbols for the daily build of Python.</description>
     <iconUrl>https://www.python.org/static/favicon.ico</iconUrl>
     <tags>python</tags>
index ebfcd6c92a4a6442be389c9b7ed95adb79372aef..27ef67e7f5d3637d6f9a8c007a28c43fc8d9fe3b 100644 (file)
@@ -5,9 +5,8 @@
     <title>Python (32-bit)</title>
     <authors>Python Software Foundation</authors>
     <version>0.0.0.0</version>
-    <licenseUrl>https://docs.python.org/3/license.html</licenseUrl>
+    <license type="file">tools\LICENSE.txt</license>
     <projectUrl>https://www.python.org/</projectUrl>
-    <requireLicenseAcceptance>false</requireLicenseAcceptance>
     <description>Installs 32-bit Python for use in build scenarios.</description>
     <iconUrl>https://www.python.org/static/favicon.ico</iconUrl>
     <tags>python</tags>
index 32828c24dd899129672dd8df05521ce1afca291d..85a0dbba271734564d330a817140b00db669575b 100644 (file)
@@ -1,6 +1,6 @@
-# generated automatically by aclocal 1.15.1 -*- Autoconf -*-
+# generated automatically by aclocal 1.16.1 -*- Autoconf -*-
 
-# Copyright (C) 1996-2017 Free Software Foundation, Inc.
+# Copyright (C) 1996-2018 Free Software Foundation, Inc.
 
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -13,7 +13,7 @@
 
 m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
 dnl pkg.m4 - Macros to locate and utilise pkg-config.   -*- Autoconf -*-
-dnl serial 11 (pkg-config-0.29)
+dnl serial 11 (pkg-config-0.29.1)
 dnl
 dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
 dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
@@ -55,7 +55,7 @@ dnl
 dnl See the "Since" comment for each macro you use to see what version
 dnl of the macros you require.
 m4_defun([PKG_PREREQ],
-[m4_define([PKG_MACROS_VERSION], [0.29])
+[m4_define([PKG_MACROS_VERSION], [0.29.1])
 m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
     [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
 ])dnl PKG_PREREQ
index 5e5f974b0e5064b0b0425e7cac651bb4fafdf83c..18047ced43494f767b885f6a8ee5e502d5c4db90 100755 (executable)
--- a/configure
+++ b/configure
@@ -784,6 +784,7 @@ infodir
 docdir
 oldincludedir
 includedir
+runstatedir
 localstatedir
 sharedstatedir
 sysconfdir
@@ -897,6 +898,7 @@ datadir='${datarootdir}'
 sysconfdir='${prefix}/etc'
 sharedstatedir='${prefix}/com'
 localstatedir='${prefix}/var'
+runstatedir='${localstatedir}/run'
 includedir='${prefix}/include'
 oldincludedir='/usr/include'
 docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
@@ -1149,6 +1151,15 @@ do
   | -silent | --silent | --silen | --sile | --sil)
     silent=yes ;;
 
+  -runstatedir | --runstatedir | --runstatedi | --runstated \
+  | --runstate | --runstat | --runsta | --runst | --runs \
+  | --run | --ru | --r)
+    ac_prev=runstatedir ;;
+  -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
+  | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
+  | --run=* | --ru=* | --r=*)
+    runstatedir=$ac_optarg ;;
+
   -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
     ac_prev=sbindir ;;
   -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@@ -1286,7 +1297,7 @@ fi
 for ac_var in  exec_prefix prefix bindir sbindir libexecdir datarootdir \
                datadir sysconfdir sharedstatedir localstatedir includedir \
                oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
-               libdir localedir mandir
+               libdir localedir mandir runstatedir
 do
   eval ac_val=\$$ac_var
   # Remove trailing slashes.
@@ -1439,6 +1450,7 @@ Fine tuning of the installation directories:
   --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
   --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
   --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]
   --libdir=DIR            object code libraries [EPREFIX/lib]
   --includedir=DIR        C header files [PREFIX/include]
   --oldincludedir=DIR     C header files for non-gcc [/usr/include]
 done
 
 
+# We search for both crypt and crypt_r as one or the other may be defined
+# This gets us our -lcrypt in LIBS when required on the target platform.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing crypt" >&5
+$as_echo_n "checking for library containing crypt... " >&6; }
+if ${ac_cv_search_crypt+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char crypt ();
+int
+main ()
+{
+return crypt ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' crypt; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_crypt=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if ${ac_cv_search_crypt+:} false; then :
+  break
+fi
+done
+if ${ac_cv_search_crypt+:} false; then :
+
+else
+  ac_cv_search_crypt=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_crypt" >&5
+$as_echo "$ac_cv_search_crypt" >&6; }
+ac_res=$ac_cv_search_crypt
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing crypt_r" >&5
+$as_echo_n "checking for library containing crypt_r... " >&6; }
+if ${ac_cv_search_crypt_r+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char crypt_r ();
+int
+main ()
+{
+return crypt_r ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' crypt; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_crypt_r=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if ${ac_cv_search_crypt_r+:} false; then :
+  break
+fi
+done
+if ${ac_cv_search_crypt_r+:} false; then :
+
+else
+  ac_cv_search_crypt_r=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_crypt_r" >&5
+$as_echo "$ac_cv_search_crypt_r" >&6; }
+ac_res=$ac_cv_search_crypt_r
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+
+ac_fn_c_check_func "$LINENO" "crypt_r" "ac_cv_func_crypt_r"
+if test "x$ac_cv_func_crypt_r" = xyes; then :
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#define _GNU_SOURCE  /* Required for crypt_r()'s prototype in glibc. */
+#include <crypt.h>
+
+int
+main ()
+{
+
+struct crypt_data d;
+char *r = crypt_r("", "", &d);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+$as_echo "#define HAVE_CRYPT_R 1" >>confdefs.h
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+
+
 for ac_func in clock_gettime
 do :
   ac_fn_c_check_func "$LINENO" "clock_gettime" "ac_cv_func_clock_gettime"
@@ -15598,6 +15754,8 @@ else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
+#include <stdlib.h>
+#include <unistd.h>
 int main()
 {
        int val1 = nice(1);
index a7de901e08b7864b7f5824b4ad4b4030ba98d819..ad0f4d42b4b5817747707dd7d0343e939548d82d 100644 (file)
@@ -3875,6 +3875,23 @@ AC_CHECK_FUNCS(gettimeofday,
     ])
 )
 
+# We search for both crypt and crypt_r as one or the other may be defined
+# This gets us our -lcrypt in LIBS when required on the target platform.
+AC_SEARCH_LIBS(crypt, crypt)
+AC_SEARCH_LIBS(crypt_r, crypt)
+
+AC_CHECK_FUNC(crypt_r,
+  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#define _GNU_SOURCE  /* Required for crypt_r()'s prototype in glibc. */
+#include <crypt.h>
+]], [[
+struct crypt_data d;
+char *r = crypt_r("", "", &d);
+]])],
+    [AC_DEFINE(HAVE_CRYPT_R, 1, [Define if you have the crypt_r() function.])],
+    [])
+)
+
 AC_CHECK_FUNCS(clock_gettime, [], [
     AC_CHECK_LIB(rt, clock_gettime, [
         LIBS="$LIBS -lrt"
@@ -4873,6 +4890,8 @@ LIBS=$LIBS_no_readline
 AC_MSG_CHECKING(for broken nice())
 AC_CACHE_VAL(ac_cv_broken_nice, [
 AC_RUN_IFELSE([AC_LANG_SOURCE([[
+#include <stdlib.h>
+#include <unistd.h>
 int main()
 {
        int val1 = nice(1);
index a82e82cc9cccacd6a6366d472ab4be936da5fd59..4032fa519f8abb05ccc8c52b204e43baee73766a 100644 (file)
 /* Define to 1 if you have the <crypt.h> header file. */
 #undef HAVE_CRYPT_H
 
+/* Define if you have the crypt_r() function. */
+#undef HAVE_CRYPT_R
+
 /* Define to 1 if you have the `ctermid' function. */
 #undef HAVE_CTERMID