Imported Upstream version 0.29.21 upstream/0.29.21
authorDongHun Kwak <dh0128.kwak@samsung.com>
Thu, 31 Dec 2020 03:11:24 +0000 (12:11 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Thu, 31 Dec 2020 03:11:24 +0000 (12:11 +0900)
66 files changed:
.coveragerc [deleted file]
.editorconfig [deleted file]
.gitignore [deleted file]
.gitrev [new file with mode: 0644]
.hgignore [deleted file]
.hgtags [deleted file]
.mailmap [deleted file]
.travis.yml [deleted file]
BUILD.bazel [deleted file]
CHANGES.rst
Cython/Build/ipython-COPYING.rst [deleted file]
Cython/Compiler/Code.py
Cython/Compiler/ExprNodes.py
Cython/Compiler/FlowControl.py
Cython/Compiler/FusedNode.py
Cython/Compiler/ModuleNode.py
Cython/Compiler/Nodes.py
Cython/Compiler/Options.py
Cython/Compiler/StringEncoding.py
Cython/Compiler/Tests/TestStringEncoding.py [new file with mode: 0644]
Cython/Compiler/TypeSlots.py
Cython/Includes/cpython/unicode.pxd
Cython/Includes/libcpp/unordered_map.pxd
Cython/Shadow.py
Cython/Shadow.pyi [deleted file]
Cython/Utility/Builtins.c
Cython/Utility/CythonFunction.c
Cython/Utility/ExtensionTypes.c
Cython/Utility/ImportExport.c
Cython/Utility/MemoryView_C.c
Cython/Utility/ModuleSetupCode.c
Cython/Utility/StringTools.c
Demos/README.rst [deleted file]
Doc/s5/Makefile [deleted file]
Doc/s5/cython-ep2008.txt [deleted file]
Doc/s5/ep2008/stupidlowercase.py [deleted file]
Doc/s5/ep2008/worker.py [deleted file]
Doc/s5/ui/default/blank.gif [deleted file]
Doc/s5/ui/default/bodybg.gif [deleted file]
Doc/s5/ui/default/cython-logo64.png [deleted file]
Doc/s5/ui/default/framing.css [deleted file]
Doc/s5/ui/default/iepngfix.htc [deleted file]
Doc/s5/ui/default/opera.css [deleted file]
Doc/s5/ui/default/outline.css [deleted file]
Doc/s5/ui/default/pretty.css [deleted file]
Doc/s5/ui/default/print.css [deleted file]
Doc/s5/ui/default/s5-core.css [deleted file]
Doc/s5/ui/default/slides.css [deleted file]
Doc/s5/ui/default/slides.js [deleted file]
PKG-INFO [new file with mode: 0644]
appveyor.yml [deleted file]
appveyor/install.ps1 [deleted file]
appveyor/run_with_env.cmd [deleted file]
pyximport/README.rst [deleted file]
runtests.py
test-requirements-cpython.txt [deleted file]
test-requirements.txt [deleted file]
tests/compile/buildenv.pyx
tests/compile/tryfinally.pyx
tests/memoryview/relaxed_strides.pyx
tests/run/cpp_classes.pyx
tests/run/cpp_stl_cpp11.pyx
tests/run/cpp_unordered_map_helper.h [new file with mode: 0644]
tests/run/exectest.pyx
tests/run/unicodeliterals.pyx
tox.ini [deleted file]

diff --git a/.coveragerc b/.coveragerc
deleted file mode 100644 (file)
index 9bc4ce4..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-[run]
-branch = True
-parallel = True
-concurrency = multiprocessing,thread
-include = Cython/*
-source = Cython
-omit = Test*
diff --git a/.editorconfig b/.editorconfig
deleted file mode 100644 (file)
index 55e1ad7..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-# top-most EditorConfig file
-root = true
-
-# Unix-style newlines with a newline ending every file
-[*]
-end_of_line = lf
-insert_final_newline = true
-max_line_length = 120
-
-# 4 space indentation
-[*.{py,pyx,pxi,pxd,c,cpp,h,hpp}]
-indent_style = space
-indent_size = 4
-trim_trailing_whitespace = true
-
-# Tab indentation (no size specified)
-[Makefile]
-indent_style = tab
-
-# Matches the exact files either package.json or .travis.yml
-[{package.json,.travis.yml}]
-indent_style = space
-indent_size = 2
diff --git a/.gitignore b/.gitignore
deleted file mode 100644 (file)
index 46da36e..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-*.pyc
-*.pyo
-__pycache__
-*.so
-*.o
-
-*.egg
-*.egg-info
-
-Cython/Compiler/*.c
-Cython/Plex/*.c
-Cython/Runtime/refnanny.c
-Cython/Tempita/*.c
-Cython/*.c
-
-Tools/*.elc
-
-/TEST_TMP/
-/build/
-/wheelhouse*/
-!tests/build/
-/dist/
-.gitrev
-.coverage
-*.orig
-*.rej
-*.dep
-*.swp
-*~
-
-.ipynb_checkpoints
-docs/build
-
-tags
-TAGS
-MANIFEST
-
-.tox
-
-# Jetbrains IDE project files
-/.idea
-/*.iml
-
diff --git a/.gitrev b/.gitrev
new file mode 100644 (file)
index 0000000..9852a62
--- /dev/null
+++ b/.gitrev
@@ -0,0 +1 @@
+976f5483c6df8570f34076ef25af7e7512dd9347
diff --git a/.hgignore b/.hgignore
deleted file mode 100644 (file)
index b64af66..0000000
--- a/.hgignore
+++ /dev/null
@@ -1,28 +0,0 @@
-syntax: glob
-
-*.pyc
-*.pyo
-__pycache__
-*.egg
-*.egg-info
-
-Cython/Compiler/*.c
-Cython/Plex/*.c
-Cython/Runtime/refnanny.c
-
-TEST_TMP/
-build/
-dist/
-.git/
-.gitrev
-.coverage
-*.orig
-*.rej
-*.dep
-*.swp
-*.so
-*.o
-*~
-
-tags
-TAGS
diff --git a/.hgtags b/.hgtags
deleted file mode 100644 (file)
index e9522be..0000000
--- a/.hgtags
+++ /dev/null
@@ -1,55 +0,0 @@
-966abe58538dfbdaccd53bd970d4998c78ea522e 0.9.6.14
-67ee5a34bfc662e4e3cf989c2c8bf78a412ae8f4 0.9.8rc1
-16a746d969e2654112fc0dc081690b891c496977 Version-0.9.8
-a09347d7b470290076b983aef98707921445a038 0.9.8.1
-82084a7b654e2a133ab64ceb47e03d6e7a204990 0.9.9.2.beta
-a89b05b78236a27a654f3004bdffc7b8a56311a7 0.10
-ef9d2c680684d0df7d81f529cda29e9e1741f575 cython-0.10.1
-92baafe0edf3cea00deb7ce1e31e337bb485af1a 0.10.2
-cdf889c30e7a7053de20bae3a578dad09ebcbdf5 0.10.3
-59c67af0674bd93c5fd8958e08c76a9dab9aae37 sage-cythonizes
-a4abf0156540db4d3ebaa95712b65811c43c5acb 0.11-beta
-838a6b7cae62e01dc0ce663cccab1f93f649fdbd 0.11.rc
-4497f635d5fdbd38ebb841be4869fbfa2bbfdbb6 0.11.1.alpha
-7bc36a0f81723117a19f92ffde1676a0884fef65 0.11.1.beta
-6454db601984145f38e28d34176fca8a3a22329c 0.11.1
-af6f1bed8cd40a2edefb57d3eacbc9274a8788b4 0.11.2.rc1
-15ad532e2127840ae09dfbe46ccc80ac8c562f99 0.11.2
-eb00d00a73c13b6aa8b440fe07cd7acb52a060e8 0.11.3.rc0
-7c695fe49fd6912f52d995fe512d66baacf90ee6 0.11.3
-4208042ceeae634f5c0999b8ab75f69faf46b6db 0.12.alpha0
-e77827f09af67560aa82a18feab778f71ca0a9d3 0.12.rc0
-fae19937e4945c59a5d9d62c63f1c3b09046c3a3 0.12
-e90c522631ae06f2170a751fb256cdea0e50fb21 0.12.1
-5ac2eaefcdc9c3a7a9c29a0bb8c3e4c6c016c64c 0.13.beta0
-14957f635a379c97d9966097276313e43491ed96 0.13.beta1
-32c957267b3ba3140fba4d1947fa98484d5e956b 0.13
-ef9d2c680684d0df7d81f529cda29e9e1741f575 0.10.1
-16a746d969e2654112fc0dc081690b891c496977 0.9.8
-16a746d969e2654112fc0dc081690b891c496977 Version-0.9.8
-0000000000000000000000000000000000000000 Version-0.9.8
-ef9d2c680684d0df7d81f529cda29e9e1741f575 cython-0.10.1
-0000000000000000000000000000000000000000 cython-0.10.1
-59c67af0674bd93c5fd8958e08c76a9dab9aae37 sage-cythonizes
-0000000000000000000000000000000000000000 sage-cythonizes
-478f57be445d18fe294db849d7ad317fe7d7658f 0.14.alpha0
-31b531a6c45b2c34ae5a1af8a2c09f152adea60d 0.14.beta1
-7fa84cb6d3d75eb3d015aeeb60bf8b642171fe93 0.14.beta2
-7fa84cb6d3d75eb3d015aeeb60bf8b642171fe93 0.14.beta2
-8412b39fbc3eb709a543e2f1e95c0c8881ea9ed4 0.14.beta2
-a6b9f0a6d02d23fc3d3a9d0587867faa3afb2fcd 0.14.rc0
-15bf34c9387444e262acb1de594405444dd571a4 0.14
-5320ddd8c3a60d00e0513f9f70d6846cd449409b 0.17.beta1
-275fb550c1d802da3df35ebae41e04eadc60e49e 0.17.2
-b0faba6967e74f652286a0de6d02d736845b0708 0.17.3
-c1a18ab6b0808e87f68d2f9d914c01934510aef5 0.18b1
-9a11631e0edb0394b17554cde8bec5d4784117e4 0.18rc1
-76f33728e8534e698267e097cf603ea59ade6f30 0.18
-4f782ac7b3fdf3b4408bbf9f2ed4c38f31e60920 0.19b1
-52beb5b16df5b8a92bb6c8c47faf42370d73cb0f 0.19b2
-4818f5b68eb4b4ea6ad7e415f6672b491e2461bc 0.19rc1
-48407fa3f3c9da84ab3dc103a6a2b1ca4c1beb2a 0.19
-58fc9a3feb83f571623a492256885d21945decb4 0.21.1
-58fc9a3feb83f571623a492256885d21945decb4 0.21.1
-d05a4acd45fca9bdc12cef82890ca569fbaae1a5 0.21.1
-ab1a3afb8775a09d37c0d478476987eee8e734a6 0.21.2
diff --git a/.mailmap b/.mailmap
deleted file mode 100644 (file)
index c7d53f5..0000000
--- a/.mailmap
+++ /dev/null
@@ -1,15 +0,0 @@
-Stefan Behnel <stefan_ml@behnel.de> Stefan Behnel <scoder@users.berlios.de>
-Stefan Behnel <stefan_ml@behnel.de> scoder <stefan_ml@behnel.de>
-Stefan Behnel <stefan_ml@behnel.de> Stefan Behnel <stb@skoobe.de>
-Robert Bradshaw <robertwb@gmail.com> Robert Bradshaw <robertwb@math.washington.edu>
-Robert Bradshaw <robertwb@gmail.com> Robert Bradshaw <robertwb@google.com>
-Robert Bradshaw <robertwb@gmail.com> robertwb <robertwb@gmail.com>
-Robert Bradshaw <robertwb@gmail.com> Robert Bradshaw <robertwb@robertwb-macbookpro.local>
-Mark Florisson <markflorisson88@gmail.com> Mark <markflorisson88@gmail.com>
-Mark Florisson <markflorisson88@gmail.com> Mark Florisson <eggy.nospam@gmail.com>
-Lars Buitinck <larsmans@gmail.com> Lars Buitinck <L.J.Buitinck@uva.nl>
-Danilo Freitas <dsurviver@gmail.com> DaniloFreitas <dsurviver@gmail.com>
-Danilo Freitas <dsurviver@gmail.com> daniloaf@daniloaf-PC <none@none>
-Danilo Freitas <dsurviver@gmail.com> daniloaf <none@none>
-Lisandro Dalcin <dalcinl@gmail.com> dalcinl <none@none>
-Christoph Gohlke <cgohlke@uci.edu> cgohlke <cgohlke@uci.edu>
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644 (file)
index 0bb8013..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-os: linux
-dist: trusty
-language: python
-# 'sudo' is enabled automatically by the 'apt' addon below.
-#sudo: false
-
-addons:
-  apt:
-    packages:
-      - gdb
-      - python-dbg
-      - python3-dbg
-      - libzmq-dev  # needed by IPython/Tornado
-      #- gcc-8
-      #- g++-8
-
-cache:
-  pip: true
-  directories:
-    - $HOME/.ccache
-
-env:
-  global:
-    - USE_CCACHE=1
-    - CCACHE_SLOPPINESS=pch_defines,time_macros
-    - CCACHE_COMPRESS=1
-    - CCACHE_MAXSIZE=250M
-    - PATH="/usr/lib/ccache:$HOME/miniconda/bin:$PATH"
-    - BACKEND=c,cpp
-
-matrix:
-  include:
-    - python: 2.7
-      env: BACKEND=c
-    - python: 2.7
-      env: BACKEND=cpp
-    - python: 3.7
-      dist: xenial    # Required for Python 3.7
-      sudo: required  # travis-ci/travis-ci#9069
-      env: BACKEND=c
-    - python: 3.7
-      dist: xenial    # Required for Python 3.7
-      sudo: required  # travis-ci/travis-ci#9069
-      env: BACKEND=cpp
-    - python: 2.6
-      env: BACKEND=c
-    - python: 2.6
-      env: BACKEND=cpp
-# Disabled: coverage analysis takes excessively long, several times longer than without.
-#    - python: 3.7
-#      dist: xenial    # Required for Python 3.7
-#      sudo: required  # travis-ci/travis-ci#9069
-#      env: COVERAGE=1
-    - python: 3.7
-      dist: xenial    # Required for Python 3.7
-      sudo: required  # travis-ci/travis-ci#9069
-      env: TEST_CODE_STYLE=1
-    - python: 3.4
-      env: BACKEND=c
-    - python: 3.4
-      env: BACKEND=cpp
-    - python: 3.5
-      env: BACKEND=c
-    - python: 3.5
-      env: BACKEND=cpp
-    - python: 3.6
-      env: BACKEND=c
-    - python: 3.6
-      env: BACKEND=cpp
-    - python: 3.8
-      dist: xenial    # Required for Python 3.7
-      sudo: required  # travis-ci/travis-ci#9069
-      env: BACKEND=c
-    - python: 3.8
-      dist: xenial    # Required for Python 3.7
-      sudo: required  # travis-ci/travis-ci#9069
-      env: BACKEND=cpp
-    - python: 3.9-dev
-      dist: xenial    # Required for Python 3.7
-      sudo: required  # travis-ci/travis-ci#9069
-      env: BACKEND=c
-    - python: 3.9-dev
-      dist: xenial    # Required for Python 3.7
-      sudo: required  # travis-ci/travis-ci#9069
-      env: BACKEND=cpp
-    - os: osx
-      osx_image: xcode6.4
-      env: PY=2
-      python: 2
-      language: c
-      compiler: clang
-      cache: false
-    - os: osx
-      osx_image: xcode6.4
-      env: PY=3
-      python: 3
-      language: c
-      compiler: clang
-      cache: false
-    - python: pypy
-      env: BACKEND=c
-    - python: pypy3
-      env: BACKEND=c
-    - env: STACKLESS=true BACKEND=c PY=2
-      python: 2.7
-    - env: STACKLESS=true BACKEND=c PY=3
-      python: 3.6
-  allow_failures:
-    - python: 3.9-dev
-    - python: pypy
-    - python: pypy3
-
-branches:
-  only:
-    - master
-    - release
-
-before_install:
-  - |
-    if [ "$TRAVIS_OS_NAME" == "linux" ]; then
-      # adding apt repos in travis is really fragile => retry a couple of times.
-      for i in {1..10}; do travis_retry sudo apt-add-repository --yes 'ppa:ubuntu-toolchain-r/test' && break; sleep 2; done
-      for i in {1..10}; do travis_retry sudo apt-get update && travis_retry sudo apt-get install --yes gcc-8  $(if [ -z "${BACKEND##*cpp*}" ]; then echo -n "g++-8"; fi ) && break; sleep 2; done
-      sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 60 $(if [ -z "${BACKEND##*cpp*}" ]; then echo " --slave /usr/bin/g++ g++ /usr/bin/g++-8"; fi)
-      sudo update-alternatives --set gcc /usr/bin/gcc-8
-      export CC=gcc
-      if [ -z "${BACKEND##*cpp*}" ]; then sudo update-alternatives --set g++ /usr/bin/g++-8; export CXX=g++; fi
-    fi
-
-  - |
-    if [ "$TRAVIS_OS_NAME" == "osx" -o "$STACKLESS" == "true" ]; then
-      echo "Installing Miniconda"
-      if [ "$TRAVIS_OS_NAME" == "osx" ]; then CONDA_PLATFORM=MacOSX; else CONDA_PLATFORM=Linux; fi
-      travis_retry wget -O miniconda.sh https://repo.continuum.io/miniconda/Miniconda$PY-latest-${CONDA_PLATFORM}-x86_64.sh || exit 1
-      bash miniconda.sh -b -p $HOME/miniconda && rm miniconda.sh || exit 1
-      conda --version || exit 1
-      #conda install --quiet --yes nomkl --file=test-requirements.txt --file=test-requirements-cpython.txt
-      if [ "$TRAVIS_OS_NAME" == "osx" ]; then
-        which clang && clang --version && export CC=clang || true
-        which clang++ && clang++ --version && export CXX=clang++ || true
-      fi
-    fi
-
-  - if [ -n "$CC" ]; then which $CC; $CC --version; fi
-  - if [ -n "$CXX" ]; then which $CXX; $CXX --version; fi
-
-  - if [ "$STACKLESS" == "true" ]; then
-      conda config --add channels stackless;
-      travis_retry conda install --quiet --yes stackless;
-    fi
-
-install:
-  - python -c 'import sys; print("Python %s" % (sys.version,))'
-  - if [ -n "${TRAVIS_PYTHON_VERSION##*-dev}" -a -n "${TRAVIS_PYTHON_VERSION##2.6*}" ]; then pip install -r test-requirements.txt $( [ -z "${TRAVIS_PYTHON_VERSION##pypy*}" -o -z "${TRAVIS_PYTHON_VERSION##3.[478]*}" ] || echo " -r test-requirements-cpython.txt" ) ; fi
-#  - CFLAGS="-O2 -ggdb -Wall -Wextra $(python -c 'import sys; print("-fno-strict-aliasing" if sys.version_info[0] == 2 else "")')" python setup.py build
-
-before_script: ccache -s || true
-
-script:
-  - PYTHON_DBG="python$( python -c 'import sys; print("%d.%d" % sys.version_info[:2])' )-dbg"
-  - if [ "$TEST_CODE_STYLE" = "1" ]; then
-      STYLE_ARGS="--no-unit --no-doctest --no-file --no-pyregr --no-examples";
-    else
-      STYLE_ARGS=--no-code-style;
-      if $PYTHON_DBG -V >&2; then CFLAGS="-O0 -ggdb" $PYTHON_DBG runtests.py -vv --no-code-style Debugger --backends=$BACKEND; fi;
-      if [ -z "${BACKEND##*cpp*}" -a -n "${TRAVIS_PYTHON_VERSION##*-dev}" ]; then pip install pythran; fi;
-      if [ "$BACKEND" != "cpp" -a -n "${TRAVIS_PYTHON_VERSION##2*}" -a -n "${TRAVIS_PYTHON_VERSION##*-dev}" -a -n "${TRAVIS_PYTHON_VERSION##*3.4}" ]; then pip install mypy; fi;
-    fi
-  - if [ "$COVERAGE" != "1" ]; then CFLAGS="-O2 -ggdb -Wall -Wextra $(python -c 'import sys; print("-fno-strict-aliasing" if sys.version_info[0] == 2 else "")')" python setup.py build_ext -i; fi
-  - CFLAGS="-O0 -ggdb -Wall -Wextra" python runtests.py -vv $STYLE_ARGS -x Debugger --backends=$BACKEND $(if [ "$COVERAGE" == "1" ]; then echo " --coverage"; fi) $(if [ -z "$TEST_CODE_STYLE" ]; then echo " -j7 "; fi)
-  - ccache -s || true
diff --git a/BUILD.bazel b/BUILD.bazel
deleted file mode 100644 (file)
index dc694c9..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-# Bazel build file for inclusion as external dependency.
-#
-# Most useful is the pyx_library rule from //Tools:rules.bzl
-# which mirrors py_library but compiles .pyx files.
-
-py_library(
-    name = "cython_lib",
-    srcs = glob(
-        ["Cython/**/*.py"],
-        exclude = [
-            "**/Tests/*.py",
-        ],
-    ) + ["cython.py"],
-    data = glob([
-        "Cython/**/*.pyx",
-        "Cython/Utility/*.*",
-        "Cython/Includes/**/*.pxd",
-    ]),
-    visibility = ["//visibility:public"],
-)
-
-py_binary(
-    name = "cythonize",
-    srcs = ["cythonize.py"],
-    visibility = ["//visibility:public"],
-    deps = ["cython_lib"],
-)
-
-py_binary(
-    name = "cython",
-    srcs = ["cython.py"],
-    visibility = ["//visibility:public"],
-    deps = ["cython_lib"],
-)
index 166dfee..96ae40c 100644 (file)
@@ -2,6 +2,46 @@
 Cython Changelog
 ================
 
+0.29.21 (2020-07-09)
+====================
+
+Bugs fixed
+----------
+
+* Fix a regression in 0.29.20 where ``__div__`` failed to be found in extension types.
+  (Github issue #3688)
+
+* Fix a regression in 0.29.20 where a call inside of a finally clause could fail to compile.
+  Patch by David Woods.  (Github issue #3712)
+
+* Zero-sized buffers could fail to validate as C/Fortran-contiguous.
+  Patch by Clemens Hofreither.  (Github issue #2093)
+
+* ``exec()`` did not allow recent Python syntax features in Py3.8+ due to
+  https://bugs.python.org/issue35975.
+  (Github issue #3695)
+
+* Binding staticmethods of Cython functions were not behaving like Python methods in Py3.
+  Patch by Jeroen Demeyer and Michał Górny.  (Github issue #3106)
+
+* Pythran calls to NumPy methods no longer generate useless method lookup code.
+
+* The ``PyUnicode_GET_LENGTH()`` macro was missing from the ``cpython.*`` declarations.
+  Patch by Thomas Caswell.  (Github issue #3692)
+
+* The deprecated ``PyUnicode_*()`` C-API functions are no longer used, except for Unicode
+  strings that contain lone surrogates.  Unicode strings that contain non-BMP characters
+  or surrogate pairs now generate different C code on 16-bit Python 2.x Unicode deployments
+  (such as MS-Windows).  Generating the C code on Python 3.x is recommended in this case.
+  Original patches by Inada Naoki and Victor Stinner.  (Github issues #3677, #3721, #3697)
+
+* Some template parameters were missing from the C++ ``std::unordered_map`` declaration.
+  Patch by will.  (Github issue #3685)
+
+* Several internal code generation issues regarding temporary variables were resolved.
+  (Github issue #3708)
+
+
 0.29.20 (2020-06-10)
 ====================
 
diff --git a/Cython/Build/ipython-COPYING.rst b/Cython/Build/ipython-COPYING.rst
deleted file mode 100644 (file)
index 07a5305..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-=============================
- The IPython licensing terms
-=============================
-
-IPython is licensed under the terms of the Modified BSD License (also known as
-New or Revised or 3-Clause BSD), as follows:
-
-- Copyright (c) 2008-2014, IPython Development Team
-- Copyright (c) 2001-2007, Fernando Perez <fernando.perez@colorado.edu>
-- Copyright (c) 2001, Janko Hauser <jhauser@zscout.de>
-- Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu>
-
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-Redistributions of source code must retain the above copyright notice, this
-list of conditions and the following disclaimer.
-
-Redistributions in binary form must reproduce the above copyright notice, this
-list of conditions and the following disclaimer in the documentation and/or
-other materials provided with the distribution.
-
-Neither the name of the IPython Development Team nor the names of its
-contributors may be used to endorse or promote products derived from this
-software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-About the IPython Development Team
-----------------------------------
-
-Fernando Perez began IPython in 2001 based on code from Janko Hauser
-<jhauser@zscout.de> and Nathaniel Gray <n8gray@caltech.edu>.  Fernando is still
-the project lead.
-
-The IPython Development Team is the set of all contributors to the IPython
-project.  This includes all of the IPython subprojects. A full list with
-details is kept in the documentation directory, in the file
-``about/credits.txt``.
-
-The core team that coordinates development on GitHub can be found here:
-https://github.com/ipython/.
-
-Our Copyright Policy
---------------------
-
-IPython uses a shared copyright model. Each contributor maintains copyright
-over their contributions to IPython. But, it is important to note that these
-contributions are typically only changes to the repositories. Thus, the IPython
-source code, in its entirety is not the copyright of any single person or
-institution.  Instead, it is the collective copyright of the entire IPython
-Development Team.  If individual contributors want to maintain a record of what
-changes/contributions they have specific copyright on, they should indicate
-their copyright in the commit message of the change, when they commit the
-change to one of the IPython repositories.
-
-With this in mind, the following banner should be used in any source code file
-to indicate the copyright and license terms:
-
-::
-
-    # Copyright (c) IPython Development Team.
-    # Distributed under the terms of the Modified BSD License.
index 515a535..26fb8a1 100644 (file)
@@ -718,9 +718,10 @@ class FunctionState(object):
         self.can_trace = False
         self.gil_owned = True
 
-        self.temps_allocated = [] # of (name, type, manage_ref, static)
-        self.temps_free = {} # (type, manage_ref) -> list of free vars with same type/managed status
-        self.temps_used_type = {} # name -> (type, manage_ref)
+        self.temps_allocated = []  # of (name, type, manage_ref, static)
+        self.temps_free = {}  # (type, manage_ref) -> list of free vars with same type/managed status
+        self.temps_used_type = {}  # name -> (type, manage_ref)
+        self.zombie_temps = set()  # temps that must not be reused after release
         self.temp_counter = 0
         self.closure_temps = None
 
@@ -735,6 +736,20 @@ class FunctionState(object):
         self.should_declare_error_indicator = False
         self.uses_error_indicator = False
 
+    # safety checks
+
+    def validate_exit(self):
+        # validate that all allocated temps have been freed
+        if self.temps_allocated:
+            leftovers = self.temps_in_use()
+            if leftovers:
+                msg = "TEMPGUARD: Temps left over at end of '%s': %s" % (self.scope.name, ', '.join([
+                    '%s [%s]' % (name, ctype)
+                    for name, ctype, is_pytemp in sorted(leftovers)]),
+                )
+                #print(msg)
+                raise RuntimeError(msg)
+
     # labels
 
     def new_label(self, name=None):
@@ -804,7 +819,7 @@ class FunctionState(object):
 
     # temp handling
 
-    def allocate_temp(self, type, manage_ref, static=False):
+    def allocate_temp(self, type, manage_ref, static=False, reusable=True):
         """
         Allocates a temporary (which may create a new one or get a previously
         allocated and released one of the same type). Type is simply registered
@@ -823,6 +838,8 @@ class FunctionState(object):
         This is only used when allocating backing store for a module-level
         C array literals.
 
+        if reusable=False, the temp will not be reused after release.
+
         A C string referring to the variable is returned.
         """
         if type.is_const and not type.is_reference:
@@ -838,7 +855,7 @@ class FunctionState(object):
             manage_ref = False
 
         freelist = self.temps_free.get((type, manage_ref))
-        if freelist is not None and freelist[0]:
+        if reusable and freelist is not None and freelist[0]:
             result = freelist[0].pop()
             freelist[1].remove(result)
         else:
@@ -847,9 +864,11 @@ class FunctionState(object):
                 result = "%s%d" % (Naming.codewriter_temp_prefix, self.temp_counter)
                 if result not in self.names_taken: break
             self.temps_allocated.append((result, type, manage_ref, static))
+            if not reusable:
+                self.zombie_temps.add(result)
         self.temps_used_type[result] = (type, manage_ref)
         if DebugFlags.debug_temp_code_comments:
-            self.owner.putln("/* %s allocated (%s) */" % (result, type))
+            self.owner.putln("/* %s allocated (%s)%s */" % (result, type, "" if reusable else " - zombie"))
 
         if self.collect_temps_stack:
             self.collect_temps_stack[-1].add((result, type))
@@ -868,10 +887,12 @@ class FunctionState(object):
             self.temps_free[(type, manage_ref)] = freelist
         if name in freelist[1]:
             raise RuntimeError("Temp %s freed twice!" % name)
-        freelist[0].append(name)
+        if name not in self.zombie_temps:
+            freelist[0].append(name)
         freelist[1].add(name)
         if DebugFlags.debug_temp_code_comments:
-            self.owner.putln("/* %s released */" % name)
+            self.owner.putln("/* %s released %s*/" % (
+                name, " - zombie" if name in self.zombie_temps else ""))
 
     def temps_in_use(self):
         """Return a list of (cname,type,manage_ref) tuples of temp names and their type
index a0baadf..831575b 100644 (file)
@@ -1623,17 +1623,23 @@ class UnicodeNode(ConstNode):
 
     def generate_evaluation_code(self, code):
         if self.type.is_pyobject:
-            if self.contains_surrogates():
-                # surrogates are not really portable and cannot be
+            # FIXME: this should go away entirely!
+            # Since string_contains_lone_surrogates() returns False for surrogate pairs in Py2/UCS2,
+            # Py2 can generate different code from Py3 here.  Let's hope we get away with claiming that
+            # the processing of surrogate pairs in code was always ambiguous and lead to different results
+            # on P16/32bit Unicode platforms.
+            if StringEncoding.string_contains_lone_surrogates(self.value):
+                # lone (unpaired) surrogates are not really portable and cannot be
                 # decoded by the UTF-8 codec in Py3.3
                 self.result_code = code.get_py_const(py_object_type, 'ustring')
-                data_cname = code.get_pyunicode_ptr_const(self.value)
+                data_cname = code.get_string_const(
+                    StringEncoding.BytesLiteral(self.value.encode('unicode_escape')))
                 const_code = code.get_cached_constants_writer(self.result_code)
                 if const_code is None:
                     return  # already initialised
                 const_code.mark_pos(self.pos)
                 const_code.putln(
-                    "%s = PyUnicode_FromUnicode(%s, (sizeof(%s) / sizeof(Py_UNICODE))-1); %s" % (
+                    "%s = PyUnicode_DecodeUnicodeEscape(%s, sizeof(%s) - 1, NULL); %s" % (
                         self.result_code,
                         data_cname,
                         data_cname,
@@ -4334,6 +4340,7 @@ class BufferIndexNode(_IndexingBaseNode):
                 pythran_indexing_code(self.indices),
                 op,
                 rhs.pythran_result()))
+            code.funcstate.release_temp(obj)
             return
 
         # Used from generate_assignment_code and InPlaceAssignmentNode
@@ -4374,11 +4381,11 @@ class BufferIndexNode(_IndexingBaseNode):
             code.putln("%s = (PyObject *) *%s;" % (self.result(), self.buffer_ptr_code))
             code.putln("__Pyx_INCREF((PyObject*)%s);" % self.result())
 
-    def free_temps(self, code):
+    def free_subexpr_temps(self, code):
         for temp in self.index_temps:
             code.funcstate.release_temp(temp)
         self.index_temps = ()
-        super(BufferIndexNode, self).free_temps(code)
+        super(BufferIndexNode, self).free_subexpr_temps(code)
 
 
 class MemoryViewIndexNode(BufferIndexNode):
@@ -4655,6 +4662,7 @@ class MemoryCopyNode(ExprNode):
         self.dst.generate_evaluation_code(code)
         self._generate_assignment_code(rhs, code)
         self.dst.generate_disposal_code(code)
+        self.dst.free_temps(code)
         rhs.generate_disposal_code(code)
         rhs.free_temps(code)
 
@@ -5558,7 +5566,7 @@ class SimpleCallNode(CallNode):
             env.add_include_file(pythran_get_func_include_file(function))
             return NumPyMethodCallNode.from_node(
                 self,
-                function=function,
+                function_cname=pythran_functor(function),
                 arg_tuple=self.arg_tuple,
                 type=PythranExpr(pythran_func_type(function, self.arg_tuple.args)),
             )
@@ -5963,13 +5971,13 @@ class SimpleCallNode(CallNode):
                 code.funcstate.release_temp(self.opt_arg_struct)
 
 
-class NumPyMethodCallNode(SimpleCallNode):
+class NumPyMethodCallNode(ExprNode):
     # Pythran call to a NumPy function or method.
     #
-    # function    ExprNode      the function/method to call
-    # arg_tuple   TupleNode     the arguments as an args tuple
+    # function_cname  string      the function/method to call
+    # arg_tuple       TupleNode   the arguments as an args tuple
 
-    subexprs = ['function', 'arg_tuple']
+    subexprs = ['arg_tuple']
     is_temp = True
     may_return_none = True
 
@@ -5977,7 +5985,6 @@ class NumPyMethodCallNode(SimpleCallNode):
         code.mark_pos(self.pos)
         self.allocate_temp_result(code)
 
-        self.function.generate_evaluation_code(code)
         assert self.arg_tuple.mult_factor is None
         args = self.arg_tuple.args
         for arg in args:
@@ -5988,7 +5995,7 @@ class NumPyMethodCallNode(SimpleCallNode):
         code.putln("new (&%s) decltype(%s){%s{}(%s)};" % (
             self.result(),
             self.result(),
-            pythran_functor(self.function),
+            self.function_cname,
             ", ".join(a.pythran_result() for a in args)))
 
 
@@ -7277,6 +7284,8 @@ class AttributeNode(ExprNode):
                 self.member.upper(),
                 self.obj.result_as(self.obj.type),
                 rhs.result_as(self.ctype())))
+            rhs.generate_disposal_code(code)
+            rhs.free_temps(code)
         else:
             select_code = self.result()
             if self.type.is_pyobject and self.use_managed_ref:
@@ -8127,20 +8136,18 @@ class ListNode(SequenceNode):
         return t
 
     def allocate_temp_result(self, code):
-        if self.type.is_array and self.in_module_scope:
-            self.temp_code = code.funcstate.allocate_temp(
-                self.type, manage_ref=False, static=True)
-        else:
-            SequenceNode.allocate_temp_result(self, code)
-
-    def release_temp_result(self, env):
         if self.type.is_array:
-            # To be valid C++, we must allocate the memory on the stack
-            # manually and be sure not to reuse it for something else.
-            # Yes, this means that we leak a temp array variable.
-            pass
+            if self.in_module_scope:
+                self.temp_code = code.funcstate.allocate_temp(
+                    self.type, manage_ref=False, static=True, reusable=False)
+            else:
+                # To be valid C++, we must allocate the memory on the stack
+                # manually and be sure not to reuse it for something else.
+                # Yes, this means that we leak a temp array variable.
+                self.temp_code = code.funcstate.allocate_temp(
+                    self.type, manage_ref=False, reusable=False)
         else:
-            SequenceNode.release_temp_result(self, env)
+            SequenceNode.allocate_temp_result(self, code)
 
     def calculate_constant_result(self):
         if self.mult_factor:
@@ -13076,9 +13083,18 @@ class PyTypeTestNode(CoercionNode):
     def generate_post_assignment_code(self, code):
         self.arg.generate_post_assignment_code(code)
 
+    def allocate_temp_result(self, code):
+        pass
+
+    def release_temp_result(self, code):
+        pass
+
     def free_temps(self, code):
         self.arg.free_temps(code)
 
+    def free_subexpr_temps(self, code):
+        self.arg.free_subexpr_temps(code)
+
 
 class NoneCheckNode(CoercionNode):
     # This node is used to check that a Python object is not None and
index 49f74a2..df04471 100644 (file)
@@ -1198,6 +1198,7 @@ class ControlFlowAnalysis(CythonTransform):
         if self.flow.loops:
             self.flow.loops[-1].exceptions.append(descr)
         self.flow.block = body_block
+        body_block.add_child(entry_point)
         self.flow.nextblock()
         self._visit(node.body)
         self.flow.exceptions.pop()
index 87a9ae2..26d6ffd 100644 (file)
@@ -878,17 +878,23 @@ class FusedCFuncDefNode(StatListNode):
                                     (self.resulting_fused_function.result(),
                                      self.__signatures__.result()))
             code.put_giveref(self.__signatures__.result())
+            self.__signatures__.generate_post_assignment_code(code)
+            self.__signatures__.free_temps(code)
 
             self.fused_func_assignment.generate_execution_code(code)
 
             # Dispose of results
             self.resulting_fused_function.generate_disposal_code(code)
+            self.resulting_fused_function.free_temps(code)
             self.defaults_tuple.generate_disposal_code(code)
+            self.defaults_tuple.free_temps(code)
             self.code_object.generate_disposal_code(code)
+            self.code_object.free_temps(code)
 
         for default in self.defaults:
             if default is not None:
                 default.generate_disposal_code(code)
+                default.free_temps(code)
 
     def annotate(self, code):
         for stat in self.stats:
index e1e9250..9733ea7 100644 (file)
@@ -29,7 +29,7 @@ from . import Pythran
 from .Errors import error, warning
 from .PyrexTypes import py_object_type
 from ..Utils import open_new_file, replace_suffix, decode_filename, build_hex_version
-from .Code import UtilityCode, IncludeCode, TempitaUtilityCode
+from .Code import UtilityCode, IncludeCode
 from .StringEncoding import EncodedString
 from .Pythran import has_np_pythran
 
@@ -1223,6 +1223,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
                 type = entry.type
                 scope = type.scope
                 if scope: # could be None if there was an error
+                    if not scope.directives['c_api_binop_methods']:
+                        error(self.pos,
+                              "The 'c_api_binop_methods' directive is only supported for forward compatibility"
+                              " and must be True.")
                     self.generate_exttype_vtable(scope, code)
                     self.generate_new_function(scope, code, entry)
                     self.generate_dealloc_function(scope, code)
@@ -1255,9 +1259,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
                         self.generate_dict_getter_function(scope, code)
                     if scope.defines_any_special(TypeSlots.richcmp_special_methods):
                         self.generate_richcmp_function(scope, code)
-                    for slot in TypeSlots.PyNumberMethods:
-                        if slot.is_binop and scope.defines_any_special(slot.user_methods):
-                            self.generate_binop_function(scope, slot, code)
                     self.generate_property_accessors(scope, code)
                     self.generate_method_table(scope, code)
                     self.generate_getset_table(scope, code)
@@ -1897,64 +1898,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
         code.putln("}")  # switch
         code.putln("}")
 
-    def generate_binop_function(self, scope, slot, code):
-        func_name = scope.mangle_internal(slot.slot_name)
-        if scope.directives['c_api_binop_methods']:
-            code.putln('#define %s %s' % (func_name, slot.left_slot.slot_code(scope)))
-            return
-        else:
-            error(self.pos,
-                  "The 'c_api_binop_methods' directive is only supported for forward compatibility"
-                  " and must be True.")
-
-        code.putln()
-        preprocessor_guard = slot.preprocessor_guard_code()
-        if preprocessor_guard:
-            code.putln(preprocessor_guard)
-
-        if slot.left_slot.signature == TypeSlots.binaryfunc:
-            slot_type = 'binaryfunc'
-            extra_arg = extra_arg_decl = ''
-        elif slot.left_slot.signature == TypeSlots.ternaryfunc:
-            slot_type = 'ternaryfunc'
-            extra_arg = ', extra_arg'
-            extra_arg_decl = ', PyObject* extra_arg'
-        else:
-            error(entry.pos, "Unexpected type lost signature: %s" % slot)
-
-        def has_slot_method(method_name):
-            entry = scope.lookup(method_name)
-            return bool(entry and entry.is_special and entry.func_cname)
-        def call_slot_method(method_name, reverse):
-            entry = scope.lookup(method_name)
-            if entry and entry.is_special and entry.func_cname:
-                return "%s(%s%s)" % (
-                    entry.func_cname,
-                    "right, left" if reverse else "left, right",
-                    extra_arg)
-            else:
-                return '%s_maybe_call_slot(%s, left, right %s)' % (
-                    func_name,
-                    'Py_TYPE(right)->tp_base' if reverse else 'Py_TYPE(left)->tp_base',
-                    extra_arg)
-
-        code.putln(
-            TempitaUtilityCode.load_as_string(
-                "BinopSlot", "ExtensionTypes.c",
-                context={
-                    "func_name": func_name,
-                    "slot_name": slot.slot_name,
-                    "overloads_left": int(has_slot_method(slot.left_slot.method_name)),
-                    "call_left": call_slot_method(slot.left_slot.method_name, reverse=False),
-                    "call_right": call_slot_method(slot.right_slot.method_name, reverse=True),
-                    "type_cname": scope.parent_type.typeptr_cname,
-                    "slot_type": slot_type,
-                    "extra_arg": extra_arg,
-                    "extra_arg_decl": extra_arg_decl,
-                    })[1])
-        if preprocessor_guard:
-            code.putln("#endif")
-
     def generate_getattro_function(self, scope, code):
         # First try to get the attribute using __getattribute__, if defined, or
         # PyObject_GenericGetAttr.
@@ -2715,6 +2658,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
 
         code.putln('static void %s(CYTHON_UNUSED PyObject *self) {' %
                    Naming.cleanup_cname)
+        code.enter_cfunc_scope(env)
+
         if Options.generate_cleanup_code >= 2:
             code.putln("/*--- Global cleanup code ---*/")
             rev_entries = list(env.var_entries)
@@ -3004,6 +2949,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
                     module.qualified_name,
                     temp,
                     code.error_goto(self.pos)))
+            code.put_gotref(temp)
             for entry in entries:
                 if env is module:
                     cname = entry.cname
@@ -3014,7 +2960,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
                     'if (__Pyx_ImportVoidPtr(%s, "%s", (void **)&%s, "%s") < 0) %s' % (
                         temp, entry.name, cname, signature,
                         code.error_goto(self.pos)))
-            code.putln("Py_DECREF(%s); %s = 0;" % (temp, temp))
+            code.put_decref_clear(temp, py_object_type)
+            code.funcstate.release_temp(temp)
 
     def generate_c_function_import_code_for_module(self, module, env, code):
         # Generate import code for all exported C functions in a cimported module.
@@ -3032,6 +2979,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
                     module.qualified_name,
                     temp,
                     code.error_goto(self.pos)))
+            code.put_gotref(temp)
             for entry in entries:
                 code.putln(
                     'if (__Pyx_ImportFunction(%s, "%s", (void (**)(void))&%s, "%s") < 0) %s' % (
@@ -3040,7 +2988,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
                         entry.cname,
                         entry.type.signature_string(),
                         code.error_goto(self.pos)))
-            code.putln("Py_DECREF(%s); %s = 0;" % (temp, temp))
+            code.put_decref_clear(temp, py_object_type)
+            code.funcstate.release_temp(temp)
 
     def generate_type_init_code(self, env, code):
         # Generate type import code for extern extension types
index d3e0590..dd79bd5 100644 (file)
@@ -5866,6 +5866,7 @@ class DelStatNode(StatNode):
                 arg.generate_evaluation_code(code)
                 code.putln("delete %s;" % arg.result())
                 arg.generate_disposal_code(code)
+                arg.free_temps(code)
             # else error reported earlier
 
     def annotate(self, code):
@@ -6410,6 +6411,8 @@ class SwitchStatNode(StatNode):
             # generate the switch statement, so shouldn't be bothered).
             code.putln("default: break;")
         code.putln("}")
+        self.test.generate_disposal_code(code)
+        self.test.free_temps(code)
 
     def generate_function_definitions(self, env, code):
         self.test.generate_function_definitions(env, code)
@@ -7673,9 +7676,10 @@ class TryFinallyStatNode(StatNode):
                     if self.func_return_type.is_pyobject:
                         code.putln("%s = 0;" % ret_temp)
                     code.funcstate.release_temp(ret_temp)
-                    ret_temp = None
                 if self.in_generator:
                     self.put_error_uncatcher(code, exc_vars)
+                    for cname in exc_vars:
+                        code.funcstate.release_temp(cname)
 
             if not self.finally_clause.is_terminator:
                 code.put_goto(old_label)
@@ -8772,6 +8776,11 @@ class ParallelStatNode(StatNode, ParallelNode):
         self.begin_of_parallel_control_block_point = None
         self.begin_of_parallel_control_block_point_after_decls = None
 
+        if self.num_threads is not None:
+            # FIXME: is it the right place? should not normally produce code.
+            self.num_threads.generate_disposal_code(code)
+            self.num_threads.free_temps(code)
+
         # Firstly, always prefer errors over returning, continue or break
         if self.error_label_used:
             c.putln("const char *%s = NULL; int %s = 0, %s = 0;" % self.parallel_pos_info)
@@ -9151,7 +9160,7 @@ class ParallelRangeNode(ParallelStatNode):
 
         # And finally, release our privates and write back any closure
         # variables
-        for temp in start_stop_step + (self.chunksize, self.num_threads):
+        for temp in start_stop_step + (self.chunksize,):
             if temp is not None:
                 temp.generate_disposal_code(code)
                 temp.free_temps(code)
index db497aa..48695db 100644 (file)
@@ -178,7 +178,7 @@ _directive_defaults = {
     'auto_pickle': None,
     'cdivision': False,  # was True before 0.12
     'cdivision_warnings': False,
-    'c_api_binop_methods': True,  # Change for 3.0
+    'c_api_binop_methods': True,
     'overflowcheck': False,
     'overflowcheck.fold': True,
     'always_allow_keywords': False,
index af0b411..c37e8aa 100644 (file)
@@ -154,6 +154,34 @@ def string_contains_surrogates(ustring):
     return False
 
 
+def string_contains_lone_surrogates(ustring):
+    """
+    Check if the unicode string contains lone surrogate code points
+    on a CPython platform with wide (UCS-4) or narrow (UTF-16)
+    Unicode, i.e. characters that would be spelled as two
+    separate code units on a narrow platform, but that do not form a pair.
+    """
+    last_was_start = False
+    unicode_uses_surrogate_encoding = sys.maxunicode == 65535
+    for c in map(ord, ustring):
+        # surrogates tend to be rare
+        if c < 0xD800 or c > 0xDFFF:
+            if last_was_start:
+                return True
+        elif not unicode_uses_surrogate_encoding:
+            # on 32bit Unicode platforms, there is never a pair
+            return True
+        elif c <= 0xDBFF:
+            if last_was_start:
+                return True  # lone start
+            last_was_start = True
+        else:
+            if not last_was_start:
+                return True  # lone end
+            last_was_start = False
+    return last_was_start
+
+
 class BytesLiteral(_bytes):
     # bytes subclass that is compatible with EncodedString
     encoding = None
diff --git a/Cython/Compiler/Tests/TestStringEncoding.py b/Cython/Compiler/Tests/TestStringEncoding.py
new file mode 100644 (file)
index 0000000..91d0993
--- /dev/null
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+
+import sys
+import unittest
+
+import Cython.Compiler.StringEncoding as StringEncoding
+
+
+class StringEncodingTest(unittest.TestCase):
+    """
+    Test the StringEncoding module.
+    """
+    def test_string_contains_lone_surrogates(self):
+        self.assertFalse(StringEncoding.string_contains_lone_surrogates(u"abc"))
+        self.assertFalse(StringEncoding.string_contains_lone_surrogates(u"\uABCD"))
+        self.assertFalse(StringEncoding.string_contains_lone_surrogates(u"\N{SNOWMAN}"))
+
+        # This behaves differently in Py2 when freshly parsed and read from a .pyc file,
+        # but it seems to be a marshalling bug in Py2, which doesn't hurt us in Cython.
+        if sys.version_info[0] != 2:
+            self.assertTrue(StringEncoding.string_contains_lone_surrogates(u"\uD800\uDFFF"))
+
+        # In Py2 with 16bit Unicode, the following is indistinguishable from the 32bit character.
+        obfuscated_surrogate_pair = (u"\uDFFF" + "\uD800")[::-1]
+        if sys.version_info[0] == 2 and sys.maxunicode == 65565:
+            self.assertFalse(StringEncoding.string_contains_lone_surrogates(obfuscated_surrogate_pair))
+        else:
+            self.assertTrue(StringEncoding.string_contains_lone_surrogates(obfuscated_surrogate_pair))
+
+        self.assertTrue(StringEncoding.string_contains_lone_surrogates(u"\uD800"))
+        self.assertTrue(StringEncoding.string_contains_lone_surrogates(u"\uDFFF"))
+        self.assertTrue(StringEncoding.string_contains_lone_surrogates(u"\uDFFF\uD800"))
+        self.assertTrue(StringEncoding.string_contains_lone_surrogates(u"\uD800x\uDFFF"))
+
+    def test_string_contains_surrogates(self):
+        self.assertFalse(StringEncoding.string_contains_surrogates(u"abc"))
+        self.assertFalse(StringEncoding.string_contains_surrogates(u"\uABCD"))
+        self.assertFalse(StringEncoding.string_contains_surrogates(u"\N{SNOWMAN}"))
+
+        self.assertTrue(StringEncoding.string_contains_surrogates(u"\uD800"))
+        self.assertTrue(StringEncoding.string_contains_surrogates(u"\uDFFF"))
+        self.assertTrue(StringEncoding.string_contains_surrogates(u"\uD800\uDFFF"))
+        self.assertTrue(StringEncoding.string_contains_surrogates(u"\uDFFF\uD800"))
+        self.assertTrue(StringEncoding.string_contains_surrogates(u"\uD800x\uDFFF"))
index 50e09cd..137ea4e 100644 (file)
@@ -180,14 +180,13 @@ class SlotDescriptor(object):
     #  ifdef                         Full #ifdef string that slot is wrapped in. Using this causes py3, py2 and flags to be ignored.)
 
     def __init__(self, slot_name, dynamic=False, inherited=False,
-                 py3=True, py2=True, ifdef=None, is_binop=False):
+                 py3=True, py2=True, ifdef=None):
         self.slot_name = slot_name
         self.is_initialised_dynamically = dynamic
         self.is_inherited = inherited
         self.ifdef = ifdef
         self.py3 = py3
         self.py2 = py2
-        self.is_binop = is_binop
 
     def preprocessor_guard_code(self):
         ifdef = self.ifdef
@@ -406,17 +405,6 @@ class SyntheticSlot(InternalMethodSlot):
             return self.default_value
 
 
-class BinopSlot(SyntheticSlot):
-    def __init__(self, signature, slot_name, left_method, **kargs):
-        assert left_method.startswith('__')
-        right_method = '__r' + left_method[2:]
-        SyntheticSlot.__init__(
-                self, slot_name, [left_method, right_method], "0", is_binop=True, **kargs)
-        # MethodSlot causes special method registration.
-        self.left_slot = MethodSlot(signature, "", left_method)
-        self.right_slot = MethodSlot(signature, "", right_method)
-
-
 class RichcmpSlot(MethodSlot):
     def slot_code(self, scope):
         entry = scope.lookup_here(self.method_name)
@@ -740,23 +728,23 @@ property_accessor_signatures = {
 PyNumberMethods_Py3_GUARD = "PY_MAJOR_VERSION < 3 || (CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x03050000)"
 
 PyNumberMethods = (
-    BinopSlot(binaryfunc, "nb_add", "__add__"),
-    BinopSlot(binaryfunc, "nb_subtract", "__sub__"),
-    BinopSlot(binaryfunc, "nb_multiply", "__mul__"),
-    BinopSlot(binaryfunc, "nb_divide", "__div__", ifdef = PyNumberMethods_Py3_GUARD),
-    BinopSlot(binaryfunc, "nb_remainder", "__mod__"),
-    BinopSlot(binaryfunc, "nb_divmod", "__divmod__"),
-    BinopSlot(ternaryfunc, "nb_power", "__pow__"),
+    MethodSlot(binaryfunc, "nb_add", "__add__"),
+    MethodSlot(binaryfunc, "nb_subtract", "__sub__"),
+    MethodSlot(binaryfunc, "nb_multiply", "__mul__"),
+    MethodSlot(binaryfunc, "nb_divide", "__div__", ifdef = PyNumberMethods_Py3_GUARD),
+    MethodSlot(binaryfunc, "nb_remainder", "__mod__"),
+    MethodSlot(binaryfunc, "nb_divmod", "__divmod__"),
+    MethodSlot(ternaryfunc, "nb_power", "__pow__"),
     MethodSlot(unaryfunc, "nb_negative", "__neg__"),
     MethodSlot(unaryfunc, "nb_positive", "__pos__"),
     MethodSlot(unaryfunc, "nb_absolute", "__abs__"),
     MethodSlot(inquiry, "nb_nonzero", "__nonzero__", py3 = ("nb_bool", "__bool__")),
     MethodSlot(unaryfunc, "nb_invert", "__invert__"),
-    BinopSlot(binaryfunc, "nb_lshift", "__lshift__"),
-    BinopSlot(binaryfunc, "nb_rshift", "__rshift__"),
-    BinopSlot(binaryfunc, "nb_and", "__and__"),
-    BinopSlot(binaryfunc, "nb_xor", "__xor__"),
-    BinopSlot(binaryfunc, "nb_or", "__or__"),
+    MethodSlot(binaryfunc, "nb_lshift", "__lshift__"),
+    MethodSlot(binaryfunc, "nb_rshift", "__rshift__"),
+    MethodSlot(binaryfunc, "nb_and", "__and__"),
+    MethodSlot(binaryfunc, "nb_xor", "__xor__"),
+    MethodSlot(binaryfunc, "nb_or", "__or__"),
     EmptySlot("nb_coerce", ifdef = PyNumberMethods_Py3_GUARD),
     MethodSlot(unaryfunc, "nb_int", "__int__", fallback="__long__"),
     MethodSlot(unaryfunc, "nb_long", "__long__", fallback="__int__", py3 = "<RESERVED>"),
@@ -779,8 +767,8 @@ PyNumberMethods = (
 
     # Added in release 2.2
     # The following require the Py_TPFLAGS_HAVE_CLASS flag
-    BinopSlot(binaryfunc, "nb_floor_divide", "__floordiv__"),
-    BinopSlot(binaryfunc, "nb_true_divide", "__truediv__"),
+    MethodSlot(binaryfunc, "nb_floor_divide", "__floordiv__"),
+    MethodSlot(binaryfunc, "nb_true_divide", "__truediv__"),
     MethodSlot(ibinaryfunc, "nb_inplace_floor_divide", "__ifloordiv__"),
     MethodSlot(ibinaryfunc, "nb_inplace_true_divide", "__itruediv__"),
 
@@ -788,7 +776,7 @@ PyNumberMethods = (
     MethodSlot(unaryfunc, "nb_index", "__index__"),
 
     # Added in release 3.5
-    BinopSlot(binaryfunc, "nb_matrix_multiply", "__matmul__", ifdef="PY_VERSION_HEX >= 0x03050000"),
+    MethodSlot(binaryfunc, "nb_matrix_multiply", "__matmul__", ifdef="PY_VERSION_HEX >= 0x03050000"),
     MethodSlot(ibinaryfunc, "nb_inplace_matrix_multiply", "__imatmul__", ifdef="PY_VERSION_HEX >= 0x03050000"),
 )
 
index 9060d8c..061be09 100644 (file)
@@ -10,8 +10,19 @@ cdef extern from *:
 
     # Return the size of the object. o has to be a PyUnicodeObject
     # (not checked).
+    #
+    # Deprecated since version 3.3, will be removed in version 3.10:
+    # Part of the old-style Unicode API, please migrate to using
+    # PyUnicode_GET_LENGTH().
     Py_ssize_t PyUnicode_GET_SIZE(object o)
 
+    # Return the length of the Unicode string, in code points. o has
+    # to be a Unicode object in the “canonical” representation (not
+    # checked).
+    #
+    # New in version 3.3.
+    Py_ssize_t PyUnicode_GET_LENGTH(object o)
+
     # Return the size of the object's internal buffer in bytes. o has
     # to be a PyUnicodeObject (not checked).
     Py_ssize_t PyUnicode_GET_DATA_SIZE(object o)
index 329c1ce..a00fbbe 100644 (file)
@@ -1,7 +1,7 @@
 from .utility cimport pair
 
 cdef extern from "<unordered_map>" namespace "std" nogil:
-    cdef cppclass unordered_map[T, U]:
+    cdef cppclass unordered_map[T, U, HASH=*, PRED=*, ALLOCATOR=*]:
         ctypedef T key_type
         ctypedef U mapped_type
         ctypedef pair[const T, U] value_type
index 1e123fd..dab8c49 100644 (file)
@@ -1,7 +1,7 @@
 # cython.* namespace for pure mode.
 from __future__ import absolute_import
 
-__version__ = "0.29.20"
+__version__ = "0.29.21"
 
 try:
     from __builtin__ import basestring
diff --git a/Cython/Shadow.pyi b/Cython/Shadow.pyi
deleted file mode 100644 (file)
index 42827a3..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-from builtins import (int as py_int, float as py_float,
-                      bool as py_bool, str as py_str, complex as py_complex)
-from typing import (Union, Dict, Any, Sequence, Optional,
-                    List, TypeVar, Type, Generic)
-
-int = py_int
-long = py_int
-longlong = py_int
-short = py_int
-char = py_int
-sint = py_int
-slong = py_int
-slonglong = py_int
-sshort = py_int
-schar = py_int
-uint = py_int
-ulong = py_int
-ulonglong = py_int
-ushort = py_int
-uchar = py_int
-size_t = py_int
-Py_ssize_t = py_int
-Py_UCS4 = Union[py_int, str]
-Py_UNICODE = Union[py_int, str]
-float = py_float
-double = py_float
-longdouble = py_float
-complex = py_complex
-floatcomplex = py_complex
-doublecomplex = py_complex
-longdoublecomplex = py_complex
-bint = py_bool
-void = Union[None]
-basestring = py_str
-unicode = py_str
-
-gs: Dict[str, Any]  # Should match the return type of globals()
-
-_T = TypeVar('_T')
-
-class _ArrayType(object, Generic[_T]):
-    is_array: bool
-    subtypes: Sequence[str]
-    dtype: _T
-    ndim: int
-    is_c_contig: bool
-    is_f_contig: bool
-    inner_contig: bool
-    broadcasting: Any
-
-    # broadcasting is not used, so it's not clear about its type
-    def __init__(self, dtype: _T, ndim: int, is_c_contig: bool = ...,
-                 is_f_contig: bool = ..., inner_contig: bool = ...,
-                 broadcasting: Any = ...) -> None: ...
-    def __repr__(self) -> str: ...
-
-class CythonTypeObject(object):
-    ...
-
-class CythonType(CythonTypeObject):
-    ...
-
-class PointerType(CythonType, Generic[_T]):
-    def __init__(
-        self,
-        value: Optional[Union[ArrayType[_T], PointerType[_T], List[_T], int]] = ...
-    ) -> None: ...
-    def __getitem__(self, ix: int) -> _T: ...
-    def __setitem__(self, ix: int, value: _T) -> None: ...
-    def __eq__(self, value: object) -> bool: ...
-    def __repr__(self) -> str: ...
-
-class ArrayType(PointerType[_T]):
-    def __init__(self) -> None: ...
-
-#class StructType(CythonType, Generic[_T]):
-#    def __init__(
-#        self,
-#        value: List[Type[_T]] = ...
-#    ) -> None: ...
-
-def index_type(
-    base_type: _T, item: Union[tuple, slice, int]) -> _ArrayType[_T]: ...
-
-def pointer(basetype: _T) -> Type[PointerType[_T]]: ...
-
-def array(basetype: _T, n: int) -> Type[ArrayType[_T]]: ...
-
-#def struct(basetype: _T) -> Type[StructType[_T]]: ...
-
-class typedef(CythonType, Generic[_T]):
-    name: str
-
-    def __init__(self, type: _T, name: Optional[str] = ...) -> None: ...
-    def __call__(self, *arg: Any) -> _T: ...
-    def __repr__(self) -> str: ...
-    __getitem__ = index_type
-
-#class _FusedType(CythonType, Generic[_T]):
-#    def __init__(self) -> None: ...
-
-#def fused_type(*args: Tuple[_T]) -> Type[FusedType[_T]]: ...
index 3c0e491..eaf93c0 100644 (file)
@@ -128,6 +128,9 @@ static PyObject* __Pyx_PyExec3(PyObject* o, PyObject* globals, PyObject* locals)
     } else {
         PyCompilerFlags cf;
         cf.cf_flags = 0;
+#if PY_VERSION_HEX >= 0x030800A3
+        cf.cf_feature_version = PY_MINOR_VERSION;
+#endif
         if (PyUnicode_Check(o)) {
             cf.cf_flags = PyCF_SOURCE_IS_UTF8;
             s = PyUnicode_AsUTF8String(o);
index a65c8ee..33d0a47 100644 (file)
@@ -548,6 +548,7 @@ static int __Pyx_CyFunction_traverse(__pyx_CyFunctionObject *m, visitproc visit,
 
 static PyObject *__Pyx_CyFunction_descr_get(PyObject *func, PyObject *obj, PyObject *type)
 {
+#if PY_MAJOR_VERSION < 3
     __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func;
 
     if (m->flags & __Pyx_CYFUNCTION_STATICMETHOD) {
@@ -563,6 +564,7 @@ static PyObject *__Pyx_CyFunction_descr_get(PyObject *func, PyObject *obj, PyObj
 
     if (obj == Py_None)
         obj = NULL;
+#endif
     return __Pyx_PyMethod_New(func, obj, type);
 }
 
index 85b262b..1b39c9e 100644 (file)
@@ -278,56 +278,3 @@ __PYX_GOOD:
     Py_XDECREF(setstate_cython);
     return ret;
 }
-
-/////////////// BinopSlot ///////////////
-
-static CYTHON_INLINE PyObject *{{func_name}}_maybe_call_slot(PyTypeObject* type, PyObject *left, PyObject *right {{extra_arg_decl}}) {
-    {{slot_type}} slot;
-#if CYTHON_USE_TYPE_SLOTS
-    slot = type->tp_as_number ? type->tp_as_number->{{slot_name}} : NULL;
-#else
-    slot = ({{slot_type}}) PyType_GetSlot(type, Py_{{slot_name}});
-#endif
-    return slot ? slot(left, right {{extra_arg}}) : __Pyx_NewRef(Py_NotImplemented);
-}
-
-static PyObject *{{func_name}}(PyObject *left, PyObject *right {{extra_arg_decl}}) {
-    PyObject *res;
-    int maybe_self_is_left, maybe_self_is_right = 0;
-    maybe_self_is_left = Py_TYPE(left) == Py_TYPE(right)
-#if CYTHON_USE_TYPE_SLOTS
-            || (Py_TYPE(left)->tp_as_number && Py_TYPE(left)->tp_as_number->{{slot_name}} == &{{func_name}})
-#endif
-            || __Pyx_TypeCheck(left, {{type_cname}});
-    // Optimize for the common case where the left operation is defined (and successful).
-    if (!{{overloads_left}}) {
-        maybe_self_is_right = Py_TYPE(left) == Py_TYPE(right)
-#if CYTHON_USE_TYPE_SLOTS
-                || (Py_TYPE(right)->tp_as_number && Py_TYPE(right)->tp_as_number->{{slot_name}} == &{{func_name}})
-#endif
-                || __Pyx_TypeCheck(right, {{type_cname}});
-    }
-    if (maybe_self_is_left) {
-        if (maybe_self_is_right && !{{overloads_left}}) {
-            res = {{call_right}};
-            if (res != Py_NotImplemented) return res;
-            Py_DECREF(res);
-            // Don't bother calling it again.
-            maybe_self_is_right = 0;
-        }
-        res = {{call_left}};
-        if (res != Py_NotImplemented) return res;
-        Py_DECREF(res);
-    }
-    if ({{overloads_left}}) {
-        maybe_self_is_right = Py_TYPE(left) == Py_TYPE(right)
-#if CYTHON_USE_TYPE_SLOTS
-                || (Py_TYPE(right)->tp_as_number && Py_TYPE(right)->tp_as_number->{{slot_name}} == &{{func_name}})
-#endif
-                || PyType_IsSubtype(Py_TYPE(right), {{type_cname}});
-    }
-    if (maybe_self_is_right) {
-        return {{call_right}};
-    }
-    return __Pyx_NewRef(Py_NotImplemented);
-}
index 676bc4c..e3c0caf 100644 (file)
@@ -152,11 +152,12 @@ __Pyx_import_all_from(PyObject *locals, PyObject *v)
         }
         if (skip_leading_underscores &&
 #if PY_MAJOR_VERSION < 3
-            PyString_Check(name) &&
+            likely(PyString_Check(name)) &&
             PyString_AS_STRING(name)[0] == '_')
 #else
-            PyUnicode_Check(name) &&
-            PyUnicode_AS_UNICODE(name)[0] == '_')
+            likely(PyUnicode_Check(name)) &&
+            likely(__Pyx_PyUnicode_GET_LENGTH(name)) &&
+            __Pyx_PyUnicode_READ_CHAR(name, 0) == '_')
 #endif
         {
             Py_DECREF(name);
index 9f4828d..0a5d8ee 100644 (file)
@@ -347,18 +347,22 @@ static int __Pyx_ValidateAndInit_memviewslice(
     }
 
     /* Check axes */
-    for (i = 0; i < ndim; i++) {
-        spec = axes_specs[i];
-        if (unlikely(!__pyx_check_strides(buf, i, ndim, spec)))
-            goto fail;
-        if (unlikely(!__pyx_check_suboffsets(buf, i, ndim, spec)))
+    if (buf->len > 0) {
+        // 0-sized arrays do not undergo these checks since their strides are
+        // irrelevant and they are always both C- and F-contiguous.
+        for (i = 0; i < ndim; i++) {
+            spec = axes_specs[i];
+            if (unlikely(!__pyx_check_strides(buf, i, ndim, spec)))
+                goto fail;
+            if (unlikely(!__pyx_check_suboffsets(buf, i, ndim, spec)))
+                goto fail;
+        }
+
+        /* Check contiguity */
+        if (unlikely(buf->strides && !__pyx_verify_contig(buf, ndim, c_or_f_flag)))
             goto fail;
     }
 
-    /* Check contiguity */
-    if (unlikely(buf->strides && !__pyx_verify_contig(buf, ndim, c_or_f_flag)))
-        goto fail;
-
     /* Initialize */
     if (unlikely(__Pyx_init_memviewslice(memview, ndim, memviewslice,
                                          new_memview != NULL) == -1)) {
index 1c3e63d..aa3f368 100644 (file)
@@ -532,7 +532,11 @@ static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) {
   #define __Pyx_PyUnicode_DATA(u)         PyUnicode_DATA(u)
   #define __Pyx_PyUnicode_READ(k, d, i)   PyUnicode_READ(k, d, i)
   #define __Pyx_PyUnicode_WRITE(k, d, i, ch)  PyUnicode_WRITE(k, d, i, ch)
+  #if defined(PyUnicode_IS_READY) && defined(PyUnicode_GET_SIZE)
   #define __Pyx_PyUnicode_IS_TRUE(u)      (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : PyUnicode_GET_SIZE(u)))
+  #else
+  #define __Pyx_PyUnicode_IS_TRUE(u)      (0 != PyUnicode_GET_LENGTH(u))
+  #endif
 #else
   #define CYTHON_PEP393_ENABLED 0
   #define PyUnicode_1BYTE_KIND  1
@@ -663,7 +667,7 @@ static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) {
 #endif
 
 #if PY_MAJOR_VERSION >= 3
-  #define __Pyx_PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : (Py_INCREF(func), func))
+  #define __Pyx_PyMethod_New(func, self, klass) ((self) ? ((void)(klass), PyMethod_New(func, self)) : __Pyx_NewRef(func))
 #else
   #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass)
 #endif
index 68315d9..7a34262 100644 (file)
@@ -66,6 +66,8 @@ static CYTHON_INLINE int __Pyx_UnicodeContainsUCS4(PyObject* unicode, Py_UCS4 ch
 
 //////////////////// PyUCS4InUnicode ////////////////////
 
+#if PY_VERSION_HEX < 0x03090000
+#if Py_UNICODE_SIZE == 2
 static int __Pyx_PyUnicodeBufferContainsUCS4_SP(Py_UNICODE* buffer, Py_ssize_t length, Py_UCS4 character) {
     /* handle surrogate pairs for Py_UNICODE buffers in 16bit Unicode builds */
     Py_UNICODE high_val, low_val;
@@ -77,6 +79,7 @@ static int __Pyx_PyUnicodeBufferContainsUCS4_SP(Py_UNICODE* buffer, Py_ssize_t l
     }
     return 0;
 }
+#endif
 
 static int __Pyx_PyUnicodeBufferContainsUCS4_BMP(Py_UNICODE* buffer, Py_ssize_t length, Py_UCS4 character) {
     Py_UNICODE uchar;
@@ -87,6 +90,7 @@ static int __Pyx_PyUnicodeBufferContainsUCS4_BMP(Py_UNICODE* buffer, Py_ssize_t
     }
     return 0;
 }
+#endif
 
 static CYTHON_INLINE int __Pyx_UnicodeContainsUCS4(PyObject* unicode, Py_UCS4 character) {
 #if CYTHON_PEP393_ENABLED
@@ -100,19 +104,26 @@ static CYTHON_INLINE int __Pyx_UnicodeContainsUCS4(PyObject* unicode, Py_UCS4 ch
         }
         return 0;
     }
+#elif PY_VERSION_HEX >= 0x03090000
+    #error Cannot use "UChar in Unicode" in Python 3.9 without PEP-393 unicode strings.
 #endif
-    if (Py_UNICODE_SIZE == 2 && unlikely(character > 65535)) {
+#if PY_VERSION_HEX < 0x03090000
+#if Py_UNICODE_SIZE == 2
+    if (unlikely(character > 65535)) {
         return __Pyx_PyUnicodeBufferContainsUCS4_SP(
             PyUnicode_AS_UNICODE(unicode),
             PyUnicode_GET_SIZE(unicode),
             character);
-    } else {
+    } else
+#endif
+    {
         return __Pyx_PyUnicodeBufferContainsUCS4_BMP(
             PyUnicode_AS_UNICODE(unicode),
             PyUnicode_GET_SIZE(unicode),
             character);
 
     }
+#endif
 }
 
 
@@ -443,6 +454,7 @@ static CYTHON_INLINE PyObject* __Pyx_decode_c_string(
 /////////////// decode_c_string ///////////////
 //@requires: IncludeStringH
 //@requires: decode_c_string_utf16
+//@substitute: naming
 
 /* duplicate code to avoid calling strlen() if start >= 0 and stop >= 0 */
 static CYTHON_INLINE PyObject* __Pyx_decode_c_string(
@@ -467,7 +479,7 @@ static CYTHON_INLINE PyObject* __Pyx_decode_c_string(
             stop += length;
     }
     if (unlikely(stop <= start))
-        return PyUnicode_FromUnicode(NULL, 0);
+        return __Pyx_NewRef($empty_unicode);
     length = stop - start;
     cstring += start;
     if (decode_func) {
@@ -486,6 +498,7 @@ static CYTHON_INLINE PyObject* __Pyx_decode_c_bytes(
 
 /////////////// decode_c_bytes ///////////////
 //@requires: decode_c_string_utf16
+//@substitute: naming
 
 static CYTHON_INLINE PyObject* __Pyx_decode_c_bytes(
          const char* cstring, Py_ssize_t length, Py_ssize_t start, Py_ssize_t stop,
@@ -503,7 +516,7 @@ static CYTHON_INLINE PyObject* __Pyx_decode_c_bytes(
     if (stop > length)
         stop = length;
     if (unlikely(stop <= start))
-        return PyUnicode_FromUnicode(NULL, 0);
+        return __Pyx_NewRef($empty_unicode);
     length = stop - start;
     cstring += start;
     if (decode_func) {
@@ -543,6 +556,7 @@ static CYTHON_INLINE PyObject* __Pyx_PyUnicode_Substring(
             PyObject* text, Py_ssize_t start, Py_ssize_t stop);
 
 /////////////// PyUnicode_Substring ///////////////
+//@substitute: naming
 
 static CYTHON_INLINE PyObject* __Pyx_PyUnicode_Substring(
             PyObject* text, Py_ssize_t start, Py_ssize_t stop) {
@@ -559,7 +573,7 @@ static CYTHON_INLINE PyObject* __Pyx_PyUnicode_Substring(
     else if (stop > length)
         stop = length;
     if (stop <= start)
-        return PyUnicode_FromUnicode(NULL, 0);
+        return __Pyx_NewRef($empty_unicode);
 #if CYTHON_PEP393_ENABLED
     return PyUnicode_FromKindAndData(PyUnicode_KIND(text),
         PyUnicode_1BYTE_DATA(text) + start*PyUnicode_KIND(text), stop-start);
diff --git a/Demos/README.rst b/Demos/README.rst
deleted file mode 100644 (file)
index 959b71f..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-To run demos do::
-
-    cd Demos
-    make test
-
-which runs ``run_primes.py``, ``run_numeric_demo.py``, ``run_spam.py``,
-``integrate_timing.py``, ``callback/runcheese.py`` and ``embed/embedded``
-
-For other demos::
-
-    cd libraries
-    python setup.py build_ext --inplace
-    python -c 'import call_mymath;print(call_mymath.call_sinc(1))'
-
-To run one of the benchmarks for 10 iterations to compare cython and python timings::
-
-    cd benchmarks
-    python setup.py build_ext --inplace
-    python nqueens.py -n 10
-    python -c 'import nqueens;print(nqueens.test_n_queens(10))'
-
-To demo ``cython/bin/cython_freeze``::
-
-    make
-    ./nCr 10 5
-    ./python
-
-* Build notes
-
-  * benchmarks/chaos.py requires cython 0.24 or newer
-
-  * embed and freeze work for python2, require cython 0.24 or higher
-    for python 3.5
-
-
diff --git a/Doc/s5/Makefile b/Doc/s5/Makefile
deleted file mode 100644 (file)
index 6623db6..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-
-SLIDES=$(subst .txt,.html,$(wildcard *.txt))
-SOURCES=$(subst .py,.c,$(subst .pyx,.c,$(wildcard */*.py */*.pyx)))
-
-slides: $(SLIDES) $(SOURCES)
-
-%.html: %.txt
-       rst2s5 --current-slide --language=en $< $@
-
-%.c: %.py
-       cython --annotate $<
-
-%.c: %.pyx
-       cython --annotate $<
-
-clean:
-       rm -f *~ $(SLIDES) $(SOURCES) $(subst .c,.html,$(SOURCES))
diff --git a/Doc/s5/cython-ep2008.txt b/Doc/s5/cython-ep2008.txt
deleted file mode 100644 (file)
index a29ca35..0000000
+++ /dev/null
@@ -1,401 +0,0 @@
-==============================================
-The Cython Compiler for C-Extensions in Python
-==============================================
-
-Dr. Stefan Behnel
------------------
-
-.. class:: center
-
-  http://www.cython.org/
-
-  cython-dev@codespeak.net
-
-.. footer:: Dr. Stefan Behnel, EuroPython 2008, Vilnius/Lietuva
-
-.. include:: <s5defs.txt>
-
-
-About myself
-============
-
-* Passionate Python developer since 2002
-
-  * after Basic, Logo, Pascal, Prolog, Scheme, Java, ...
-
-* CS studies in Germany, Ireland, France
-
-* PhD in distributed systems in 2007
-
-  * Language design for self-organising systems
-
-  * Darmstadt University of Technologies, Germany
-
-* Current occupations:
-
-  * Employed by Senacor Technologies AG, Germany
-
-    * IT transformations, SOA design, Java-Development, ...
-
-  * »lxml« OpenSource XML toolkit for Python
-
-    * http://codespeak.net/lxml/
-
-  * Cython
-
-
-What is Cython?
-===============
-
-Cython is
-
-* an Open-Source project
-
-  * http://cython.org
-
-* a Python compiler (almost)
-
-  * an enhanced, optimising fork of Pyrex
-
-* an extended Python language for
-
-  * writing fast Python extension modules
-
-  * interfacing Python with C libraries
-
-
-A little bit of history
-=======================
-
-* April 2002: release of Pyrex 0.1 by Greg Ewing
-
-  * Greg considers Pyrex a language in design phase
-
-  * Pyrex became a key language for many projects
-
-    * over the years, many people patched their Pyrex
-
-    * not all patches were answered by Greg (not in time)
-
-* minor forks and enhanced branches followed
-
-  * March 2006: my fork of Pyrex for »lxml« XML toolkit
-
-  * November 2006: »SageX« fork of Pyrex
-
-    * by Robert Bradshaw, William Stein (Univ. Seattle, USA)
-
-    * context: »Sage«, a free mathematics software package
-
-* 28th July 2007: official Cython launch
-
-  * integration of lxml's Pyrex fork into SageX
-
-  * the rest is in http://hg.cython.org/cython-devel/
-
-
-Major Cython Developers
-=======================
-
-* Robert Bradshaw and Stefan Behnel
-
-  * lead developers
-
-* Greg Ewing
-
-  * main developer and maintainer of Pyrex
-
-  * we happily share code and discuss ideas
-
-* Dag Sverre Seljebotn
-
-  * Google Summer-of-Code developer
-
-  * NumPy integration, many ideas and enhancements
-
-* many, *many* others - see
-
-  * http://cython.org/
-
-  * the mailing list archives of Cython and Pyrex
-
-
-How to use Cython
-=================
-
-* you write Python code
-
-  * Cython translates it into C code
-
-  * your C compiler builds a shared library for CPython
-
-  * you import your module
-
-* Cython has support for
-
-  * compile-time includes/imports
-
-    * with dependency tracking
-
-  * distutils
-
-    * *optionally* compile Python code from setup.py!
-
-
-Example: compiling Python code
-==============================
-
-.. sourcecode:: bash
-
-    $ cat worker.py
-
-.. sourcecode:: python
-
-    class HardWorker(object):
-        u"Almost Sisyphus"
-        def __init__(self, task):
-            self.task = task
-
-        def work_hard(self):
-            for i in range(100):
-               self.task()
-
-.. sourcecode:: bash
-
-    $ cython worker.py
-
-* translates to 842 line `.c file <ep2008/worker.c>`_ (Cython 0.9.8)
-
-  * lots of portability #define's
-
-  * tons of helpful C comments with Python code snippets
-
-  * a lot of code that you don't want to write yourself
-
-
-Portable Code
-=============
-
-* Cython compiler generates C code that compiles
-
-  * with all major compilers (C and C++)
-
-  * on all major platforms
-
-  * in Python 2.3 to 3.0 beta1
-
-* Cython language syntax follows Python 2.6
-
-  * optional Python 3 syntax support is on TODO list
-
-    * get involved to get it quicker!
-
-\... the fastest way to port Python 2 code to Py3 ;-)
-
-
-Python 2 feature support
-========================
-
-* most of Python 2 syntax is supported
-
-  * top-level classes and functions
-
-  * exceptions
-
-  * object operations, arithmetic, ...
-
-* plus some Py3/2.6 features:
-
-  * keyword-only arguments
-
-  * unicode literals via ``__future__`` import
-
-* in recent developer branch:
-
-  * ``with`` statement
-
-  * closures (i.e. local classes and functions) are close!
-
-
-Speed
-=====
-
-Cython generates very efficient C code
-
-* according to PyBench:
-
-  * conditions and loops run 2-8x faster than in Py2.5
-
-  * most benchmarks run 30%-80% faster
-
-  * overall more than 30% faster for plain Python code
-
-* optional type declarations
-
-  * let Cython generate plain C instead of C-API calls
-
-  * make code several times faster than the above
-
-
-Type declarations
-=================
-
-* »cdef« keyword declares
-
-  * local variables with C types
-
-  * functions with C signatures
-
-  * classes as builtin extension types
-
-* Example::
-
-    def stupid_lower_case(char* s):
-        cdef Py_ssize_t size, i
-
-       size = len(s)
-        for i in range(size):
-            if s[i] >= 'A' and s[i] <= 'Z':
-                s[i] += 'a' - 'A'
-        return s
-
-
-Why is this stupid?
-===================
-
-Ask Cython!
-
-.. sourcecode:: bash
-
-    $ cat stupidlowercase.py
-
-::
-
-    def stupid_lower_case(char* s):
-        cdef Py_ssize_t size, i
-
-       size = len(s)
-        for i in range(size):
-            if s[i] >= 'A' and s[i] <= 'Z':
-                s[i] += 'a' - 'A'
-        return s
-
-.. sourcecode:: bash
-
-    $ cython --annotate stupidlowercase.py
-
-=> `stupidlowercase.html <ep2008/stupidlowercase.html>`_
-
-
-Calling C functions
-===================
-
-* Example::
-
-    cdef extern from "Python.h":
-        # copied from the Python C-API docs:
-        object PyUnicode_DecodeASCII(
-            char* s, Py_ssize_t size, char* errors)
-
-    cdef extern from "string.h":
-        int strlen(char *s)
-
-
-    cdef slightly_better_lower_case(char* s):
-        cdef Py_ssize_t i, size = strlen(s)
-        for i in range(size):
-            if s[i] >= 'A' and s[i] <= 'Z':
-                s[i] += 'a' - 'A'
-       return PyUnicode_DecodeASCII(s, size, NULL)
-
-
-Features in work
-================
-
-* Dynamic classes and functions with closures
-
-  .. sourcecode:: python
-
-    def factory(a,b):
-        def closure_function(c):
-            return a+b+c
-        return closure_function
-
-* Native support for new ``buffer`` protocol
-
-  * part of NumPy integration by Dag Seljebotn
-
-  .. sourcecode:: python
-
-    def inplace_negative_grayscale_image(
-                      ndarray[unsigned char, 2] image):
-        cdef int i, j
-        for i in range(image.shape[0]):
-            for j in range(image.shape[1]):
-                arr[i, j] = 255 - arr[i, j]
-
-
-Huge pile of great ideas
-========================
-
-* Cython Enhancement Proposals (CEPs)
-
-  * http://wiki.cython.org/enhancements
-
-* native pickle support for extension classes
-
-* meta-programming facilities
-
-* type inference strategies
-
-* compile-time assertions for optimisations
-
-* object-like C-array handling
-
-* improved C++ integration
-
-* ...
-
-
-Conclusion
-==========
-
-* Cython is a tool for
-
-  * efficiently translating Python code to C
-
-  * easily interfacing to external C libraries
-
-* Use it to
-
-  * speed up existing Python modules
-
-    * concentrate on optimisations, not rewrites!
-
-  * write C extensions for CPython
-
-    * don't change the language just to get fast code!
-
-  * wrap C libraries *in Python*
-
-    * concentrate on the mapping, not the glue!
-
-
-... but Cython is also
-======================
-
-* a great project
-
-* a very open playground for great ideas!
-
-
-Cython
-======
-
-  **Cython**
-
-  **C-Extensions in Python**
-
-  \... use it, and join the project!
-
-  http://cython.org/
diff --git a/Doc/s5/ep2008/stupidlowercase.py b/Doc/s5/ep2008/stupidlowercase.py
deleted file mode 100644 (file)
index 8f2812d..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-
-def stupid_lower_case(char* s):
-    cdef Py_ssize_t size, i
-
-    size = len(s)
-    for i in range(size):
-        if s[i] >= 'A' and s[i] <= 'Z':
-            s[i] += 'a' - 'A'
-    return s
diff --git a/Doc/s5/ep2008/worker.py b/Doc/s5/ep2008/worker.py
deleted file mode 100644 (file)
index 2b26028..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-
-class HardWorker(object):
-    u"Almost Sisyphus"
-    def __init__(self, task):
-        self.task = task
-
-    def work_hard(self):
-        for i in range(100):
-            self.task()
diff --git a/Doc/s5/ui/default/blank.gif b/Doc/s5/ui/default/blank.gif
deleted file mode 100644 (file)
index 75b945d..0000000
Binary files a/Doc/s5/ui/default/blank.gif and /dev/null differ
diff --git a/Doc/s5/ui/default/bodybg.gif b/Doc/s5/ui/default/bodybg.gif
deleted file mode 100644 (file)
index 5f448a1..0000000
Binary files a/Doc/s5/ui/default/bodybg.gif and /dev/null differ
diff --git a/Doc/s5/ui/default/cython-logo64.png b/Doc/s5/ui/default/cython-logo64.png
deleted file mode 100644 (file)
index 7ff4f6e..0000000
Binary files a/Doc/s5/ui/default/cython-logo64.png and /dev/null differ
diff --git a/Doc/s5/ui/default/framing.css b/Doc/s5/ui/default/framing.css
deleted file mode 100644 (file)
index 2a5901a..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/* The following styles size, place, and layer the slide components.
-   Edit these if you want to change the overall slide layout.
-   The commented lines can be uncommented (and modified, if necessary)
-    to help you with the rearrangement process. */
-
-/* target = 1024x768 */
-
-div#header, div#footer, .slide {width: 100%; top: 0; left: 0;}
-div#header {top: 0; height: 3em; z-index: 1;}
-div#footer {top: auto; bottom: 0; height: 2.5em; z-index: 5;}
-.slide {top: 0; width: 92%; padding: 3.5em 4% 4%; z-index: 2;  list-style: none;}
-div#controls {left: 50%; bottom: 0; width: 50%; z-index: 100;}
-div#controls form {position: absolute; bottom: 0; right: 0; width: 100%;
-  margin: 0;}
-#currentSlide {position: absolute; width: 10%; left: 45%; bottom: 1em; z-index: 10;}
-html>body #currentSlide {position: fixed;}
-
-/*
-div#header {background: #FCC;}
-div#footer {background: #CCF;}
-div#controls {background: #BBD;}
-div#currentSlide {background: #FFC;}
-*/
diff --git a/Doc/s5/ui/default/iepngfix.htc b/Doc/s5/ui/default/iepngfix.htc
deleted file mode 100644 (file)
index 4d90c87..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-<public:component>\r
-<public:attach event="onpropertychange" onevent="doFix()" />\r
-\r
-<script>\r
-\r
-// IE5.5+ PNG Alpha Fix v1.0 by Angus Turnbull http://www.twinhelix.com\r
-// Free usage permitted as long as this notice remains intact.\r
-\r
-// This must be a path to a blank image. That's all the configuration you need here.\r
-var blankImg = 'v11rc1/default/blank.gif';\r
-\r
-var f = 'DXImageTransform.Microsoft.AlphaImageLoader';\r
-\r
-function filt(s, m) {\r
- if (filters[f]) {\r
-  filters[f].enabled = s ? true : false;\r
-  if (s) with (filters[f]) { src = s; sizingMethod = m }\r
- } else if (s) style.filter = 'progid:'+f+'(src="'+s+'",sizingMethod="'+m+'")';\r
-}\r
-\r
-function doFix() {\r
- if ((parseFloat(navigator.userAgent.match(/MSIE (\S+)/)[1]) < 5.5) ||\r
-  (event && !/(background|src)/.test(event.propertyName))) return;\r
-\r
- if (tagName == 'IMG') {\r
-  if ((/\.png$/i).test(src)) {\r
-   filt(src, 'image');  // was 'scale'\r
-   src = blankImg;\r
-  } else if (src.indexOf(blankImg) < 0) filt();\r
- } else if (style.backgroundImage) {\r
-  if (style.backgroundImage.match(/^url[("']+(.*\.png)[)"']+$/i)) {\r
-   var s = RegExp.$1;\r
-   style.backgroundImage = '';\r
-   filt(s, 'crop');\r
-  } else filt();\r
- }\r
-}\r
-\r
-doFix();\r
-\r
-</script>\r
-</public:component>
\ No newline at end of file
diff --git a/Doc/s5/ui/default/opera.css b/Doc/s5/ui/default/opera.css
deleted file mode 100644 (file)
index 9e9d2a3..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-/* DO NOT CHANGE THESE unless you really want to break Opera Show */
-.slide {
-       visibility: visible !important;
-       position: static !important;
-       page-break-before: always;
-}
-#slide0 {page-break-before: avoid;}
diff --git a/Doc/s5/ui/default/outline.css b/Doc/s5/ui/default/outline.css
deleted file mode 100644 (file)
index 62db519..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/* don't change this unless you want the layout stuff to show up in the outline view! */
-
-.layout div, #footer *, #controlForm * {display: none;}
-#footer, #controls, #controlForm, #navLinks, #toggle {
-  display: block; visibility: visible; margin: 0; padding: 0;}
-#toggle {float: right; padding: 0.5em;}
-html>body #toggle {position: fixed; top: 0; right: 0;}
-
-/* making the outline look pretty-ish */
-
-#slide0 h1, #slide0 h2, #slide0 h3, #slide0 h4 {border: none; margin: 0;}
-#slide0 h1 {padding-top: 1.5em;}
-.slide h1 {margin: 1.5em 0 0; padding-top: 0.25em;
-  border-top: 1px solid #888; border-bottom: 1px solid #AAA;}
-#toggle {border: 1px solid; border-width: 0 0 1px 1px; background: #FFF;}
diff --git a/Doc/s5/ui/default/pretty.css b/Doc/s5/ui/default/pretty.css
deleted file mode 100644 (file)
index b0e58c6..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-/* Following are the presentation styles -- edit away! */
-
-/* body {background: #FFF url(cython.png) 1em 1em no-repeat; color: #000; font-size: 2em;} */
-:link, :visited {text-decoration: none; color: #545454;}
-#controls :active {color: #545454 !important;}
-#controls :focus {outline: 1px dotted #545454;}
-h1, h2, h3, h4 {font-size: 100%; margin: 0; padding: 0; font-weight: inherit;}
-ul, pre {margin: 0; line-height: 1em;}
-html, body {margin: 0; padding: 0;}
-
-blockquote, q {font-style: italic;}
-blockquote {padding: 0 2em 0.5em; margin: 0 1.5em 0.5em; text-align: center; font-size: 1em;}
-blockquote p {margin: 2em;}
-blockquote p strong {font-size: 1.5em;}
-blockquote i {font-style: normal;}
-blockquote b {display: block; margin-top: 0.5em; font-weight: normal; font-size: smaller; font-style: normal;}
-blockquote b i {font-style: italic;}
-
-kbd {font-weight: bold; font-size: 1em;}
-sup {font-size: smaller; line-height: 1px;}
-
-.slide {padding-top: 3em; }
-
-.slide code {padding: 2px 0.25em; font-weight: bold; color: #533;}
-.slide code.bad, code del {color: red;}
-.slide code.old {color: silver;}
-.slide .pre {padding: 0; margin: 0 0 0 0; color: #533; font-size: 80%;}
-.slide pre {padding: 0; margin: 0.25em 0 0.5em 0.5em; color: #533; font-size: 90%;}
-/* .slide pre {padding: 0; margin: 0 0 0 0; color: #533; font-size: 90%;} */
-.slide pre code {display: block;}
-.slide div > ul {padding-left: 0; margin-left: 0; list-style: disc; }
-.slide li {margin-top: 0.75em; margin-right: 0;}
-.slide ul ul {line-height: 1; padding-left: 1em; margin-left: 2%; margin-right: 5%; list-style: disc; }
-.slide ul ul li {margin: .4em; font-size: 85%; list-style: square;}
-.slide img.leader {display: block; margin: 0 auto;}
-
-div#header, div#footer {background: #f0f0f0; color: #545454;
-  font-family: Verdana, Helvetica, sans-serif; padding: 0;}
-div#header {background: #f0f0f0 url(cython-logo64.png) 1ex 0.2ex no-repeat;
-  line-height: 1px; border-bottom: solid #545454 4px; height: 2.4em;}
-div#footer {font-size: 0.5em; font-weight: bold; padding: 0.6em 0;
-            border-top: solid #545454 3px;}
-#footer h1, #footer h2 {display: block; padding: 0 1.5ex;}
-#footer h2 {font-style: italic;}
-#footer a {color: #545454;}
-
-div.long {font-size: 0.75em;}
-.slide h1 {position: absolute; top: 0.2em; left: 87px; z-index: 1;
-  margin: 0; padding: 0.3ex 0 0 25px; white-space: nowrap;
-  font: bold 150%/1em Helvetica, sans-serif; /* text-transform: capitalize; */
-  color: #646464; background: #f0f0f0;}
-.slide h3 {font-size: 130%;}
-h1 abbr {font-variant: small-caps;}
-
-div#controls {position: absolute; left: 50%; bottom: 0;
-  width: 50%;
-  text-align: right; font: bold 0.7em Verdana, Helvetica, sans-serif;}
-html>body div#controls {position: fixed; padding: 0 0 1em 0;
-  top: auto;}
-div#controls form {position: absolute; bottom: 0; right: 0; width: 100%;
-  margin: 0; padding: 0;}
-#controls #navLinks a {padding: 0; margin: 0 0.5em;
-  background: #f0f0f0; border: none; color: #545454;
-  cursor: pointer;}
-#controls #navList {height: 1em;}
-#controls #navList #jumplist {position: absolute; bottom: 0; right: 0; background: #f0f0f0; color: black;}
-
-#currentSlide {text-align: center; font-size: 0.5em; color: #545454; left: 90%; bottom: 2px;}
-
-#slide0 {padding-top: 3em; font-size: 90%;}
-#slide0 h1 {position: static; margin: 1em 0 0; padding: 0;
-   font: bold 2em Helvetica, sans-serif; white-space: normal;
-   color: #000; background: transparent;}
-#slide0 h2 {font: bold italic 1em Helvetica, sans-serif; margin: 1.25em;}
-#slide0 h3 {margin-top: 1.5em; font-size: 1.5em;}
-#slide0 h4 {margin-top: 0; font-size: 1em;}
-
-ul.urls {list-style: none; display: inline; margin: 0;}
-.urls li {display: inline; margin: 0;}
-.note {display: none;}
-.external {border-bottom: 1px dotted gray;}
-html>body .external {border-bottom: none;}
-/* .external:after {content: " \274F"; font-size: smaller; color: #7B7;} */
-
-/* .incremental, .incremental *, .incremental *:after {color: #545454; visibility: visible;} */
-.incremental, .incremental *, .incremental *:after {visibility: hidden;}
-img.incremental {visibility: hidden;}
-.slide .current {color: #B02;}
-
-.center {text-align: center; }
-.right {text-align: right; }
-.small {font-size: 60%; }
-img.center {display: block; margin-left: auto; margin-right: auto; }
-
-.slide .syntax {padding: 2px 0.25em; font-weight: bold; color: #533; font-size:85%; }
-
-/* diagnostics
-
-li:after {content: " [" attr(class) "]"; color: #F88;}
- */
-
-/* Syntax highlighting */
-
-/* .syntax  { background: #f0f0f0; } */
-.syntax .c { color: #60a0b0; font-style: italic } /* Comment */
-.syntax .err { border: 1px solid #FF0000 } /* Error */
-.syntax .k { color: #007020; font-weight: bold } /* Keyword */
-.syntax .o { color: #666666 } /* Operator */
-.syntax .cm { color: #60a0b0; font-style: italic } /* Comment.Multiline */
-.syntax .cp { color: #007020 } /* Comment.Preproc */
-.syntax .c1 { color: #60a0b0; font-style: italic } /* Comment.Single */
-.syntax .cs { color: #60a0b0; background-color: #fff0f0 } /* Comment.Special */
-.syntax .gd { color: #A00000 } /* Generic.Deleted */
-.syntax .ge { font-style: italic } /* Generic.Emph */
-.syntax .gr { color: #FF0000 } /* Generic.Error */
-.syntax .gh { color: #000080; font-weight: bold } /* Generic.Heading */
-.syntax .gi { color: #00A000 } /* Generic.Inserted */
-.syntax .go { color: #404040 } /* Generic.Output */
-.syntax .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
-.syntax .gs { font-weight: bold } /* Generic.Strong */
-.syntax .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
-.syntax .gt { color: #0040D0 } /* Generic.Traceback */
-.syntax .kc { color: #007020; font-weight: bold } /* Keyword.Constant */
-.syntax .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
-.syntax .kp { color: #007020 } /* Keyword.Pseudo */
-.syntax .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
-.syntax .kt { color: #902000 } /* Keyword.Type */
-.syntax .m { color: #40a070 } /* Literal.Number */
-.syntax .s { color: #4070a0 } /* Literal.String */
-.syntax .na { color: #4070a0 } /* Name.Attribute */
-.syntax .nb { color: #007020 } /* Name.Builtin */
-.syntax .nc { color: #0e84b5; font-weight: bold } /* Name.Class */
-.syntax .no { color: #60add5 } /* Name.Constant */
-.syntax .nd { color: #555555; font-weight: bold } /* Name.Decorator */
-.syntax .ni { color: #d55537; font-weight: bold } /* Name.Entity */
-.syntax .ne { color: #007020 } /* Name.Exception */
-.syntax .nf { color: #06287e } /* Name.Function */
-.syntax .nl { color: #002070; font-weight: bold } /* Name.Label */
-.syntax .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
-.syntax .nt { color: #062873; font-weight: bold } /* Name.Tag */
-.syntax .nv { color: #bb60d5 } /* Name.Variable */
-.syntax .ow { color: #007020; font-weight: bold } /* Operator.Word */
-.syntax .w { color: #bbbbbb } /* Text.Whitespace */
-.syntax .mf { color: #40a070 } /* Literal.Number.Float */
-.syntax .mh { color: #40a070 } /* Literal.Number.Hex */
-.syntax .mi { color: #40a070 } /* Literal.Number.Integer */
-.syntax .mo { color: #40a070 } /* Literal.Number.Oct */
-.syntax .sb { color: #4070a0 } /* Literal.String.Backtick */
-.syntax .sc { color: #4070a0 } /* Literal.String.Char */
-.syntax .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
-.syntax .s2 { color: #4070a0 } /* Literal.String.Double */
-.syntax .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
-.syntax .sh { color: #4070a0 } /* Literal.String.Heredoc */
-.syntax .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
-.syntax .sx { color: #c65d09 } /* Literal.String.Other */
-.syntax .sr { color: #235388 } /* Literal.String.Regex */
-.syntax .s1 { color: #4070a0 } /* Literal.String.Single */
-.syntax .ss { color: #517918 } /* Literal.String.Symbol */
-.syntax .bp { color: #007020 } /* Name.Builtin.Pseudo */
-.syntax .vc { color: #bb60d5 } /* Name.Variable.Class */
-.syntax .vg { color: #bb60d5 } /* Name.Variable.Global */
-.syntax .vi { color: #bb60d5 } /* Name.Variable.Instance */
-.syntax .il { color: #40a070 } /* Literal.Number.Integer.Long */
diff --git a/Doc/s5/ui/default/print.css b/Doc/s5/ui/default/print.css
deleted file mode 100644 (file)
index 4a3554d..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/* The following rule is necessary to have all slides appear in print! DO NOT REMOVE IT! */
-.slide, ul {page-break-inside: avoid; visibility: visible !important;}
-h1 {page-break-after: avoid;}
-
-body {font-size: 12pt; background: white;}
-* {color: black;}
-
-#slide0 h1 {font-size: 200%; border: none; margin: 0.5em 0 0.25em;}
-#slide0 h3 {margin: 0; padding: 0;}
-#slide0 h4 {margin: 0 0 0.5em; padding: 0;}
-#slide0 {margin-bottom: 3em;}
-
-h1 {border-top: 2pt solid gray; border-bottom: 1px dotted silver;}
-.extra {background: transparent !important;}
-div.extra, pre.extra, .example {font-size: 10pt; color: #333;}
-ul.extra a {font-weight: bold;}
-p.example {display: none;}
-
-#header {display: none;}
-#footer h1 {margin: 0; border-bottom: 1px solid; color: gray; font-style: italic;}
-#footer h2, #controls {display: none;}
-
-/* The following rule keeps the layout stuff out of print.  Remove at your own risk! */
-.layout, .layout * {display: none !important;}
diff --git a/Doc/s5/ui/default/s5-core.css b/Doc/s5/ui/default/s5-core.css
deleted file mode 100644 (file)
index 304c07f..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-/* Do not edit or override these styles! The system will likely break if you do. */
-
-div#header, div#footer, div#controls, .slide {position: absolute;}
-html>body div#header, html>body div#footer,
-  html>body div#controls, html>body .slide {position: fixed;}
-.handout {display: none;}
-.layout {display: block;}
-.slide, .hideme, .incremental {visibility: hidden;}
-#slide0 {visibility: visible;}
diff --git a/Doc/s5/ui/default/slides.css b/Doc/s5/ui/default/slides.css
deleted file mode 100644 (file)
index 0786d7d..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-@import url(s5-core.css); /* required to make the slide show run at all */
-@import url(framing.css); /* sets basic placement and size of slide components */
-@import url(pretty.css);  /* stuff that makes the slides look better than blah */
\ No newline at end of file
diff --git a/Doc/s5/ui/default/slides.js b/Doc/s5/ui/default/slides.js
deleted file mode 100644 (file)
index 4522035..0000000
+++ /dev/null
@@ -1,552 +0,0 @@
-// S5 v1.1 slides.js -- released into the Public Domain
-//
-// Please see http://www.meyerweb.com/eric/tools/s5/credits.html for information
-// about all the wonderful and talented contributors to this code!
-
-var undef;
-var slideCSS = '';
-var snum = 0;
-var smax = 1;
-var incpos = 0;
-var number = undef;
-var s5mode = true;
-var defaultView = 'slideshow';
-var controlVis = 'visible';
-
-var isIE = navigator.appName == 'Microsoft Internet Explorer' ? 1 : 0;
-var isOp = navigator.userAgent.indexOf('Opera') > -1 ? 1 : 0;
-var isGe = navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('Safari') < 1 ? 1 : 0;
-
-function hasClass(object, className) {
-       if (!object.className) return false;
-       return (object.className.search('(^|\\s)' + className + '(\\s|$)') != -1);
-}
-
-function hasValue(object, value) {
-       if (!object) return false;
-       return (object.search('(^|\\s)' + value + '(\\s|$)') != -1);
-}
-
-function removeClass(object,className) {
-       if (!object) return;
-       object.className = object.className.replace(new RegExp('(^|\\s)'+className+'(\\s|$)'), RegExp.$1+RegExp.$2);
-}
-
-function addClass(object,className) {
-       if (!object || hasClass(object, className)) return;
-       if (object.className) {
-               object.className += ' '+className;
-       } else {
-               object.className = className;
-       }
-}
-
-function GetElementsWithClassName(elementName,className) {
-       var allElements = document.getElementsByTagName(elementName);
-       var elemColl = new Array();
-       for (var i = 0; i< allElements.length; i++) {
-               if (hasClass(allElements[i], className)) {
-                       elemColl[elemColl.length] = allElements[i];
-               }
-       }
-       return elemColl;
-}
-
-function isParentOrSelf(element, id) {
-       if (element == null || element.nodeName=='BODY') return false;
-       else if (element.id == id) return true;
-       else return isParentOrSelf(element.parentNode, id);
-}
-
-function nodeValue(node) {
-       var result = "";
-       if (node.nodeType == 1) {
-               var children = node.childNodes;
-               for (var i = 0; i < children.length; ++i) {
-                       result += nodeValue(children[i]);
-               }
-       }
-       else if (node.nodeType == 3) {
-               result = node.nodeValue;
-       }
-       return(result);
-}
-
-function slideLabel() {
-       var slideColl = GetElementsWithClassName('*','slide');
-       var list = document.getElementById('jumplist');
-       smax = slideColl.length;
-       for (var n = 0; n < smax; n++) {
-               var obj = slideColl[n];
-
-               var did = 'slide' + n.toString();
-               obj.setAttribute('id',did);
-               if (isOp) continue;
-
-               var otext = '';
-               var menu = obj.firstChild;
-               if (!menu) continue; // to cope with empty slides
-               while (menu && menu.nodeType == 3) {
-                       menu = menu.nextSibling;
-               }
-               if (!menu) continue; // to cope with slides with only text nodes
-
-               var menunodes = menu.childNodes;
-               for (var o = 0; o < menunodes.length; o++) {
-                       otext += nodeValue(menunodes[o]);
-               }
-               list.options[list.length] = new Option(n + ' : '  + otext, n);
-       }
-}
-
-function currentSlide() {
-       var cs;
-       if (document.getElementById) {
-               cs = document.getElementById('currentSlide');
-       } else {
-               cs = document.currentSlide;
-       }
-       cs.innerHTML = '<span id="csHere">' + snum + '<\/span> ' +
-               '<span id="csSep">\/<\/span> ' +
-               '<span id="csTotal">' + (smax-1) + '<\/span>';
-       if (snum == 0) {
-               cs.style.visibility = 'hidden';
-       } else {
-               cs.style.visibility = 'visible';
-       }
-}
-
-function go(step) {
-       if (document.getElementById('slideProj').disabled || step == 0) return;
-       var jl = document.getElementById('jumplist');
-       var cid = 'slide' + snum;
-       var ce = document.getElementById(cid);
-       if (incrementals[snum].length > 0) {
-               for (var i = 0; i < incrementals[snum].length; i++) {
-                       removeClass(incrementals[snum][i], 'current');
-                       removeClass(incrementals[snum][i], 'incremental');
-               }
-       }
-       if (step != 'j') {
-               snum += step;
-               lmax = smax - 1;
-               if (snum > lmax) snum = lmax;
-               if (snum < 0) snum = 0;
-       } else
-               snum = parseInt(jl.value);
-       var nid = 'slide' + snum;
-       var ne = document.getElementById(nid);
-       if (!ne) {
-               ne = document.getElementById('slide0');
-               snum = 0;
-       }
-       if (step < 0) {incpos = incrementals[snum].length} else {incpos = 0;}
-       if (incrementals[snum].length > 0 && incpos == 0) {
-               for (var i = 0; i < incrementals[snum].length; i++) {
-                       if (hasClass(incrementals[snum][i], 'current'))
-                               incpos = i + 1;
-                       else
-                               addClass(incrementals[snum][i], 'incremental');
-               }
-       }
-       if (incrementals[snum].length > 0 && incpos > 0)
-               addClass(incrementals[snum][incpos - 1], 'current');
-       ce.style.visibility = 'hidden';
-       ne.style.visibility = 'visible';
-       jl.selectedIndex = snum;
-       currentSlide();
-       number = 0;
-}
-
-function goTo(target) {
-       if (target >= smax || target == snum) return;
-       go(target - snum);
-}
-
-function subgo(step) {
-       if (step > 0) {
-               removeClass(incrementals[snum][incpos - 1],'current');
-               removeClass(incrementals[snum][incpos], 'incremental');
-               addClass(incrementals[snum][incpos],'current');
-               incpos++;
-       } else {
-               incpos--;
-               removeClass(incrementals[snum][incpos],'current');
-               addClass(incrementals[snum][incpos], 'incremental');
-               addClass(incrementals[snum][incpos - 1],'current');
-       }
-}
-
-function toggle() {
-       var slideColl = GetElementsWithClassName('*','slide');
-       var slides = document.getElementById('slideProj');
-       var outline = document.getElementById('outlineStyle');
-       if (!slides.disabled) {
-               slides.disabled = true;
-               outline.disabled = false;
-               s5mode = false;
-               fontSize('1em');
-               for (var n = 0; n < smax; n++) {
-                       var slide = slideColl[n];
-                       slide.style.visibility = 'visible';
-               }
-       } else {
-               slides.disabled = false;
-               outline.disabled = true;
-               s5mode = true;
-               fontScale();
-               for (var n = 0; n < smax; n++) {
-                       var slide = slideColl[n];
-                       slide.style.visibility = 'hidden';
-               }
-               slideColl[snum].style.visibility = 'visible';
-       }
-}
-
-function showHide(action) {
-       var obj = GetElementsWithClassName('*','hideme')[0];
-       switch (action) {
-       case 's': obj.style.visibility = 'visible'; break;
-       case 'h': obj.style.visibility = 'hidden'; break;
-       case 'k':
-               if (obj.style.visibility != 'visible') {
-                       obj.style.visibility = 'visible';
-               } else {
-                       obj.style.visibility = 'hidden';
-               }
-       break;
-       }
-}
-
-// 'keys' code adapted from MozPoint (http://mozpoint.mozdev.org/)
-function keys(key) {
-       if (!key) {
-               key = event;
-               key.which = key.keyCode;
-       }
-       if (key.which == 84) {
-               toggle();
-               return;
-       }
-       if (s5mode) {
-               switch (key.which) {
-                       case 10: // return
-                       case 13: // enter
-                               if (window.event && isParentOrSelf(window.event.srcElement, 'controls')) return;
-                               if (key.target && isParentOrSelf(key.target, 'controls')) return;
-                               if(number != undef) {
-                                       goTo(number);
-                                       break;
-                               }
-                       case 32: // spacebar
-                       case 34: // page down
-                       case 39: // rightkey
-                       case 40: // downkey
-                               if(number != undef) {
-                                       go(number);
-                               } else if (!incrementals[snum] || incpos >= incrementals[snum].length) {
-                                       go(1);
-                               } else {
-                                       subgo(1);
-                               }
-                               break;
-                       case 33: // page up
-                       case 37: // leftkey
-                       case 38: // upkey
-                               if(number != undef) {
-                                       go(-1 * number);
-                               } else if (!incrementals[snum] || incpos <= 0) {
-                                       go(-1);
-                               } else {
-                                       subgo(-1);
-                               }
-                               break;
-                       case 36: // home
-                               goTo(0);
-                               break;
-                       case 35: // end
-                               goTo(smax-1);
-                               break;
-                       case 67: // c
-                               showHide('k');
-                               break;
-               }
-               if (key.which < 48 || key.which > 57) {
-                       number = undef;
-               } else {
-                       if (window.event && isParentOrSelf(window.event.srcElement, 'controls')) return;
-                       if (key.target && isParentOrSelf(key.target, 'controls')) return;
-                       number = (((number != undef) ? number : 0) * 10) + (key.which - 48);
-               }
-       }
-       return false;
-}
-
-function clicker(e) {
-       number = undef;
-       var target;
-       if (window.event) {
-               target = window.event.srcElement;
-               e = window.event;
-       } else target = e.target;
-       if (target.getAttribute('href') != null || hasValue(target.rel, 'external') || isParentOrSelf(target, 'controls') || isParentOrSelf(target,'embed') || isParentOrSelf(target,'object')) return true;
-       if (!e.which || e.which == 1) {
-               if (!incrementals[snum] || incpos >= incrementals[snum].length) {
-                       go(1);
-               } else {
-                       subgo(1);
-               }
-       }
-}
-
-function findSlide(hash) {
-       var target = null;
-       var slides = GetElementsWithClassName('*','slide');
-       for (var i = 0; i < slides.length; i++) {
-               var targetSlide = slides[i];
-               if ( (targetSlide.name && targetSlide.name == hash)
-                || (targetSlide.id && targetSlide.id == hash) ) {
-                       target = targetSlide;
-                       break;
-               }
-       }
-       while(target != null && target.nodeName != 'BODY') {
-               if (hasClass(target, 'slide')) {
-                       return parseInt(target.id.slice(5));
-               }
-               target = target.parentNode;
-       }
-       return null;
-}
-
-function slideJump() {
-       if (window.location.hash == null) return;
-       var sregex = /^#slide(\d+)$/;
-       var matches = sregex.exec(window.location.hash);
-       var dest = null;
-       if (matches != null) {
-               dest = parseInt(matches[1]);
-       } else {
-               dest = findSlide(window.location.hash.slice(1));
-       }
-       if (dest != null)
-               go(dest - snum);
-}
-
-function fixLinks() {
-       var thisUri = window.location.href;
-       thisUri = thisUri.slice(0, thisUri.length - window.location.hash.length);
-       var aelements = document.getElementsByTagName('A');
-       for (var i = 0; i < aelements.length; i++) {
-               var a = aelements[i].href;
-               var slideID = a.match('\#slide[0-9]{1,2}');
-               if ((slideID) && (slideID[0].slice(0,1) == '#')) {
-                       var dest = findSlide(slideID[0].slice(1));
-                       if (dest != null) {
-                               if (aelements[i].addEventListener) {
-                                       aelements[i].addEventListener("click", new Function("e",
-                                               "if (document.getElementById('slideProj').disabled) return;" +
-                                               "go("+dest+" - snum); " +
-                                               "if (e.preventDefault) e.preventDefault();"), true);
-                               } else if (aelements[i].attachEvent) {
-                                       aelements[i].attachEvent("onclick", new Function("",
-                                               "if (document.getElementById('slideProj').disabled) return;" +
-                                               "go("+dest+" - snum); " +
-                                               "event.returnValue = false;"));
-                               }
-                       }
-               }
-       }
-}
-
-function externalLinks() {
-       if (!document.getElementsByTagName) return;
-       var anchors = document.getElementsByTagName('a');
-       for (var i=0; i<anchors.length; i++) {
-               var anchor = anchors[i];
-               if (anchor.getAttribute('href') && hasValue(anchor.rel, 'external')) {
-                       anchor.target = '_blank';
-                       addClass(anchor,'external');
-               }
-       }
-}
-
-function createControls() {
-       var controlsDiv = document.getElementById("controls");
-       if (!controlsDiv) return;
-       var hider = ' onmouseover="showHide(\'s\');" onmouseout="showHide(\'h\');"';
-       var hideDiv, hideList = '';
-       if (controlVis == 'hidden') {
-               hideDiv = hider;
-       } else {
-               hideList = hider;
-       }
-       controlsDiv.innerHTML = '<form action="#" id="controlForm"' + hideDiv + '>' +
-       '<div id="navLinks">' +
-       '<a accesskey="t" id="toggle" href="javascript:toggle();">&#216;<\/a>' +
-       '<a accesskey="z" id="prev" href="javascript:go(-1);">&laquo;<\/a>' +
-       '<a accesskey="x" id="next" href="javascript:go(1);">&raquo;<\/a>' +
-       '<div id="navList"' + hideList + '><select id="jumplist" onchange="go(\'j\');"><\/select><\/div>' +
-       '<\/div><\/form>';
-       if (controlVis == 'hidden') {
-               var hidden = document.getElementById('navLinks');
-       } else {
-               var hidden = document.getElementById('jumplist');
-       }
-       addClass(hidden,'hideme');
-}
-
-function fontScale() {  // causes layout problems in FireFox that get fixed if browser's Reload is used; same may be true of other Gecko-based browsers
-       if (!s5mode) return false;
-       var vScale = 22;  // both yield 32 (after rounding) at 1024x768
-       var hScale = 32;  // perhaps should auto-calculate based on theme's declared value?
-       if (window.innerHeight) {
-               var vSize = window.innerHeight;
-               var hSize = window.innerWidth;
-       } else if (document.documentElement.clientHeight) {
-               var vSize = document.documentElement.clientHeight;
-               var hSize = document.documentElement.clientWidth;
-       } else if (document.body.clientHeight) {
-               var vSize = document.body.clientHeight;
-               var hSize = document.body.clientWidth;
-       } else {
-               var vSize = 700;  // assuming 1024x768, minus chrome and such
-               var hSize = 1024; // these do not account for kiosk mode or Opera Show
-       }
-       var newSize = Math.min(Math.round(vSize/vScale),Math.round(hSize/hScale));
-       fontSize(newSize + 'px');
-       if (isGe) {  // hack to counter incremental reflow bugs
-               var obj = document.getElementsByTagName('body')[0];
-               obj.style.display = 'none';
-               obj.style.display = 'block';
-       }
-}
-
-function fontSize(value) {
-       if (!(s5ss = document.getElementById('s5ss'))) {
-               if (!isIE) {
-                       document.getElementsByTagName('head')[0].appendChild(s5ss = document.createElement('style'));
-                       s5ss.setAttribute('media','screen, projection');
-                       s5ss.setAttribute('id','s5ss');
-               } else {
-                       document.createStyleSheet();
-                       document.s5ss = document.styleSheets[document.styleSheets.length - 1];
-               }
-       }
-       if (!isIE) {
-               while (s5ss.lastChild) s5ss.removeChild(s5ss.lastChild);
-               s5ss.appendChild(document.createTextNode('body {font-size: ' + value + ' !important;}'));
-       } else {
-               document.s5ss.addRule('body','font-size: ' + value + ' !important;');
-       }
-}
-
-function notOperaFix() {
-       slideCSS = document.getElementById('slideProj').href;
-       var slides = document.getElementById('slideProj');
-       var outline = document.getElementById('outlineStyle');
-       slides.setAttribute('media','screen');
-       outline.disabled = true;
-       if (isGe) {
-               slides.setAttribute('href','null');   // Gecko fix
-               slides.setAttribute('href',slideCSS); // Gecko fix
-       }
-       if (isIE && document.styleSheets && document.styleSheets[0]) {
-               document.styleSheets[0].addRule('img', 'behavior: url(ui/default/iepngfix.htc)');
-               document.styleSheets[0].addRule('div', 'behavior: url(ui/default/iepngfix.htc)');
-               document.styleSheets[0].addRule('.slide', 'behavior: url(ui/default/iepngfix.htc)');
-       }
-}
-
-function getIncrementals(obj) {
-       var incrementals = new Array();
-       if (!obj)
-               return incrementals;
-       var children = obj.childNodes;
-       for (var i = 0; i < children.length; i++) {
-               var child = children[i];
-               if (hasClass(child, 'incremental')) {
-                       if (child.nodeName == 'OL' || child.nodeName == 'UL') {
-                               removeClass(child, 'incremental');
-                               for (var j = 0; j < child.childNodes.length; j++) {
-                                       if (child.childNodes[j].nodeType == 1) {
-                                               addClass(child.childNodes[j], 'incremental');
-                                       }
-                               }
-                       } else {
-                               incrementals[incrementals.length] = child;
-                               removeClass(child,'incremental');
-                       }
-               }
-               if (hasClass(child, 'show-first')) {
-                       if (child.nodeName == 'OL' || child.nodeName == 'UL') {
-                               removeClass(child, 'show-first');
-                               if (child.childNodes[isGe].nodeType == 1) {
-                                       removeClass(child.childNodes[isGe], 'incremental');
-                               }
-                       } else {
-                               incrementals[incrementals.length] = child;
-                       }
-               }
-               incrementals = incrementals.concat(getIncrementals(child));
-       }
-       return incrementals;
-}
-
-function createIncrementals() {
-       var incrementals = new Array();
-       for (var i = 0; i < smax; i++) {
-               incrementals[i] = getIncrementals(document.getElementById('slide'+i));
-       }
-       return incrementals;
-}
-
-function defaultCheck() {
-       var allMetas = document.getElementsByTagName('meta');
-       for (var i = 0; i< allMetas.length; i++) {
-               if (allMetas[i].name == 'defaultView') {
-                       defaultView = allMetas[i].content;
-               }
-               if (allMetas[i].name == 'controlVis') {
-                       controlVis = allMetas[i].content;
-               }
-       }
-}
-
-// Key trap fix, new function body for trap()
-function trap(e) {
-       if (!e) {
-               e = event;
-               e.which = e.keyCode;
-       }
-       try {
-               modifierKey = e.ctrlKey || e.altKey || e.metaKey;
-       }
-       catch(e) {
-               modifierKey = false;
-       }
-       return modifierKey || e.which == 0;
-}
-
-function startup() {
-       defaultCheck();
-       if (!isOp) createControls();
-       slideLabel();
-       fixLinks();
-       externalLinks();
-       fontScale();
-       if (!isOp) {
-               notOperaFix();
-               incrementals = createIncrementals();
-               slideJump();
-               if (defaultView == 'outline') {
-                       toggle();
-               }
-               document.onkeyup = keys;
-               document.onkeypress = trap;
-               document.onclick = clicker;
-       }
-}
-
-window.onload = startup;
-window.onresize = function(){setTimeout('fontScale()', 50);}
\ No newline at end of file
diff --git a/PKG-INFO b/PKG-INFO
new file mode 100644 (file)
index 0000000..e3bee73
--- /dev/null
+++ b/PKG-INFO
@@ -0,0 +1,54 @@
+Metadata-Version: 1.2
+Name: Cython
+Version: 0.29.21
+Summary: The Cython compiler for writing C extensions for the Python language.
+Home-page: http://cython.org/
+Author: Robert Bradshaw, Stefan Behnel, Dag Seljebotn, Greg Ewing, et al.
+Author-email: cython-devel@python.org
+License: Apache
+Description: The Cython language makes writing C extensions for the Python language as
+        easy as Python itself.  Cython is a source code translator based on Pyrex_,
+        but supports more cutting edge functionality and optimizations.
+        
+        The Cython language is a superset of the Python language (almost all Python
+        code is also valid Cython code), but Cython additionally supports optional
+        static typing to natively call C functions, operate with C++ classes and
+        declare fast C types on variables and class attributes.  This allows the
+        compiler to generate very efficient C code from Cython code.
+        
+        This makes Cython the ideal language for writing glue code for external
+        C/C++ libraries, and for fast C modules that speed up the execution of
+        Python code.
+        
+        Note that for one-time builds, e.g. for CI/testing, on platforms that are not
+        covered by one of the wheel packages provided on PyPI *and* the pure Python wheel
+        that we provide is not used, it is substantially faster than a full source build
+        to install an uncompiled (slower) version of Cython with::
+        
+            pip install Cython --install-option="--no-cython-compile"
+        
+        .. _Pyrex: http://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/
+        
+Platform: UNKNOWN
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: Apache Software License
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 2
+Classifier: Programming Language :: Python :: 2.6
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: Implementation :: CPython
+Classifier: Programming Language :: Python :: Implementation :: PyPy
+Classifier: Programming Language :: C
+Classifier: Programming Language :: Cython
+Classifier: Topic :: Software Development :: Code Generators
+Classifier: Topic :: Software Development :: Compilers
+Classifier: Topic :: Software Development :: Libraries :: Python Modules
+Requires-Python: >=2.6, !=3.0.*, !=3.1.*, !=3.2.*
diff --git a/appveyor.yml b/appveyor.yml
deleted file mode 100644 (file)
index 56e47e1..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-# https://ci.appveyor.com/project/cython/cython
-
-environment:
-
-  global:
-    # SDK v7.0 MSVC Express 2008's SetEnv.cmd script will fail if the
-    # /E:ON and /V:ON options are not enabled in the batch script interpreter
-    # See: http://stackoverflow.com/a/13751649/163740
-    WITH_ENV: "cmd /E:ON /V:ON /C .\\appveyor\\run_with_env.cmd"
-
-  matrix:
-    - PYTHON: "C:\\Python27"
-      PYTHON_VERSION: "2.7"
-      PYTHON_ARCH: "32"
-
-    - PYTHON: "C:\\Python27-x64"
-      PYTHON_VERSION: "2.7"
-      PYTHON_ARCH: "64"
-
-    - PYTHON: "C:\\Python38"
-      PYTHON_VERSION: "3.8"
-      PYTHON_ARCH: "32"
-
-    - PYTHON: "C:\\Python38-x64"
-      PYTHON_VERSION: "3.8"
-      PYTHON_ARCH: "64"
-
-    - PYTHON: "C:\\Python37"
-      PYTHON_VERSION: "3.7"
-      PYTHON_ARCH: "32"
-
-    - PYTHON: "C:\\Python37-x64"
-      PYTHON_VERSION: "3.7"
-      PYTHON_ARCH: "64"
-
-    - PYTHON: "C:\\Python36"
-      PYTHON_VERSION: "3.6"
-      PYTHON_ARCH: "32"
-
-    - PYTHON: "C:\\Python36-x64"
-      PYTHON_VERSION: "3.6"
-      PYTHON_ARCH: "64"
-
-    - PYTHON: "C:\\Python35"
-      PYTHON_VERSION: "3.5"
-      PYTHON_ARCH: "32"
-
-    - PYTHON: "C:\\Python35-x64"
-      PYTHON_VERSION: "3.5"
-      PYTHON_ARCH: "64"
-
-    - PYTHON: "C:\\Python34"
-      PYTHON_VERSION: "3.4"
-      PYTHON_ARCH: "32"
-
-    - PYTHON: "C:\\Python34-x64"
-      PYTHON_VERSION: "3.4"
-      PYTHON_ARCH: "64"
-
-clone_depth: 5
-
-branches:
-  only:
-    - master
-    - release
-
-init:
-  - "ECHO Python %PYTHON_VERSION% (%PYTHON_ARCH%bit) from %PYTHON%"
-
-install:
-  - "powershell appveyor\\install.ps1"
-  - "%PYTHON%\\python.exe --version"
-  - "%PYTHON%\\Scripts\\pip.exe --version"
-  - "%PYTHON%\\Scripts\\wheel.exe version"
-
-build: off
-build_script:
-  - "%WITH_ENV% %PYTHON%\\python.exe setup.py build_ext --inplace"
-  - "%WITH_ENV% %PYTHON%\\python.exe setup.py bdist_wheel"
-
-test: off
-test_script:
-  - "%PYTHON%\\Scripts\\pip.exe install -r test-requirements.txt"
-  - "set CFLAGS=/Od"
-  - "%WITH_ENV% %PYTHON%\\python.exe runtests.py -vv --no-cpp --no-code-style -j5"
-
-artifacts:
-  - path: dist\*
-
-cache:
-  - C:\Downloads\Cython -> appveyor\install.ps1
-
-#on_success:
-#  - TODO: upload the content of dist/*.whl to a public wheelhouse
diff --git a/appveyor/install.ps1 b/appveyor/install.ps1
deleted file mode 100644 (file)
index ab027fc..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-# Sample script to install Python and pip under Windows
-# Authors: Olivier Grisel and Kyle Kastner
-# License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/
-
-$PYTHON_BASE_URL = "https://www.python.org/ftp/python/"
-$GET_PIP_URL = "https://bootstrap.pypa.io/get-pip.py"
-$GET_PIP_PATH = "C:\get-pip.py"
-
-$DOWNLOADS = "C:\Downloads\Cython"
-
-
-function Download ($url, $filename, $destdir) {
-    if ($destdir) {
-        $item = New-Item $destdir -ItemType directory -Force
-        $destdir = $item.FullName
-    } else {
-        $destdir = $pwd.Path
-    }
-    $filepath = Join-Path $destdir $filename
-    if (Test-Path $filepath) {
-        Write-Host "Reusing" $filename "from" $destdir
-        return $filepath
-    }
-    Write-Host "Downloading" $filename "from" $url
-    $webclient = New-Object System.Net.WebClient
-    foreach($i in 1..3) {
-        try {
-            $webclient.DownloadFile($url, $filepath)
-            Write-Host "File saved at" $filepath
-            return $filepath
-        }
-        Catch [Exception] {
-            Start-Sleep 1
-        }
-    }
-    Write-Host "Failed to download" $filename "from" $url
-    return $null
-}
-
-
-function InstallPython ($python_version, $architecture, $python_home) {
-    Write-Host "Installing Python $python_version ($architecture-bit) to $python_home"
-    if (Test-Path $python_home) {
-        Write-Host $python_home "already exists, skipping."
-        return
-    }
-    $py_major = $python_version[0]; $py_minor = $python_version[2]
-    $installer_exe = ($py_major + $py_minor) -as [int] -ge 35
-    if ($installer_exe) {
-        $arch_suffix = @{"32"="";"64"="-amd64"}[$architecture]
-        $filename = "python-" + $python_version + $arch_suffix + ".exe"
-    } else {
-        $arch_suffix = @{"32"="";"64"=".amd64"}[$architecture]
-        $filename = "python-" + $python_version + $arch_suffix + ".msi"
-    }
-    $url = $PYTHON_BASE_URL + $python_version + "/" + $filename
-    $filepath = Download $url $filename $DOWNLOADS
-    Write-Host "Installing" $filename "to" $python_home
-    if ($installer_exe) {
-        $prog = "$filepath"
-        $args = "/quiet TargetDir=$python_home"
-    } else {
-        $prog = "msiexec.exe"
-        $args = "/quiet /qn /i $filepath TARGETDIR=$python_home"
-    }
-    Write-Host $prog $args
-    Start-Process -FilePath $prog -ArgumentList $args -Wait
-    Write-Host "Python $python_version ($architecture-bit) installation complete"
-}
-
-
-function InstallPip ($python_home) {
-    $python_path = Join-Path $python_home "python.exe"
-    $pip_path = Join-Path $python_home "Scripts\pip.exe"
-    if (Test-Path $pip_path) {
-        Write-Host "Upgrading pip"
-        $args = "-m pip.__main__ install --upgrade pip"
-        Write-Host "Executing:" $python_path $args
-        Start-Process -FilePath $python_path -ArgumentList $args -Wait
-        Write-Host "pip upgrade complete"
-    } else {
-        Write-Host "Installing pip"
-        $webclient = New-Object System.Net.WebClient
-        $webclient.DownloadFile($GET_PIP_URL, $GET_PIP_PATH)
-        Write-Host "Executing:" $python_path $GET_PIP_PATH
-        Start-Process -FilePath $python_path -ArgumentList "$GET_PIP_PATH" -Wait
-        Write-Host "pip installation complete"
-    }
-}
-
-
-function InstallPipPackage ($python_home, $package) {
-    $pip_path = Join-Path $python_home "Scripts\pip.exe"
-    Write-Host "Installing/Upgrading $package"
-    $args = "install --upgrade $package"
-    Write-Host "Executing:" $pip_path $args
-    Start-Process -FilePath $pip_path -ArgumentList $args -Wait
-    Write-Host "$package install/upgrade complete"
-}
-
-function main () {
-    InstallPython $env:PYTHON_VERSION $env:PYTHON_ARCH $env:PYTHON
-    InstallPip $env:PYTHON
-    InstallPipPackage $env:PYTHON setuptools
-    InstallPipPackage $env:PYTHON wheel
-}
-
-main
diff --git a/appveyor/run_with_env.cmd b/appveyor/run_with_env.cmd
deleted file mode 100644 (file)
index c8a7877..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-:: Author:  Lisandro Dalcin
-:: Contact: dalcinl@gmail.com
-:: Credits: Olivier Grisel and Kyle Kastner
-@ECHO OFF
-
-SET COMMAND_TO_RUN=%*
-
-SET PYTHON_VERSION_MAJOR=%PYTHON_VERSION:~0,1%
-SET PYTHON_VERSION_MINOR=%PYTHON_VERSION:~2,1%
-
-SET WIN_SDK_ROOT=C:\Program Files\Microsoft SDKs\Windows
-IF %PYTHON_VERSION_MAJOR% == 2 SET WIN_SDK_VERSION="v7.0"
-IF %PYTHON_VERSION_MAJOR% == 3 SET WIN_SDK_VERSION="v7.1"
-
-IF %PYTHON_ARCH% == 64 SET USE_WIN_SDK=1
-IF %PYTHON_VERSION_MAJOR% EQU 3 IF %PYTHON_VERSION_MINOR% GEQ 5 SET USE_WIN_SDK=0
-IF %PYTHON_VERSION_MAJOR% GTR 3 SET USE_WIN_SDK=0
-if %PYTHON_ARCH% == 32 SET USE_WIN_SDK=0
-
-IF %USE_WIN_SDK% == 1 (
-    ECHO Configuring Windows SDK %WIN_SDK_VERSION% for %PYTHON_ARCH% bit architecture
-    SET DISTUTILS_USE_SDK=1
-    SET MSSdk=1
-    "%WIN_SDK_ROOT%\%WIN_SDK_VERSION%\Setup\WindowsSdkVer.exe" -q -version:%WIN_SDK_VERSION%
-    "%WIN_SDK_ROOT%\%WIN_SDK_VERSION%\Bin\SetEnv.cmd" /x64 /release
-    ECHO Executing: %COMMAND_TO_RUN%
-    CALL %COMMAND_TO_RUN% || EXIT 1
-) ELSE (
-    ECHO Using default MSVC build environment for %PYTHON_ARCH% bit architecture
-    ECHO Executing: %COMMAND_TO_RUN%
-    CALL %COMMAND_TO_RUN% || EXIT 1
-)
diff --git a/pyximport/README.rst b/pyximport/README.rst
deleted file mode 100644 (file)
index 0e91ac4..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-Pyximport
-=========
-
-Cython is a compiler. Therefore it is natural that people tend to go
-through an edit/compile/test cycle with Cython modules. But my personal
-opinion is that one of the deep insights in Python's implementation is
-that a language can be compiled (Python modules are compiled to .pyc)
-files and hide that compilation process from the end-user so that they
-do not have to worry about it. Pyximport does this for Cython modules.
-For instance if you write a Cython module called ``foo.pyx``, with
-Pyximport you can import it in a regular Python module like this::
-
-    import pyximport; pyximport.install()
-    import foo
-
-Doing so will result in the compilation of ``foo.pyx`` (with appropriate
-exceptions if it has an error in it).
-
-If you would always like to import Cython files without building them
-specially, you can also add the first line above to your sitecustomize.py.
-That will install the hook every time you run Python. Then you can use
-Cython modules just with simple import statements. I like to test my
-Cython modules like this::
-
-    python -c "import foo"
-
-See help(pyximport.install) to learn its options for controlling the
-default behavior of ``import`` and ``reload``.
-
-Dependency Handling
--------------------
-
-In Pyximport 1.1 it is possible to declare that your module depends on
-multiple files, (likely ``.h`` and ``.pxd`` files). If your Cython module is
-named ``foo`` and thus has the filename ``foo.pyx`` then you should make
-another file in the same directory called ``foo.pyxdep``. The
-``modname.pyxdep`` file can be a list of filenames or ``globs`` (like
-``*.pxd`` or ``include/*.h``). Each filename or glob must be on a separate
-line. Pyximport will check the file date for each of those files before
-deciding whether to rebuild the module. In order to keep track of the
-fact that the dependency has been handled, Pyximport updates the
-modification time of your ``.pyx`` source file. Future versions may do
-something more sophisticated like informing distutils of the
-dependencies directly.
-
-Limitations
------------
-Pyximport does not give you any control over how your Cython file is
-compiled. Usually the defaults are fine. You might run into problems if
-you wanted to write your program in half-C, half-Cython and build them
-into a single library. Pyximport 1.2 will probably do this.
-
-Pyximport does not hide the Distutils/GCC warnings and errors generated
-by the import process. Arguably this will give you better feedback if
-something went wrong and why. And if nothing went wrong it will give you
-the warm fuzzy that pyximport really did rebuild your module as it was
-supposed to.
-
-For further thought and discussion
-----------------------------------
-
-``setup.py install`` does not modify ``sitecustomize.py`` for you. Should it?
-Modifying Python's "standard interpreter" behaviour may be more than
-most people expect of a package they install..
-
-Pyximport puts your ``.c`` file beside your ``.pyx`` file (analogous to
-``.pyc`` beside ``.py``). But it puts the platform-specific binary in a
-build directory as per normal for Distutils. If I could wave a magic
-wand and get Cython or distutils or whoever to put the build directory I
-might do it but not necessarily: having it at the top level is VERY
-HELPFUL for debugging Cython problems.
index 1167270..b7bb315 100755 (executable)
@@ -1747,6 +1747,8 @@ class EndToEndTest(unittest.TestCase):
                 out.append(_out)
                 err.append(_err)
             res = p.returncode
+            if res == 0 and b'REFNANNY: ' in _out:
+                res = -1
             if res != 0:
                 for c, o, e in zip(cmd, out, err):
                     sys.stderr.write("%s\n%s\n%s\n\n" % (
diff --git a/test-requirements-cpython.txt b/test-requirements-cpython.txt
deleted file mode 100644 (file)
index db74d13..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-jupyter
-line_profiler
-# transitive dependency of jupyter (17.0+ lacks wheels for Py3.4)
-pyzmq<17
diff --git a/test-requirements.txt b/test-requirements.txt
deleted file mode 100644 (file)
index 27254b8..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-numpy
-coverage
-pycodestyle
index e614917..ec2445c 100644 (file)
@@ -121,4 +121,12 @@ CFLAGS (distutils) = {config_var('CFLAGS')}
 CFLAGS (env) = {get_env('CFLAGS', '')}
 LINKCC (distutils) = {config_var('LINKCC')}
 LINKCC (env) = {get_env('LINKCC', '')}
+
+Encodings:
+sys maxunicode = {sys.maxunicode}
+LANG (env) = {get_env('LANG', '')}
+PYTHONIOENCODING (env) = {get_env('PYTHONIOENCODING', '')}
+sys stdout encoding = {sys.stdout.encoding}
+sys default encoding = {sys.getdefaultencoding()}
+sys FS encoding = {sys.getfilesystemencoding()}
 """)
index c6f4e2e..726acfb 100644 (file)
@@ -18,4 +18,11 @@ def f(a, b, c, x):
         finally:
             i = 42
 
+def use_name_in_finally(name):
+    # GH3712
+    try:
+        []
+    finally:
+        name()
+
 
index 3e4ba15..1743f23 100644 (file)
@@ -37,6 +37,13 @@ NUMPY_HAS_RELAXED_STRIDES = (
     np.ones((10, 1), order="C").flags.f_contiguous)
 
 
+def not_py26(f):
+    import sys
+    if sys.version_info < (2, 7):
+        return lambda a: None
+    return f
+
+
 def test_one_sized(array):
     """
     >>> contig = np.ascontiguousarray(np.arange(10, dtype=np.double)[::100])
@@ -62,3 +69,26 @@ def test_zero_sized(array):
     """
     cdef double[::1] a = array
     return a
+
+def test_zero_sized_multidim_ccontig(array):
+    """
+    >>> contig = np.ascontiguousarray(np.zeros((4,4,4))[::2, 2:2, ::2])
+    >>> _ = test_zero_sized_multidim_ccontig(contig)
+
+    >>> a = np.zeros((4,4,4))[::2, 2:2, ::2]
+    >>> if NUMPY_HAS_RELAXED_STRIDES: _ = test_zero_sized_multidim_ccontig(a)
+    """
+    cdef double[:, :, ::1] a = array
+    return a
+
+@not_py26
+def test_zero_sized_multidim_fcontig(array):
+    """
+    >>> contig = np.ascontiguousarray(np.zeros((4,4,4))[::2, 2:2, ::2])
+    >>> _ = test_zero_sized_multidim_fcontig(contig)
+
+    >>> a = np.zeros((4,4,4))[::2, 2:2, ::2]
+    >>> if NUMPY_HAS_RELAXED_STRIDES: _ = test_zero_sized_multidim_fcontig(a)
+    """
+    cdef double[::1, :, :] a = array
+    return a
index e423404..c7654c0 100644 (file)
@@ -212,6 +212,7 @@ cdef vector[vector_int_ptr] create_to_delete() except *:
 cdef int f(int x):
     return x
 
+
 def test_nested_del():
     """
     >>> test_nested_del()
@@ -220,3 +221,15 @@ def test_nested_del():
     v.push_back(new vector[int]())
     del v[0]
     del create_to_delete()[f(f(0))]
+
+
+def test_nested_del_repeat():
+    """
+    >>> test_nested_del_repeat()
+    """
+    cdef vector[vector_int_ptr] v
+    v.push_back(new vector[int]())
+    del v[0]
+    del create_to_delete()[f(f(0))]
+    del create_to_delete()[f(f(0))]
+    del create_to_delete()[f(f(0))]
index bf0e048..f4fa4d3 100644 (file)
@@ -140,6 +140,11 @@ def test_unordered_set_functionality():
     return "pass"
 
 
+cdef extern from "cpp_unordered_map_helper.h":
+    cdef cppclass IntVectorHash:
+        pass
+
+
 def test_unordered_map_functionality():
     """
     >>> test_unordered_map_functionality()
@@ -153,6 +158,8 @@ def test_unordered_map_functionality():
         unordered_map[int, int] int_map2
         unordered_map[int, int*] intptr_map
         const int* intptr
+        unordered_map[vector[int], int, IntVectorHash] int_vector_map
+        vector[int] intvec
     assert int_map[1] == 2
     assert int_map.size() == 1
     assert int_map.erase(1) == 1 # returns number of elements erased
@@ -183,4 +190,12 @@ def test_unordered_map_functionality():
 
     intptr_map[0] = NULL
     intptr = intptr_map.const_at(0)
+
+    intvec = [1, 2]
+    int_vector_map[intvec] = 3
+    intvec = [4, 5]
+    int_vector_map[intvec] = 6
+    assert int_vector_map[intvec] == 6
+    intvec = [1, 2]
+    assert int_vector_map[intvec] == 3
     return "pass"
diff --git a/tests/run/cpp_unordered_map_helper.h b/tests/run/cpp_unordered_map_helper.h
new file mode 100644 (file)
index 0000000..de24473
--- /dev/null
@@ -0,0 +1,13 @@
+#include <functional>
+#include <vector>
+
+struct IntVectorHash {
+  size_t operator()(const std::vector<int>& v) const {
+    std::hash<int> hasher;
+    size_t seed = 0;
+    for (int i : v) {
+      seed ^= hasher(i) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
+    }
+    return seed;
+  }
+};
index ec65951..6b5f849 100644 (file)
@@ -145,3 +145,18 @@ def exec_invalid_type(x):
     TypeError: exec: arg 1 must be string, bytes or code object, got int
     """
     exec x in {}
+
+
+def exec_with_new_features(s, d):
+    """
+    >>> import sys
+    >>> pyversion = sys.version_info[:2]
+
+    >>> d = {}
+    >>> exec_with_new_features('print(123)', d)
+    123
+    >>> if pyversion == (2, 7): exec_with_new_features('exec "123"', d)
+    >>> if pyversion >= (3, 6): exec_with_new_features('f = f"abc"', d)
+    >>> if pyversion >= (3, 8): exec_with_new_features('a = (b := 1)', d)
+    """
+    exec s in d
index 7d4806e..bcc34d2 100644 (file)
@@ -21,6 +21,13 @@ __doc__ = br"""
     u'\udc00'
     >>> h
     u'\ud800'
+    >>> q
+    u'\udc00\ud800'
+
+    # The output of surrogate pairs differs between 16/32bit Unicode runtimes.
+    #>>> p
+    #u'\ud800\udc00'
+
     >>> add
     u'S\xf8k ik\xfc\xd6\xe4abc'
     >>> null
@@ -44,6 +51,10 @@ __doc__ = br"""
     1
     >>> len(h)
     1
+    >>> len(q)
+    2
+    >>> len(q)
+    2
     >>> len(add)
     12
     >>> len(null)
@@ -75,11 +86,15 @@ __doc__ = br"""
     True
     >>> h == u'\\ud800' # unescaped by Python (required by doctest)
     True
-    >>> k == u'\\N{SNOWMAN}' == u'\\u2603'
+    >>> p == (u'\\ud800\\udc00' if sys.maxunicode == 1114111 else u'\\U00010000')  or  p  # unescaped by Python (required by doctest)
+    True
+    >>> q == u'\\udc00\\ud800'  or  q  # unescaped by Python (required by doctest)
+    True
+    >>> k == u'\\N{SNOWMAN}' == u'\\u2603'  or  k
     True
-    >>> m == u'abc\\\\xf8\\\\t\\u00f8\\U000000f8'  # unescaped by Python (required by doctest)
+    >>> m == u'abc\\\\xf8\\\\t\\u00f8\\U000000f8'  or  m  # unescaped by Python (required by doctest)
     True
-    >>> add == u'Søk ik' + u'üÖä' + 'abc'
+    >>> add == u'Søk ik' + u'üÖä' + 'abc'  or  add
     True
     >>> null == u'\\x00' # unescaped by Python (required by doctest)
     True
@@ -115,6 +130,8 @@ g = u'\udc00'   # lone trail surrogate
 h = u'\ud800'   # lone lead surrogate
 k = u'\N{SNOWMAN}'
 m = ur'abc\xf8\t\u00f8\U000000f8'
+p = u'\ud800\udc00'  # surrogate pair
+q = u'\udc00\ud800'  # reversed surrogate pair
 
 add = u'Søk ik' + u'üÖä' + u'abc'
 null = u'\x00'
diff --git a/tox.ini b/tox.ini
deleted file mode 100644 (file)
index 5f86476..0000000
--- a/tox.ini
+++ /dev/null
@@ -1,18 +0,0 @@
-# Tox (http://tox.testrun.org/) is a tool for running tests
-# in multiple virtualenvs. This configuration file will run the
-# test suite on all supported python versions. To use it, "pip install tox"
-# and then run "tox" from this directory.
-
-[tox]
-envlist = py26, py27, py32, py33, py34, pypy
-
-[testenv]
-setenv = CFLAGS=-O0 -ggdb
-commands =
-    {envpython} runtests.py -vv
-
-[pycodestyle]
-ignore = W, E
-select = E711, E714, E501, W291
-max-line-length = 150
-format = pylint