diff --git a/.coveragerc b/.coveragerc
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_LmNvdmVyYWdlcmM=..0000000000000000000000000000000000000000
--- a/.coveragerc
+++ /dev/null
@@ -1,7 +0,0 @@
-[run]
-branch = True
-parallel = True
-concurrency = multiprocessing,thread
-include = Cython/*
-source = Cython
-omit = Test*
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_LmdpdGh1Yi9GVU5ESU5HLnltbA==
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,12 @@
+# These are supported funding model platforms
+
+github: scoder # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
+patreon: # Replace with a single Patreon username
+open_collective: # Replace with a single Open Collective username
+ko_fi: # Replace with a single Ko-fi username
+tidelift: pypi/Cython # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
+community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
+liberapay: # Replace with a single Liberapay username
+issuehunt: # Replace with a single IssueHunt username
+otechie: # Replace with a single Otechie username
+custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
diff --git a/.gitignore b/.gitignore
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_LmdpdGlnbm9yZQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_LmdpdGlnbm9yZQ== 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,9 +6,11 @@
 
 *.egg
 *.egg-info
+.*cache*/
+*venv*/
 
 Cython/Compiler/*.c
 Cython/Plex/*.c
 Cython/Runtime/refnanny.c
 Cython/Tempita/*.c
 Cython/*.c
@@ -9,8 +11,10 @@
 
 Cython/Compiler/*.c
 Cython/Plex/*.c
 Cython/Runtime/refnanny.c
 Cython/Tempita/*.c
 Cython/*.c
+Cython/*.html
+Cython/*/*.html
 
 Tools/*.elc
@@ -15,5 +19,7 @@
 
 Tools/*.elc
+Demos/*.html
+Demos/*/*.html
 
 /TEST_TMP/
 /build/
@@ -17,8 +23,9 @@
 
 /TEST_TMP/
 /build/
+/cython_build/
 /wheelhouse*/
 !tests/build/
 /dist/
 .gitrev
 .coverage
@@ -20,6 +27,8 @@
 /wheelhouse*/
 !tests/build/
 /dist/
 .gitrev
 .coverage
+*.patch
+*.diff
 *.orig
@@ -25,2 +34,3 @@
 *.orig
+*.prof
 *.rej
@@ -26,4 +36,5 @@
 *.rej
+*.log
 *.dep
 *.swp
 *~
@@ -27,6 +38,7 @@
 *.dep
 *.swp
 *~
+callgrind.out.*
 
 .ipynb_checkpoints
 docs/build
@@ -41,3 +53,5 @@
 /.idea
 /*.iml
 
+# Komodo EDIT/IDE project files
+/*.komodoproject
diff --git a/.travis.yml b/.travis.yml
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_LnRyYXZpcy55bWw=..162972e7c0335748b70e02edc37e5e3bbb4858ae_LnRyYXZpcy55bWw= 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,3 +1,2 @@
 os: linux
-dist: trusty
 language: python
@@ -3,6 +2,4 @@
 language: python
-# 'sudo' is enabled automatically by the 'apt' addon below.
-#sudo: false
 
 addons:
   apt:
@@ -19,6 +16,15 @@
   directories:
     - $HOME/.ccache
 
+python:
+  - 3.8
+  - 2.7
+  - 3.9-dev
+  - 3.7
+  - 3.6
+  - 3.5
+  - 3.4
+
 env:
   global:
     - USE_CCACHE=1
@@ -27,6 +33,9 @@
     - CCACHE_MAXSIZE=250M
     - PATH="/usr/lib/ccache:$HOME/miniconda/bin:$PATH"
     - BACKEND=c,cpp
+  matrix:
+    - BACKEND=c
+    - BACKEND=cpp
 
 matrix:
   include:
@@ -30,49 +39,5 @@
 
 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
+    # slowest first
     - os: osx
@@ -78,8 +43,8 @@
     - os: osx
-      osx_image: xcode6.4
-      env: PY=2
+      osx_image: xcode10.3
+      env: PY=2 MACOSX_DEPLOYMENT_TARGET=10.9
       python: 2
       language: c
       compiler: clang
       cache: false
     - os: osx
@@ -81,11 +46,11 @@
       python: 2
       language: c
       compiler: clang
       cache: false
     - os: osx
-      osx_image: xcode6.4
-      env: PY=3
+      osx_image: xcode10.3
+      env: PY=3 MACOSX_DEPLOYMENT_TARGET=10.9
       python: 3
       language: c
       compiler: clang
       cache: false
@@ -88,8 +53,23 @@
       python: 3
       language: c
       compiler: clang
       cache: false
+# Disabled: coverage analysis takes excessively long, several times longer than without.
+#    - python: 3.7
+#      env: COVERAGE=1
+    - python: 3.7
+      env: TEST_CODE_STYLE=1
+    - python: 3.8
+      env: LIMITED_API=--limited-api EXCLUDE=--no-file
+    - python: 3.7
+      env: LIMITED_API=--limited-api EXCLUDE=--no-file
+    - python: 3.6
+      env: LIMITED_API=--limited-api EXCLUDE=--no-file
+    - env: STACKLESS=true BACKEND=c PY=2
+      python: 2.7
+    - env: STACKLESS=true BACKEND=c PY=3
+      python: 3.6
     - python: pypy
       env: BACKEND=c
     - python: pypy3
       env: BACKEND=c
@@ -92,9 +72,11 @@
     - 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
+# a secondary pypy tests which is allowed to fail and which specifically
+# tests known bugs
+    - python: pypy
+      env: BACKEND=c EXCLUDE="--listfile=tests/pypy_bugs.txt --listfile=tests/pypy2_bugs.txt bugs"
+    - python: pypy3
+      env: BACKEND=c EXCLUDE="--listfile=tests/pypy_bugs.txt bugs"
   allow_failures:
@@ -100,6 +82,7 @@
   allow_failures:
-    - python: pypy
-    - python: pypy3
+    - python: 3.9-dev
+    - env: BACKEND=c EXCLUDE="--listfile=tests/pypy_bugs.txt bugs"
+    - env: BACKEND=c EXCLUDE="--listfile=tests/pypy_bugs.txt --listfile=tests/pypy2_bugs.txt bugs"
 
 branches:
   only:
@@ -108,7 +91,7 @@
 
 before_install:
   - |
-    if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
+    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
@@ -119,8 +102,10 @@
     fi
 
   - |
-    if [[ "$TRAVIS_OS_NAME" == "osx" ]] || [[ "$STACKLESS" == "true" ]]; then # Install Miniconda
-      if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then CONDA_PLATFORM=MacOSX; else CONDA_PLATFORM=Linux; fi
-      travis_retry curl -s -o miniconda.sh https://repo.continuum.io/miniconda/Miniconda$PY-latest-${CONDA_PLATFORM}-x86_64.sh
-      bash miniconda.sh -b -p $HOME/miniconda && rm miniconda.sh
+    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
@@ -126,3 +111,3 @@
       #conda install --quiet --yes nomkl --file=test-requirements.txt --file=test-requirements-cpython.txt
-      if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
+      if [ "$TRAVIS_OS_NAME" == "osx" ]; then
         which clang && clang --version && export CC=clang || true
@@ -128,5 +113,5 @@
         which clang && clang --version && export CC=clang || true
-        which clang++ && clang++ --version && export CXX=clang++ || true
+        which clang++ && clang++ --version && export CXX="clang++ -stdlib=libc++" || true
       fi
     fi
 
@@ -130,6 +115,6 @@
       fi
     fi
 
-  - if [ -n "$CC" ]; then which $CC; $CC --version; fi
-  - if [ -n "$CXX" ]; then which $CXX; $CXX --version; fi
+  - if [ -n "$CC" ]; then which ${CC%% *}; $CC --version; fi
+  - if [ -n "$CXX" ]; then which ${CXX%% *}; $CXX --version; fi
 
@@ -135,8 +120,8 @@
 
-  - if [[ "$STACKLESS" == "true" ]]; then
+  - 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,))'
@@ -137,10 +122,10 @@
       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
+  - if [ -n "${TRAVIS_PYTHON_VERSION##*-dev}" ]; then pip install -r test-requirements.txt $( [ -z "${TRAVIS_PYTHON_VERSION##pypy*}" -o -z "${TRAVIS_PYTHON_VERSION##3.[4789]*}" ] || 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
@@ -153,5 +138,5 @@
       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;
+      if [ "$BACKEND" != "cpp" -a -n "${TRAVIS_PYTHON_VERSION##2*}"  -a -n "${TRAVIS_PYTHON_VERSION##pypy*}" -a -n "${TRAVIS_PYTHON_VERSION##*-dev}" -a -n "${TRAVIS_PYTHON_VERSION##*3.4}" ]; then pip install mypy; fi;
     fi
@@ -157,4 +142,6 @@
     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)
+# Need to clear the ccache? Try something like this:
+#  - if [ -n "${BACKEND##*cpp*}" -a -z "${TRAVIS_PYTHON_VERSION##*3.4}" ]; then ccache -C || true; 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 $(python -c 'import sys; print("-j5" if sys.version_info >= (3,5) else "")'); fi
+  - CFLAGS="-O0 -ggdb -Wall -Wextra" python runtests.py -vv $STYLE_ARGS -x Debugger --backends=$BACKEND $LIMITED_API $EXCLUDE $(if [ "$COVERAGE" == "1" ]; then echo " --coverage"; fi) $(if [ -z "$TEST_CODE_STYLE" ]; then echo " -j7 "; fi)
   - ccache -s || true
diff --git a/CHANGES.rst b/CHANGES.rst
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q0hBTkdFUy5yc3Q=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q0hBTkdFUy5yc3Q= 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -2,6 +2,408 @@
 Cython Changelog
 ================
 
+3.0.0 alpha 4 (2020-0?-??)
+==========================
+
+Features added
+--------------
+
+* The ``print`` statement (not the ``print()`` function) is allowed in
+  ``nogil`` code without an explicit ``with gil`` section.
+
+* The ``assert`` statement is allowed in ``nogil`` sections.  Here, the GIL is
+  only acquired if the ``AssertionError`` is really raised, which means that the
+  evaluation of the asserted condition only allows C expressions.
+
+* Cython generates C compiler branch hints for unlikely user defined if-clauses
+  in more cases, when they end up raising exceptions.
+
+Bugs fixed
+----------
+
+* Exception position reporting could run into race conditions on threaded code.
+  It now uses function-local variables again.
+
+* Error handling early in the module init code could lead to a crash.
+
+* The improved GIL handling in ``nogil`` functions introduced in 3.0a2
+  could generate invalid C code.
+  (Github issue #3558)
+
+
+3.0.0 alpha 3 (2020-04-27)
+==========================
+
+Features added
+--------------
+
+* ``nogil`` functions now avoid acquiring the GIL on function exit if possible
+  even if they contain ``with gil`` blocks.
+  (Github issue #3554)
+
+* Python private name mangling now falls back to unmangled names for non-Python
+  globals, since double-underscore names are not uncommon in C.  Unmangled Python
+  names are also still found as a legacy fallback but produce a warning.
+  Patch by David Woods.  (Github issue #3548)
+
+Bugs fixed
+----------
+
+* Includes all bug-fixes from the 0.29.17 release.
+
+
+3.0.0 alpha 2 (2020-04-23)
+==========================
+
+Features added
+--------------
+
+* ``std::move()`` is now used in C++ mode for internal temp variables to
+  make them work without copying values.
+  Patch by David Woods.  (Github issues #3253, 1612)
+
+* ``__class_getitem__`` is supported for types on item access (PEP-560).
+  Patch by msg555.  (Github issue #2753)
+
+* The simplified Py3.6 customisation of class creation is implemented (PEP-487).
+  (Github issue #2781)
+
+* Conditional blocks in Python code that depend on ``cython.compiled`` are
+  eliminated at an earlier stage, which gives more freedom in writing
+  replacement Python code.
+  Patch by David Woods.  (Github issue #3507)
+
+* ``numpy.import_array()`` is automatically called if ``numpy`` has been cimported
+  and it has not been called in the module code.  This is intended as a hidden
+  fail-safe so user code should continue to call ``numpy.import_array``.
+  Patch by David Woods.  (Github issue #3524)
+
+* The Cython AST code serialiser class ``CodeWriter`` in ``Cython.CodeWriter``
+  supports more syntax nodes.
+
+* The fastcall/vectorcall protocols are used for several internal Python calls.
+  (Github issue #3540)
+
+Bugs fixed
+----------
+
+* With ``language_level=3/3str``, Python classes without explicit base class
+  are now new-style (type) classes also in Py2.  Previously, they were created
+  as old-style (non-type) classes.
+  (Github issue #3530)
+
+* C++ ``typeid()`` failed for fused types.
+  Patch by David Woods.  (Github issue #3203)
+
+* ``__arg`` argument names in methods were not mangled with the class name.
+  Patch by David Woods.  (Github issue #1382)
+
+* Creating an empty unicode slice with large bounds could crash.
+  Patch by Sam Sneddon.  (Github issue #3531)
+
+* Decoding an empty bytes/char* slice with large bounds could crash.
+  Patch by Sam Sneddon.  (Github issue #3534)
+
+* Temporary buffer indexing variables were not released and could show up in
+  C compiler warnings, e.g. in generators.
+  Patch by David Woods.  (Github issues #3430, #3522)
+
+* Several C compiler warnings were fixed.
+
+
+3.0.0 alpha 1 (2020-04-12)
+==========================
+
+Features added
+--------------
+
+* Cython functions now use the PEP-590 vectorcall protocol in Py3.7+.
+  Patch by Jeroen Demeyer.  (Github issue #2263)
+
+* Unicode identifiers are supported in Cython code (PEP 3131).
+  Patch by David Woods.  (Github issue #2601)
+
+* Unicode module names and imports are supported.
+  Patch by David Woods.  (Github issue #3119)
+
+* Annotations are no longer parsed, keeping them as strings following PEP-563.
+  Patch by David Woods.  (Github issue #3285)
+
+* Preliminary support for the CPython's ``Py_LIMITED_API`` (stable ABI) is
+  available by setting the  ``CYTHON_LIMITED_API`` C macro.  Note that the
+  support is currently in an early stage and many features do not yet work.
+  Patches by Eddie Elizondo and David Woods.  (Github issues #3223, #3311, #3501)
+
+* The dispatch to fused functions is now linear in the number of arguments,
+  which makes it much faster, often 2x or more, and several times faster for
+  larger fused types with many specialisations.
+  Patch by will-ca.  (Github issue #1385)
+
+* ``with gil/nogil`` statements can be conditional based on compile-time
+  constants, e.g. fused type checks.
+  Patch by Noam Hershtig.  (Github issue #2579)
+
+* ``const`` can be used together with fused types.
+  Patch by Thomas Vincent.  (Github issue #1772)
+
+* Reimports of already imported modules are substantially faster.
+  (Github issue #2854)
+
+* Positional-only arguments are supported in Python functions.
+  Patch by Josh Tobin.  (Github issue #2915)
+
+* The ``volatile`` C modifier is supported in Cython code.
+  Patch by Jeroen Demeyer.  (Github issue #1667)
+
+* ``@cython.trashcan(True)`` can be used on an extension type to enable the
+  CPython trashcan. This allows deallocating deeply recursive objects without
+  overflowing the stack.  Patch by Jeroen Demeyer.  (Github issue #2842)
+
+* Inlined properties can be defined for external extension types.
+  Patch by Matti Picus.  (Github issue #2640)
+
+* The ``str()`` builtin now calls ``PyObject_Str()`` instead of going
+  through a Python call.
+  Patch by William Ayd.  (Github issue #3279)
+
+* String concatenation can now happen in place if possible, by extending the
+  existing string rather than always creating a new one.
+  Patch by David Woods.  (Github issue #3453)
+
+* Multiplication of Python numbers with small constant integers is faster.
+  (Github issue #2808)
+
+* Some list copying is avoided internally when a new list needs to be created
+  but we already have a fresh one.
+  (Github issue #3494)
+
+* Extension types that do not need their own ``tp_new`` implementation (because
+  they have no object attributes etc.) directly inherit the implementation of
+  their parent type if possible.
+  (Github issue #1555)
+
+* The attributes ``gen.gi_frame`` and ``coro.cr_frame`` of Cython compiled
+  generators and coroutines now return an actual frame object for introspection.
+  (Github issue #2306)
+
+* Several declarations in ``cpython.*``, ``libc.*`` and ``libcpp.*`` were added.
+  Patches by Jeroen Demeyer, Matthew Edwards, Chris Gyurgyik, Jerome Kieffer
+  and Zackery Spytz.
+  (Github issues #3468, #3332, #3202, #3188, #3179, #2891, #2826, #2713)
+
+* Deprecated NumPy API usages were removed from ``numpy.pxd``.
+  Patch by Matti Picus.  (Github issue #3365)
+
+* ``cython.inline()`` now sets the ``NPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION``
+  C macro automatically when ``numpy`` is imported in the code, to avoid C compiler
+  warnings about deprecated NumPy C-API usage.
+
+* The builtin ``abs()`` function can now be used on C numbers in nogil code.
+  Patch by Elliott Sales de Andrade.  (Github issue #2748)
+
+* PEP-479 (``generator_stop``) is now enabled by default with language level 3.
+  (Github issue #2580)
+
+* The ``cython.view.array`` type supports inheritance.
+  Patch by David Woods.  (Github issue #3413)
+
+* Code annotation accepts a new debugging argument ``--annotate-fullc`` that
+  will include the complete syntax highlighted C file in the HTML output.
+  (Github issue #2855)
+
+* ``--no-capture`` added to ``runtests.py`` to prevent stdout/stderr capturing
+  during srctree tests.
+  Patch by Matti Picus.  (Github issue #2701)
+
+* ``--no-docstrings`` option added to ``cythonize`` script.
+  Original patch by mo-han.  (Github issue #2889)
+
+* ``cygdb`` gives better error messages when it fails to initialise the
+  Python runtime support in gdb.
+  Patch by Volker Weissmann.  (Github issue #3489)
+
+* The Pythran ``shape`` attribute is supported.
+  Patch by Serge Guelton.  (Github issue #3307)
+
+Bugs fixed
+----------
+
+* The unicode methods ``.upper()``, ``.lower()`` and ``.title()`` were
+  incorrectly optimised for single character input values and only returned
+  the first character if multiple characters should have been returned.
+  They now use the original Python methods again.
+
+* Fused argument types were not correctly handled in type annotations and
+  ``cython.locals()``.
+  Patch by David Woods.  (Github issues #3391, #3142)
+
+* Diverging from the usual behaviour, ``len(memoryview)``, ``len(char*)``
+  and ``len(Py_UNICODE*)`` returned an unsigned ``size_t`` value.  They now
+  return a signed ``Py_ssize_t``, like other usages of ``len()``.
+
+* Nested dict literals in function call kwargs could incorrectly raise an
+  error about duplicate keyword arguments, which are allowed when passing
+  them from dict literals.
+  (Github issue #2963)
+
+* Item access (subscripting) with integer indices/keys always tried the
+  Sequence protocol before the Mapping protocol, which diverged from Python
+  semantics.  It now passes through the Mapping protocol first when supported.
+  (Github issue #1807)
+
+* Name lookups in class bodies no longer go through an attribute lookup.
+  Patch by Jeroen Demeyer.  (Github issue #3100)
+
+* Broadcast assignments to a multi-dimensional memory view slice could end
+  up in the wrong places when the underlying memory view is known to be
+  contiguous but the slice is not.
+  (Github issue #2941)
+
+* Pickling unbound methods of Python classes failed.
+  Patch by Pierre Glaser.  (Github issue #2972)
+
+* The ``Py_hash_t`` type failed to accept arbitrary "index" values.
+  (Github issue #2752)
+
+* The first function line number of functions with decorators pointed to the
+  signature line and not the first decorator line, as in Python.
+  Patch by Felix Kohlgrüber.  (Github issue #2536)
+
+* Constant integer expressions that used a negative exponent were evaluated
+  as integer 0 instead of the expected float value.
+  Patch by Kryštof Pilnáček.  (Github issue #2133)
+
+* The ``cython.declare()`` and ``cython.cast()`` functions could fail in pure mode.
+  Patch by Dmitry Shesterkin.  (Github issue #3244)
+
+* ``__doc__`` was not available inside of the class body during class creation.
+  (Github issue #1635)
+
+* Setting ``language_level=2`` in a file did not work if ``language_level=3``
+  was enabled globally before.
+  Patch by Jeroen Demeyer.  (Github issue #2791)
+
+* ``__init__.pyx`` files were not always considered as package indicators.
+  (Github issue #2665)
+
+* Compiling package ``__init__`` files could fail under Windows due to an
+  undefined export symbol.  (Github issue #2968)
+
+* A C compiler cast warning was resolved.
+  Patch by Michael Buesch.  (Github issue #2775)
+
+* Binding staticmethods of Cython functions were not behaving like Python methods.
+  Patch by Jeroen Demeyer.  (Github issue #3106, #3102)
+
+* Memoryviews failed to compile when the ``cache_builtins`` feature was disabled.
+  Patch by David Woods.  (Github issue #3406)
+
+Other changes
+-------------
+
+* The default language level was changed to ``3str``, i.e. Python 3 semantics,
+  but with ``str`` literals (also in Python 2.7).  This is a backwards incompatible
+  change from the previous default of Python 2 semantics.  The previous behaviour
+  is available through the directive ``language_level=2``.
+  (Github issue #2565)
+
+* Cython no longer generates ``__qualname__`` attributes for classes in Python
+  2.x since they are problematic there and not correctly maintained for subclasses.
+  Patch by Jeroen Demeyer.  (Github issue #2772)
+
+* Source file fingerprinting now uses SHA-1 instead of MD5 since the latter
+  tends to be slower and less widely supported these days.
+  (Github issue #2790)
+
+* The long deprecated include files ``python_*``, ``stdio``, ``stdlib`` and
+  ``stl`` in ``Cython/Includes/Deprecated/`` were removed.  Use the ``libc.*``
+  and ``cpython.*`` pxd modules instead.
+  Patch by Jeroen Demeyer.  (Github issue #2904)
+
+* The search order for include files was changed. Previously it was
+  ``include_directories``, ``Cython/Includes``, ``sys.path``. Now it is
+  ``include_directories``, ``sys.path``, ``Cython/Includes``. This was done to
+  allow third-party ``*.pxd`` files to override the ones in Cython.
+  Patch by Matti Picus.  (Github issue #2905)
+
+* The command line parser was rewritten and modernised using ``argparse``.
+  Patch by Egor Dranischnikow.  (Github issue #2952, #3001)
+
+* Dotted filenames for qualified module names (``pkg.mod.pyx``) are deprecated.
+  Use the normal Python package directory layout instead.
+  (Github issue #2686)
+
+* Binary Linux wheels now follow the manylinux2010 standard.
+  Patch by Alexey Stepanov.  (Github issue #3355)
+
+* Support for Python 2.6 was removed.
+
+
+0.29.18 (2020-0?-??)
+====================
+
+Bugs fixed
+----------
+
+* Exception position reporting could run into race conditions on threaded code.
+  It now uses function-local variables again.
+
+* Error handling early in the module init code could lead to a crash.
+
+* Error handling in ``cython.array`` creation was improved to avoid calling
+  C-API functions with and error held.
+
+* Complex buffer item types of structs of arrays could fail to validate.
+  Patch by Leo and smutch.  (Github issue #1407)
+
+* When importing the old Cython ``build_ext`` integration with distutils, the
+  additional command line arguments leaked into the regular command.
+  Patch by Kamekameha.  (Github issue #2209)
+
+
+0.29.17 (2020-04-26)
+====================
+
+Features added
+--------------
+
+* ``std::move()`` is now available from ``libcpp.utility``.
+  Patch by Omer Ozarslan.  (Github issue #2169)
+
+* The ``@cython.binding`` decorator is available in Python code.
+  (Github issue #3505)
+
+Bugs fixed
+----------
+
+* Creating an empty unicode slice with large bounds could crash.
+  Patch by Sam Sneddon.  (Github issue #3531)
+
+* Decoding an empty bytes/char* slice with large bounds could crash.
+  Patch by Sam Sneddon.  (Github issue #3534)
+
+* Re-importing a Cython extension no longer raises the error
+  "``__reduce_cython__ not found``".
+  (Github issue #3545)
+
+* Unused C-tuples could generate incorrect code in 0.29.16.
+  Patch by Kirk Meyer.  (Github issue #3543)
+
+* Creating a fused function attached it to the garbage collector before it
+  was fully initialised, thus risking crashes in rare failure cases.
+  Original patch by achernomorov.  (Github issue #3215)
+
+* Temporary buffer indexing variables were not released and could show up in
+  C compiler warnings, e.g. in generators.
+  Patch by David Woods.  (Github issues #3430, #3522)
+
+* The compilation cache in ``cython.inline("…")`` failed to take the language
+  level into account.
+  Patch by will-ca.  (Github issue #3419)
+
+* The deprecated ``PyUnicode_GET_SIZE()`` function is no longer used in Py3.
+
+
 0.29.16 (2020-03-24)
 ====================
 
@@ -134,7 +536,6 @@
 * The declaration of ``PyGILState_STATE`` in ``cpython.pystate`` was unusable.
   Patch by Kirill Smelkov.  (Github issue #2997)
 
-
 Other changes
 -------------
 
@@ -1168,7 +1569,7 @@
   Patch by Syrtis Major (Github issue #1625).
 
 * ``abs()`` is optimised for C complex numbers.
-  Patch by da-woods (Github issue #1648).
+  Patch by David Woods (Github issue #1648).
 
 * The display of C lines in Cython tracebacks can now be enabled at runtime
   via ``import cython_runtime; cython_runtime.cline_in_traceback=True``.
@@ -1179,7 +1580,7 @@
 * "cdef extern" include files are now also searched relative to the current file.
   Patch by Jeroen Demeyer (Github issue #1654).
 
-* Optional optimization for re-aquiring the GIL, controlled by the
+* Optional optimization for re-acquiring the GIL, controlled by the
   `fast_gil` directive.
 
 Bugs fixed
@@ -1297,7 +1698,7 @@
   Patch by Claudio Freire.
 
 * Buffer variables are no longer excluded from ``locals()``.
-  Patch by da-woods.
+  Patch by David Woods.
 
 * Building f-strings is faster, especially when formatting C integers.
 
@@ -1445,7 +1846,7 @@
 * Compile errors and warnings in integer type conversion code.  This fixes
   ticket 877.  Patches by Christian Neukirchen, Nikolaus Rath, Ian Henriksen.
 
-* Reference leak when "*args" argument was reassigned in closures.
+* Reference leak when ``*args`` argument was reassigned in closures.
 
 * Truth-testing Unicode strings could waste time and memory in Py3.3+.
 
@@ -1901,7 +2302,7 @@
 
 * Generators have new properties ``__name__`` and ``__qualname__``
   that provide the plain/qualified name of the generator function
-  (following CPython 3.5).  See http://bugs.python.org/issue21205
+  (following CPython 3.5).  See https://bugs.python.org/issue21205
 
 * The ``inline`` function modifier is available as a decorator
   ``@cython.inline`` in pure mode.
@@ -1947,7 +2348,7 @@
   evaluation and generally improves the code flow in the generated C code.
 
 * The Python expression "2 ** N" is optimised into bit shifting.
-  See http://bugs.python.org/issue21420
+  See https://bugs.python.org/issue21420
 
 * Cascaded assignments (a = b = ...) try to minimise the number of
   type coercions.
diff --git a/Cython/Build/Cythonize.py b/Cython/Build/Cythonize.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0J1aWxkL0N5dGhvbml6ZS5weQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0J1aWxkL0N5dGhvbml6ZS5weQ== 100644
--- a/Cython/Build/Cythonize.py
+++ b/Cython/Build/Cythonize.py
@@ -38,34 +38,5 @@
         pass
 
 
-def parse_directives(option, name, value, parser):
-    dest = option.dest
-    old_directives = dict(getattr(parser.values, dest,
-                                  Options.get_directive_defaults()))
-    directives = Options.parse_directive_list(
-        value, relaxed_bool=True, current_settings=old_directives)
-    setattr(parser.values, dest, directives)
-
-
-def parse_options(option, name, value, parser):
-    dest = option.dest
-    options = dict(getattr(parser.values, dest, {}))
-    for opt in value.split(','):
-        if '=' in opt:
-            n, v = opt.split('=', 1)
-            v = v.lower() not in ('false', 'f', '0', 'no')
-        else:
-            n, v = opt, True
-        options[n] = v
-    setattr(parser.values, dest, options)
-
-
-def parse_compile_time_env(option, name, value, parser):
-    dest = option.dest
-    old_env = dict(getattr(parser.values, dest, {}))
-    new_env = Options.parse_compile_time_env(value, current_settings=old_env)
-    setattr(parser.values, dest, new_env)
-
-
 def find_package_base(path):
     base_dir, package_path = os.path.split(path)
@@ -70,6 +41,6 @@
 def find_package_base(path):
     base_dir, package_path = os.path.split(path)
-    while os.path.isfile(os.path.join(base_dir, '__init__.py')):
+    while is_package_dir(base_dir):
         base_dir, parent = os.path.split(base_dir)
         package_path = '%s/%s' % (parent, package_path)
     return base_dir, package_path
@@ -148,7 +119,9 @@
                 shutil.rmtree(temp_dir)
 
 
-def parse_args(args):
-    from optparse import OptionParser
-    parser = OptionParser(usage='%prog [options] [sources and packages]+')
+def create_args_parser():
+    from argparse import ArgumentParser
+    from ..Compiler.CmdLine import ParseDirectivesAction, ParseOptionsAction, ParseCompileTimeEnvAction
+
+    parser = ArgumentParser()
 
@@ -154,5 +127,5 @@
 
-    parser.add_option('-X', '--directive', metavar='NAME=VALUE,...',
-                      dest='directives', default={}, type="str",
-                      action='callback', callback=parse_directives,
+    parser.add_argument('-X', '--directive', metavar='NAME=VALUE,...',
+                      dest='directives', default={}, type=str,
+                      action=ParseDirectivesAction,
                       help='set a compiler directive')
@@ -158,5 +131,5 @@
                       help='set a compiler directive')
-    parser.add_option('-E', '--compile-time-env', metavar='NAME=VALUE,...',
-                      dest='compile_time_env', default={}, type="str",
-                      action='callback', callback=parse_compile_time_env,
+    parser.add_argument('-E', '--compile-time-env', metavar='NAME=VALUE,...',
+                      dest='compile_time_env', default={}, type=str,
+                      action=ParseCompileTimeEnvAction,
                       help='set a compile time environment variable')
@@ -162,5 +135,5 @@
                       help='set a compile time environment variable')
-    parser.add_option('-s', '--option', metavar='NAME=VALUE',
-                      dest='options', default={}, type="str",
-                      action='callback', callback=parse_options,
+    parser.add_argument('-s', '--option', metavar='NAME=VALUE',
+                      dest='options', default={}, type=str,
+                      action=ParseOptionsAction,
                       help='set a cythonize option')
@@ -166,3 +139,3 @@
                       help='set a cythonize option')
-    parser.add_option('-2', dest='language_level', action='store_const', const=2, default=None,
+    parser.add_argument('-2', dest='language_level', action='store_const', const=2, default=None,
                       help='use Python 2 syntax mode by default')
@@ -168,3 +141,3 @@
                       help='use Python 2 syntax mode by default')
-    parser.add_option('-3', dest='language_level', action='store_const', const=3,
+    parser.add_argument('-3', dest='language_level', action='store_const', const=3,
                       help='use Python 3 syntax mode by default')
@@ -170,3 +143,3 @@
                       help='use Python 3 syntax mode by default')
-    parser.add_option('--3str', dest='language_level', action='store_const', const='3str',
+    parser.add_argument('--3str', dest='language_level', action='store_const', const='3str',
                       help='use Python 3 syntax mode by default')
@@ -172,8 +145,10 @@
                       help='use Python 3 syntax mode by default')
-    parser.add_option('-a', '--annotate', dest='annotate', action='store_true',
-                      help='generate annotated HTML page for source files')
-
-    parser.add_option('-x', '--exclude', metavar='PATTERN', dest='excludes',
+    parser.add_argument('-a', '--annotate', action='store_const', const='default', dest='annotate',
+                      help='Produce a colorized HTML version of the source.')
+    parser.add_argument('--annotate-fullc', action='store_const', const='fullc', dest='annotate',
+                      help='Produce a colorized HTML version of the source '
+                           'which includes entire generated C/C++-code.')
+    parser.add_argument('-x', '--exclude', metavar='PATTERN', dest='excludes',
                       action='append', default=[],
                       help='exclude certain file patterns from the compilation')
 
@@ -177,5 +152,5 @@
                       action='append', default=[],
                       help='exclude certain file patterns from the compilation')
 
-    parser.add_option('-b', '--build', dest='build', action='store_true',
+    parser.add_argument('-b', '--build', dest='build', action='store_true', default=None,
                       help='build extension modules using distutils')
@@ -181,3 +156,3 @@
                       help='build extension modules using distutils')
-    parser.add_option('-i', '--inplace', dest='build_inplace', action='store_true',
+    parser.add_argument('-i', '--inplace', dest='build_inplace', action='store_true', default=None,
                       help='build extension modules in place using distutils (implies -b)')
@@ -183,5 +158,5 @@
                       help='build extension modules in place using distutils (implies -b)')
-    parser.add_option('-j', '--parallel', dest='parallel', metavar='N',
+    parser.add_argument('-j', '--parallel', dest='parallel', metavar='N',
                       type=int, default=parallel_compiles,
                       help=('run builds in N parallel jobs (default: %d)' %
                             parallel_compiles or 1))
@@ -185,5 +160,5 @@
                       type=int, default=parallel_compiles,
                       help=('run builds in N parallel jobs (default: %d)' %
                             parallel_compiles or 1))
-    parser.add_option('-f', '--force', dest='force', action='store_true',
+    parser.add_argument('-f', '--force', dest='force', action='store_true', default=None,
                       help='force recompilation')
@@ -189,4 +164,4 @@
                       help='force recompilation')
-    parser.add_option('-q', '--quiet', dest='quiet', action='store_true',
+    parser.add_argument('-q', '--quiet', dest='quiet', action='store_true', default=None,
                       help='be less verbose during compilation')
 
@@ -191,4 +166,4 @@
                       help='be less verbose during compilation')
 
-    parser.add_option('--lenient', dest='lenient', action='store_true',
+    parser.add_argument('--lenient', dest='lenient', action='store_true', default=None,
                       help='increase Python compatibility by ignoring some compile time errors')
@@ -194,3 +169,3 @@
                       help='increase Python compatibility by ignoring some compile time errors')
-    parser.add_option('-k', '--keep-going', dest='keep_going', action='store_true',
+    parser.add_argument('-k', '--keep-going', dest='keep_going', action='store_true', default=None,
                       help='compile as much as possible, ignore compilation failures')
@@ -196,2 +171,6 @@
                       help='compile as much as possible, ignore compilation failures')
+    parser.add_argument('--no-docstrings', dest='no_docstrings', action='store_true', default=None,
+                      help='strip docstrings')
+    parser.add_argument('sources', nargs='*')
+    return parser
 
@@ -197,5 +176,23 @@
 
-    options, args = parser.parse_args(args)
+
+def parse_args_raw(parser, args):
+    options, unknown = parser.parse_known_args(args)
+    sources = options.sources
+    # if positional arguments were interspersed
+    # some of them are in unknown
+    for option in unknown:
+        if option.startswith('-'):
+            parser.error("unknown option "+option)
+        else:
+            sources.append(option)
+    del options.sources
+    return (options, sources)
+
+
+def parse_args(args):
+    parser = create_args_parser()
+    options, args = parse_args_raw(parser, args)
+
     if not args:
         parser.error("no source files provided")
     if options.build_inplace:
@@ -205,11 +202,6 @@
     if options.language_level:
         assert options.language_level in (2, 3, '3str')
         options.options['language_level'] = options.language_level
-    return options, args
-
-
-def main(args=None):
-    options, paths = parse_args(args)
 
     if options.lenient:
         # increase Python compatibility by ignoring compile time errors
@@ -217,7 +209,16 @@
         Options.error_on_uninitialized = False
 
     if options.annotate:
-        Options.annotate = True
+        Options.annotate = options.annotate
+
+    if options.no_docstrings:
+        Options.docstrings = False
+
+    return options, args
+
+
+def main(args=None):
+    options, paths = parse_args(args)
 
     for path in paths:
         cython_compile(path, options)
diff --git a/Cython/Build/Dependencies.py b/Cython/Build/Dependencies.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0J1aWxkL0RlcGVuZGVuY2llcy5weQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0J1aWxkL0RlcGVuZGVuY2llcy5weQ== 100644
--- a/Cython/Build/Dependencies.py
+++ b/Cython/Build/Dependencies.py
@@ -45,7 +45,8 @@
 from .. import Utils
 from ..Utils import (cached_function, cached_method, path_exists,
     safe_makedirs, copy_file_to_dir_if_newer, is_package_dir, replace_suffix)
-from ..Compiler.Main import Context, CompilationOptions, default_options
+from ..Compiler.Main import Context
+from ..Compiler.Options import CompilationOptions, default_options
 
 join_path = cached_function(os.path.join)
 copy_once_if_newer = cached_function(copy_file_to_dir_if_newer)
@@ -118,7 +119,7 @@
 def file_hash(filename):
     path = os.path.normpath(filename)
     prefix = ('%d:%s' % (len(path), path)).encode("UTF-8")
-    m = hashlib.md5(prefix)
+    m = hashlib.sha1(prefix)
     with open(path, 'rb') as f:
         data = f.read(65000)
         while data:
@@ -538,7 +539,7 @@
                 all.add(include_path)
                 all.update(self.included_files(include_path))
             elif not self.quiet:
-                print("Unable to locate '%s' referenced from '%s'" % (filename, include))
+                print(u"Unable to locate '%s' referenced from '%s'" % (filename, include))
         return all
 
     @cached_method
@@ -637,7 +638,7 @@
         incorporate everything that has an influence on the generated code.
         """
         try:
-            m = hashlib.md5(__version__.encode('UTF-8'))
+            m = hashlib.sha1(__version__.encode('UTF-8'))
             m.update(file_hash(filename).encode('UTF-8'))
             for x in sorted(self.all_dependencies(filename)):
                 if os.path.splitext(x)[1] not in ('.c', '.cpp', '.h'):
@@ -782,6 +783,8 @@
     create_extension = ctx.options.create_extension or default_create_extension
 
     for pattern in patterns:
+        if not isinstance(pattern, (Extension_distutils, Extension_setuptools)):
+            pattern = encode_filename_in_py2(pattern)
         if isinstance(pattern, str):
             filepattern = pattern
             template = Extension(pattern, [])  # Fake Extension without sources
@@ -794,9 +797,9 @@
             if cython_sources:
                 filepattern = cython_sources[0]
                 if len(cython_sources) > 1:
-                    print("Warning: Multiple cython sources found for extension '%s': %s\n"
-                          "See http://cython.readthedocs.io/en/latest/src/userguide/sharing_declarations.html "
-                          "for sharing declarations among Cython files." % (pattern.name, cython_sources))
+                    print(u"Warning: Multiple cython sources found for extension '%s': %s\n"
+                          u"See https://cython.readthedocs.io/en/latest/src/userguide/sharing_declarations.html "
+                          u"for sharing declarations among Cython files." % (pattern.name, cython_sources))
             else:
                 # ignore non-cython modules
                 module_list.append(pattern)
@@ -870,7 +873,7 @@
                         m.sources.remove(target_file)
                     except ValueError:
                         # never seen this in the wild, but probably better to warn about this unexpected case
-                        print("Warning: Cython source file not found in sources list, adding %s" % file)
+                        print(u"Warning: Cython source file not found in sources list, adding %s" % file)
                     m.sources.insert(0, file)
                 seen.add(name)
     return module_list, module_metadata
@@ -960,7 +963,7 @@
 
     c_options = CompilationOptions(**options)
     cpp_options = CompilationOptions(**options); cpp_options.cplus = True
-    ctx = c_options.create_context()
+    ctx = Context.from_options(c_options)
     options = c_options
     module_list, module_metadata = create_extension_list(
         module_list,
@@ -970,6 +973,9 @@
         exclude_failures=exclude_failures,
         language=language,
         aliases=aliases)
+
+    fix_windows_unicode_modules(module_list)
+
     deps = create_dependency_tree(ctx, quiet=quiet)
     build_dir = getattr(options, 'build_dir', None)
 
@@ -1038,5 +1044,5 @@
                 if force or c_timestamp < dep_timestamp:
                     if not quiet and not force:
                         if source == dep:
-                            print("Compiling %s because it changed." % source)
+                            print(u"Compiling %s because it changed." % Utils.decode_filename(source))
                         else:
@@ -1042,5 +1048,8 @@
                         else:
-                            print("Compiling %s because it depends on %s." % (source, dep))
+                            print(u"Compiling %s because it depends on %s." % (
+                                Utils.decode_filename(source),
+                                Utils.decode_filename(dep),
+                            ))
                     if not force and options.cache:
                         fingerprint = deps.transitive_fingerprint(source, m, options)
                     else:
@@ -1072,5 +1081,11 @@
     if N <= 1:
         nthreads = 0
     if nthreads:
-        # Requires multiprocessing (or Python >= 2.6)
+        import multiprocessing
+        pool = multiprocessing.Pool(
+            nthreads, initializer=_init_multiprocessing_helper)
+        # This is a bit more involved than it should be, because KeyboardInterrupts
+        # break the multiprocessing workers when using a normal pool.map().
+        # See, for example:
+        # https://noswap.com/blog/python-multiprocessing-keyboardinterrupt
         try:
@@ -1076,27 +1091,15 @@
         try:
-            import multiprocessing
-            pool = multiprocessing.Pool(
-                nthreads, initializer=_init_multiprocessing_helper)
-        except (ImportError, OSError):
-            print("multiprocessing required for parallel cythonization")
-            nthreads = 0
-        else:
-            # This is a bit more involved than it should be, because KeyboardInterrupts
-            # break the multiprocessing workers when using a normal pool.map().
-            # See, for example:
-            # http://noswap.com/blog/python-multiprocessing-keyboardinterrupt
-            try:
-                result = pool.map_async(cythonize_one_helper, to_compile, chunksize=1)
-                pool.close()
-                while not result.ready():
-                    try:
-                        result.get(99999)  # seconds
-                    except multiprocessing.TimeoutError:
-                        pass
-            except KeyboardInterrupt:
-                pool.terminate()
-                raise
-            pool.join()
+            result = pool.map_async(cythonize_one_helper, to_compile, chunksize=1)
+            pool.close()
+            while not result.ready():
+                try:
+                    result.get(99999)  # seconds
+                except multiprocessing.TimeoutError:
+                    pass
+        except KeyboardInterrupt:
+            pool.terminate()
+            raise
+        pool.join()
     if not nthreads:
         for args in to_compile:
             cythonize_one(*args)
@@ -1117,7 +1120,7 @@
         if failed_modules:
             for module in failed_modules:
                 module_list.remove(module)
-            print("Failed compilations: %s" % ', '.join(sorted([
+            print(u"Failed compilations: %s" % ', '.join(sorted([
                 module.name for module in failed_modules])))
 
     if options.cache:
@@ -1128,6 +1131,41 @@
     return module_list
 
 
+def fix_windows_unicode_modules(module_list):
+    # Hack around a distutils 3.[5678] bug on Windows for unicode module names.
+    # https://bugs.python.org/issue39432
+    if sys.platform != "win32":
+        return
+    if sys.version_info < (3, 5) or sys.version_info >= (3, 8, 2):
+        return
+
+    def make_filtered_list(ignored_symbol, old_entries):
+        class FilteredExportSymbols(list):
+            # export_symbols for unicode filename cause link errors on Windows
+            # Cython doesn't need them (it already defines PyInit with the correct linkage)
+            # so use this class as a temporary fix to stop them from being generated
+            def __contains__(self, val):
+                # so distutils doesn't "helpfully" add PyInit_<name>
+                return val == ignored_symbol or list.__contains__(self, val)
+
+        filtered_list = FilteredExportSymbols(old_entries)
+        if old_entries:
+            filtered_list.extend(name for name in old_entries if name != ignored_symbol)
+        return filtered_list
+
+    for m in module_list:
+        # TODO: use m.name.isascii() in Py3.7+
+        try:
+            m.name.encode("ascii")
+            continue
+        except UnicodeEncodeError:
+            pass
+        m.export_symbols = make_filtered_list(
+            "PyInit_" + m.name.rsplit(".", 1)[-1],
+            m.export_symbols,
+        )
+
+
 if os.environ.get('XML_RESULTS'):
     compile_result_dir = os.environ['XML_RESULTS']
     def record_results(func):
@@ -1183,7 +1221,7 @@
         zip_fingerprint_file = fingerprint_file_base + '.zip'
         if os.path.exists(gz_fingerprint_file) or os.path.exists(zip_fingerprint_file):
             if not quiet:
-                print("%sFound compiled %s in cache" % (progress, pyx_file))
+                print(u"%sFound compiled %s in cache" % (progress, pyx_file))
             if os.path.exists(gz_fingerprint_file):
                 os.utime(gz_fingerprint_file, None)
                 with contextlib.closing(gzip_open(gz_fingerprint_file, 'rb')) as g:
@@ -1197,7 +1235,7 @@
                         z.extract(artifact, os.path.join(dirname, artifact))
             return
     if not quiet:
-        print("%sCythonizing %s" % (progress, pyx_file))
+        print(u"%sCythonizing %s" % (progress, Utils.decode_filename(pyx_file)))
     if options is None:
         options = CompilationOptions(default_options)
     options.output_file = c_file
@@ -1261,5 +1299,6 @@
 def cleanup_cache(cache, target_size, ratio=.85):
     try:
         p = subprocess.Popen(['du', '-s', '-k', os.path.abspath(cache)], stdout=subprocess.PIPE)
+        stdout, _ = p.communicate()
         res = p.wait()
         if res == 0:
@@ -1264,6 +1303,6 @@
         res = p.wait()
         if res == 0:
-            total_size = 1024 * int(p.stdout.read().strip().split()[0])
+            total_size = 1024 * int(stdout.strip().split()[0])
             if total_size < target_size:
                 return
     except (OSError, ValueError):
diff --git a/Cython/Build/Inline.py b/Cython/Build/Inline.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0J1aWxkL0lubGluZS5weQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0J1aWxkL0lubGluZS5weQ== 100644
--- a/Cython/Build/Inline.py
+++ b/Cython/Build/Inline.py
@@ -1,14 +1,12 @@
 from __future__ import absolute_import
 
-import sys, os, re, inspect
-import imp
-
-try:
-    import hashlib
-except ImportError:
-    import md5 as hashlib
+import hashlib
+import inspect
+import os
+import re
+import sys
 
 from distutils.core import Distribution, Extension
 from distutils.command.build_ext import build_ext
 
 import Cython
@@ -10,7 +8,8 @@
 
 from distutils.core import Distribution, Extension
 from distutils.command.build_ext import build_ext
 
 import Cython
-from ..Compiler.Main import Context, CompilationOptions, default_options
+from ..Compiler.Main import Context
+from ..Compiler.Options import default_options
 
@@ -16,6 +15,5 @@
 
-from ..Compiler.ParseTreeTransforms import (CythonTransform,
-        SkipDeclarations, AnalyseDeclarationsTransform, EnvTransform)
+from ..Compiler.ParseTreeTransforms import CythonTransform, SkipDeclarations, EnvTransform
 from ..Compiler.TreeFragment import parse_from_strings
 from ..Compiler.StringEncoding import _unicode
 from .Dependencies import strip_string_literals, cythonize, cached_function
@@ -19,7 +17,7 @@
 from ..Compiler.TreeFragment import parse_from_strings
 from ..Compiler.StringEncoding import _unicode
 from .Dependencies import strip_string_literals, cythonize, cached_function
-from ..Compiler import Pipeline, Nodes
+from ..Compiler import Pipeline
 from ..Utils import get_cython_cache_dir
 import cython as cython_module
 
@@ -23,6 +21,7 @@
 from ..Utils import get_cython_cache_dir
 import cython as cython_module
 
-IS_PY3 = sys.version_info >= (3, 0)
+
+IS_PY3 = sys.version_info >= (3,)
 
 # A utility function to convert user-supplied ASCII strings to unicode.
@@ -27,6 +26,6 @@
 
 # A utility function to convert user-supplied ASCII strings to unicode.
-if sys.version_info[0] < 3:
+if not IS_PY3:
     def to_unicode(s):
         if isinstance(s, bytes):
             return s.decode('ascii')
@@ -35,8 +34,9 @@
 else:
     to_unicode = lambda x: x
 
-if sys.version_info[:2] < (3, 3):
+
+if sys.version_info < (3, 5):
     import imp
     def load_dynamic(name, module_path):
         return imp.load_dynamic(name, module_path)
 else:
@@ -39,6 +39,6 @@
     import imp
     def load_dynamic(name, module_path):
         return imp.load_dynamic(name, module_path)
 else:
-    from importlib.machinery import ExtensionFileLoader
+    import importlib.util as _importlib_util
     def load_dynamic(name, module_path):
@@ -44,5 +44,10 @@
     def load_dynamic(name, module_path):
-        return ExtensionFileLoader(name, module_path).load_module()
+        spec = _importlib_util.spec_from_file_location(name, module_path)
+        module = _importlib_util.module_from_spec(spec)
+        # sys.modules[name] = module
+        spec.loader.exec_module(module)
+        return module
+
 
 class UnboundSymbols(EnvTransform, SkipDeclarations):
     def __init__(self):
@@ -128,6 +133,7 @@
 _cython_inline_cache = {}
 _cython_inline_default_context = _create_context(('.',))
 
+
 def _populate_unbound(kwds, unbound_symbols, locals=None, globals=None):
     for symbol in unbound_symbols:
         if symbol not in kwds:
@@ -144,6 +150,12 @@
             else:
                 print("Couldn't find %r" % symbol)
 
+
+def _inline_key(orig_code, arg_sigs, language_level):
+    key = orig_code, arg_sigs, sys.version_info, sys.executable, language_level, Cython.__version__
+    return hashlib.sha1(_unicode(key).encode('utf-8')).hexdigest()
+
+
 def cython_inline(code, get_type=unsafe_type,
                   lib_dir=os.path.join(get_cython_cache_dir(), 'inline'),
                   cython_include_dirs=None, cython_compiler_directives=None,
@@ -153,9 +165,17 @@
         get_type = lambda x: 'object'
     ctx = _create_context(tuple(cython_include_dirs)) if cython_include_dirs else _cython_inline_default_context
 
+    cython_compiler_directives = dict(cython_compiler_directives) if cython_compiler_directives else {}
+    if language_level is None and 'language_level' not in cython_compiler_directives:
+        language_level = '3str'
+    if language_level is not None:
+        cython_compiler_directives['language_level'] = language_level
+
+    key_hash = None
+
     # Fast path if this has been called in this session.
     _unbound_symbols = _cython_inline_cache.get(code)
     if _unbound_symbols is not None:
         _populate_unbound(kwds, _unbound_symbols, locals, globals)
         args = sorted(kwds.items())
         arg_sigs = tuple([(get_type(value, ctx), arg) for arg, value in args])
@@ -156,10 +176,11 @@
     # Fast path if this has been called in this session.
     _unbound_symbols = _cython_inline_cache.get(code)
     if _unbound_symbols is not None:
         _populate_unbound(kwds, _unbound_symbols, locals, globals)
         args = sorted(kwds.items())
         arg_sigs = tuple([(get_type(value, ctx), arg) for arg, value in args])
-        invoke = _cython_inline_cache.get((code, arg_sigs))
+        key_hash = _inline_key(code, arg_sigs, language_level)
+        invoke = _cython_inline_cache.get((code, arg_sigs, key_hash))
         if invoke is not None:
             arg_list = [arg[1] for arg in args]
             return invoke(*arg_list)
@@ -180,10 +201,6 @@
             # Parsing from strings not fully supported (e.g. cimports).
             print("Could not parse code as a string (to extract unbound symbols).")
 
-    cython_compiler_directives = dict(cython_compiler_directives or {})
-    if language_level is not None:
-        cython_compiler_directives['language_level'] = language_level
-
     cimports = []
     for name, arg in list(kwds.items()):
         if arg is cython_module:
@@ -191,8 +208,9 @@
             del kwds[name]
     arg_names = sorted(kwds)
     arg_sigs = tuple([(get_type(kwds[arg], ctx), arg) for arg in arg_names])
-    key = orig_code, arg_sigs, sys.version_info, sys.executable, language_level, Cython.__version__
-    module_name = "_cython_inline_" + hashlib.md5(_unicode(key).encode('utf-8')).hexdigest()
+    if key_hash is None:
+        key_hash = _inline_key(orig_code, arg_sigs, language_level)
+    module_name = "_cython_inline_" + key_hash
 
     if module_name in sys.modules:
         module = sys.modules[module_name]
@@ -210,6 +228,7 @@
             os.makedirs(lib_dir)
         if force or not os.path.isfile(module_path):
             cflags = []
+            define_macros = []
             c_include_dirs = []
             qualified = re.compile(r'([.\w]+)[.]')
             for type, _ in arg_sigs:
@@ -220,6 +239,7 @@
                     if m.groups()[0] == 'numpy':
                         import numpy
                         c_include_dirs.append(numpy.get_include())
+                        define_macros.append(("NPY_NO_DEPRECATED_API", "NPY_1_7_API_VERSION"))
                         # cflags.append('-Wno-unused')
             module_body, func_body = extract_func_code(code)
             params = ', '.join(['%s %s' % a for a in arg_sigs])
@@ -242,10 +262,12 @@
             finally:
                 fh.close()
             extension = Extension(
-                name = module_name,
-                sources = [pyx_file],
-                include_dirs = c_include_dirs,
-                extra_compile_args = cflags)
+                name=module_name,
+                sources=[pyx_file],
+                include_dirs=c_include_dirs or None,
+                extra_compile_args=cflags or None,
+                define_macros=define_macros or None,
+            )
             if build_extension is None:
                 build_extension = _get_build_extension()
             build_extension.extensions = cythonize(
@@ -259,7 +281,7 @@
 
         module = load_dynamic(module_name, module_path)
 
-    _cython_inline_cache[orig_code, arg_sigs] = module.__invoke
+    _cython_inline_cache[orig_code, arg_sigs, key_hash] = module.__invoke
     arg_list = [kwds[arg] for arg in arg_names]
     return module.__invoke(*arg_list)
 
@@ -263,6 +285,7 @@
     arg_list = [kwds[arg] for arg in arg_names]
     return module.__invoke(*arg_list)
 
+
 # Cached suffix used by cython_inline above.  None should get
 # overridden with actual value upon the first cython_inline invocation
 cython_inline.so_ext = None
@@ -307,37 +330,6 @@
     return '\n'.join(module), '    ' + '\n    '.join(function)
 
 
-try:
-    from inspect import getcallargs
-except ImportError:
-    def getcallargs(func, *arg_values, **kwd_values):
-        all = {}
-        args, varargs, kwds, defaults = inspect.getargspec(func)
-        if varargs is not None:
-            all[varargs] = arg_values[len(args):]
-        for name, value in zip(args, arg_values):
-            all[name] = value
-        for name, value in list(kwd_values.items()):
-            if name in args:
-                if name in all:
-                    raise TypeError("Duplicate argument %s" % name)
-                all[name] = kwd_values.pop(name)
-        if kwds is not None:
-            all[kwds] = kwd_values
-        elif kwd_values:
-            raise TypeError("Unexpected keyword arguments: %s" % list(kwd_values))
-        if defaults is None:
-            defaults = ()
-        first_default = len(args) - len(defaults)
-        for ix, name in enumerate(args):
-            if name not in all:
-                if ix >= first_default:
-                    all[name] = defaults[ix - first_default]
-                else:
-                    raise TypeError("Missing argument: %s" % name)
-        return all
-
-
 def get_body(source):
     ix = source.index(':')
     if source[:5] == 'lambda':
@@ -355,7 +347,7 @@
         self._body = get_body(inspect.getsource(f))
 
     def __call__(self, *args, **kwds):
-        all = getcallargs(self._f, *args, **kwds)
+        all = inspect.getcallargs(self._f, *args, **kwds)
         if IS_PY3:
             return cython_inline(self._body, locals=self._f.__globals__, globals=self._f.__globals__, **all)
         else:
diff --git a/Cython/Build/IpythonMagic.py b/Cython/Build/IpythonMagic.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0J1aWxkL0lweXRob25NYWdpYy5weQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0J1aWxkL0lweXRob25NYWdpYy5weQ== 100644
--- a/Cython/Build/IpythonMagic.py
+++ b/Cython/Build/IpythonMagic.py
@@ -60,7 +60,7 @@
 IS_PY2 = sys.version_info[0] < 3
 
 try:
-    reload
-except NameError:   # Python 3
-    from imp import reload
+    from importlib import reload
+except ImportError:   # Python 2 had a builtin function
+    pass
 
@@ -66,9 +66,5 @@
 
-try:
-    import hashlib
-except ImportError:
-    import md5 as hashlib
-
+import hashlib
 from distutils.core import Distribution, Extension
 from distutils.command.build_ext import build_ext
 
@@ -192,7 +188,7 @@
 
     @magic_arguments.magic_arguments()
     @magic_arguments.argument(
-        '-a', '--annotate', action='store_true', default=False,
+        '-a', '--annotate', action='store_const', const='default', dest='annotate',
         help="Produce a colorized HTML version of the source."
     )
     @magic_arguments.argument(
@@ -196,6 +192,11 @@
         help="Produce a colorized HTML version of the source."
     )
     @magic_arguments.argument(
+        '--annotate-fullc', action='store_const', const='fullc', dest='annotate',
+        help="Produce a colorized HTML version of the source "
+             "which includes entire generated C/C++-code."
+    )
+    @magic_arguments.argument(
         '-+', '--cplus', action='store_true', default=False,
         help="Output a C++ rather than C file."
     )
@@ -317,7 +318,7 @@
         if args.name:
             module_name = str(args.name)  # no-op in Py3
         else:
-            module_name = "_cython_magic_" + hashlib.md5(str(key).encode('utf-8')).hexdigest()
+            module_name = "_cython_magic_" + hashlib.sha1(str(key).encode('utf-8')).hexdigest()
         html_file = os.path.join(lib_dir, module_name + '.html')
         module_path = os.path.join(lib_dir, module_name + self.so_ext)
 
@@ -439,7 +440,8 @@
                 quiet=quiet,
                 annotate=args.annotate,
                 force=True,
+                language_level=min(3, sys.version_info[0]),
             )
             if args.language_level is not None:
                 assert args.language_level in (2, 3)
                 opts['language_level'] = args.language_level
@@ -442,9 +444,7 @@
             )
             if args.language_level is not None:
                 assert args.language_level in (2, 3)
                 opts['language_level'] = args.language_level
-            elif sys.version_info[0] >= 3:
-                opts['language_level'] = 3
             return cythonize([extension], **opts)
         except CompileError:
             return None
diff --git a/Cython/Build/Tests/TestCyCache.py b/Cython/Build/Tests/TestCyCache.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0J1aWxkL1Rlc3RzL1Rlc3RDeUNhY2hlLnB5..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0J1aWxkL1Rlc3RzL1Rlc3RDeUNhY2hlLnB5 100644
--- a/Cython/Build/Tests/TestCyCache.py
+++ b/Cython/Build/Tests/TestCyCache.py
@@ -33,7 +33,8 @@
         a_pyx = os.path.join(self.src_dir, 'a.pyx')
         a_c = a_pyx[:-4] + '.c'
 
-        open(a_pyx, 'w').write(content1)
+        with open(a_pyx, 'w') as f:
+            f.write(content1)
         self.fresh_cythonize(a_pyx, cache=self.cache_dir)
         self.fresh_cythonize(a_pyx, cache=self.cache_dir)
         self.assertEqual(1, len(self.cache_files('a.c*')))
@@ -37,6 +38,7 @@
         self.fresh_cythonize(a_pyx, cache=self.cache_dir)
         self.fresh_cythonize(a_pyx, cache=self.cache_dir)
         self.assertEqual(1, len(self.cache_files('a.c*')))
-        a_contents1 = open(a_c).read()
+        with open(a_c) as f:
+            a_contents1 = f.read()
         os.unlink(a_c)
 
@@ -41,4 +43,5 @@
         os.unlink(a_c)
 
-        open(a_pyx, 'w').write(content2)
+        with open(a_pyx, 'w') as f:
+            f.write(content2)
         self.fresh_cythonize(a_pyx, cache=self.cache_dir)
@@ -44,7 +47,8 @@
         self.fresh_cythonize(a_pyx, cache=self.cache_dir)
-        a_contents2 = open(a_c).read()
+        with open(a_c) as f:
+            a_contents2 = f.read()
         os.unlink(a_c)
 
         self.assertNotEqual(a_contents1, a_contents2, 'C file not changed!')
         self.assertEqual(2, len(self.cache_files('a.c*')))
 
@@ -46,8 +50,9 @@
         os.unlink(a_c)
 
         self.assertNotEqual(a_contents1, a_contents2, 'C file not changed!')
         self.assertEqual(2, len(self.cache_files('a.c*')))
 
-        open(a_pyx, 'w').write(content1)
+        with open(a_pyx, 'w') as f:
+            f.write(content1)
         self.fresh_cythonize(a_pyx, cache=self.cache_dir)
         self.assertEqual(2, len(self.cache_files('a.c*')))
@@ -52,6 +57,7 @@
         self.fresh_cythonize(a_pyx, cache=self.cache_dir)
         self.assertEqual(2, len(self.cache_files('a.c*')))
-        a_contents = open(a_c).read()
+        with open(a_c) as f:
+            a_contents = f.read()
         self.assertEqual(
             a_contents, a_contents1,
             msg='\n'.join(list(difflib.unified_diff(
@@ -60,9 +66,10 @@
     def test_cycache_uses_cache(self):
         a_pyx = os.path.join(self.src_dir, 'a.pyx')
         a_c = a_pyx[:-4] + '.c'
-        open(a_pyx, 'w').write('pass')
+        with open(a_pyx, 'w') as f:
+            f.write('pass')
         self.fresh_cythonize(a_pyx, cache=self.cache_dir)
         a_cache = os.path.join(self.cache_dir, os.listdir(self.cache_dir)[0])
         gzip.GzipFile(a_cache, 'wb').write('fake stuff'.encode('ascii'))
         os.unlink(a_c)
         self.fresh_cythonize(a_pyx, cache=self.cache_dir)
@@ -64,9 +71,10 @@
         self.fresh_cythonize(a_pyx, cache=self.cache_dir)
         a_cache = os.path.join(self.cache_dir, os.listdir(self.cache_dir)[0])
         gzip.GzipFile(a_cache, 'wb').write('fake stuff'.encode('ascii'))
         os.unlink(a_c)
         self.fresh_cythonize(a_pyx, cache=self.cache_dir)
-        a_contents = open(a_c).read()
+        with open(a_c) as f:
+            a_contents = f.read()
         self.assertEqual(a_contents, 'fake stuff',
                          'Unexpected contents: %s...' % a_contents[:100])
 
@@ -75,7 +83,8 @@
         a_c = a_pyx[:-4] + '.c'
         a_h = a_pyx[:-4] + '.h'
         a_api_h = a_pyx[:-4] + '_api.h'
-        open(a_pyx, 'w').write('cdef public api int foo(int x): return x\n')
+        with open(a_pyx, 'w') as f:
+            f.write('cdef public api int foo(int x): return x\n')
         self.fresh_cythonize(a_pyx, cache=self.cache_dir)
         expected = [a_c, a_h, a_api_h]
         for output in expected:
@@ -89,7 +98,8 @@
         hash_pyx = os.path.join(self.src_dir, 'options.pyx')
         hash_c = hash_pyx[:-len('.pyx')] + '.c'
 
-        open(hash_pyx, 'w').write('pass')
+        with open(hash_pyx, 'w') as f:
+            f.write('pass')
         self.fresh_cythonize(hash_pyx, cache=self.cache_dir, cplus=False)
         self.assertEqual(1, len(self.cache_files('options.c*')))
 
diff --git a/Cython/Build/Tests/TestCythonizeArgsParser.py b/Cython/Build/Tests/TestCythonizeArgsParser.py
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0J1aWxkL1Rlc3RzL1Rlc3RDeXRob25pemVBcmdzUGFyc2VyLnB5
--- /dev/null
+++ b/Cython/Build/Tests/TestCythonizeArgsParser.py
@@ -0,0 +1,482 @@
+from Cython.Build.Cythonize import (
+    create_args_parser, parse_args_raw, parse_args,
+    parallel_compiles
+)
+
+from Cython.Compiler import Options
+from Cython.Compiler.Tests.Utils import backup_Options, restore_Options, check_global_options
+
+from unittest import TestCase
+
+import sys
+try:
+    from StringIO import StringIO
+except ImportError:
+    from io import StringIO  # doesn't accept 'str' in Py2
+
+
+class TestCythonizeArgsParser(TestCase):
+
+    def setUp(self):
+        TestCase.setUp(self)
+        self.parse_args = lambda x, parser=create_args_parser() : parse_args_raw(parser, x)
+
+
+    def are_default(self, options, skip):
+        # empty containers
+        empty_containers = ['directives', 'compile_time_env', 'options', 'excludes']
+        are_none = ['language_level', 'annotate', 'build', 'build_inplace', 'force', 'quiet', 'lenient', 'keep_going', 'no_docstrings']
+        for opt_name in empty_containers:
+            if len(getattr(options, opt_name))!=0 and (not opt_name in skip):
+                self.assertEqual(opt_name,"", msg="For option "+opt_name)
+                return False
+        for opt_name in are_none:
+            if (getattr(options, opt_name) is not None) and (not opt_name in skip):
+                self.assertEqual(opt_name,"", msg="For option "+opt_name)
+                return False
+        if options.parallel!=parallel_compiles and (not 'parallel' in skip):
+            return False
+        return True
+
+    # testing directives:
+    def test_directive_short(self):
+        options, args =  self.parse_args(['-X', 'cdivision=True'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['directives']))
+        self.assertEqual(options.directives['cdivision'], True)
+
+    def test_directive_long(self):
+        options, args =  self.parse_args(['--directive', 'cdivision=True'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['directives']))
+        self.assertEqual(options.directives['cdivision'], True)
+
+    def test_directive_multiple(self):
+        options, args =  self.parse_args(['-X', 'cdivision=True', '-X', 'c_string_type=bytes'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['directives']))
+        self.assertEqual(options.directives['cdivision'], True)
+        self.assertEqual(options.directives['c_string_type'], 'bytes')
+
+    def test_directive_multiple_v2(self):
+        options, args =  self.parse_args(['-X', 'cdivision=True,c_string_type=bytes'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['directives']))
+        self.assertEqual(options.directives['cdivision'], True)
+        self.assertEqual(options.directives['c_string_type'], 'bytes')
+
+    def test_directive_value_yes(self):
+        options, args =  self.parse_args(['-X', 'cdivision=YeS'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['directives']))
+        self.assertEqual(options.directives['cdivision'], True)
+
+    def test_directive_value_no(self):
+        options, args =  self.parse_args(['-X', 'cdivision=no'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['directives']))
+        self.assertEqual(options.directives['cdivision'], False)
+
+    def test_directive_value_invalid(self):
+        with self.assertRaises(ValueError) as context:
+            options, args =  self.parse_args(['-X', 'cdivision=sadfasd'])
+
+    def test_directive_key_invalid(self):
+        with self.assertRaises(ValueError) as context:
+            options, args =  self.parse_args(['-X', 'abracadabra'])
+
+    def test_directive_no_value(self):
+        with self.assertRaises(ValueError) as context:
+            options, args =  self.parse_args(['-X', 'cdivision'])
+
+    def test_directives_types(self):
+        directives = {
+                'auto_pickle': True,
+                'c_string_type': 'bytearray',
+                'c_string_type': 'bytes',
+                'c_string_type': 'str',
+                'c_string_type': 'bytearray',
+                'c_string_type': 'unicode',
+                'c_string_encoding' : 'ascii',
+                'language_level' : 2,
+                'language_level' : 3,
+                'language_level' : '3str',
+                'set_initial_path' : 'my_initial_path',
+        }
+        for key, value in directives.items():
+            cmd = '{key}={value}'.format(key=key, value=str(value))
+            options, args =  self.parse_args(['-X', cmd])
+            self.assertFalse(args)
+            self.assertTrue(self.are_default(options, ['directives']), msg = "Error for option: "+cmd)
+            self.assertEqual(options.directives[key], value, msg = "Error for option: "+cmd)
+
+    def test_directives_wrong(self):
+        directives = {
+                'auto_pickle': 42,       # for bool type
+                'auto_pickle': 'NONONO', # for bool type
+                'c_string_type': 'bites',
+                #'c_string_encoding' : 'a',
+                #'language_level' : 4,
+        }
+        for key, value in directives.items():
+            cmd = '{key}={value}'.format(key=key, value=str(value))
+            with self.assertRaises(ValueError, msg = "Error for option: "+cmd) as context:
+                options, args =  self.parse_args(['-X', cmd])
+
+    def test_compile_time_env_short(self):
+        options, args =  self.parse_args(['-E', 'MYSIZE=10'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['compile_time_env']))
+        self.assertEqual(options.compile_time_env['MYSIZE'], 10)
+
+    def test_compile_time_env_long(self):
+        options, args =  self.parse_args(['--compile-time-env', 'MYSIZE=10'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['compile_time_env']))
+        self.assertEqual(options.compile_time_env['MYSIZE'], 10)
+
+    def test_compile_time_env_multiple(self):
+        options, args =  self.parse_args(['-E', 'MYSIZE=10', '-E', 'ARRSIZE=11'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['compile_time_env']))
+        self.assertEqual(options.compile_time_env['MYSIZE'], 10)
+        self.assertEqual(options.compile_time_env['ARRSIZE'], 11)
+
+    def test_compile_time_env_multiple_v2(self):
+        options, args =  self.parse_args(['-E', 'MYSIZE=10,ARRSIZE=11'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['compile_time_env']))
+        self.assertEqual(options.compile_time_env['MYSIZE'], 10)
+        self.assertEqual(options.compile_time_env['ARRSIZE'], 11)
+
+    #testing options
+    def test_option_short(self):
+        options, args =  self.parse_args(['-s', 'docstrings=True'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['options']))
+        self.assertEqual(options.options['docstrings'], True)
+
+    def test_option_long(self):
+        options, args =  self.parse_args(['--option', 'docstrings=True'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['options']))
+        self.assertEqual(options.options['docstrings'], True)
+
+    def test_option_multiple(self):
+        options, args =  self.parse_args(['-s', 'docstrings=True', '-s', 'buffer_max_dims=8'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['options']))
+        self.assertEqual(options.options['docstrings'], True)
+        self.assertEqual(options.options['buffer_max_dims'], True) #  really?
+
+    def test_option_multiple_v2(self):
+        options, args =  self.parse_args(['-s', 'docstrings=True,buffer_max_dims=8'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['options']))
+        self.assertEqual(options.options['docstrings'], True)
+        self.assertEqual(options.options['buffer_max_dims'], True) #  really?
+
+    def test_option_value_yes(self):
+        options, args =  self.parse_args(['-s', 'docstrings=YeS'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['options']))
+        self.assertEqual(options.options['docstrings'], True)
+
+    def test_option_value_4242(self):
+        options, args =  self.parse_args(['-s', 'docstrings=4242'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['options']))
+        self.assertEqual(options.options['docstrings'], True)
+
+    def test_option_value_0(self):
+        options, args =  self.parse_args(['-s', 'docstrings=0'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['options']))
+        self.assertEqual(options.options['docstrings'], False)
+
+    def test_option_value_emptystr(self):
+        options, args =  self.parse_args(['-s', 'docstrings='])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['options']))
+        self.assertEqual(options.options['docstrings'], True)
+
+    def test_option_value_a_str(self):
+        options, args =  self.parse_args(['-s', 'docstrings=BB'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['options']))
+        self.assertEqual(options.options['docstrings'], True)
+
+    def test_option_value_no(self):
+        options, args =  self.parse_args(['-s', 'docstrings=nO'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['options']))
+        self.assertEqual(options.options['docstrings'], False)
+
+    def test_option_no_value(self):
+        options, args =  self.parse_args(['-s', 'docstrings'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['options']))
+        self.assertEqual(options.options['docstrings'], True)
+
+    def test_option_any_key(self):
+        options, args =  self.parse_args(['-s', 'abracadabra'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['options']))
+        self.assertEqual(options.options['abracadabra'], True)
+
+    def test_language_level_2(self):
+        options, args =  self.parse_args(['-2'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['language_level']))
+        self.assertEqual(options.language_level, 2)
+
+    def test_language_level_3(self):
+        options, args =  self.parse_args(['-3'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['language_level']))
+        self.assertEqual(options.language_level, 3)
+
+    def test_language_level_3str(self):
+        options, args =  self.parse_args(['--3str'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['language_level']))
+        self.assertEqual(options.language_level, '3str')
+
+    def test_annotate_short(self):
+        options, args =  self.parse_args(['-a'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['annotate']))
+        self.assertEqual(options.annotate, 'default')
+
+    def test_annotate_long(self):
+        options, args =  self.parse_args(['--annotate'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['annotate']))
+        self.assertEqual(options.annotate, 'default')
+
+    def test_annotate_fullc(self):
+        options, args =  self.parse_args(['--annotate-fullc'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['annotate']))
+        self.assertEqual(options.annotate, 'fullc')
+
+    def test_annotate_and_positional(self):
+        options, args =  self.parse_args(['-a', 'foo.pyx'])
+        self.assertEqual(args, ['foo.pyx'])
+        self.assertTrue(self.are_default(options, ['annotate']))
+        self.assertEqual(options.annotate, 'default')
+
+    def test_annotate_and_optional(self):
+        options, args =  self.parse_args(['-a', '--3str'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['annotate', 'language_level']))
+        self.assertEqual(options.annotate, 'default')
+        self.assertEqual(options.language_level, '3str')
+
+    def test_exclude_short(self):
+        options, args =  self.parse_args(['-x', '*.pyx'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['excludes']))
+        self.assertTrue('*.pyx' in options.excludes)
+
+    def test_exclude_long(self):
+        options, args =  self.parse_args(['--exclude', '*.pyx'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['excludes']))
+        self.assertTrue('*.pyx' in options.excludes)
+
+    def test_exclude_multiple(self):
+        options, args =  self.parse_args(['--exclude', '*.pyx', '--exclude', '*.py', ])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['excludes']))
+        self.assertEqual(options.excludes, ['*.pyx', '*.py'])
+
+    def test_build_short(self):
+        options, args =  self.parse_args(['-b'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['build']))
+        self.assertEqual(options.build, True)
+
+    def test_build_long(self):
+        options, args =  self.parse_args(['--build'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['build']))
+        self.assertEqual(options.build, True)
+
+    def test_inplace_short(self):
+        options, args =  self.parse_args(['-i'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['build_inplace']))
+        self.assertEqual(options.build_inplace, True)
+
+    def test_inplace_long(self):
+        options, args =  self.parse_args(['--inplace'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['build_inplace']))
+        self.assertEqual(options.build_inplace, True)
+
+    def test_parallel_short(self):
+        options, args =  self.parse_args(['-j', '42'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['parallel']))
+        self.assertEqual(options.parallel, 42)
+
+    def test_parallel_long(self):
+        options, args =  self.parse_args(['--parallel', '42'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['parallel']))
+        self.assertEqual(options.parallel, 42)
+
+    def test_force_short(self):
+        options, args =  self.parse_args(['-f'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['force']))
+        self.assertEqual(options.force, True)
+
+    def test_force_long(self):
+        options, args =  self.parse_args(['--force'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['force']))
+        self.assertEqual(options.force, True)
+
+    def test_quite_short(self):
+        options, args =  self.parse_args(['-q'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['quiet']))
+        self.assertEqual(options.quiet, True)
+
+    def test_quite_long(self):
+        options, args =  self.parse_args(['--quiet'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['quiet']))
+        self.assertEqual(options.quiet, True)
+
+    def test_lenient_long(self):
+        options, args =  self.parse_args(['--lenient'])
+        self.assertTrue(self.are_default(options, ['lenient']))
+        self.assertFalse(args)
+        self.assertEqual(options.lenient, True)
+
+    def test_keep_going_short(self):
+        options, args =  self.parse_args(['-k'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['keep_going']))
+        self.assertEqual(options.keep_going, True)
+
+    def test_keep_going_long(self):
+        options, args =  self.parse_args(['--keep-going'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['keep_going']))
+        self.assertEqual(options.keep_going, True)
+
+    def test_no_docstrings_long(self):
+        options, args =  self.parse_args(['--no-docstrings'])
+        self.assertFalse(args)
+        self.assertTrue(self.are_default(options, ['no_docstrings']))
+        self.assertEqual(options.no_docstrings, True)
+
+    def test_file_name(self):
+        options, args =  self.parse_args(['file1.pyx', 'file2.pyx'])
+        self.assertEqual(len(args), 2)
+        self.assertEqual(args[0], 'file1.pyx')
+        self.assertEqual(args[1], 'file2.pyx')
+        self.assertTrue(self.are_default(options, []))
+
+    def test_option_first(self):
+        options, args =  self.parse_args(['-i', 'file.pyx'])
+        self.assertEqual(args, ['file.pyx'])
+        self.assertEqual(options.build_inplace, True)
+        self.assertTrue(self.are_default(options, ['build_inplace']))
+
+    def test_file_inbetween(self):
+        options, args =  self.parse_args(['-i', 'file.pyx', '-a'])
+        self.assertEqual(args, ['file.pyx'])
+        self.assertEqual(options.build_inplace, True)
+        self.assertEqual(options.annotate, 'default')
+        self.assertTrue(self.are_default(options, ['build_inplace', 'annotate']))
+
+    def test_option_trailing(self):
+        options, args =  self.parse_args(['file.pyx', '-i'])
+        self.assertEqual(args, ['file.pyx'])
+        self.assertEqual(options.build_inplace, True)
+        self.assertTrue(self.are_default(options, ['build_inplace']))
+
+    def test_interspersed_positional(self):
+        options, sources = self.parse_args([
+             'file1.pyx', '-a',
+             'file2.pyx'
+        ])
+        self.assertEqual(sources, ['file1.pyx', 'file2.pyx'])
+        self.assertEqual(options.annotate, 'default')
+        self.assertTrue(self.are_default(options, ['annotate']))
+
+    def test_interspersed_positional2(self):
+        options, sources = self.parse_args([
+             'file1.pyx', '-a',
+             'file2.pyx', '-a', 'file3.pyx'
+        ])
+        self.assertEqual(sources, ['file1.pyx', 'file2.pyx', 'file3.pyx'])
+        self.assertEqual(options.annotate, 'default')
+        self.assertTrue(self.are_default(options, ['annotate']))
+
+    def test_interspersed_positional3(self):
+        options, sources = self.parse_args([
+             '-f', 'f1', 'f2', '-a',
+             'f3', 'f4', '-a', 'f5'
+        ])
+        self.assertEqual(sources, ['f1', 'f2', 'f3', 'f4', 'f5'])
+        self.assertEqual(options.annotate, 'default')
+        self.assertEqual(options.force, True)
+        self.assertTrue(self.are_default(options, ['annotate', 'force']))
+
+    def test_wrong_option(self):
+        old_stderr = sys.stderr
+        stderr = sys.stderr = StringIO()
+        try:
+            self.assertRaises(SystemExit, self.parse_args,
+                              ['--unknown-option']
+                              )
+        finally:
+            sys.stderr = old_stderr
+        self.assertTrue(stderr.getvalue())
+
+
+class TestParseArgs(TestCase):
+    def setUp(self):
+        self._options_backup = backup_Options()
+
+    def tearDown(self):
+        restore_Options(self._options_backup)
+
+    def check_default_global_options(self, white_list=[]):
+        self.assertEqual(check_global_options(self._options_backup, white_list), "")
+
+    def test_build_set_for_inplace(self):
+        options, args = parse_args(['foo.pyx', '-i'])
+        self.assertEqual(options.build, True)
+        self.check_default_global_options()
+
+    def test_lenient(self):
+        options, sources = parse_args(['foo.pyx', '--lenient'])
+        self.assertEqual(sources, ['foo.pyx'])
+        self.assertEqual(Options.error_on_unknown_names, False)
+        self.assertEqual(Options.error_on_uninitialized, False)
+        self.check_default_global_options(['error_on_unknown_names', 'error_on_uninitialized'])
+
+    def test_annotate(self):
+        options, sources = parse_args(['foo.pyx', '--annotate'])
+        self.assertEqual(sources, ['foo.pyx'])
+        self.assertEqual(Options.annotate, 'default')
+        self.check_default_global_options(['annotate'])
+
+    def test_annotate_fullc(self):
+        options, sources = parse_args(['foo.pyx', '--annotate-fullc'])
+        self.assertEqual(sources, ['foo.pyx'])
+        self.assertEqual(Options.annotate, 'fullc')
+        self.check_default_global_options(['annotate'])
+
+    def test_no_docstrings(self):
+        options, sources = parse_args(['foo.pyx', '--no-docstrings'])
+        self.assertEqual(sources, ['foo.pyx'])
+        self.assertEqual(Options.docstrings, False)
+        self.check_default_global_options(['docstrings'])
diff --git a/Cython/Build/Tests/TestInline.py b/Cython/Build/Tests/TestInline.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0J1aWxkL1Rlc3RzL1Rlc3RJbmxpbmUucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0J1aWxkL1Rlc3RzL1Rlc3RJbmxpbmUucHk= 100644
--- a/Cython/Build/Tests/TestInline.py
+++ b/Cython/Build/Tests/TestInline.py
@@ -1,4 +1,6 @@
-import os, tempfile
+import os
+import tempfile
+import unittest
 from Cython.Shadow import inline
 from Cython.Build.Inline import safe_type
 from Cython.TestUtils import CythonTest
@@ -24,6 +26,6 @@
         self.test_kwds['lib_dir'] = lib_dir
 
     def test_simple(self):
-        self.assertEquals(inline("return 1+2", **self.test_kwds), 3)
+        self.assertEqual(inline("return 1+2", **self.test_kwds), 3)
 
     def test_types(self):
@@ -28,6 +30,6 @@
 
     def test_types(self):
-        self.assertEquals(inline("""
+        self.assertEqual(inline("""
             cimport cython
             return cython.typeof(a), cython.typeof(b)
         """, a=1.0, b=[], **self.test_kwds), ('double', 'list object'))
@@ -35,6 +37,6 @@
     def test_locals(self):
         a = 1
         b = 2
-        self.assertEquals(inline("return a+b", **self.test_kwds), 3)
+        self.assertEqual(inline("return a+b", **self.test_kwds), 3)
 
     def test_globals(self):
@@ -39,5 +41,5 @@
 
     def test_globals(self):
-        self.assertEquals(inline("return global_value + 1", **self.test_kwds), global_value + 1)
+        self.assertEqual(inline("return global_value + 1", **self.test_kwds), global_value + 1)
 
     def test_no_return(self):
@@ -42,6 +44,6 @@
 
     def test_no_return(self):
-        self.assertEquals(inline("""
+        self.assertEqual(inline("""
             a = 1
             cdef double b = 2
             cdef c = []
@@ -49,7 +51,7 @@
 
     def test_def_node(self):
         foo = inline("def foo(x): return x * x", **self.test_kwds)['foo']
-        self.assertEquals(foo(7), 49)
+        self.assertEqual(foo(7), 49)
 
     def test_class_ref(self):
         class Type(object):
@@ -64,7 +66,7 @@
         c = cy.declare(cy.pointer(cy.float), &b)
         return b
         """, a=3, **self.test_kwds)
-        self.assertEquals(type(b), float)
+        self.assertEqual(type(b), float)
 
     def test_compiler_directives(self):
         self.assertEqual(
@@ -74,5 +76,19 @@
             6
         )
 
-    if has_numpy:
+    def test_lang_version(self):
+        # GH-3419. Caching for inline code didn't always respect compiler directives.
+        inline_divcode = "def f(int a, int b): return a/b"
+        self.assertEqual(
+            inline(inline_divcode, language_level=2)['f'](5,2),
+            2
+        )
+        self.assertEqual(
+            inline(inline_divcode, language_level=3)['f'](5,2),
+            2.5
+        )
+        self.assertEqual(
+            inline(inline_divcode, language_level=2)['f'](5,2),
+            2
+        )
 
@@ -78,7 +94,19 @@
 
-        def test_numpy(self):
-            import numpy
-            a = numpy.ndarray((10, 20))
-            a[0,0] = 10
-            self.assertEquals(safe_type(a), 'numpy.ndarray[numpy.float64_t, ndim=2]')
-            self.assertEquals(inline("return a[0,0]", a=a, **self.test_kwds), 10.0)
+    def test_repeated_use(self):
+        inline_mulcode = "def f(int a, int b): return a * b"
+        self.assertEqual(inline(inline_mulcode)['f'](5, 2), 10)
+        self.assertEqual(inline(inline_mulcode)['f'](5, 3), 15)
+        self.assertEqual(inline(inline_mulcode)['f'](6, 2), 12)
+        self.assertEqual(inline(inline_mulcode)['f'](5, 2), 10)
+
+        f = inline(inline_mulcode)['f']
+        self.assertEqual(f(5, 2), 10)
+        self.assertEqual(f(5, 3), 15)
+
+    @unittest.skipIf(not has_numpy, "NumPy is not available")
+    def test_numpy(self):
+        import numpy
+        a = numpy.ndarray((10, 20))
+        a[0,0] = 10
+        self.assertEqual(safe_type(a), 'numpy.ndarray[numpy.float64_t, ndim=2]')
+        self.assertEqual(inline("return a[0,0]", a=a, **self.test_kwds), 10.0)
diff --git a/Cython/Build/Tests/TestIpythonMagic.py b/Cython/Build/Tests/TestIpythonMagic.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0J1aWxkL1Rlc3RzL1Rlc3RJcHl0aG9uTWFnaWMucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0J1aWxkL1Rlc3RzL1Rlc3RJcHl0aG9uTWFnaWMucHk= 100644
--- a/Cython/Build/Tests/TestIpythonMagic.py
+++ b/Cython/Build/Tests/TestIpythonMagic.py
@@ -10,6 +10,7 @@
 from contextlib import contextmanager
 from Cython.Build import IpythonMagic
 from Cython.TestUtils import CythonTest
+from Cython.Compiler.Annotate import AnnotationCCodeWriter
 
 try:
     import IPython.testing.globalipapp
@@ -195,10 +196,10 @@
             ip.run_cell_magic('cython', '--verbose', code)
             ip.ex('g = f(10)')
         self.assertEqual(ip.user_ns['g'], 20.0)
-        self.assertEquals([verbose_log.INFO, verbose_log.DEBUG, verbose_log.INFO],
+        self.assertEqual([verbose_log.INFO, verbose_log.DEBUG, verbose_log.INFO],
                           verbose_log.thresholds)
 
         with mock_distutils() as normal_log:
             ip.run_cell_magic('cython', '', code)
             ip.ex('g = f(10)')
         self.assertEqual(ip.user_ns['g'], 20.0)
@@ -199,7 +200,33 @@
                           verbose_log.thresholds)
 
         with mock_distutils() as normal_log:
             ip.run_cell_magic('cython', '', code)
             ip.ex('g = f(10)')
         self.assertEqual(ip.user_ns['g'], 20.0)
-        self.assertEquals([normal_log.INFO], normal_log.thresholds)
+        self.assertEqual([normal_log.INFO], normal_log.thresholds)
+
+    def test_cython_no_annotate(self):
+        ip = self._ip
+        html = ip.run_cell_magic('cython', '', code)
+        self.assertTrue(html is None)
+
+    def test_cython_annotate(self):
+        ip = self._ip
+        html = ip.run_cell_magic('cython', '--annotate', code)
+        # somewhat brittle way to differentiate between annotated htmls
+        # with/without complete source code:
+        self.assertTrue(AnnotationCCodeWriter.COMPLETE_CODE_TITLE not in html.data)
+
+    def test_cython_annotate_default(self):
+        ip = self._ip
+        html = ip.run_cell_magic('cython', '-a', code)
+        # somewhat brittle way to differentiate between annotated htmls
+        # with/without complete source code:
+        self.assertTrue(AnnotationCCodeWriter.COMPLETE_CODE_TITLE not in html.data)
+
+    def test_cython_annotate_complete_c_code(self):
+        ip = self._ip
+        html = ip.run_cell_magic('cython', '--annotate-fullc', code)
+        # somewhat brittle way to differentiate between annotated htmls
+        # with/without complete source code:
+        self.assertTrue(AnnotationCCodeWriter.COMPLETE_CODE_TITLE in html.data)
diff --git a/Cython/CodeWriter.py b/Cython/CodeWriter.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvZGVXcml0ZXIucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvZGVXcml0ZXIucHk= 100644
--- a/Cython/CodeWriter.py
+++ b/Cython/CodeWriter.py
@@ -28,4 +28,5 @@
         self.put(s)
         self.newline()
 
+
 class DeclarationWriter(TreeVisitor):
@@ -31,4 +32,7 @@
 class DeclarationWriter(TreeVisitor):
+    """
+    A Cython code writer that is limited to declarations nodes.
+    """
 
     indent_string = u"    "
 
@@ -111,13 +115,6 @@
             self.visit(node.dimension)
         self.put(u']')
 
-    def visit_CArrayDeclaratorNode(self, node):
-        self.visit(node.base)
-        self.put(u'[')
-        if node.dimension is not None:
-            self.visit(node.dimension)
-        self.put(u']')
-
     def visit_CFuncDeclaratorNode(self, node):
         # TODO: except, gil, etc.
         self.visit(node.base)
@@ -240,6 +237,7 @@
         self.endline()
 
     def visit_FuncDefNode(self, node):
+        # TODO: support cdef + cpdef functions
         self.startline(u"def %s(" % node.name)
         self.comma_separated_list(node.args)
         self.endline(u"):")
@@ -284,19 +282,8 @@
     def visit_NameNode(self, node):
         self.put(node.name)
 
-    def visit_IntNode(self, node):
-        self.put(node.value)
-
-    def visit_NoneNode(self, node):
-        self.put(u"None")
-
-    def visit_NotNode(self, node):
-        self.put(u"(not ")
-        self.visit(node.operand)
-        self.put(u")")
-
     def visit_DecoratorNode(self, node):
         self.startline("@")
         self.visit(node.decorator)
         self.endline()
 
@@ -298,28 +285,9 @@
     def visit_DecoratorNode(self, node):
         self.startline("@")
         self.visit(node.decorator)
         self.endline()
 
-    def visit_BinopNode(self, node):
-        self.visit(node.operand1)
-        self.put(u" %s " % node.operator)
-        self.visit(node.operand2)
-
-    def visit_AttributeNode(self, node):
-        self.visit(node.obj)
-        self.put(u".%s" % node.attribute)
-
-    def visit_BoolNode(self, node):
-        self.put(str(node.value))
-
-    # FIXME: represent string nodes correctly
-    def visit_StringNode(self, node):
-        value = node.value
-        if value.encoding is not None:
-            value = value.encode(value.encoding)
-        self.put(repr(value))
-
     def visit_PassStatNode(self, node):
         self.startline(u"pass")
         self.endline()
 
@@ -322,8 +290,12 @@
     def visit_PassStatNode(self, node):
         self.startline(u"pass")
         self.endline()
 
-class CodeWriter(DeclarationWriter):
+
+class StatementWriter(DeclarationWriter):
+    """
+    A Cython code writer for most language statement features.
+    """
 
     def visit_SingleAssignmentNode(self, node):
         self.startline()
@@ -349,7 +321,10 @@
 
     def visit_ForInStatNode(self, node):
         self.startline(u"for ")
-        self.visit(node.target)
+        if node.target.is_sequence_constructor:
+            self.comma_separated_list(node.target.args)
+        else:
+            self.visit(node.target)
         self.put(u" in ")
         self.visit(node.iterator.sequence)
         self.endline(u":")
@@ -387,32 +362,6 @@
     def visit_SequenceNode(self, node):
         self.comma_separated_list(node.args) # Might need to discover whether we need () around tuples...hmm...
 
-    def visit_SimpleCallNode(self, node):
-        self.visit(node.function)
-        self.put(u"(")
-        self.comma_separated_list(node.args)
-        self.put(")")
-
-    def visit_GeneralCallNode(self, node):
-        self.visit(node.function)
-        self.put(u"(")
-        posarg = node.positional_args
-        if isinstance(posarg, AsTupleNode):
-            self.visit(posarg.arg)
-        else:
-            self.comma_separated_list(posarg.args)  # TupleNode.args
-        if node.keyword_args:
-            if isinstance(node.keyword_args, DictNode):
-                for i, (name, value) in enumerate(node.keyword_args.key_value_pairs):
-                    if i > 0:
-                        self.put(', ')
-                    self.visit(name)
-                    self.put('=')
-                    self.visit(value)
-            else:
-                raise Exception("Not implemented yet")
-        self.put(u")")
-
     def visit_ExprStatNode(self, node):
         self.startline()
         self.visit(node.expr)
@@ -498,27 +447,4 @@
         self.put(self.tempnames[node.handle])
 
 
-class PxdWriter(DeclarationWriter):
-    def __call__(self, node):
-        print(u'\n'.join(self.write(node).lines))
-        return node
-
-    def visit_CFuncDefNode(self, node):
-        if 'inline' in node.modifiers:
-            return
-        if node.overridable:
-            self.startline(u'cpdef ')
-        else:
-            self.startline(u'cdef ')
-        if node.visibility != 'private':
-            self.put(node.visibility)
-            self.put(u' ')
-        if node.api:
-            self.put(u'api ')
-        self.visit(node.declarator)
-
-    def visit_StatNode(self, node):
-        pass
-
-
 class ExpressionWriter(TreeVisitor):
@@ -524,4 +450,7 @@
 class ExpressionWriter(TreeVisitor):
+    """
+    A Cython code writer that is intentionally limited to expressions.
+    """
 
     def __init__(self, result=None):
         super(ExpressionWriter, self).__init__()
@@ -814,3 +743,37 @@
             # type(body) is Nodes.ExprStatNode
             body = body.expr.arg
         self.emit_comprehension(body, target, sequence, condition, u"()")
+
+
+class PxdWriter(DeclarationWriter, ExpressionWriter):
+    """
+    A Cython code writer for everything supported in pxd files.
+    (currently unused)
+    """
+
+    def __call__(self, node):
+        print(u'\n'.join(self.write(node).lines))
+        return node
+
+    def visit_CFuncDefNode(self, node):
+        if 'inline' in node.modifiers:
+            return
+        if node.overridable:
+            self.startline(u'cpdef ')
+        else:
+            self.startline(u'cdef ')
+        if node.visibility != 'private':
+            self.put(node.visibility)
+            self.put(u' ')
+        if node.api:
+            self.put(u'api ')
+        self.visit(node.declarator)
+
+    def visit_StatNode(self, node):
+        pass
+
+
+class CodeWriter(StatementWriter, ExpressionWriter):
+    """
+    A complete Cython code writer.
+    """
diff --git a/Cython/Compiler/Annotate.py b/Cython/Compiler/Annotate.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL0Fubm90YXRlLnB5..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL0Fubm90YXRlLnB5 100644
--- a/Cython/Compiler/Annotate.py
+++ b/Cython/Compiler/Annotate.py
@@ -22,4 +22,7 @@
 
 
 class AnnotationCCodeWriter(CCodeWriter):
+ 
+    # also used as marker for detection of complete code emission in tests
+    COMPLETE_CODE_TITLE = "Complete cythonized code"
 
@@ -25,3 +28,3 @@
 
-    def __init__(self, create_from=None, buffer=None, copy_formatting=True):
+    def __init__(self, create_from=None, buffer=None, copy_formatting=True, show_entire_c_code=False):
         CCodeWriter.__init__(self, create_from, buffer, copy_formatting=copy_formatting)
@@ -27,4 +30,5 @@
         CCodeWriter.__init__(self, create_from, buffer, copy_formatting=copy_formatting)
+        self.show_entire_c_code = show_entire_c_code
         if create_from is None:
             self.annotation_buffer = StringIO()
             self.last_annotated_pos = None
@@ -198,6 +202,6 @@
             for line in coverage_data.iterfind('lines/line')
         )
 
-    def _htmlify_code(self, code):
+    def _htmlify_code(self, code, language):
         try:
             from pygments import highlight
@@ -202,8 +206,8 @@
         try:
             from pygments import highlight
-            from pygments.lexers import CythonLexer
+            from pygments.lexers import CythonLexer, CppLexer
             from pygments.formatters import HtmlFormatter
         except ImportError:
             # no Pygments, just escape the code
             return html_escape(code)
 
@@ -205,6 +209,13 @@
             from pygments.formatters import HtmlFormatter
         except ImportError:
             # no Pygments, just escape the code
             return html_escape(code)
 
+        if language == "cython":
+            lexer = CythonLexer(stripnl=False, stripall=False)
+        elif language == "c/cpp":
+            lexer = CppLexer(stripnl=False, stripall=False)
+        else:
+            # unknown language, use fallback
+            return html_escape(code)
         html_code = highlight(
@@ -210,5 +221,5 @@
         html_code = highlight(
-            code, CythonLexer(stripnl=False, stripall=False),
+            code, lexer,
             HtmlFormatter(nowrap=True))
         return html_code
 
@@ -228,7 +239,7 @@
             return u"<span class='%s'>%s</span>" % (
                 group_name, match.group(group_name))
 
-        lines = self._htmlify_code(cython_code).splitlines()
+        lines = self._htmlify_code(cython_code, "cython").splitlines()
         lineno_width = len(str(len(lines)))
         if not covered_lines:
             covered_lines = None
@@ -279,6 +290,19 @@
                 outlist.append(u"<pre class='cython code score-{score} {covered}'>{code}</pre>".format(
                     score=score, covered=covered, code=c_code))
         outlist.append(u"</div>")
+
+        # now the whole c-code if needed:
+        if self.show_entire_c_code:
+            outlist.append(u'<p><div class="cython">')
+            onclick_title = u"<pre class='cython line'{onclick}>+ {title}</pre>\n";
+            outlist.append(onclick_title.format(
+                              onclick=self._onclick_attr,
+                              title=AnnotationCCodeWriter.COMPLETE_CODE_TITLE,
+                           ))
+            complete_code_as_html = self._htmlify_code(self.buffer.getvalue(), "c/cpp")
+            outlist.append(u"<pre class='cython code'>{code}</pre>".format(code=complete_code_as_html))
+            outlist.append(u"</div></p>")
+
         return outlist
 
 
diff --git a/Cython/Compiler/AutoDocTransforms.py b/Cython/Compiler/AutoDocTransforms.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL0F1dG9Eb2NUcmFuc2Zvcm1zLnB5..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL0F1dG9Eb2NUcmFuc2Zvcm1zLnB5 100644
--- a/Cython/Compiler/AutoDocTransforms.py
+++ b/Cython/Compiler/AutoDocTransforms.py
@@ -3,5 +3,5 @@
 from .Visitor import CythonTransform
 from .StringEncoding import EncodedString
 from . import Options
-from . import PyrexTypes, ExprNodes
+from . import PyrexTypes
 from ..CodeWriter import ExpressionWriter
@@ -7,4 +7,5 @@
 from ..CodeWriter import ExpressionWriter
+from .Errors import warning
 
 
 class AnnotationWriter(ExpressionWriter):
@@ -8,6 +9,16 @@
 
 
 class AnnotationWriter(ExpressionWriter):
+    """
+    A Cython code writer for Python expressions in argument/variable annotations.
+    """
+    def __init__(self, description=None):
+        """description is optional. If specified it is used in
+        warning messages for the nodes that don't convert to string properly.
+        If not specified then no messages are generated.
+        """
+        ExpressionWriter.__init__(self)
+        self.description = description
 
     def visit_Node(self, node):
         self.put(u"<???>")
@@ -11,7 +22,11 @@
 
     def visit_Node(self, node):
         self.put(u"<???>")
+        if self.description:
+            warning(node.pos,
+                    "Failed to convert code to string representation in {0}".format(
+                        self.description), level=1)
 
     def visit_LambdaNode(self, node):
         # XXX Should we do better?
         self.put("<lambda>")
@@ -14,7 +29,14 @@
 
     def visit_LambdaNode(self, node):
         # XXX Should we do better?
         self.put("<lambda>")
+        if self.description:
+            warning(node.pos,
+                    "Failed to convert lambda to string representation in {0}".format(
+                        self.description), level=1)
+
+    def visit_AnnotationNode(self, node):
+        self.put(node.string.unicode_value)
 
 
 class EmbedSignature(CythonTransform):
@@ -55,7 +77,7 @@
         return arg_doc
 
     def _fmt_arglist(self, args,
-                     npargs=0, pargs=None,
+                     npoargs=0, npargs=0, pargs=None,
                      nkargs=0, kargs=None,
                      hide_self=False):
         arglist = []
@@ -65,5 +87,5 @@
                 arglist.append(arg_doc)
         if pargs:
             arg_doc = self._fmt_star_arg(pargs)
-            arglist.insert(npargs, '*%s' % arg_doc)
+            arglist.insert(npargs + npoargs, '*%s' % arg_doc)
         elif nkargs:
@@ -69,5 +91,7 @@
         elif nkargs:
-            arglist.insert(npargs, '*')
+            arglist.insert(npargs + npoargs, '*')
+        if npoargs:
+            arglist.insert(npoargs, '/')
         if kargs:
             arg_doc = self._fmt_star_arg(kargs)
             arglist.append('**%s' % arg_doc)
@@ -80,8 +104,8 @@
             return ret.declaration_code("", for_display=1)
 
     def _fmt_signature(self, cls_name, func_name, args,
-                       npargs=0, pargs=None,
+                       npoargs=0, npargs=0, pargs=None,
                        nkargs=0, kargs=None,
                        return_expr=None,
                        return_type=None, hide_self=False):
         arglist = self._fmt_arglist(args,
@@ -84,8 +108,8 @@
                        nkargs=0, kargs=None,
                        return_expr=None,
                        return_type=None, hide_self=False):
         arglist = self._fmt_arglist(args,
-                                    npargs, pargs,
+                                    npoargs, npargs, pargs,
                                     nkargs, kargs,
                                     hide_self=hide_self)
         arglist_doc = ', '.join(arglist)
@@ -147,4 +171,5 @@
         else:
             class_name, func_name = self.class_name, node.name
 
+        npoargs = getattr(node, 'num_posonly_args', 0)
         nkargs = getattr(node, 'num_kwonly_args', 0)
@@ -150,4 +175,4 @@
         nkargs = getattr(node, 'num_kwonly_args', 0)
-        npargs = len(node.args) - nkargs
+        npargs = len(node.args) - nkargs - npoargs
         signature = self._fmt_signature(
             class_name, func_name, node.args,
@@ -152,6 +177,6 @@
         signature = self._fmt_signature(
             class_name, func_name, node.args,
-            npargs, node.star_arg,
+            npoargs, npargs, node.star_arg,
             nkargs, node.starstar_arg,
             return_expr=node.return_type_annotation,
             return_type=None, hide_self=hide_self)
diff --git a/Cython/Compiler/Builtin.py b/Cython/Compiler/Builtin.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL0J1aWx0aW4ucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL0J1aWx0aW4ucHk= 100644
--- a/Cython/Compiler/Builtin.py
+++ b/Cython/Compiler/Builtin.py
@@ -30,10 +30,11 @@
 class _BuiltinOverride(object):
     def __init__(self, py_name, args, ret_type, cname, py_equiv="*",
                  utility_code=None, sig=None, func_type=None,
-                 is_strict_signature=False, builtin_return_type=None):
+                 is_strict_signature=False, builtin_return_type=None,
+                 nogil=None):
         self.py_name, self.cname, self.py_equiv = py_name, cname, py_equiv
         self.args, self.ret_type = args, ret_type
         self.func_type, self.sig = func_type, sig
         self.builtin_return_type = builtin_return_type
         self.is_strict_signature = is_strict_signature
         self.utility_code = utility_code
@@ -34,9 +35,10 @@
         self.py_name, self.cname, self.py_equiv = py_name, cname, py_equiv
         self.args, self.ret_type = args, ret_type
         self.func_type, self.sig = func_type, sig
         self.builtin_return_type = builtin_return_type
         self.is_strict_signature = is_strict_signature
         self.utility_code = utility_code
+        self.nogil = nogil
 
     def build_func_type(self, sig=None, self_arg=None):
         if sig is None:
@@ -40,7 +42,7 @@
 
     def build_func_type(self, sig=None, self_arg=None):
         if sig is None:
-            sig = Signature(self.args, self.ret_type)
+            sig = Signature(self.args, self.ret_type, nogil=self.nogil)
             sig.exception_check = False  # not needed for the current builtins
         func_type = sig.function_type(self_arg)
         if self.is_strict_signature:
@@ -92,5 +94,5 @@
 builtin_function_table = [
     # name,        args,   return,  C API func,           py equiv = "*"
     BuiltinFunction('abs',        "d",    "d",     "fabs",
-                    is_strict_signature = True),
+                    is_strict_signature=True, nogil=True),
     BuiltinFunction('abs',        "f",    "f",     "fabsf",
@@ -96,3 +98,3 @@
     BuiltinFunction('abs',        "f",    "f",     "fabsf",
-                    is_strict_signature = True),
+                    is_strict_signature=True, nogil=True),
     BuiltinFunction('abs',        "i",    "i",     "abs",
@@ -98,3 +100,3 @@
     BuiltinFunction('abs',        "i",    "i",     "abs",
-                    is_strict_signature = True),
+                    is_strict_signature=True, nogil=True),
     BuiltinFunction('abs',        "l",    "l",     "labs",
@@ -100,5 +102,5 @@
     BuiltinFunction('abs',        "l",    "l",     "labs",
-                    is_strict_signature = True),
+                    is_strict_signature=True, nogil=True),
     BuiltinFunction('abs',        None,    None,   "__Pyx_abs_longlong",
                 utility_code = UtilityCode.load("abs_longlong", "Builtins.c"),
                 func_type = PyrexTypes.CFuncType(
diff --git a/Cython/Compiler/CmdLine.py b/Cython/Compiler/CmdLine.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL0NtZExpbmUucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL0NtZExpbmUucHk= 100644
--- a/Cython/Compiler/CmdLine.py
+++ b/Cython/Compiler/CmdLine.py
@@ -5,6 +5,6 @@
 from __future__ import absolute_import
 
 import os
-import sys
+from argparse import ArgumentParser, Action, SUPPRESS
 from . import Options
 
@@ -9,6 +9,12 @@
 from . import Options
 
-usage = """\
-Cython (http://cython.org) is a compiler for code written in the
-Cython language.  Cython is based on Pyrex by Greg Ewing.
+
+class ParseDirectivesAction(Action):
+    def __call__(self, parser, namespace, values, option_string=None):
+        old_directives = dict(getattr(namespace, self.dest,
+                                      Options.get_directive_defaults()))
+        directives = Options.parse_directive_list(
+            values, relaxed_bool=True, current_settings=old_directives)
+        setattr(namespace, self.dest, directives)
+
 
@@ -14,3 +20,21 @@
 
-Usage: cython [options] sourcefile.{pyx,py} ...
+class ParseOptionsAction(Action):
+    def __call__(self, parser, namespace, values, option_string=None):
+        options = dict(getattr(namespace, self.dest, {}))
+        for opt in values.split(','):
+            if '=' in opt:
+                n, v = opt.split('=', 1)
+                v = v.lower() not in ('false', 'f', '0', 'no')
+            else:
+                n, v = opt, True
+            options[n] = v
+        setattr(namespace, self.dest, options)
+
+
+class ParseCompileTimeEnvAction(Action):
+    def __call__(self, parser, namespace, values, option_string=None):
+        old_env = dict(getattr(namespace, self.dest, {}))
+        new_env = Options.parse_compile_time_env(values, current_settings=old_env)
+        setattr(namespace, self.dest, new_env)
+
 
@@ -16,19 +40,14 @@
 
-Options:
-  -V, --version                  Display version number of cython compiler
-  -l, --create-listing           Write error messages to a listing file
-  -I, --include-dir <directory>  Search for include files in named directory
-                                 (multiple include directories are allowed).
-  -o, --output-file <filename>   Specify name of generated C file
-  -t, --timestamps               Only compile newer source files
-  -f, --force                    Compile all source files (overrides implied -t)
-  -v, --verbose                  Be verbose, print file names on multiple compilation
-  -p, --embed-positions          If specified, the positions in Cython files of each
-                                 function definition is embedded in its docstring.
-  --cleanup <level>              Release interned objects on python exit, for memory debugging.
-                                 Level indicates aggressiveness, default 0 releases nothing.
-  -w, --working <directory>      Sets the working directory for Cython (the directory modules
-                                 are searched from)
-  --gdb                          Output debug information for cygdb
-  --gdb-outdir <directory>       Specify gdb debug information output directory. Implies --gdb.
+class ActivateAllWarningsAction(Action):
+    def __call__(self, parser, namespace, values, option_string=None):
+        directives = getattr(namespace, 'compiler_directives', {})
+        directives.update(Options.extra_warnings)
+        namespace.compiler_directives = directives
+
+
+class SetLenientAction(Action):
+    def __call__(self, parser, namespace, values, option_string=None):
+        namespace.error_on_unknown_names = False
+        namespace.error_on_uninitialized = False
+
 
@@ -34,22 +53,19 @@
 
-  -D, --no-docstrings            Strip docstrings from the compiled module.
-  -a, --annotate                 Produce a colorized HTML version of the source.
-  --annotate-coverage <cov.xml>  Annotate and include coverage information from cov.xml.
-  --line-directives              Produce #line directives pointing to the .pyx source
-  --cplus                        Output a C++ rather than C file.
-  --embed[=<method_name>]        Generate a main() function that embeds the Python interpreter.
-  -2                             Compile based on Python-2 syntax and code semantics.
-  -3                             Compile based on Python-3 syntax and code semantics.
-  --3str                         Compile based on Python-3 syntax and code semantics without
-                                 assuming unicode by default for string literals under Python 2.
-  --lenient                      Change some compile time errors to runtime errors to
-                                 improve Python compatibility
-  --capi-reexport-cincludes      Add cincluded headers to any auto-generated header files.
-  --fast-fail                    Abort the compilation on the first error
-  --warning-errors, -Werror      Make all warnings into errors
-  --warning-extra, -Wextra       Enable extra warnings
-  -X, --directive <name>=<value>[,<name=value,...] Overrides a compiler directive
-  -E, --compile-time-env name=value[,<name=value,...] Provides compile time env like DEF would do.
-"""
+class SetGDBDebugAction(Action):
+    def __call__(self, parser, namespace, values, option_string=None):
+        namespace.gdb_debug = True
+        namespace.output_dir = os.curdir
+
+
+class SetGDBDebugOutputAction(Action):
+    def __call__(self, parser, namespace, values, option_string=None):
+        namespace.gdb_debug = True
+        namespace.output_dir = values
+
+
+class SetAnnotateCoverageAction(Action):
+    def __call__(self, parser, namespace, values, option_string=None):
+        namespace.annotate = True
+        namespace.annotate_coverage_xml = values
 
 
@@ -54,8 +70,8 @@
 
 
-# The following experimental options are supported only on MacOSX:
-#  -C, --compile    Compile generated .c file to .o file
-#  --link           Link .o file to produce extension module (implies -C)
-#  -+, --cplus      Use C++ compiler for compiling and linking
-#  Additional .o files to link may be supplied when using -X."""
+def create_cython_argparser():
+    description = "Cython (https://cython.org/) is a compiler for code written in the "\
+                  "Cython language.  Cython is based on Pyrex by Greg Ewing."
+
+    parser = ArgumentParser(description=description, argument_default=SUPPRESS)
 
@@ -61,7 +77,127 @@
 
-def bad_usage():
-    sys.stderr.write(usage)
-    sys.exit(1)
+    parser.add_argument("-V", "--version", dest='show_version', action='store_const', const=1,
+                      help='Display version number of cython compiler')
+    parser.add_argument("-l", "--create-listing", dest='use_listing_file', action='store_const', const=1,
+                      help='Write error messages to a listing file')
+    parser.add_argument("-I", "--include-dir", dest='include_path', action='append',
+                      help='Search for include files in named directory '
+                           '(multiple include directories are allowed).')
+    parser.add_argument("-o", "--output-file", dest='output_file', action='store', type=str,
+                      help='Specify name of generated C file')
+    parser.add_argument("-t", "--timestamps", dest='timestamps', action='store_const', const=1,
+                      help='Only compile newer source files')
+    parser.add_argument("-f", "--force", dest='timestamps', action='store_const', const=0,
+                      help='Compile all source files (overrides implied -t)')
+    parser.add_argument("-v", "--verbose", dest='verbose', action='count',
+                      help='Be verbose, print file names on multiple compilation')
+    parser.add_argument("-p", "--embed-positions", dest='embed_pos_in_docstring', action='store_const', const=1,
+                      help='If specified, the positions in Cython files of each '
+                           'function definition is embedded in its docstring.')
+    parser.add_argument("--cleanup", dest='generate_cleanup_code', action='store', type=int,
+                      help='Release interned objects on python exit, for memory debugging. '
+                           'Level indicates aggressiveness, default 0 releases nothing.')
+    parser.add_argument("-w", "--working", dest='working_path', action='store', type=str,
+                      help='Sets the working directory for Cython (the directory modules are searched from)')
+    parser.add_argument("--gdb", action=SetGDBDebugAction, nargs=0,
+                      help='Output debug information for cygdb')
+    parser.add_argument("--gdb-outdir", action=SetGDBDebugOutputAction, type=str,
+                      help='Specify gdb debug information output directory. Implies --gdb.')
+    parser.add_argument("-D", "--no-docstrings", dest='docstrings', action='store_false',
+                      help='Strip docstrings from the compiled module.')
+    parser.add_argument('-a', '--annotate', action='store_const', const='default', dest='annotate',
+                      help='Produce a colorized HTML version of the source.')
+    parser.add_argument('--annotate-fullc', action='store_const', const='fullc', dest='annotate',
+                      help='Produce a colorized HTML version of the source '
+                           'which includes entire generated C/C++-code.')
+    parser.add_argument("--annotate-coverage", dest='annotate_coverage_xml', action=SetAnnotateCoverageAction, type=str,
+                      help='Annotate and include coverage information from cov.xml.')
+    parser.add_argument("--line-directives", dest='emit_linenums', action='store_true',
+                      help='Produce #line directives pointing to the .pyx source')
+    parser.add_argument("-+", "--cplus", dest='cplus', action='store_const', const=1,
+                      help='Output a C++ rather than C file.')
+    parser.add_argument('--embed', action='store_const', const='main',
+                      help='Generate a main() function that embeds the Python interpreter. '
+                           'Pass --embed=<method_name> for a name other than main().')
+    parser.add_argument('-2', dest='language_level', action='store_const', const=2,
+                      help='Compile based on Python-2 syntax and code semantics.')
+    parser.add_argument('-3', dest='language_level', action='store_const', const=3,
+                      help='Compile based on Python-3 syntax and code semantics.')
+    parser.add_argument('--3str', dest='language_level', action='store_const', const='3str',
+                      help='Compile based on Python-3 syntax and code semantics without '
+                           'assuming unicode by default for string literals under Python 2.')
+    parser.add_argument("--lenient", action=SetLenientAction, nargs=0,
+                      help='Change some compile time errors to runtime errors to '
+                           'improve Python compatibility')
+    parser.add_argument("--capi-reexport-cincludes", dest='capi_reexport_cincludes', action='store_true',
+                      help='Add cincluded headers to any auto-generated header files.')
+    parser.add_argument("--fast-fail", dest='fast_fail', action='store_true',
+                      help='Abort the compilation on the first error')
+    parser.add_argument("-Werror", "--warning-errors", dest='warning_errors', action='store_true',
+                      help='Make all warnings into errors')
+    parser.add_argument("-Wextra", "--warning-extra", action=ActivateAllWarningsAction, nargs=0,
+                      help='Enable extra warnings')
+
+    parser.add_argument('-X', '--directive', metavar='NAME=VALUE,...',
+                      dest='compiler_directives', type=str,
+                      action=ParseDirectivesAction,
+                      help='Overrides a compiler directive')
+    parser.add_argument('-E', '--compile-time-env', metavar='NAME=VALUE,...',
+                      dest='compile_time_env', type=str,
+                      action=ParseCompileTimeEnvAction,
+                      help='Provides compile time env like DEF would do.')
+    parser.add_argument('sources', nargs='*', default=[])
+
+    # TODO: add help
+    parser.add_argument("-z", "--pre-import", dest='pre_import', action='store', type=str, help=SUPPRESS)
+    parser.add_argument("--convert-range", dest='convert_range', action='store_true', help=SUPPRESS)
+    parser.add_argument("--no-c-in-traceback", dest='c_line_in_traceback', action='store_false', help=SUPPRESS)
+    parser.add_argument("--cimport-from-pyx", dest='cimport_from_pyx', action='store_true', help=SUPPRESS)
+    parser.add_argument("--old-style-globals", dest='old_style_globals', action='store_true', help=SUPPRESS)
+
+    # debug stuff:
+    from . import DebugFlags
+    for name in vars(DebugFlags):
+        if name.startswith("debug"):
+            option_name = name.replace('_', '-')
+            parser.add_argument("--" + option_name, action='store_true', help=SUPPRESS)
+
+    return parser
+
+
+def parse_command_line_raw(parser, args):
+    # special handling for --embed and --embed=xxxx as they aren't correctly parsed
+    def filter_out_embed_options(args):
+        with_embed, without_embed = [], []
+        for x in args:
+            if x == '--embed' or x.startswith('--embed='):
+                with_embed.append(x)
+            else:
+                without_embed.append(x)
+        return with_embed, without_embed
+
+    with_embed, args_without_embed = filter_out_embed_options(args)
+
+    arguments, unknown = parser.parse_known_args(args_without_embed)
+
+    sources = arguments.sources
+    del arguments.sources
+
+    # unknown can be either debug, embed or input files or really unknown
+    for option in unknown:
+        if option.startswith('-'):
+            parser.error("unknown option " + option)
+        else:
+            sources.append(option)
+
+    # embed-stuff must be handled extra:
+    for x in with_embed:
+        if x == '--embed':
+            name = 'main'  # default value
+        else:
+            name = x[len('--embed='):]
+        setattr(arguments, 'embed', name)
+
+    return arguments, sources
 
 
 def parse_command_line(args):
@@ -65,32 +201,6 @@
 
 
 def parse_command_line(args):
-    from .Main import CompilationOptions, default_options
-
-    pending_arg = []
-
-    def pop_arg():
-        if not args or pending_arg:
-            bad_usage()
-        if '=' in args[0] and args[0].startswith('--'):  # allow "--long-option=xyz"
-            name, value = args.pop(0).split('=', 1)
-            pending_arg.append(value)
-            return name
-        return args.pop(0)
-
-    def pop_value(default=None):
-        if pending_arg:
-            return pending_arg.pop()
-        elif default is not None:
-            return default
-        elif not args:
-            bad_usage()
-        return args.pop(0)
-
-    def get_param(option):
-        tail = option[2:]
-        if tail:
-            return tail
-        else:
-            return pop_arg()
+    parser = create_cython_argparser()
+    arguments, sources = parse_command_line_raw(parser, args)
 
@@ -96,109 +206,8 @@
 
-    options = CompilationOptions(default_options)
-    sources = []
-    while args:
-        if args[0].startswith("-"):
-            option = pop_arg()
-            if option in ("-V", "--version"):
-                options.show_version = 1
-            elif option in ("-l", "--create-listing"):
-                options.use_listing_file = 1
-            elif option in ("-+", "--cplus"):
-                options.cplus = 1
-            elif option == "--embed":
-                Options.embed = pop_value("main")
-            elif option.startswith("-I"):
-                options.include_path.append(get_param(option))
-            elif option == "--include-dir":
-                options.include_path.append(pop_value())
-            elif option in ("-w", "--working"):
-                options.working_path = pop_value()
-            elif option in ("-o", "--output-file"):
-                options.output_file = pop_value()
-            elif option in ("-t", "--timestamps"):
-                options.timestamps = 1
-            elif option in ("-f", "--force"):
-                options.timestamps = 0
-            elif option in ("-v", "--verbose"):
-                options.verbose += 1
-            elif option in ("-p", "--embed-positions"):
-                Options.embed_pos_in_docstring = 1
-            elif option in ("-z", "--pre-import"):
-                Options.pre_import = pop_value()
-            elif option == "--cleanup":
-                Options.generate_cleanup_code = int(pop_value())
-            elif option in ("-D", "--no-docstrings"):
-                Options.docstrings = False
-            elif option in ("-a", "--annotate"):
-                Options.annotate = True
-            elif option == "--annotate-coverage":
-                Options.annotate = True
-                Options.annotate_coverage_xml = pop_value()
-            elif option == "--convert-range":
-                Options.convert_range = True
-            elif option == "--line-directives":
-                options.emit_linenums = True
-            elif option == "--no-c-in-traceback":
-                options.c_line_in_traceback = False
-            elif option == "--gdb":
-                options.gdb_debug = True
-                options.output_dir = os.curdir
-            elif option == "--gdb-outdir":
-                options.gdb_debug = True
-                options.output_dir = pop_value()
-            elif option == "--lenient":
-                Options.error_on_unknown_names = False
-                Options.error_on_uninitialized = False
-            elif option == '-2':
-                options.language_level = 2
-            elif option == '-3':
-                options.language_level = 3
-            elif option == '--3str':
-                options.language_level = '3str'
-            elif option == "--capi-reexport-cincludes":
-                options.capi_reexport_cincludes = True
-            elif option == "--fast-fail":
-                Options.fast_fail = True
-            elif option == "--cimport-from-pyx":
-                Options.cimport_from_pyx = True
-            elif option in ('-Werror', '--warning-errors'):
-                Options.warning_errors = True
-            elif option in ('-Wextra', '--warning-extra'):
-                options.compiler_directives.update(Options.extra_warnings)
-            elif option == "--old-style-globals":
-                Options.old_style_globals = True
-            elif option == "--directive" or option.startswith('-X'):
-                if option.startswith('-X') and option[2:].strip():
-                    x_args = option[2:]
-                else:
-                    x_args = pop_value()
-                try:
-                    options.compiler_directives = Options.parse_directive_list(
-                        x_args, relaxed_bool=True,
-                        current_settings=options.compiler_directives)
-                except ValueError as e:
-                    sys.stderr.write("Error in compiler directive: %s\n" % e.args[0])
-                    sys.exit(1)
-            elif option == "--compile-time-env" or option.startswith('-E'):
-                if option.startswith('-E') and option[2:].strip():
-                    x_args = option[2:]
-                else:
-                    x_args = pop_value()
-                try:
-                    options.compile_time_env = Options.parse_compile_time_env(
-                        x_args, current_settings=options.compile_time_env)
-                except ValueError as e:
-                    sys.stderr.write("Error in compile-time-env: %s\n" % e.args[0])
-                    sys.exit(1)
-            elif option.startswith('--debug'):
-                option = option[2:].replace('-', '_')
-                from . import DebugFlags
-                if option in dir(DebugFlags):
-                    setattr(DebugFlags, option, True)
-                else:
-                    sys.stderr.write("Unknown debug flag: %s\n" % option)
-                    bad_usage()
-            elif option in ('-h', '--help'):
-                sys.stdout.write(usage)
-                sys.exit(0)
+    options = Options.CompilationOptions(Options.default_options)
+    for name, value in vars(arguments).items():
+        if name.startswith('debug'):
+            from . import DebugFlags
+            if name in dir(DebugFlags):
+                setattr(DebugFlags, name, value)
             else:
@@ -204,4 +213,5 @@
             else:
-                sys.stderr.write("Unknown compiler flag: %s\n" % option)
-                sys.exit(1)
+                parser.error("Unknown debug flag: %s\n" % name)
+        elif hasattr(Options, name):
+            setattr(Options, name, value)
         else:
@@ -207,7 +217,4 @@
         else:
-            sources.append(pop_arg())
-
-    if pending_arg:
-        bad_usage()
+            setattr(options, name, value)
 
     if options.use_listing_file and len(sources) > 1:
@@ -212,6 +219,4 @@
 
     if options.use_listing_file and len(sources) > 1:
-        sys.stderr.write(
-            "cython: Only one source file allowed when using -o\n")
-        sys.exit(1)
+        parser.error("cython: Only one source file allowed when using -o\n")
     if len(sources) == 0 and not options.show_version:
@@ -217,3 +222,3 @@
     if len(sources) == 0 and not options.show_version:
-        bad_usage()
+        parser.error("cython: Need at least one source file\n")
     if Options.embed and len(sources) > 1:
@@ -219,5 +224,3 @@
     if Options.embed and len(sources) > 1:
-        sys.stderr.write(
-            "cython: Only one source file allowed when using -embed\n")
-        sys.exit(1)
+        parser.error("cython: Only one source file allowed when using -embed\n")
     return options, sources
@@ -223,2 +226,1 @@
     return options, sources
-
diff --git a/Cython/Compiler/Code.py b/Cython/Compiler/Code.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL0NvZGUucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL0NvZGUucHk= 100644
--- a/Cython/Compiler/Code.py
+++ b/Cython/Compiler/Code.py
@@ -1,4 +1,4 @@
-# cython: language_level = 2
+# cython: language_level=3str
 # cython: auto_pickle=False
 #
 #   Code output module
@@ -13,6 +13,8 @@
                DebugFlags=object, basestring=object, defaultdict=object,
                closing=object, partial=object)
 
+import hashlib
+import operator
 import os
 import re
 import shutil
@@ -16,11 +18,9 @@
 import os
 import re
 import shutil
-import sys
-import operator
 import textwrap
 from string import Template
 from functools import partial
 from contextlib import closing
 from collections import defaultdict
 
@@ -21,14 +21,9 @@
 import textwrap
 from string import Template
 from functools import partial
 from contextlib import closing
 from collections import defaultdict
 
-try:
-    import hashlib
-except ImportError:
-    import md5 as hashlib
-
 from . import Naming
 from . import Options
 from . import DebugFlags
@@ -43,8 +38,6 @@
 except ImportError:
     from builtins import str as basestring
 
-KEYWORDS_MUST_BE_BYTES = sys.version_info < (2, 7)
-
 
 non_portable_builtins_map = {
     # builtins that have different names in different Python versions
@@ -101,8 +94,6 @@
     '__build_class__',
     'ascii',  # might deserve an implementation in Cython
     #'exec',  # implemented in Cython
-    ## - Py2.7+
-    'memoryview',
     ## - platform specific
     'WindowsError',
     ## - others
@@ -203,6 +194,28 @@
     Cython_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
     return os.path.join(Cython_dir, "Utility")
 
+read_utilities_hook = None
+"""
+Override the hook for reading a utilities file that contains code fragments used
+by the codegen.
+
+The hook functions takes the path of the utilities file, and returns a list
+of strings, one per line.
+
+The default behavior is to open a file relative to get_utility_dir().
+"""
+
+def read_utilities_from_utility_dir(path):
+    """
+    Read all lines of the file at the provided path from a path relative
+    to get_utility_dir().
+    """
+    filename = os.path.join(get_utility_dir(), path)
+    with closing(Utils.open_source_file(filename, encoding='UTF-8')) as f:
+        return f.readlines()
+
+# by default, read utilities from the utility directory.
+read_utilities_hook = read_utilities_from_utility_dir
 
 class UtilityCodeBase(object):
     """
@@ -224,6 +237,15 @@
 
         [definitions]
 
+        ##### MyUtility #####
+        #@subsitute: tempita
+
+        [requires tempita substitution
+         - context can't be specified here though so only
+           tempita utility that requires no external context
+           will benefit from this tag
+         - only necessary when @required from non-tempita code]
+
     for prototypes and implementation respectively.  For non-python or
     -cython files backslashes should be used instead.  5 to 30 comment
     characters may be used on either side.
@@ -242,8 +264,7 @@
             return
 
         code = '\n'.join(lines)
-        if tags and 'substitute' in tags and tags['substitute'] == set(['naming']):
-            del tags['substitute']
+        if tags and 'substitute' in tags and 'naming' in tags['substitute']:
             try:
                 code = Template(code).substitute(vars(Naming))
             except (KeyError, ValueError) as e:
@@ -259,10 +280,8 @@
             utility[1] = code
         else:
             all_tags = utility[2]
-            if KEYWORDS_MUST_BE_BYTES:
-                type = type.encode('ASCII')
             all_tags[type] = code
 
         if tags:
             all_tags = utility[2]
             for name, values in tags.items():
@@ -264,10 +283,8 @@
             all_tags[type] = code
 
         if tags:
             all_tags = utility[2]
             for name, values in tags.items():
-                if KEYWORDS_MUST_BE_BYTES:
-                    name = name.encode('ASCII')
                 all_tags.setdefault(name, set()).update(values)
 
     @classmethod
@@ -276,7 +293,6 @@
         if utilities:
             return utilities
 
-        filename = os.path.join(get_utility_dir(), path)
         _, ext = os.path.splitext(path)
         if ext in ('.pyx', '.py', '.pxd', '.pxi'):
             comment = '#'
@@ -292,8 +308,7 @@
             {'C': comment}).match
         match_type = re.compile(r'(.+)[.](proto(?:[.]\S+)?|impl|init|cleanup)$').match
 
-        with closing(Utils.open_source_file(filename, encoding='UTF-8')) as f:
-            all_lines = f.readlines()
+        all_lines = read_utilities_hook(path)
 
         utilities = defaultdict(lambda: [None, None, {}])
         lines = []
@@ -335,6 +350,6 @@
         return utilities
 
     @classmethod
-    def load(cls, util_code_name, from_file=None, **kwargs):
+    def load(cls, util_code_name, from_file, **kwargs):
         """
         Load utility code from a file specified by from_file (relative to
@@ -339,6 +354,4 @@
         """
         Load utility code from a file specified by from_file (relative to
-        Cython/Utility) and name util_code_name.  If from_file is not given,
-        load it from the file util_code_name.*.  There should be only one
-        file matched by this pattern.
+        Cython/Utility) and name util_code_name.
         """
@@ -344,3 +357,4 @@
         """
+
         if '::' in util_code_name:
             from_file, util_code_name = util_code_name.rsplit('::', 1)
@@ -345,30 +359,7 @@
         if '::' in util_code_name:
             from_file, util_code_name = util_code_name.rsplit('::', 1)
-        if not from_file:
-            utility_dir = get_utility_dir()
-            prefix = util_code_name + '.'
-            try:
-                listing = os.listdir(utility_dir)
-            except OSError:
-                # XXX the code below assumes as 'zipimport.zipimporter' instance
-                # XXX should be easy to generalize, but too lazy right now to write it
-                import zipfile
-                global __loader__
-                loader = __loader__
-                archive = loader.archive
-                with closing(zipfile.ZipFile(archive)) as fileobj:
-                    listing = [os.path.basename(name)
-                               for name in fileobj.namelist()
-                               if os.path.join(archive, name).startswith(utility_dir)]
-            files = [filename for filename in listing
-                     if filename.startswith(prefix)]
-            if not files:
-                raise ValueError("No match found for utility code " + util_code_name)
-            if len(files) > 1:
-                raise ValueError("More than one filename match found for utility code " + util_code_name)
-            from_file = files[0]
-
+        assert from_file
         utilities = cls.load_utilities_from_file(from_file)
         proto, impl, tags = utilities[util_code_name]
 
         if tags:
@@ -371,7 +362,10 @@
         utilities = cls.load_utilities_from_file(from_file)
         proto, impl, tags = utilities[util_code_name]
 
         if tags:
+            if "substitute" in tags and "tempita" in tags["substitute"]:
+                if not issubclass(cls, TempitaUtilityCode):
+                    return TempitaUtilityCode.load(util_code_name, from_file, **kwargs)
             orig_kwargs = kwargs.copy()
             for name, values in tags.items():
                 if name in kwargs:
@@ -385,6 +379,12 @@
                         # dependencies are rarely unique, so use load_cached() when we can
                         values = [cls.load_cached(dep, from_file)
                                   for dep in sorted(values)]
+                elif name == 'substitute':
+                    # don't want to pass "naming" or "tempita" to the constructor
+                    # since these will have been handled
+                    values = values - set(['naming', 'tempita'])
+                    if not values:
+                        continue
                 elif not values:
                     values = None
                 elif len(values) == 1:
@@ -404,7 +404,7 @@
         return cls(**kwargs)
 
     @classmethod
-    def load_cached(cls, utility_code_name, from_file=None, __cache={}):
+    def load_cached(cls, utility_code_name, from_file, __cache={}):
         """
         Calls .load(), but using a per-type cache based on utility name and file name.
         """
@@ -417,7 +417,7 @@
         return code
 
     @classmethod
-    def load_as_string(cls, util_code_name, from_file=None, **kwargs):
+    def load_as_string(cls, util_code_name, from_file, **kwargs):
         """
         Load a utility code as a string. Returns (proto, implementation)
         """
@@ -828,8 +828,8 @@
 
         A C string referring to the variable is returned.
         """
-        if type.is_const and not type.is_reference:
-            type = type.const_base_type
+        if type.is_cv_qualified and not type.is_reference:
+            type = type.cv_base_type
         elif type.is_reference and not type.is_fake_reference:
             type = type.ref_base_type
         elif type.is_cfunction:
@@ -1110,7 +1110,11 @@
         'string_decls',
         'decls',
         'late_includes',
-        'all_the_rest',
+        'module_state',
+        'module_state_clear',
+        'module_state_traverse',
+        'module_state_defines',  # redefines names used in module_state/_clear/_traverse
+        'module_code',  # user code goes here
         'pystring_table',
         'cached_builtins',
         'cached_constants',
@@ -1151,8 +1155,10 @@
 
     def initialize_main_c_code(self):
         rootwriter = self.rootwriter
-        for part in self.code_layout:
-            self.parts[part] = rootwriter.insertion_point()
+        for i, part in enumerate(self.code_layout):
+            w = self.parts[part] = rootwriter.insertion_point()
+            if i > 0:
+                w.putln("/* #### Code section: %s ### */" % part)
 
         if not Options.cache_builtins:
             del self.parts['cached_builtins']
@@ -1166,7 +1172,7 @@
         w.putln("")
         w.putln("static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {")
         w.put_declare_refcount_context()
-        w.put_setup_refcount_context("__Pyx_InitCachedConstants")
+        w.put_setup_refcount_context(StringEncoding.EncodedString("__Pyx_InitCachedConstants"))
 
         w = self.parts['init_globals']
         w.enter_cfunc_scope()
@@ -1439,4 +1445,5 @@
                   for c in self.py_constants]
         consts.sort()
         decls_writer = self.parts['decls']
+        decls_writer.putln("#if !CYTHON_COMPILING_IN_LIMITED_API")
         for _, cname, c in consts:
@@ -1442,3 +1449,10 @@
         for _, cname, c in consts:
+            self.parts['module_state'].putln("%s;" % c.type.declaration_code(cname))
+            self.parts['module_state_defines'].putln(
+                "#define %s %s->%s" % (cname, Naming.modulestateglobal_cname, cname))
+            self.parts['module_state_clear'].putln(
+                "Py_CLEAR(clear_module_state->%s);" % cname)
+            self.parts['module_state_traverse'].putln(
+                "Py_VISIT(traverse_module_state->%s);" % cname)
             decls_writer.putln(
                 "static %s;" % c.type.declaration_code(cname))
@@ -1443,5 +1457,6 @@
             decls_writer.putln(
                 "static %s;" % c.type.declaration_code(cname))
+        decls_writer.putln("#endif")
 
     def generate_cached_methods_decls(self):
         if not self.cached_cmethods:
@@ -1453,8 +1468,8 @@
         for (type_cname, method_name), cname in sorted(self.cached_cmethods.items()):
             cnames.append(cname)
             method_name_cname = self.get_interned_identifier(StringEncoding.EncodedString(method_name)).cname
-            decl.putln('static __Pyx_CachedCFunction %s = {0, &%s, 0, 0, 0};' % (
-                cname, method_name_cname))
+            decl.putln('static __Pyx_CachedCFunction %s = {0, 0, 0, 0, 0};' % (
+                cname))
             # split type reference storage as it might not be static
             init.putln('%s.type = (PyObject*)&%s;' % (
                 cname, type_cname))
@@ -1458,6 +1473,9 @@
             # split type reference storage as it might not be static
             init.putln('%s.type = (PyObject*)&%s;' % (
                 cname, type_cname))
+            # method name string isn't static in limited api
+            init.putln('%s.method_name = &%s;' % (
+                cname, method_name_cname))
 
         if Options.generate_cleanup_code:
             cleanup = self.parts['cleanup_globals']
@@ -1495,9 +1513,10 @@
                 decls_writer.putln("static Py_UNICODE %s[] = { %s };" % (cname, utf16_array))
                 decls_writer.putln("#endif")
 
+        init_globals = self.parts['init_globals']
         if py_strings:
             self.use_utility_code(UtilityCode.load_cached("InitStrings", "StringTools.c"))
             py_strings.sort()
             w = self.parts['pystring_table']
             w.putln("")
             w.putln("static __Pyx_StringTabEntry %s[] = {" % Naming.stringtab_cname)
@@ -1498,10 +1517,22 @@
         if py_strings:
             self.use_utility_code(UtilityCode.load_cached("InitStrings", "StringTools.c"))
             py_strings.sort()
             w = self.parts['pystring_table']
             w.putln("")
             w.putln("static __Pyx_StringTabEntry %s[] = {" % Naming.stringtab_cname)
-            for c_cname, _, py_string in py_strings:
+            w.putln("#if CYTHON_COMPILING_IN_LIMITED_API")
+            w_limited_writer = w.insertion_point()
+            w.putln("#else")
+            w_not_limited_writer = w.insertion_point()
+            w.putln("#endif")
+            decls_writer.putln("#if !CYTHON_COMPILING_IN_LIMITED_API")
+            not_limited_api_decls_writer = decls_writer.insertion_point()
+            decls_writer.putln("#endif")
+            init_globals.putln("#if CYTHON_COMPILING_IN_LIMITED_API")
+            init_globals_limited_api = init_globals.insertion_point()
+            init_globals.putln("#endif")
+            for idx, py_string_args in enumerate(py_strings):
+                c_cname, _, py_string = py_string_args
                 if not py_string.is_str or not py_string.encoding or \
                         py_string.encoding in ('ASCII', 'USASCII', 'US-ASCII',
                                                'UTF8', 'UTF-8'):
@@ -1509,6 +1540,15 @@
                 else:
                     encoding = '"%s"' % py_string.encoding.lower()
 
-                decls_writer.putln(
+                self.parts['module_state'].putln("PyObject *%s;" % py_string.cname)
+                self.parts['module_state_defines'].putln("#define %s %s->%s" % (
+                    py_string.cname,
+                    Naming.modulestateglobal_cname,
+                    py_string.cname))
+                self.parts['module_state_clear'].putln("Py_CLEAR(clear_module_state->%s);" %
+                    py_string.cname)
+                self.parts['module_state_traverse'].putln("Py_VISIT(traverse_module_state->%s);" %
+                    py_string.cname)
+                not_limited_api_decls_writer.putln(
                     "static PyObject *%s;" % py_string.cname)
                 if py_string.py3str_cstring:
@@ -1513,10 +1553,10 @@
                     "static PyObject *%s;" % py_string.cname)
                 if py_string.py3str_cstring:
-                    w.putln("#if PY_MAJOR_VERSION >= 3")
-                    w.putln("{&%s, %s, sizeof(%s), %s, %d, %d, %d}," % (
+                    w_not_limited_writer.putln("#if PY_MAJOR_VERSION >= 3")
+                    w_not_limited_writer.putln("{&%s, %s, sizeof(%s), %s, %d, %d, %d}," % (
                         py_string.cname,
                         py_string.py3str_cstring.cname,
                         py_string.py3str_cstring.cname,
                         '0', 1, 0,
                         py_string.intern
                         ))
@@ -1517,11 +1557,11 @@
                         py_string.cname,
                         py_string.py3str_cstring.cname,
                         py_string.py3str_cstring.cname,
                         '0', 1, 0,
                         py_string.intern
                         ))
-                    w.putln("#else")
-                w.putln("{&%s, %s, sizeof(%s), %s, %d, %d, %d}," % (
+                    w_not_limited_writer.putln("#else")
+                w_not_limited_writer.putln("{&%s, %s, sizeof(%s), %s, %d, %d, %d}," % (
                     py_string.cname,
                     c_cname,
                     c_cname,
@@ -1531,7 +1571,20 @@
                     py_string.intern
                     ))
                 if py_string.py3str_cstring:
-                    w.putln("#endif")
+                    w_not_limited_writer.putln("#endif")
+                w_limited_writer.putln("{0, %s, sizeof(%s), %s, %d, %d, %d}," % (
+                    c_cname if not py_string.py3str_cstring else py_string.py3str_cstring.cname,
+                    c_cname if not py_string.py3str_cstring else py_string.py3str_cstring.cname,
+                    encoding if not py_string.py3str_cstring else '0',
+                    py_string.is_unicode,
+                    py_string.is_str,
+                    py_string.intern
+                    ))
+                init_globals_limited_api.putln("if (__Pyx_InitString(%s[%d], &%s) < 0) %s;" % (
+                    Naming.stringtab_cname,
+                    idx,
+                    py_string.cname,
+                    init_globals.error_goto(self.module_pos)))
             w.putln("{0, 0, 0, 0, 0, 0, 0}")
             w.putln("};")
 
@@ -1535,8 +1588,8 @@
             w.putln("{0, 0, 0, 0, 0, 0, 0}")
             w.putln("};")
 
-            init_globals = self.parts['init_globals']
+            init_globals.putln("#if !CYTHON_COMPILING_IN_LIMITED_API")
             init_globals.putln(
                 "if (__Pyx_InitStrings(%s) < 0) %s;" % (
                     Naming.stringtab_cname,
                     init_globals.error_goto(self.module_pos)))
@@ -1539,10 +1592,11 @@
             init_globals.putln(
                 "if (__Pyx_InitStrings(%s) < 0) %s;" % (
                     Naming.stringtab_cname,
                     init_globals.error_goto(self.module_pos)))
+            init_globals.putln("#endif")
 
     def generate_num_constants(self):
         consts = [(c.py_type, c.value[0] == '-', len(c.value), c.value, c.value_code, c)
                   for c in self.num_const_index.values()]
         consts.sort()
         decls_writer = self.parts['decls']
@@ -1543,9 +1597,10 @@
 
     def generate_num_constants(self):
         consts = [(c.py_type, c.value[0] == '-', len(c.value), c.value, c.value_code, c)
                   for c in self.num_const_index.values()]
         consts.sort()
         decls_writer = self.parts['decls']
+        decls_writer.putln("#if !CYTHON_COMPILING_IN_LIMITED_API")
         init_globals = self.parts['init_globals']
         for py_type, _, _, value, value_code, c in consts:
             cname = c.cname
@@ -1549,6 +1604,13 @@
         init_globals = self.parts['init_globals']
         for py_type, _, _, value, value_code, c in consts:
             cname = c.cname
+            self.parts['module_state'].putln("PyObject *%s;" % cname)
+            self.parts['module_state_defines'].putln("#define %s %s->%s" % (
+                cname, Naming.modulestateglobal_cname, cname))
+            self.parts['module_state_clear'].putln(
+                "Py_CLEAR(clear_module_state->%s);" % cname)
+            self.parts['module_state_traverse'].putln(
+                "Py_VISIT(traverse_module_state->%s);" % cname)
             decls_writer.putln("static PyObject *%s;" % cname)
             if py_type == 'float':
                 function = 'PyFloat_FromDouble(%s)'
@@ -1563,6 +1625,7 @@
             init_globals.putln('%s = %s; %s' % (
                 cname, function % value_code,
                 init_globals.error_goto_if_null(cname, self.module_pos)))
+        decls_writer.putln("#endif")
 
     # The functions below are there in a transition phase only
     # and will be deprecated. They are called from Nodes.BlockNode.
@@ -1890,7 +1953,7 @@
         include_dir = self.globalstate.common_utility_include_dir
         if include_dir and len(code) > 1024:
             include_file = "%s_%s.h" % (
-                name, hashlib.md5(code.encode('utf8')).hexdigest())
+                name, hashlib.sha1(code.encode('utf8')).hexdigest())
             path = os.path.join(include_dir, include_file)
             if not os.path.exists(path):
                 tmp_path = '%s.tmp%s' % (path, os.getpid())
@@ -1986,8 +2049,7 @@
             if type.is_pyobject:
                 self.putln("%s = NULL;" % decl)
             elif type.is_memoryviewslice:
-                from . import MemoryView
-                self.putln("%s = %s;" % (decl, MemoryView.memslice_entry_init))
+                self.putln("%s = %s;" % (decl, type.literal_code(type.default_value)))
             else:
                 self.putln("%s%s;" % (static and "static " or "", decl))
 
@@ -2034,16 +2096,16 @@
         from .PyrexTypes import py_object_type, typecast
         return typecast(py_object_type, type, cname)
 
-    def put_gotref(self, cname):
-        self.putln("__Pyx_GOTREF(%s);" % cname)
-
-    def put_giveref(self, cname):
-        self.putln("__Pyx_GIVEREF(%s);" % cname)
-
-    def put_xgiveref(self, cname):
-        self.putln("__Pyx_XGIVEREF(%s);" % cname)
-
-    def put_xgotref(self, cname):
-        self.putln("__Pyx_XGOTREF(%s);" % cname)
+    def put_gotref(self, cname, type):
+        type.generate_gotref(self, cname)
+
+    def put_giveref(self, cname, type):
+        type.generate_giveref(self, cname)
+
+    def put_xgiveref(self, cname, type):
+        type.generate_xgiveref(self, cname)
+
+    def put_xgotref(self, cname, type):
+        type.generate_xgotref(self, cname)
 
     def put_incref(self, cname, type, nanny=True):
@@ -2048,42 +2110,14 @@
 
     def put_incref(self, cname, type, nanny=True):
-        if nanny:
-            self.putln("__Pyx_INCREF(%s);" % self.as_pyobject(cname, type))
-        else:
-            self.putln("Py_INCREF(%s);" % self.as_pyobject(cname, type))
-
-    def put_decref(self, cname, type, nanny=True):
-        self._put_decref(cname, type, nanny, null_check=False, clear=False)
-
-    def put_var_gotref(self, entry):
-        if entry.type.is_pyobject:
-            self.putln("__Pyx_GOTREF(%s);" % self.entry_as_pyobject(entry))
-
-    def put_var_giveref(self, entry):
-        if entry.type.is_pyobject:
-            self.putln("__Pyx_GIVEREF(%s);" % self.entry_as_pyobject(entry))
-
-    def put_var_xgotref(self, entry):
-        if entry.type.is_pyobject:
-            self.putln("__Pyx_XGOTREF(%s);" % self.entry_as_pyobject(entry))
-
-    def put_var_xgiveref(self, entry):
-        if entry.type.is_pyobject:
-            self.putln("__Pyx_XGIVEREF(%s);" % self.entry_as_pyobject(entry))
-
-    def put_var_incref(self, entry, nanny=True):
-        if entry.type.is_pyobject:
-            if nanny:
-                self.putln("__Pyx_INCREF(%s);" % self.entry_as_pyobject(entry))
-            else:
-                self.putln("Py_INCREF(%s);" % self.entry_as_pyobject(entry))
-
-    def put_var_xincref(self, entry):
-        if entry.type.is_pyobject:
-            self.putln("__Pyx_XINCREF(%s);" % self.entry_as_pyobject(entry))
-
-    def put_decref_clear(self, cname, type, nanny=True, clear_before_decref=False):
-        self._put_decref(cname, type, nanny, null_check=False,
-                         clear=True, clear_before_decref=clear_before_decref)
+        # Note: original put_Memslice_Incref/Decref also added in some utility code
+        # this is unnecessary since the relevant utility code is loaded anyway if a memoryview is used
+        # and so has been removed. However, it's potentially a feature that might be useful here
+        type.generate_incref(self, cname, nanny=nanny)
+
+    def put_xincref(self, cname, type, nanny=True):
+        type.generate_xincref(self, cname, nanny=nanny)
+
+    def put_decref(self, cname, type, nanny=True, have_gil=True):
+        type.generate_decref(self, cname, nanny=nanny, have_gil=have_gil)
 
     def put_xdecref(self, cname, type, nanny=True, have_gil=True):
@@ -2088,69 +2122,63 @@
 
     def put_xdecref(self, cname, type, nanny=True, have_gil=True):
-        self._put_decref(cname, type, nanny, null_check=True,
-                         have_gil=have_gil, clear=False)
-
-    def put_xdecref_clear(self, cname, type, nanny=True, clear_before_decref=False):
-        self._put_decref(cname, type, nanny, null_check=True,
-                         clear=True, clear_before_decref=clear_before_decref)
-
-    def _put_decref(self, cname, type, nanny=True, null_check=False,
-                    have_gil=True, clear=False, clear_before_decref=False):
-        if type.is_memoryviewslice:
-            self.put_xdecref_memoryviewslice(cname, have_gil=have_gil)
-            return
-
-        prefix = '__Pyx' if nanny else 'Py'
-        X = 'X' if null_check else ''
-
-        if clear:
-            if clear_before_decref:
-                if not nanny:
-                    X = ''  # CPython doesn't have a Py_XCLEAR()
-                self.putln("%s_%sCLEAR(%s);" % (prefix, X, cname))
-            else:
-                self.putln("%s_%sDECREF(%s); %s = 0;" % (
-                    prefix, X, self.as_pyobject(cname, type), cname))
-        else:
-            self.putln("%s_%sDECREF(%s);" % (
-                prefix, X, self.as_pyobject(cname, type)))
-
-    def put_decref_set(self, cname, rhs_cname):
-        self.putln("__Pyx_DECREF_SET(%s, %s);" % (cname, rhs_cname))
-
-    def put_xdecref_set(self, cname, rhs_cname):
-        self.putln("__Pyx_XDECREF_SET(%s, %s);" % (cname, rhs_cname))
-
-    def put_var_decref(self, entry):
-        if entry.type.is_pyobject:
-            self.putln("__Pyx_XDECREF(%s);" % self.entry_as_pyobject(entry))
-
-    def put_var_xdecref(self, entry, nanny=True):
-        if entry.type.is_pyobject:
-            if nanny:
-                self.putln("__Pyx_XDECREF(%s);" % self.entry_as_pyobject(entry))
-            else:
-                self.putln("Py_XDECREF(%s);" % self.entry_as_pyobject(entry))
-
-    def put_var_decref_clear(self, entry):
-        self._put_var_decref_clear(entry, null_check=False)
-
-    def put_var_xdecref_clear(self, entry):
-        self._put_var_decref_clear(entry, null_check=True)
-
-    def _put_var_decref_clear(self, entry, null_check):
-        if entry.type.is_pyobject:
-            if entry.in_closure:
-                # reset before DECREF to make sure closure state is
-                # consistent during call to DECREF()
-                self.putln("__Pyx_%sCLEAR(%s);" % (
-                    null_check and 'X' or '',
-                    entry.cname))
-            else:
-                self.putln("__Pyx_%sDECREF(%s); %s = 0;" % (
-                    null_check and 'X' or '',
-                    self.entry_as_pyobject(entry),
-                    entry.cname))
+        type.generate_xdecref(self, cname, nanny=nanny, have_gil=have_gil)
+
+    def put_decref_clear(self, cname, type, clear_before_decref=False, nanny=True, have_gil=True):
+        type.generate_decref_clear(self, cname, clear_before_decref=clear_before_decref,
+                              nanny=nanny, have_gil=have_gil)
+
+    def put_xdecref_clear(self, cname, type, clear_before_decref=False, nanny=True, have_gil=True):
+        type.generate_xdecref_clear(self, cname, clear_before_decref=clear_before_decref,
+                              nanny=nanny, have_gil=have_gil)
+
+    def put_decref_set(self, cname, type, rhs_cname):
+        type.generate_decref_set(self, cname, rhs_cname)
+
+    def put_xdecref_set(self, cname, type, rhs_cname):
+        type.generate_xdecref_set(self, cname, rhs_cname)
+
+    def put_incref_memoryviewslice(self, slice_cname, type, have_gil):
+        # TODO ideally this would just be merged into "put_incref"
+        type.generate_incref_memoryviewslice(self, slice_cname, have_gil=have_gil)
+
+    def put_var_incref_memoryviewslice(self, entry, have_gil):
+        self.put_incref_memoryviewslice(entry.cname, entry.type, have_gil=have_gil)
+
+    def put_var_gotref(self, entry):
+        self.put_gotref(entry.cname, entry.type)
+
+    def put_var_giveref(self, entry):
+        self.put_giveref(entry.cname, entry.type)
+
+    def put_var_xgotref(self, entry):
+        self.put_xgotref(entry.cname, entry.type)
+
+    def put_var_xgiveref(self, entry):
+        self.put_xgiveref(entry.cname, entry.type)
+
+    def put_var_incref(self, entry, **kwds):
+        self.put_incref(entry.cname, entry.type, **kwds)
+
+    def put_var_xincref(self, entry, **kwds):
+        self.put_xincref(entry.cname, entry.type, **kwds)
+
+    def put_var_decref(self, entry, **kwds):
+        self.put_decref(entry.cname, entry.type, **kwds)
+
+    def put_var_xdecref(self, entry, **kwds):
+        self.put_xdecref(entry.cname, entry.type, **kwds)
+
+    def put_var_decref_clear(self, entry, **kwds):
+        self.put_decref_clear(entry.cname, entry.type, clear_before_decref=entry.in_closure, **kwds)
+
+    def put_var_decref_set(self, entry, rhs_cname, **kwds):
+        self.put_decref_set(entry.cname, entry.type, rhs_cname, **kwds)
+
+    def put_var_xdecref_set(self, entry, rhs_cname, **kwds):
+        self.put_xdecref_set(entry.cname, entry.type, rhs_cname, **kwds)
+
+    def put_var_xdecref_clear(self, entry, **kwds):
+        self.put_xdecref_clear(entry.cname, entry.type, clear_before_decref=entry.in_closure, **kwds)
 
     def put_var_decrefs(self, entries, used_only = 0):
         for entry in entries:
@@ -2168,19 +2196,6 @@
         for entry in entries:
             self.put_var_xdecref_clear(entry)
 
-    def put_incref_memoryviewslice(self, slice_cname, have_gil=False):
-        from . import MemoryView
-        self.globalstate.use_utility_code(MemoryView.memviewslice_init_code)
-        self.putln("__PYX_INC_MEMVIEW(&%s, %d);" % (slice_cname, int(have_gil)))
-
-    def put_xdecref_memoryviewslice(self, slice_cname, have_gil=False):
-        from . import MemoryView
-        self.globalstate.use_utility_code(MemoryView.memviewslice_init_code)
-        self.putln("__PYX_XDEC_MEMVIEW(&%s, %d);" % (slice_cname, int(have_gil)))
-
-    def put_xgiveref_memoryviewslice(self, slice_cname):
-        self.put_xgiveref("%s.memview" % slice_cname)
-
     def put_init_to_py_none(self, cname, type, nanny=True):
         from .PyrexTypes import py_object_type, typecast
         py_none = typecast(type, py_object_type, "Py_None")
@@ -2216,8 +2231,6 @@
             method_flags += [TypeSlots.method_coexist]
         func_ptr = wrapper_code_writer.put_pymethoddef_wrapper(entry) if wrapper_code_writer else entry.func_cname
         # Add required casts, but try not to shadow real warnings.
-        cast = '__Pyx_PyCFunctionFast' if 'METH_FASTCALL' in method_flags else 'PyCFunction'
-        if 'METH_KEYWORDS' in method_flags:
-            cast += 'WithKeywords'
+        cast = entry.signature.method_function_type()
         if cast != 'PyCFunction':
             func_ptr = '(void*)(%s)%s' % (cast, func_ptr)
@@ -2222,3 +2235,4 @@
         if cast != 'PyCFunction':
             func_ptr = '(void*)(%s)%s' % (cast, func_ptr)
+        entry_name = entry.name.as_c_string_literal()
         self.putln(
@@ -2224,6 +2238,6 @@
         self.putln(
-            '{"%s", (PyCFunction)%s, %s, %s}%s' % (
-                entry.name,
+            '{%s, (PyCFunction)%s, %s, %s}%s' % (
+                entry_name,
                 func_ptr,
                 "|".join(method_flags),
                 entry.doc_cname if entry.doc else '0',
@@ -2232,8 +2246,9 @@
     def put_pymethoddef_wrapper(self, entry):
         func_cname = entry.func_cname
         if entry.is_special:
-            method_flags = entry.signature.method_flags()
-            if method_flags and 'METH_NOARGS' in method_flags:
+            method_flags = entry.signature.method_flags() or []
+            from .TypeSlots import method_noargs
+            if method_noargs in method_flags:
                 # Special NOARGS methods really take no arguments besides 'self', but PyCFunction expects one.
                 func_cname = Naming.method_wrapper_prefix + func_cname
                 self.putln("static PyObject *%s(PyObject *self, CYTHON_UNUSED PyObject *arg) {return %s(self);}" % (
@@ -2242,6 +2257,12 @@
 
     # GIL methods
 
+    def use_fast_gil_utility_code(self):
+        if self.globalstate.directives['fast_gil']:
+            self.globalstate.use_utility_code(UtilityCode.load_cached("FastGil", "ModuleSetupCode.c"))
+        else:
+            self.globalstate.use_utility_code(UtilityCode.load_cached("NoFastGil", "ModuleSetupCode.c"))
+
     def put_ensure_gil(self, declare_gilstate=True, variable=None):
         """
         Acquire the GIL. The generated code is safe even when no PyThreadState
@@ -2251,10 +2272,7 @@
         """
         self.globalstate.use_utility_code(
             UtilityCode.load_cached("ForceInitThreads", "ModuleSetupCode.c"))
-        if self.globalstate.directives['fast_gil']:
-          self.globalstate.use_utility_code(UtilityCode.load_cached("FastGil", "ModuleSetupCode.c"))
-        else:
-          self.globalstate.use_utility_code(UtilityCode.load_cached("NoFastGil", "ModuleSetupCode.c"))
+        self.use_fast_gil_utility_code()
         self.putln("#ifdef WITH_THREAD")
         if not variable:
             variable = '__pyx_gilstate_save'
@@ -2267,10 +2285,7 @@
         """
         Releases the GIL, corresponds to `put_ensure_gil`.
         """
-        if self.globalstate.directives['fast_gil']:
-          self.globalstate.use_utility_code(UtilityCode.load_cached("FastGil", "ModuleSetupCode.c"))
-        else:
-          self.globalstate.use_utility_code(UtilityCode.load_cached("NoFastGil", "ModuleSetupCode.c"))
+        self.use_fast_gil_utility_code()
         if not variable:
             variable = '__pyx_gilstate_save'
         self.putln("#ifdef WITH_THREAD")
@@ -2282,10 +2297,7 @@
         Acquire the GIL. The thread's thread state must have been initialized
         by a previous `put_release_gil`
         """
-        if self.globalstate.directives['fast_gil']:
-          self.globalstate.use_utility_code(UtilityCode.load_cached("FastGil", "ModuleSetupCode.c"))
-        else:
-          self.globalstate.use_utility_code(UtilityCode.load_cached("NoFastGil", "ModuleSetupCode.c"))
+        self.use_fast_gil_utility_code()
         self.putln("#ifdef WITH_THREAD")
         self.putln("__Pyx_FastGIL_Forget();")
         if variable:
@@ -2295,10 +2307,7 @@
 
     def put_release_gil(self, variable=None):
         "Release the GIL, corresponds to `put_acquire_gil`."
-        if self.globalstate.directives['fast_gil']:
-          self.globalstate.use_utility_code(UtilityCode.load_cached("FastGil", "ModuleSetupCode.c"))
-        else:
-          self.globalstate.use_utility_code(UtilityCode.load_cached("NoFastGil", "ModuleSetupCode.c"))
+        self.use_fast_gil_utility_code()
         self.putln("#ifdef WITH_THREAD")
         self.putln("PyThreadState *_save;")
         self.putln("Py_UNBLOCK_THREADS")
@@ -2344,12 +2353,5 @@
         self.funcstate.should_declare_error_indicator = True
         if used:
             self.funcstate.uses_error_indicator = True
-        if self.code_config.c_line_in_traceback:
-            cinfo = " %s = %s;" % (Naming.clineno_cname, Naming.line_c_macro)
-        else:
-            cinfo = ""
-
-        return "%s = %s[%s]; %s = %s;%s" % (
-            Naming.filename_cname,
-            Naming.filetable_cname,
+        return "__PYX_MARK_ERR_POS(%s, %s)" % (
             self.lookup_filename(pos[0]),
@@ -2355,10 +2357,8 @@
             self.lookup_filename(pos[0]),
-            Naming.lineno_cname,
-            pos[1],
-            cinfo)
-
-    def error_goto(self, pos):
+            pos[1])
+
+    def error_goto(self, pos, used=True):
         lbl = self.funcstate.error_label
         self.funcstate.use_label(lbl)
         if pos is None:
             return 'goto %s;' % lbl
@@ -2361,7 +2361,10 @@
         lbl = self.funcstate.error_label
         self.funcstate.use_label(lbl)
         if pos is None:
             return 'goto %s;' % lbl
+        self.funcstate.should_declare_error_indicator = True
+        if used:
+            self.funcstate.uses_error_indicator = True
         return "__PYX_ERR(%s, %s, %s)" % (
             self.lookup_filename(pos[0]),
             pos[1],
@@ -2386,6 +2389,7 @@
         self.putln('__Pyx_RefNannyDeclarations')
 
     def put_setup_refcount_context(self, name, acquire_gil=False):
+        name = name.as_c_string_literal() # handle unicode names
         if acquire_gil:
             self.globalstate.use_utility_code(
                 UtilityCode.load_cached("ForceInitThreads", "ModuleSetupCode.c"))
@@ -2389,10 +2393,10 @@
         if acquire_gil:
             self.globalstate.use_utility_code(
                 UtilityCode.load_cached("ForceInitThreads", "ModuleSetupCode.c"))
-        self.putln('__Pyx_RefNannySetupContext("%s", %d);' % (name, acquire_gil and 1 or 0))
-
-    def put_finish_refcount_context(self):
-        self.putln("__Pyx_RefNannyFinishContext();")
+        self.putln('__Pyx_RefNannySetupContext(%s, %d);' % (name, acquire_gil and 1 or 0))
+
+    def put_finish_refcount_context(self, nogil=False):
+        self.putln("__Pyx_RefNannyFinishContextNogil()" if nogil else "__Pyx_RefNannyFinishContext();")
 
     def put_add_traceback(self, qualified_name, include_cline=True):
         """
@@ -2400,9 +2404,10 @@
 
         qualified_name should be the qualified name of the function.
         """
+        qualified_name = qualified_name.as_c_string_literal() # handle unicode names
         format_tuple = (
             qualified_name,
             Naming.clineno_cname if include_cline else 0,
             Naming.lineno_cname,
             Naming.filename_cname,
         )
@@ -2403,7 +2408,8 @@
         format_tuple = (
             qualified_name,
             Naming.clineno_cname if include_cline else 0,
             Naming.lineno_cname,
             Naming.filename_cname,
         )
+
         self.funcstate.uses_error_indicator = True
@@ -2409,5 +2415,5 @@
         self.funcstate.uses_error_indicator = True
-        self.putln('__Pyx_AddTraceback("%s", %s, %s, %s);' % format_tuple)
+        self.putln('__Pyx_AddTraceback(%s, %s, %s, %s);' % format_tuple)
 
     def put_unraisable(self, qualified_name, nogil=False):
         """
diff --git a/Cython/Compiler/CythonScope.py b/Cython/Compiler/CythonScope.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL0N5dGhvblNjb3BlLnB5..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL0N5dGhvblNjb3BlLnB5 100644
--- a/Cython/Compiler/CythonScope.py
+++ b/Cython/Compiler/CythonScope.py
@@ -127,6 +127,15 @@
                                             self.viewscope, cython_scope=self,
                                             whitelist=MemoryView.view_utility_whitelist)
 
+        # Marks the types as being cython_builtin_type so that they can be
+        # extended from without Cython attempting to import cython.view
+        ext_types = [ entry.type
+                         for entry in view_utility_scope.entries.values()
+                         if entry.type.is_extension_type ]
+        for ext_type in ext_types:
+            ext_type.is_cython_builtin_type = 1
+
+
         # self.entries["array"] = view_utility_scope.entries.pop("array")
 
 
diff --git a/Cython/Compiler/Errors.py b/Cython/Compiler/Errors.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL0Vycm9ycy5weQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL0Vycm9ycy5weQ== 100644
--- a/Cython/Compiler/Errors.py
+++ b/Cython/Compiler/Errors.py
@@ -60,7 +60,5 @@
         self.message_only = message
         self.formatted_message = format_error(message, position)
         self.reported = False
-    # Deprecated and withdrawn in 2.6:
-    #   self.message = message
         Exception.__init__(self, self.formatted_message)
         # Python Exception subclass pickling is broken,
@@ -65,6 +63,6 @@
         Exception.__init__(self, self.formatted_message)
         # Python Exception subclass pickling is broken,
-        # see http://bugs.python.org/issue1692335
+        # see https://bugs.python.org/issue1692335
         self.args = (position, message)
 
     def __str__(self):
@@ -74,8 +72,6 @@
 
     def __init__(self, position = None, message = ""):
         self.position = position
-    # Deprecated and withdrawn in 2.6:
-    #   self.message = message
         Exception.__init__(self, format_position(position) + message)
 
 class InternalError(Exception):
@@ -114,7 +110,7 @@
             message += u'%s: %s' % (cause.__class__.__name__, cause)
         CompileError.__init__(self, pos, message)
         # Python Exception subclass pickling is broken,
-        # see http://bugs.python.org/issue1692335
+        # see https://bugs.python.org/issue1692335
         self.args = (pos, context, message, cause, stacktrace)
 
 class NoElementTreeInstalledException(PyrexError):
@@ -171,7 +167,6 @@
         if Options.fast_fail:
             raise AbortError("fatal errors")
 
-
 def error(position, message):
     #print("Errors.error:", repr(position), repr(message)) ###
     if position is None:
@@ -184,8 +179,14 @@
 
 LEVEL = 1 # warn about all errors level 1 or higher
 
+def _write_file_encode(file, line):
+    try:
+        file.write(line)
+    except UnicodeEncodeError:
+        file.write(line.encode('ascii', 'replace'))
+
 
 def message(position, message, level=1):
     if level < LEVEL:
         return
     warn = CompileWarning(position, message)
@@ -187,7 +188,7 @@
 
 def message(position, message, level=1):
     if level < LEVEL:
         return
     warn = CompileWarning(position, message)
-    line = "note: %s\n" % warn
+    line = u"note: %s\n" % warn
     if listing_file:
@@ -193,3 +194,3 @@
     if listing_file:
-        listing_file.write(line)
+        _write_file_encode(listing_file, line)
     if echo_file:
@@ -195,5 +196,5 @@
     if echo_file:
-        echo_file.write(line)
+        _write_file_encode(echo_file, line)
     return warn
 
 
@@ -203,5 +204,5 @@
     if Options.warning_errors and position:
         return error(position, message)
     warn = CompileWarning(position, message)
-    line = "warning: %s\n" % warn
+    line = u"warning: %s\n" % warn
     if listing_file:
@@ -207,3 +208,3 @@
     if listing_file:
-        listing_file.write(line)
+        _write_file_encode(listing_file, line)
     if echo_file:
@@ -209,5 +210,5 @@
     if echo_file:
-        echo_file.write(line)
+        _write_file_encode(echo_file, line)
     return warn
 
 
@@ -216,5 +217,5 @@
     if level < LEVEL or message in _warn_once_seen:
         return
     warn = CompileWarning(position, message)
-    line = "warning: %s\n" % warn
+    line = u"warning: %s\n" % warn
     if listing_file:
@@ -220,3 +221,3 @@
     if listing_file:
-        listing_file.write(line)
+        _write_file_encode(listing_file, line)
     if echo_file:
@@ -222,5 +223,5 @@
     if echo_file:
-        echo_file.write(line)
+        _write_file_encode(echo_file, line)
     _warn_once_seen[message] = True
     return warn
 
diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL0V4cHJOb2Rlcy5weQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL0V4cHJOb2Rlcy5weQ== 100644
--- a/Cython/Compiler/ExprNodes.py
+++ b/Cython/Compiler/ExprNodes.py
@@ -28,7 +28,7 @@
 from . import StringEncoding
 from . import Naming
 from . import Nodes
-from .Nodes import Node, utility_code_for_imports, analyse_type_annotation
+from .Nodes import Node, utility_code_for_imports
 from . import PyrexTypes
 from .PyrexTypes import py_object_type, c_long_type, typecast, error_type, \
     unspecified_type
@@ -448,6 +448,7 @@
 
     saved_subexpr_nodes = None
     is_temp = False
+    has_temp_moved = False  # if True then attempting to do anything but free the temp is invalid
     is_target = False
     is_starred = False
 
@@ -498,6 +499,22 @@
         else:
             return self.calculate_result_code()
 
+    def _make_move_result_rhs(self, result, allow_move=True):
+        if (self.is_temp and allow_move and
+                self.type.is_cpp_class and not self.type.is_reference):
+            self.has_temp_moved = True
+            return "__PYX_STD_MOVE_IF_SUPPORTED({0})".format(result)
+        else:
+            return result
+
+    def move_result_rhs(self):
+        return self._make_move_result_rhs(self.result())
+
+    def move_result_rhs_as(self, type):
+        allow_move = (type and not type.is_reference and not type.needs_refcounting)
+        return self._make_move_result_rhs(self.result_as(type),
+                                          allow_move=allow_move)
+
     def pythran_result(self, type_=None):
         if is_pythran_supported_node_or_none(self):
             return to_pythran(self)
@@ -655,6 +672,19 @@
         # type, return that type, else None.
         return None
 
+    def analyse_as_specialized_type(self, env):
+        type = self.analyse_as_type(env)
+        if type and type.is_fused and env.fused_to_specific:
+            # while it would be nice to test "if entry.type in env.fused_to_specific"
+            # rather than try/catch this doesn't work reliably (mainly for nested fused types)
+            try:
+                return type.specialize(env.fused_to_specific)
+            except KeyError:
+                pass
+        if type and type.is_fused:
+            error(self.pos, "Type is not specific")
+        return type
+
     def analyse_as_extension_type(self, env):
         # If this node can be interpreted as a reference to an
         # extension type or builtin type, return its type, else None.
@@ -746,6 +776,6 @@
 
     def make_owned_reference(self, code):
         """
-        If result is a pyobject, make sure we own a reference to it.
+        Make sure we own a reference to result.
         If the result is in a temp, it is already a new reference.
         """
@@ -750,9 +780,9 @@
         If the result is in a temp, it is already a new reference.
         """
-        if self.type.is_pyobject and not self.result_in_temp():
+        if not self.result_in_temp():
             code.put_incref(self.result(), self.ctype())
 
     def make_owned_memoryviewslice(self, code):
         """
         Make sure we own the reference to this memoryview slice.
         """
@@ -753,7 +783,8 @@
             code.put_incref(self.result(), self.ctype())
 
     def make_owned_memoryviewslice(self, code):
         """
         Make sure we own the reference to this memoryview slice.
         """
+        # TODO ideally this would be shared with "make_owned_reference"
         if not self.result_in_temp():
@@ -759,6 +790,6 @@
         if not self.result_in_temp():
-            code.put_incref_memoryviewslice(self.result(),
-                                            have_gil=self.in_nogil_context)
+            code.put_incref_memoryviewslice(self.result(), self.type,
+                                            have_gil=not self.in_nogil_context)
 
     def generate_evaluation_code(self, code):
         #  Generate code to evaluate this node and
@@ -791,13 +822,11 @@
                 self.generate_subexpr_disposal_code(code)
                 self.free_subexpr_temps(code)
             if self.result():
-                if self.type.is_pyobject:
-                    code.put_decref_clear(self.result(), self.ctype())
-                elif self.type.is_memoryviewslice:
-                    code.put_xdecref_memoryviewslice(
-                            self.result(), have_gil=not self.in_nogil_context)
-                    code.putln("%s.memview = NULL;" % self.result())
-                    code.putln("%s.data = NULL;" % self.result())
+                code.put_decref_clear(self.result(), self.ctype(),
+                                        have_gil=not self.in_nogil_context)
+            if self.has_temp_moved:
+                code.globalstate.use_utility_code(
+                    UtilityCode.load_cached("MoveIfSupported", "CppSupport.cpp"))
         else:
             # Already done if self.is_temp
             self.generate_subexpr_disposal_code(code)
@@ -819,6 +848,10 @@
             elif self.type.is_memoryviewslice:
                 code.putln("%s.memview = NULL;" % self.result())
                 code.putln("%s.data = NULL;" % self.result())
+
+            if self.has_temp_moved:
+                code.globalstate.use_utility_code(
+                    UtilityCode.load_cached("MoveIfSupported", "CppSupport.cpp"))
         else:
             self.generate_subexpr_disposal_code(code)
 
@@ -849,6 +882,32 @@
     def generate_function_definitions(self, env, code):
         pass
 
+    # ----Generation of small bits of reference counting --
+
+    def generate_decref_set(self, code, rhs):
+        code.put_decref_set(self.result(), self.ctype(), rhs)
+
+    def generate_xdecref_set(self, code, rhs):
+        code.put_xdecref_set(self.result(), self.ctype(), rhs)
+
+    def generate_gotref(self, code, handle_null=False,
+                        maybe_null_extra_check=True):
+        if not (handle_null and self.cf_is_null):
+            if (handle_null and self.cf_maybe_null
+                    and maybe_null_extra_check):
+                self.generate_xgotref(code)
+            else:
+                code.put_gotref(self.result(), self.ctype())
+
+    def generate_xgotref(self, code):
+        code.put_xgotref(self.result(), self.ctype())
+
+    def generate_giveref(self, code):
+        code.put_giveref(self.result(), self.ctype())
+
+    def generate_xgiveref(self, code):
+        code.put_xgiveref(self.result(), self.ctype())
+
     # ---------------- Annotation ---------------------
 
     def annotate(self, code):
@@ -883,8 +942,8 @@
         if used_as_reference and not src_type.is_reference:
             dst_type = dst_type.ref_base_type
 
-        if src_type.is_const:
-            src_type = src_type.const_base_type
+        if src_type.is_cv_qualified:
+            src_type = src_type.cv_base_type
 
         if src_type.is_fused or dst_type.is_fused:
             # See if we are coercing a fused function to a pointer to a
@@ -1108,6 +1167,7 @@
 
     is_literal = 1
     type = py_object_type
+    nogil_check = None
 
     def is_simple(self):
         return 1
@@ -1133,8 +1193,6 @@
 
     constant_result = None
 
-    nogil_check = None
-
     def compile_time_value(self, denv):
         return None
 
@@ -1204,7 +1262,7 @@
 
     def calculate_result_code(self):
         if self.type.is_pyobject:
-            return self.value and 'Py_True' or 'Py_False'
+            return 'Py_True' if self.value else 'Py_False'
         else:
             return str(int(self.value))
 
@@ -1434,11 +1492,7 @@
         return type
 
     global_entry = env.global_scope().lookup(name)
-    if global_entry and global_entry.type and (
-            global_entry.type.is_extension_type
-            or global_entry.type.is_struct_or_union
-            or global_entry.type.is_builtin_type
-            or global_entry.type.is_cpp_class):
+    if global_entry and global_entry.is_type and global_entry.type:
         return global_entry.type
 
     from .TreeFragment import TreeFragment
@@ -1778,7 +1832,7 @@
                     self.result(),
                     float(self.value),
                     code.error_goto_if_null(self.result(), self.pos)))
-            code.put_gotref(self.py_result())
+            self.generate_gotref(code)
 
 
 class NewExprNode(AtomicExprNode):
@@ -1928,7 +1982,7 @@
             return
 
         annotation = self.annotation
-        if annotation.is_string_literal:
+        if annotation.expr.is_string_literal:
             # name: "description" => not a type, but still a declared variable or attribute
             atype = None
         else:
@@ -1932,6 +1986,6 @@
             # name: "description" => not a type, but still a declared variable or attribute
             atype = None
         else:
-            _, atype = analyse_type_annotation(annotation, env)
+            _, atype = annotation.analyse_type_annotation(env)
         if atype is None:
             atype = unspecified_type if as_target and env.directives['infer_types'] != False else py_object_type
@@ -1936,3 +1990,5 @@
         if atype is None:
             atype = unspecified_type if as_target and env.directives['infer_types'] != False else py_object_type
+        if atype.is_fused and env.fused_to_specific:
+            atype = atype.specialize(env.fused_to_specific)
         self.entry = env.declare_var(name, atype, self.pos, is_cdef=not as_target)
@@ -1938,5 +1994,5 @@
         self.entry = env.declare_var(name, atype, self.pos, is_cdef=not as_target)
-        self.entry.annotation = annotation
+        self.entry.annotation = annotation.expr
 
     def analyse_as_module(self, env):
         # Try to interpret this as a reference to a cimported module.
@@ -2116,7 +2172,7 @@
     def may_be_none(self):
         if self.cf_state and self.type and (self.type.is_pyobject or
                                             self.type.is_memoryviewslice):
-            # gard against infinite recursion on self-dependencies
+            # guard against infinite recursion on self-dependencies
             if getattr(self, '_none_checking', False):
                 # self-dependency - either this node receives a None
                 # value from *another* node, or it can not reference
@@ -2219,7 +2275,7 @@
             if not self.cf_is_null:
                 code.putln("}")
             code.putln(code.error_goto_if_null(self.result(), self.pos))
-            code.put_gotref(self.py_result())
+            self.generate_gotref(code)
 
         elif entry.is_builtin and not entry.scope.is_module_scope:
             # known builtin
@@ -2232,7 +2288,7 @@
                 self.result(),
                 interned_cname,
                 code.error_goto_if_null(self.result(), self.pos)))
-            code.put_gotref(self.py_result())
+            self.generate_gotref(code)
 
         elif entry.is_pyglobal or (entry.is_builtin and entry.scope.is_module_scope):
             # name in class body, global name or unknown builtin
@@ -2256,7 +2312,7 @@
                         entry.scope.namespace_cname,
                         interned_cname,
                         code.error_goto_if_null(self.result(), self.pos)))
-            code.put_gotref(self.py_result())
+            self.generate_gotref(code)
 
         elif entry.is_local or entry.in_closure or entry.from_closure or entry.type.is_memoryviewslice:
             # Raise UnboundLocalError for objects and memoryviewslices
@@ -2294,4 +2350,10 @@
             elif entry.scope.is_module_scope:
                 setter = 'PyDict_SetItem'
                 namespace = Naming.moddict_cname
+                code.putln("{")
+                code.putln("#if CYTHON_COMPILING_IN_LIMITED_API")
+                # global module dict doesn't seems to exist in the limited API so create a temp variable
+                code.putln("PyObject *%s = PyModule_GetDict(%s); %s" % (
+                    namespace, Naming.module_cname, code.error_goto_if_null(namespace, self.pos)))
+                code.putln("#endif")
             elif entry.is_pyclass_attr:
@@ -2297,6 +2359,8 @@
             elif entry.is_pyclass_attr:
-                code.globalstate.use_utility_code(UtilityCode.load_cached("SetNameInClass", "ObjectHandling.c"))
-                setter = '__Pyx_SetNameInClass'
+                # Special-case setting __new__
+                n = "SetNewInClass" if self.name == "__new__" else "SetNameInClass"
+                code.globalstate.use_utility_code(UtilityCode.load_cached(n, "ObjectHandling.c"))
+                setter = '__Pyx_' + n
             else:
                 assert False, repr(entry)
             code.put_error_if_neg(
@@ -2315,6 +2379,8 @@
                 # in Py2.6+, we need to invalidate the method cache
                 code.putln("PyType_Modified(%s);" %
                            entry.scope.parent_type.typeptr_cname)
+            elif entry.scope.is_module_scope:
+                code.putln("}")
         else:
             if self.type.is_memoryviewslice:
                 self.generate_acquire_memoryviewslice(rhs, code)
@@ -2338,10 +2404,6 @@
                     rhs.make_owned_reference(code)
                     is_external_ref = entry.is_cglobal or self.entry.in_closure or self.entry.from_closure
                     if is_external_ref:
-                        if not self.cf_is_null:
-                            if self.cf_maybe_null:
-                                code.put_xgotref(self.py_result())
-                            else:
-                                code.put_gotref(self.py_result())
+                        self.generate_gotref(code, handle_null=True)
                     assigned = True
                     if entry.is_cglobal:
@@ -2346,7 +2408,6 @@
                     assigned = True
                     if entry.is_cglobal:
-                        code.put_decref_set(
-                            self.result(), rhs.result_as(self.ctype()))
+                        self.generate_decref_set(code, rhs.result_as(self.ctype()))
                     else:
                         if not self.cf_is_null:
                             if self.cf_maybe_null:
@@ -2350,6 +2411,5 @@
                     else:
                         if not self.cf_is_null:
                             if self.cf_maybe_null:
-                                code.put_xdecref_set(
-                                    self.result(), rhs.result_as(self.ctype()))
+                                self.generate_xdecref_set(code, rhs.result_as(self.ctype()))
                             else:
@@ -2355,6 +2415,5 @@
                             else:
-                                code.put_decref_set(
-                                    self.result(), rhs.result_as(self.ctype()))
+                                self.generate_decref_set(code, rhs.result_as(self.ctype()))
                         else:
                             assigned = False
                     if is_external_ref:
@@ -2358,7 +2417,7 @@
                         else:
                             assigned = False
                     if is_external_ref:
-                        code.put_giveref(rhs.py_result())
+                        rhs.generate_giveref(code)
             if not self.type.is_memoryviewslice:
                 if not assigned:
                     if overloaded_assignment:
@@ -2362,7 +2421,7 @@
             if not self.type.is_memoryviewslice:
                 if not assigned:
                     if overloaded_assignment:
-                        result = rhs.result()
+                        result = rhs.move_result_rhs()
                         if exception_check == '+':
                             translate_cpp_exception(
                                 code, self.pos,
@@ -2372,7 +2431,7 @@
                         else:
                             code.putln('%s = %s;' % (self.result(), result))
                     else:
-                        result = rhs.result_as(self.ctype())
+                        result = rhs.move_result_rhs_as(self.ctype())
 
                         if is_pythran_expr(self.type):
                             code.putln('new (&%s) decltype(%s){%s};' % (self.result(), self.result(), result))
@@ -2461,16 +2520,10 @@
                 if self.cf_maybe_null and not ignore_nonexisting:
                     code.put_error_if_unbound(self.pos, self.entry)
 
-                if self.entry.type.is_pyobject:
-                    if self.entry.in_closure:
-                        # generator
-                        if ignore_nonexisting and self.cf_maybe_null:
-                            code.put_xgotref(self.result())
-                        else:
-                            code.put_gotref(self.result())
-                    if ignore_nonexisting and self.cf_maybe_null:
-                        code.put_xdecref(self.result(), self.ctype())
-                    else:
-                        code.put_decref(self.result(), self.ctype())
-                    code.putln('%s = NULL;' % self.result())
+                if self.entry.in_closure:
+                    # generator
+                    self.generate_gotref(code, handle_null=True, maybe_null_extra_check=ignore_nonexisting)
+                if ignore_nonexisting and self.cf_maybe_null:
+                    code.put_xdecref_clear(self.result(), self.ctype(),
+                                        have_gil=not self.nogil)
                 else:
@@ -2476,6 +2529,6 @@
                 else:
-                    code.put_xdecref_memoryviewslice(self.entry.cname,
-                                                     have_gil=not self.nogil)
+                    code.put_decref_clear(self.result(), self.ctype(),
+                                          have_gil=not self.nogil)
         else:
             error(self.pos, "Deletion of C names not supported")
 
@@ -2514,7 +2567,7 @@
                 self.result(),
                 self.arg.py_result(),
                 code.error_goto_if_null(self.result(), self.pos)))
-        code.put_gotref(self.py_result())
+        self.generate_gotref(code)
 
 
 class ImportNode(ExprNode):
@@ -2533,5 +2586,7 @@
     #                           relative to the current module.
     #                     None: decide the level according to language level and
     #                           directives
+    #  get_top_level_module   int          true: return top-level module, false: return imported module
+    #  module_names           TupleNode    the separate names of the module and submodules, or None
 
     type = py_object_type
@@ -2536,7 +2591,10 @@
 
     type = py_object_type
-
-    subexprs = ['module_name', 'name_list']
+    module_names = None
+    get_top_level_module = False
+    is_temp = True
+
+    subexprs = ['module_name', 'name_list', 'module_names']
 
     def analyse_types(self, env):
         if self.level is None:
@@ -2540,10 +2598,12 @@
 
     def analyse_types(self, env):
         if self.level is None:
-            if (env.directives['py2_import'] or
-                Future.absolute_import not in env.global_scope().context.future_directives):
+            # For modules in packages, and without 'absolute_import' enabled, try relative (Py2) import first.
+            if env.global_scope().parent_module and (
+                    env.directives['py2_import'] or
+                    Future.absolute_import not in env.global_scope().context.future_directives):
                 self.level = -1
             else:
                 self.level = 0
         module_name = self.module_name.analyse_types(env)
         self.module_name = module_name.coerce_to_pyobject(env)
@@ -2545,8 +2605,9 @@
                 self.level = -1
             else:
                 self.level = 0
         module_name = self.module_name.analyse_types(env)
         self.module_name = module_name.coerce_to_pyobject(env)
+        assert self.module_name.is_string_literal
         if self.name_list:
             name_list = self.name_list.analyse_types(env)
             self.name_list = name_list.coerce_to_pyobject(env)
@@ -2550,9 +2611,13 @@
         if self.name_list:
             name_list = self.name_list.analyse_types(env)
             self.name_list = name_list.coerce_to_pyobject(env)
-        self.is_temp = 1
+        elif '.' in self.module_name.value:
+            self.module_names = TupleNode(self.module_name.pos, args=[
+                IdentifierStringNode(self.module_name.pos, value=part, constant_result=part)
+                for part in map(StringEncoding.EncodedString, self.module_name.value.split('.'))
+            ]).analyse_types(env)
         return self
 
     gil_message = "Python import"
 
     def generate_result_code(self, code):
@@ -2554,23 +2619,28 @@
         return self
 
     gil_message = "Python import"
 
     def generate_result_code(self, code):
-        if self.name_list:
-            name_list_code = self.name_list.py_result()
-        else:
-            name_list_code = "0"
-
-        code.globalstate.use_utility_code(UtilityCode.load_cached("Import", "ImportExport.c"))
-        import_code = "__Pyx_Import(%s, %s, %d)" % (
-            self.module_name.py_result(),
-            name_list_code,
-            self.level)
-
-        if (self.level <= 0 and
-                self.module_name.is_string_literal and
-                self.module_name.value in utility_code_for_imports):
-            helper_func, code_name, code_file = utility_code_for_imports[self.module_name.value]
+        assert self.module_name.is_string_literal
+        module_name = self.module_name.value
+
+        if self.level == 0 and not self.name_list and not self.get_top_level_module:
+            if self.module_names:
+                assert self.module_names.is_literal  # make sure we create the tuple only once
+            code.globalstate.use_utility_code(UtilityCode.load_cached("ImportDottedModule", "ImportExport.c"))
+            import_code = "__Pyx_ImportDottedModule(%s, %s)" % (
+                self.module_name.py_result(),
+                self.module_names.py_result() if self.module_names else 'NULL',
+            )
+        else:
+            code.globalstate.use_utility_code(UtilityCode.load_cached("Import", "ImportExport.c"))
+            import_code = "__Pyx_Import(%s, %s, %d)" % (
+                self.module_name.py_result(),
+                self.name_list.py_result() if self.name_list else '0',
+                self.level)
+
+        if self.level <= 0 and module_name in utility_code_for_imports:
+            helper_func, code_name, code_file = utility_code_for_imports[module_name]
             code.globalstate.use_utility_code(UtilityCode.load_cached(code_name, code_file))
             import_code = '%s(%s)' % (helper_func, import_code)
 
@@ -2578,7 +2648,7 @@
             self.result(),
             import_code,
             code.error_goto_if_null(self.result(), self.pos)))
-        code.put_gotref(self.py_result())
+        self.generate_gotref(code)
 
 
 class IteratorNode(ExprNode):
@@ -2734,7 +2804,7 @@
                 self.result(),
                 self.sequence.py_result(),
                 code.error_goto_if_null(self.result(), self.pos)))
-            code.put_gotref(self.py_result())
+            self.generate_gotref(code)
 
             # PyObject_GetIter() fails if "tp_iternext" is not set, but the check below
             # makes it visible to the C compiler that the pointer really isn't NULL, so that
@@ -2781,7 +2851,7 @@
                 self.counter_cname,
                 inc_dec,
                 code.error_goto_if_null(result_name, self.pos)))
-        code.put_gotref(result_name)
+        code.put_gotref(result_name, py_object_type)
         code.putln("#endif")
 
     def generate_iter_next_result_code(self, result_name, code):
@@ -2832,7 +2902,7 @@
         code.putln("}")
         code.putln("break;")
         code.putln("}")
-        code.put_gotref(result_name)
+        code.put_gotref(result_name, py_object_type)
         code.putln("}")
 
     def free_temps(self, code):
@@ -2874,8 +2944,8 @@
             item_type = env.lookup_operator_for_types(self.pos, "*", [iterator_type]).type.return_type
             if item_type.is_reference:
                 item_type = item_type.ref_base_type
-            if item_type.is_const:
-                item_type = item_type.const_base_type
+            if item_type.is_cv_qualified:
+                item_type = item_type.cv_base_type
             return item_type
         else:
             # Avoid duplication of complicated logic.
@@ -2924,7 +2994,7 @@
             self.result(),
             self.sequence.py_result(),
             code.error_goto_if_null(self.result(), self.pos)))
-        code.put_gotref(self.result())
+        self.generate_gotref(code)
 
 
 class AsyncNextNode(AtomicExprNode):
@@ -2954,7 +3024,7 @@
             self.result(),
             self.iterator.py_result(),
             code.error_goto_if_null(self.result(), self.pos)))
-        code.put_gotref(self.result())
+        self.generate_gotref(code)
 
 
 class WithExitCallNode(ExprNode):
@@ -2997,7 +3067,7 @@
         self.args.free_temps(code)
 
         code.putln(code.error_goto_if_null(result_var, self.pos))
-        code.put_gotref(result_var)
+        code.put_gotref(result_var, py_object_type)
 
         if self.await_expr:
             # FIXME: result_var temp currently leaks into the closure
@@ -3129,6 +3199,7 @@
     #
     type = unicode_type
     is_temp = True
+    gil_message = "String concatenation"
 
     subexprs = ['values']
 
@@ -3151,7 +3222,7 @@
             list_var,
             num_items,
             code.error_goto_if_null(list_var, self.pos)))
-        code.put_gotref(list_var)
+        code.put_gotref(list_var, py_object_type)
         code.putln("%s = 0;" % ulength_var)
         code.putln("%s = 127;" % max_char_var)  # at least ASCII character range
 
@@ -3195,7 +3266,7 @@
                     max_char_var, max_char_value, max_char_var, max_char_value, max_char_var))
             code.putln("%s += %s;" % (ulength_var, ulength))
 
-            code.put_giveref(node.py_result())
+            node.generate_giveref(code)
             code.putln('PyTuple_SET_ITEM(%s, %s, %s);' % (list_var, i, node.py_result()))
             node.generate_post_assignment_code(code)
             node.free_temps(code)
@@ -3210,7 +3281,7 @@
             ulength_var,
             max_char_var,
             code.error_goto_if_null(self.py_result(), self.pos)))
-        code.put_gotref(self.py_result())
+        self.generate_gotref(code)
 
         code.put_decref_clear(list_var, py_object_type)
         code.funcstate.release_temp(list_var)
@@ -3231,6 +3302,7 @@
     type = unicode_type
     is_temp = True
     c_format_spec = None
+    gil_message = "String formatting"
 
     find_conversion_func = {
         's': 'PyObject_Unicode',
@@ -3267,7 +3339,7 @@
                 self.result(),
                 convert_func_call,
                 code.error_goto_if_null(self.result(), self.pos)))
-            code.put_gotref(self.py_result())
+            self.generate_gotref(code)
             return
 
         value_result = self.value.py_result()
@@ -3306,7 +3378,7 @@
             value_result,
             format_spec,
             code.error_goto_if_null(self.result(), self.pos)))
-        code.put_gotref(self.py_result())
+        self.generate_gotref(code)
 
 
 #-------------------------------------------------------------------
@@ -3952,9 +4024,12 @@
             else:
                 assert False, "unexpected base type in indexing: %s" % self.base.type
         elif self.base.type.is_cfunction:
-            return "%s<%s>" % (
-                self.base.result(),
-                ",".join([param.empty_declaration_code() for param in self.type_indices]))
+            if self.base.entry.is_cgetter:
+                index_code = "(%s[%s])"
+            else:
+                return "%s<%s>" % (
+                    self.base.result(),
+                    ",".join([param.empty_declaration_code() for param in self.type_indices]))
         elif self.base.type.is_ctuple:
             index = self.index.constant_result
             if index < 0:
@@ -4053,7 +4128,7 @@
                     self.extra_index_params(code),
                     code.error_goto_if(error_check % self.result(), self.pos)))
         if self.type.is_pyobject:
-            code.put_gotref(self.py_result())
+            self.generate_gotref(code)
 
     def generate_setitem_code(self, value_code, code):
         if self.index.type.is_int:
@@ -4200,6 +4275,9 @@
     # Whether we're assigning to a buffer (in that case it needs to be writable)
     writable_needed = False
 
+    # Any indexing temp variables that we need to clean up.
+    index_temps = ()
+
     def analyse_target_types(self, env):
         self.analyse_types(env, getting=False)
 
@@ -4284,7 +4362,7 @@
                     warning(self.pos, "Use boundscheck(False) for faster access", level=1)
 
         # Assign indices to temps of at least (s)size_t to allow further index calculations.
-        index_temps = [self.get_index_in_temp(code,ivar) for ivar in self.indices]
+        self.index_temps = index_temps = [self.get_index_in_temp(code,ivar) for ivar in self.indices]
 
         # Generate buffer access code using these temps
         from . import Buffer
@@ -4342,7 +4420,7 @@
                                                manage_ref=False)
             rhs_code = rhs.result()
             code.putln("%s = %s;" % (ptr, ptrexpr))
-            code.put_gotref("*%s" % ptr)
+            code.put_gotref("*%s" % ptr, self.buffer_type.dtype)
             code.putln("__Pyx_INCREF(%s); __Pyx_DECREF(*%s);" % (
                 rhs_code, ptr))
             code.putln("*%s %s= %s;" % (ptr, op, rhs_code))
@@ -4346,7 +4424,7 @@
             code.putln("__Pyx_INCREF(%s); __Pyx_DECREF(*%s);" % (
                 rhs_code, ptr))
             code.putln("*%s %s= %s;" % (ptr, op, rhs_code))
-            code.put_giveref("*%s" % ptr)
+            code.put_giveref("*%s" % ptr, self.buffer_type.dtype)
             code.funcstate.release_temp(ptr)
         else:
             # Simple case
@@ -4370,6 +4448,12 @@
             code.putln("%s = (PyObject *) *%s;" % (self.result(), self.buffer_ptr_code))
             code.putln("__Pyx_INCREF((PyObject*)%s);" % self.result())
 
+    def free_temps(self, code):
+        for temp in self.index_temps:
+            code.funcstate.release_temp(temp)
+        self.index_temps = ()
+        super(BufferIndexNode, self).free_temps(code)
+
 
 class MemoryViewIndexNode(BufferIndexNode):
 
@@ -4603,7 +4687,7 @@
         assert not list(it)
 
         buffer_entry.generate_buffer_slice_code(
-            code, self.original_indices, self.result(),
+            code, self.original_indices, self.result(), self.type,
             have_gil=have_gil, have_slices=have_slices,
             directives=code.globalstate.directives)
 
@@ -4705,4 +4789,12 @@
             code.putln("%s __pyx_temp_slice = %s;" % (slice_decl, self.dst.result()))
             dst_temp = "__pyx_temp_slice"
 
+        force_strided = False
+        indices = self.dst.original_indices
+        for idx in indices:
+            if isinstance(idx, SliceNode) and not (idx.start.is_none and
+                                                   idx.stop.is_none and
+                                                   idx.step.is_none):
+                force_strided = True
+
         slice_iter_obj = MemoryView.slice_iter(self.dst.type, dst_temp,
@@ -4708,5 +4800,6 @@
         slice_iter_obj = MemoryView.slice_iter(self.dst.type, dst_temp,
-                                               self.dst.type.ndim, code)
+                                               self.dst.type.ndim, code,
+                                               force_strided=force_strided)
         p = slice_iter_obj.start_loops()
 
         if dtype.is_pyobject:
@@ -5039,7 +5132,7 @@
                     start_code,
                     stop_code,
                     code.error_goto_if_null(result, self.pos)))
-        code.put_gotref(self.py_result())
+        self.generate_gotref(code)
 
     def generate_assignment_code(self, rhs, code, overloaded_assignment=False,
         exception_check=None, exception_value=None):
@@ -5274,5 +5367,5 @@
                 self.stop.py_result(),
                 self.step.py_result(),
                 code.error_goto_if_null(self.result(), self.pos)))
-        code.put_gotref(self.py_result())
+        self.generate_gotref(code)
         if self.is_literal:
@@ -5278,5 +5371,5 @@
         if self.is_literal:
-            code.put_giveref(self.py_result())
+            self.generate_giveref(code)
 
 class SliceIntNode(SliceNode):
     #  start:stop:step in subscript list
@@ -5373,6 +5466,9 @@
                         return PyrexTypes.c_double_type
                     elif function.entry.name in Builtin.types_that_construct_their_instance:
                         return result_type
+        func_type = self.function.analyse_as_type(env)
+        if func_type and (func_type.is_struct_or_union or func_type.is_cpp_class):
+            return func_type
         return py_object_type
 
     def type_dependencies(self, env):
@@ -5563,6 +5659,7 @@
             self.analyse_c_function_call(env)
             if func_type.exception_check == '+':
                 self.is_temp = True
+
         return self
 
     def function_type(self):
@@ -5799,8 +5896,8 @@
         expected_nargs = max_nargs - func_type.optional_arg_count
         actual_nargs = len(self.args)
         for formal_arg, actual_arg in args[:expected_nargs]:
-                arg_code = actual_arg.result_as(formal_arg.type)
-                arg_list_code.append(arg_code)
+            arg_code = actual_arg.move_result_rhs_as(formal_arg.type)
+            arg_list_code.append(arg_code)
 
         if func_type.is_overridable:
             arg_list_code.append(str(int(self.wrapper_call or self.function.entry.is_unbound_cmethod)))
@@ -5813,7 +5910,7 @@
             arg_list_code.append(optional_args)
 
         for actual_arg in self.args[len(formal_args):]:
-            arg_list_code.append(actual_arg.result())
+            arg_list_code.append(actual_arg.move_result_rhs())
 
         result = "%s(%s)" % (self.function.result(), ', '.join(arg_list_code))
         return result
@@ -5863,7 +5960,7 @@
                     arg.py_result(),
                     code.error_goto_if_null(self.result(), self.pos)))
 
-        code.put_gotref(self.py_result())
+        self.generate_gotref(code)
 
         for subexpr in subexprs:
             if subexpr is not None:
@@ -5882,7 +5979,7 @@
                     self.function.py_result(),
                     arg_code,
                     code.error_goto_if_null(self.result(), self.pos)))
-            code.put_gotref(self.py_result())
+            self.generate_gotref(code)
         elif func_type.is_cfunction:
             if self.has_optional_args:
                 actual_nargs = len(self.args)
@@ -5943,7 +6040,7 @@
                         goto_error = ""
                     code.putln("%s%s; %s" % (lhs, rhs, goto_error))
                 if self.type.is_pyobject and self.result():
-                    code.put_gotref(self.py_result())
+                    self.generate_gotref(code)
             if self.has_optional_args:
                 code.funcstate.release_temp(self.opt_arg_struct)
 
@@ -6010,10 +6107,8 @@
 
         self_arg = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
         code.putln("%s = NULL;" % self_arg)
-        arg_offset_cname = None
-        if len(args) > 1:
-            arg_offset_cname = code.funcstate.allocate_temp(PyrexTypes.c_int_type, manage_ref=False)
-            code.putln("%s = 0;" % arg_offset_cname)
+        arg_offset_cname = code.funcstate.allocate_temp(PyrexTypes.c_int_type, manage_ref=False)
+        code.putln("%s = 0;" % arg_offset_cname)
 
         def attribute_is_likely_method(attr):
             obj = attr.obj
@@ -6045,9 +6140,8 @@
         code.put_incref(self_arg, py_object_type)
         code.put_incref("function", py_object_type)
         # free method object as early to possible to enable reuse from CPython's freelist
-        code.put_decref_set(function, "function")
-        if len(args) > 1:
-            code.putln("%s = 1;" % arg_offset_cname)
+        code.put_decref_set(function, py_object_type, "function")
+        code.putln("%s = 1;" % arg_offset_cname)
         code.putln("}")
         code.putln("}")
 
@@ -6051,34 +6145,25 @@
         code.putln("}")
         code.putln("}")
 
-        if not args:
-            # fastest special case: try to avoid tuple creation
-            code.globalstate.use_utility_code(
-                UtilityCode.load_cached("PyObjectCallNoArg", "ObjectHandling.c"))
-            code.globalstate.use_utility_code(
-                UtilityCode.load_cached("PyObjectCallOneArg", "ObjectHandling.c"))
-            code.putln(
-                "%s = (%s) ? __Pyx_PyObject_CallOneArg(%s, %s) : __Pyx_PyObject_CallNoArg(%s);" % (
-                    self.result(), self_arg,
-                    function, self_arg,
-                    function))
-            code.put_xdecref_clear(self_arg, py_object_type)
-            code.funcstate.release_temp(self_arg)
-            code.putln(code.error_goto_if_null(self.result(), self.pos))
-            code.put_gotref(self.py_result())
-        elif len(args) == 1:
-            # fastest special case: try to avoid tuple creation
-            code.globalstate.use_utility_code(
-                UtilityCode.load_cached("PyObjectCall2Args", "ObjectHandling.c"))
-            code.globalstate.use_utility_code(
-                UtilityCode.load_cached("PyObjectCallOneArg", "ObjectHandling.c"))
-            arg = args[0]
-            code.putln(
-                "%s = (%s) ? __Pyx_PyObject_Call2Args(%s, %s, %s) : __Pyx_PyObject_CallOneArg(%s, %s);" % (
-                    self.result(), self_arg,
-                    function, self_arg, arg.py_result(),
-                    function, arg.py_result()))
-            code.put_xdecref_clear(self_arg, py_object_type)
-            code.funcstate.release_temp(self_arg)
+        # actually call the function
+        code.globalstate.use_utility_code(
+            UtilityCode.load_cached("PyObjectFastCall", "ObjectHandling.c"))
+
+        code.putln("{")
+        code.putln("PyObject *__pyx_callargs[%d] = {%s, %s};" % (
+            len(args)+1,
+            self_arg,
+            ', '.join(arg.py_result() for arg in args)))
+        code.putln("%s = __Pyx_PyObject_FastCall(%s, __pyx_callargs+1-%s, %d+%s);" % (
+            self.result(),
+            function,
+            arg_offset_cname,
+            len(args),
+            arg_offset_cname))
+
+        code.put_xdecref_clear(self_arg, py_object_type)
+        code.funcstate.release_temp(self_arg)
+        code.funcstate.release_temp(arg_offset_cname)
+        for arg in args:
             arg.generate_disposal_code(code)
             arg.free_temps(code)
@@ -6083,78 +6168,7 @@
             arg.generate_disposal_code(code)
             arg.free_temps(code)
-            code.putln(code.error_goto_if_null(self.result(), self.pos))
-            code.put_gotref(self.py_result())
-        else:
-            code.globalstate.use_utility_code(
-                UtilityCode.load_cached("PyFunctionFastCall", "ObjectHandling.c"))
-            code.globalstate.use_utility_code(
-                UtilityCode.load_cached("PyCFunctionFastCall", "ObjectHandling.c"))
-            for test_func, call_prefix in [('PyFunction_Check', 'Py'), ('__Pyx_PyFastCFunction_Check', 'PyC')]:
-                code.putln("#if CYTHON_FAST_%sCALL" % call_prefix.upper())
-                code.putln("if (%s(%s)) {" % (test_func, function))
-                code.putln("PyObject *%s[%d] = {%s, %s};" % (
-                    Naming.quick_temp_cname,
-                    len(args)+1,
-                    self_arg,
-                    ', '.join(arg.py_result() for arg in args)))
-                code.putln("%s = __Pyx_%sFunction_FastCall(%s, %s+1-%s, %d+%s); %s" % (
-                    self.result(),
-                    call_prefix,
-                    function,
-                    Naming.quick_temp_cname,
-                    arg_offset_cname,
-                    len(args),
-                    arg_offset_cname,
-                    code.error_goto_if_null(self.result(), self.pos)))
-                code.put_xdecref_clear(self_arg, py_object_type)
-                code.put_gotref(self.py_result())
-                for arg in args:
-                    arg.generate_disposal_code(code)
-                code.putln("} else")
-                code.putln("#endif")
-
-            code.putln("{")
-            args_tuple = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
-            code.putln("%s = PyTuple_New(%d+%s); %s" % (
-                args_tuple, len(args), arg_offset_cname,
-                code.error_goto_if_null(args_tuple, self.pos)))
-            code.put_gotref(args_tuple)
-
-            if len(args) > 1:
-                code.putln("if (%s) {" % self_arg)
-            code.putln("__Pyx_GIVEREF(%s); PyTuple_SET_ITEM(%s, 0, %s); %s = NULL;" % (
-                self_arg, args_tuple, self_arg, self_arg))  # stealing owned ref in this case
-            code.funcstate.release_temp(self_arg)
-            if len(args) > 1:
-                code.putln("}")
-
-            for i, arg in enumerate(args):
-                arg.make_owned_reference(code)
-                code.put_giveref(arg.py_result())
-                code.putln("PyTuple_SET_ITEM(%s, %d+%s, %s);" % (
-                    args_tuple, i, arg_offset_cname, arg.py_result()))
-            if len(args) > 1:
-                code.funcstate.release_temp(arg_offset_cname)
-
-            for arg in args:
-                arg.generate_post_assignment_code(code)
-                arg.free_temps(code)
-
-            code.globalstate.use_utility_code(
-                UtilityCode.load_cached("PyObjectCall", "ObjectHandling.c"))
-            code.putln(
-                "%s = __Pyx_PyObject_Call(%s, %s, NULL); %s" % (
-                    self.result(),
-                    function, args_tuple,
-                    code.error_goto_if_null(self.result(), self.pos)))
-            code.put_gotref(self.py_result())
-
-            code.put_decref_clear(args_tuple, py_object_type)
-            code.funcstate.release_temp(args_tuple)
-
-            if len(args) == 1:
-                code.putln("}")
-            code.putln("}")  # !CYTHON_FAST_PYCALL
+        code.putln(code.error_goto_if_null(self.result(), self.pos))
+        self.generate_gotref(code)
 
         if reuse_function_temp:
             self.function.generate_disposal_code(code)
@@ -6162,6 +6176,7 @@
         else:
             code.put_decref_clear(function, py_object_type)
             code.funcstate.release_temp(function)
+        code.putln("}")
 
 
 class InlinedDefNodeCallNode(CallNode):
@@ -6259,7 +6274,7 @@
                 self.function.def_node.entry.pyfunc_cname,
                 arg_code,
                 code.error_goto_if_null(self.result(), self.pos)))
-        code.put_gotref(self.py_result())
+        self.generate_gotref(code)
 
 
 class PythonCapiFunctionNode(ExprNode):
@@ -6329,7 +6344,7 @@
             self.result(), call_code,
             code.error_goto_if_null(self.result(), self.pos)
         ))
-        code.put_gotref(self.result())
+        self.generate_gotref(code)
 
 
 class GeneralCallNode(CallNode):
@@ -6547,7 +6562,7 @@
                 self.positional_args.py_result(),
                 kwargs,
                 code.error_goto_if_null(self.result(), self.pos)))
-        code.put_gotref(self.py_result())
+        self.generate_gotref(code)
 
 
 class AsTupleNode(ExprNode):
@@ -6589,7 +6604,7 @@
                 self.result(),
                 cfunc, self.arg.py_result(),
                 code.error_goto_if_null(self.result(), self.pos)))
-        code.put_gotref(self.py_result())
+        self.generate_gotref(code)
 
 
 class MergedDictNode(ExprNode):
@@ -6691,8 +6706,8 @@
                 self.result(),
                 item.py_result(),
                 code.error_goto_if_null(self.result(), item.pos)))
-            code.put_gotref(self.result())
+            self.generate_gotref(code)
             item.generate_disposal_code(code)
 
         if item.type is not dict_type:
             code.putln('} else {')
@@ -6695,8 +6710,10 @@
             item.generate_disposal_code(code)
 
         if item.type is not dict_type:
             code.putln('} else {')
-            code.putln("%s = PyObject_CallFunctionObjArgs((PyObject*)&PyDict_Type, %s, NULL); %s" % (
+            code.globalstate.use_utility_code(UtilityCode.load_cached(
+                "PyObjectCallOneArg", "ObjectHandling.c"))
+            code.putln("%s = __Pyx_PyObject_CallOneArg((PyObject*)&PyDict_Type, %s); %s" % (
                 self.result(),
                 item.py_result(),
                 code.error_goto_if_null(self.result(), self.pos)))
@@ -6700,7 +6717,7 @@
                 self.result(),
                 item.py_result(),
                 code.error_goto_if_null(self.result(), self.pos)))
-            code.put_gotref(self.py_result())
+            self.generate_gotref(code)
             item.generate_disposal_code(code)
             code.putln('}')
         item.free_temps(code)
@@ -6772,7 +6789,7 @@
     is_attribute = 1
     subexprs = ['obj']
 
-    type = PyrexTypes.error_type
+    _type = PyrexTypes.error_type
     entry = None
     is_called = 0
     needs_none_check = True
@@ -6780,6 +6797,20 @@
     is_special_lookup = False
     is_py_attr = 0
 
+    @property
+    def type(self):
+        if self._type.is_cfunction and hasattr(self._type, 'entry') and self._type.entry.is_cgetter:
+            return self._type.return_type
+        return self._type
+
+    @type.setter
+    def type(self, value):
+        # XXX review where the attribute is set
+        # make sure it is not already a cgetter
+        if self._type.is_cfunction and hasattr(self._type, 'entry') and self._type.entry.is_cgetter:
+            error(self.pos, "%s.type already set" % self.__name__)
+        self._type = value
+
     def as_cython_attribute(self):
         if (isinstance(self.obj, NameNode) and
                 self.obj.is_cython_module and not
@@ -7055,7 +7086,7 @@
                 # (foo = pycfunction(foo_func_obj)) and need to go through
                 # regular Python lookup as well
                 if (entry.is_variable and not entry.fused_cfunction) or entry.is_cmethod:
-                    self.type = entry.type
+                    self._type = entry.type
                     self.member = entry.cname
                     return
                 else:
@@ -7075,7 +7106,7 @@
         # mangle private '__*' Python attributes used inside of a class
         self.attribute = env.mangle_class_private_name(self.attribute)
         self.member = self.attribute
-        self.type = py_object_type
+        self._type = py_object_type
         self.is_py_attr = 1
 
         if not obj_type.is_pyobject and not obj_type.is_error:
@@ -7157,6 +7188,8 @@
         obj_code = obj.result_as(obj.type)
         #print "...obj_code =", obj_code ###
         if self.entry and self.entry.is_cmethod:
+            if self.entry.is_cgetter:
+                return "%s(%s)" % (self.entry.func_cname, obj_code)
             if obj.type.is_extension_type and not self.entry.is_builtin_cmethod:
                 if self.entry.final_func_cname:
                     return self.entry.final_func_cname
@@ -7203,7 +7236,7 @@
                     self.obj.py_result(),
                     code.intern_identifier(self.attribute),
                     code.error_goto_if_null(self.result(), self.pos)))
-            code.put_gotref(self.py_result())
+            self.generate_gotref(code)
         elif self.type.is_memoryviewslice:
             if self.is_memslice_transpose:
                 # transpose the slice
@@ -7214,10 +7247,11 @@
                         return
 
                 code.putln("%s = %s;" % (self.result(), self.obj.result()))
-                code.put_incref_memoryviewslice(self.result(), have_gil=True)
-
-                T = "__pyx_memslice_transpose(&%s) == 0"
-                code.putln(code.error_goto_if(T % self.result(), self.pos))
+                code.put_incref_memoryviewslice(self.result(), self.type,
+                                have_gil=True)
+
+                T = "__pyx_memslice_transpose(&%s)" % self.result()
+                code.putln(code.error_goto_if_neg(T, self.pos))
             elif self.initialized_check:
                 code.putln(
                     'if (unlikely(!%s.memview)) {'
@@ -7237,10 +7271,7 @@
     def generate_disposal_code(self, code):
         if self.is_temp and self.type.is_memoryviewslice and self.is_memslice_transpose:
             # mirror condition for putting the memview incref here:
-            code.put_xdecref_memoryviewslice(
-                    self.result(), have_gil=True)
-            code.putln("%s.memview = NULL;" % self.result())
-            code.putln("%s.data = NULL;" % self.result())
+            code.put_xdecref_clear(self.result(), self.type, have_gil=True)
         else:
             ExprNode.generate_disposal_code(self, code)
 
@@ -7266,8 +7297,8 @@
             select_code = self.result()
             if self.type.is_pyobject and self.use_managed_ref:
                 rhs.make_owned_reference(code)
-                code.put_giveref(rhs.py_result())
-                code.put_gotref(select_code)
+                rhs.generate_giveref(code)
+                code.put_gotref(select_code, self.type)
                 code.put_decref(select_code, self.ctype())
             elif self.type.is_memoryviewslice:
                 from . import MemoryView
@@ -7278,7 +7309,7 @@
                 code.putln(
                     "%s = %s;" % (
                         select_code,
-                        rhs.result_as(self.ctype())))
+                        rhs.move_result_rhs_as(self.ctype())))
                         #rhs.result()))
             rhs.generate_post_assignment_code(code)
             rhs.free_temps(code)
@@ -7513,7 +7544,7 @@
                 len(self.args),
                 ', '.join(arg.py_result() for arg in self.args),
                 code.error_goto_if_null(target, self.pos)))
-            code.put_gotref(target)
+            code.put_gotref(target, py_object_type)
         elif self.type.is_ctuple:
             for i, arg in enumerate(self.args):
                 code.putln("%s.f%s = %s;" % (
@@ -7530,7 +7561,7 @@
             code.putln("%s = %s(%s%s); %s" % (
                 target, create_func, arg_count, size_factor,
                 code.error_goto_if_null(target, self.pos)))
-            code.put_gotref(target)
+            code.put_gotref(target, py_object_type)
 
             if c_mult:
                 # FIXME: can't use a temp variable here as the code may
@@ -7554,7 +7585,7 @@
                 arg = self.args[i]
                 if c_mult or not arg.result_in_temp():
                     code.put_incref(arg.result(), arg.ctype())
-                code.put_giveref(arg.py_result())
+                arg.generate_giveref(code)
                 code.putln("%s(%s, %s, %s);" % (
                     set_item_func,
                     target,
@@ -7571,7 +7602,7 @@
                 Naming.quick_temp_cname, target, mult_factor.py_result(),
                 code.error_goto_if_null(Naming.quick_temp_cname, self.pos)
                 ))
-            code.put_gotref(Naming.quick_temp_cname)
+            code.put_gotref(Naming.quick_temp_cname, py_object_type)
             code.put_decref(target, py_object_type)
             code.putln('%s = %s;' % (target, Naming.quick_temp_cname))
             code.putln('}')
@@ -7689,7 +7720,7 @@
                 code.putln("%s = PySequence_ITEM(sequence, %d); %s" % (
                     item.result(), i,
                     code.error_goto_if_null(item.result(), self.pos)))
-                code.put_gotref(item.result())
+                code.put_gotref(item.result(), item.type)
         else:
             code.putln("{")
             code.putln("Py_ssize_t i;")
@@ -7699,7 +7730,7 @@
             code.putln("for (i=0; i < %s; i++) {" % len(self.unpacked_items))
             code.putln("PyObject* item = PySequence_ITEM(sequence, i); %s" % (
                 code.error_goto_if_null('item', self.pos)))
-            code.put_gotref('item')
+            code.put_gotref('item', py_object_type)
             code.putln("*(temps[i]) = item;")
             code.putln("}")
             code.putln("}")
@@ -7738,7 +7769,7 @@
                 iterator_temp,
                 rhs.py_result(),
                 code.error_goto_if_null(iterator_temp, self.pos)))
-        code.put_gotref(iterator_temp)
+        code.put_gotref(iterator_temp, py_object_type)
         rhs.generate_disposal_code(code)
 
         iternext_func = code.funcstate.allocate_temp(self._func_iternext_type, manage_ref=False)
@@ -7751,7 +7782,7 @@
             code.putln("for (index=0; index < %s; index++) {" % len(unpacked_items))
             code.put("PyObject* item = %s; if (unlikely(!item)) " % unpack_code)
             code.put_goto(unpacking_error_label)
-            code.put_gotref("item")
+            code.put_gotref("item", py_object_type)
             code.putln("*(temps[index]) = item;")
             code.putln("}")
         else:
@@ -7763,7 +7794,7 @@
                         unpack_code,
                         item.result()))
                 code.put_goto(unpacking_error_label)
-                code.put_gotref(item.py_result())
+                item.generate_gotref(code)
 
         if terminate:
             code.globalstate.use_utility_code(
@@ -7816,5 +7847,5 @@
 
         starred_target.allocate(code)
         target_list = starred_target.result()
-        code.putln("%s = PySequence_List(%s); %s" % (
+        code.putln("%s = %s(%s); %s" % (
             target_list,
@@ -7820,3 +7851,6 @@
             target_list,
+            "__Pyx_PySequence_ListKeepNew" if (
+                    not iterator_temp and rhs.is_temp and rhs.type in (py_object_type, list_type))
+                else "PySequence_List",
             iterator_temp or rhs.py_result(),
             code.error_goto_if_null(target_list, self.pos)))
@@ -7821,6 +7855,6 @@
             iterator_temp or rhs.py_result(),
             code.error_goto_if_null(target_list, self.pos)))
-        code.put_gotref(target_list)
+        starred_target.generate_gotref(code)
 
         if iterator_temp:
             code.put_decref_clear(iterator_temp, py_object_type)
@@ -7851,7 +7885,7 @@
                 code.putln("%s = PySequence_ITEM(%s, %s-%d); " % (
                     item.py_result(), target_list, length_temp, i+1))
                 code.putln('#endif')
-                code.put_gotref(item.py_result())
+                item.generate_gotref(code)
                 coerced_arg.generate_evaluation_code(code)
 
             code.putln('#if !CYTHON_COMPILING_IN_CPYTHON')
@@ -7859,7 +7893,7 @@
             code.putln('%s = PySequence_GetSlice(%s, 0, %s-%d); %s' % (
                 sublist_temp, target_list, length_temp, len(unpacked_fixed_items_right),
                 code.error_goto_if_null(sublist_temp, self.pos)))
-            code.put_gotref(sublist_temp)
+            code.put_gotref(sublist_temp, py_object_type)
             code.funcstate.release_temp(length_temp)
             code.put_decref(target_list, py_object_type)
             code.putln('%s = %s; %s = NULL;' % (target_list, sublist_temp, sublist_temp))
@@ -8005,7 +8039,7 @@
                 # constant is not yet initialised
                 const_code.mark_pos(self.pos)
                 self.generate_sequence_packing_code(const_code, tuple_target, plain=not self.is_literal)
-                const_code.put_giveref(tuple_target)
+                const_code.put_giveref(tuple_target, py_object_type)
             if self.is_literal:
                 self.result_code = tuple_target
             else:
@@ -8013,7 +8047,7 @@
                     self.result(), tuple_target, self.mult_factor.py_result(),
                     code.error_goto_if_null(self.result(), self.pos)
                 ))
-                code.put_gotref(self.py_result())
+                self.generate_gotref(code)
         else:
             self.type.entry.used = True
             self.generate_sequence_packing_code(code)
@@ -8265,7 +8299,7 @@
         for entry in py_entries:
             if entry.is_cglobal:
                 code.put_var_gotref(entry)
-                code.put_decref_set(entry.cname, "Py_None")
+                code.put_var_decref_set(entry, "Py_None")
             else:
                 code.put_var_xdecref_clear(entry)
 
@@ -8317,7 +8351,7 @@
             self.result(), create_code,
             code.error_goto_if_null(self.result(), self.pos)))
 
-        code.put_gotref(self.result())
+        self.generate_gotref(code)
         self.loop.generate_execution_code(code)
 
     def annotate(self, code):
@@ -8442,7 +8476,7 @@
         code.putln("%s = __Pyx_Generator_Next(%s); %s" % (
             self.result(), self.gen.result(),
             code.error_goto_if_null(self.result(), self.pos)))
-        code.put_gotref(self.result())
+        self.generate_gotref(code)
 
 
 class MergedSequenceNode(ExprNode):
@@ -8550,6 +8584,8 @@
         else:
             code.putln("%s = %s(%s); %s" % (
                 self.result(),
-                'PySet_New' if is_set else 'PySequence_List',
+                'PySet_New' if is_set
+                    else "__Pyx_PySequence_ListKeepNew" if item.is_temp and item.type in (py_object_type, list_type)
+                    else "PySequence_List",
                 item.py_result(),
                 code.error_goto_if_null(self.result(), self.pos)))
@@ -8554,6 +8590,6 @@
                 item.py_result(),
                 code.error_goto_if_null(self.result(), self.pos)))
-            code.put_gotref(self.py_result())
+            self.generate_gotref(code)
             item.generate_disposal_code(code)
         item.free_temps(code)
 
@@ -8603,7 +8639,7 @@
                 self.result(),
                 Naming.quick_temp_cname,
                 code.error_goto_if_null(self.result(), self.pos)))
-            code.put_gotref(self.result())
+            self.generate_gotref(code)
             code.putln("}")
 
         for helper in sorted(helpers):
@@ -8653,7 +8689,7 @@
             "%s = PySet_New(0); %s" % (
                 self.result(),
                 code.error_goto_if_null(self.result(), self.pos)))
-        code.put_gotref(self.py_result())
+        self.generate_gotref(code)
         for arg in self.args:
             code.put_error_if_neg(
                 self.pos,
@@ -8775,7 +8811,7 @@
                     self.result(),
                     len(self.key_value_pairs),
                     code.error_goto_if_null(self.result(), self.pos)))
-            code.put_gotref(self.py_result())
+            self.generate_gotref(code)
 
         keys_seen = set()
         key_type = None
@@ -8903,7 +8939,7 @@
             code.putln('%s = PyDict_Keys(%s); %s' % (
                 self.result(), dict_result,
                 code.error_goto_if_null(self.result(), self.pos)))
-            code.put_gotref(self.py_result())
+            self.generate_gotref(code)
         else:
             # originally used PyMapping_Keys() here, but that may return a tuple
             code.globalstate.use_utility_code(UtilityCode.load_cached(
@@ -8912,5 +8948,5 @@
             code.putln('%s = __Pyx_PyObject_CallMethod0(%s, %s); %s' % (
                 self.result(), dict_result, keys_cname,
                 code.error_goto_if_null(self.result(), self.pos)))
-            code.put_gotref(self.py_result())
+            self.generate_gotref(code)
             code.putln("if (unlikely(!PyList_Check(%s))) {" % self.result())
@@ -8916,3 +8952,3 @@
             code.putln("if (unlikely(!PyList_Check(%s))) {" % self.result())
-            code.put_decref_set(self.result(), "PySequence_List(%s)" % self.result())
+            self.generate_decref_set(code, "PySequence_List(%s)" % self.result())
             code.putln(code.error_goto_if_null(self.result(), self.pos))
@@ -8918,5 +8954,5 @@
             code.putln(code.error_goto_if_null(self.result(), self.pos))
-            code.put_gotref(self.py_result())
+            self.generate_gotref(code)
             code.putln("}")
         code.put_error_if_neg(
             self.pos, 'PyList_Sort(%s)' % self.py_result())
@@ -8984,7 +9020,7 @@
                 qualname,
                 py_mod_name,
                 code.error_goto_if_null(self.result(), self.pos)))
-        code.put_gotref(self.py_result())
+        self.generate_gotref(code)
 
 
 class Py3ClassNode(ExprNode):
@@ -8997,6 +9033,7 @@
     #  class_def_node  PyClassDefNode  PyClassDefNode defining this class
     #  calculate_metaclass  bool       should call CalculateMetaclass()
     #  allow_py2_metaclass  bool       should look for Py2 metaclass
+    #  force_type           bool       always create a "new style" class, even with no bases
 
     subexprs = []
     type = py_object_type
@@ -9000,6 +9037,7 @@
 
     subexprs = []
     type = py_object_type
+    force_type = False
     is_temp = True
 
     def infer_type(self, env):
@@ -9021,6 +9059,8 @@
         mkw = class_def_node.mkw.py_result() if class_def_node.mkw else 'NULL'
         if class_def_node.metaclass:
             metaclass = class_def_node.metaclass.py_result()
+        elif self.force_type:
+            metaclass = "((PyObject*)&PyType_Type)"
         else:
             metaclass = "((PyObject*)&__Pyx_DefaultClassType)"
         code.putln(
@@ -9034,7 +9074,7 @@
                 self.calculate_metaclass,
                 self.allow_py2_metaclass,
                 code.error_goto_if_null(self.result(), self.pos)))
-        code.put_gotref(self.py_result())
+        self.generate_gotref(code)
 
 
 class PyClassMetaclassNode(ExprNode):
@@ -9070,7 +9110,7 @@
             "%s = %s; %s" % (
                 self.result(), call,
                 code.error_goto_if_null(self.result(), self.pos)))
-        code.put_gotref(self.py_result())
+        self.generate_gotref(code)
 
 
 class PyClassNamespaceNode(ExprNode, ModuleNameMixin):
@@ -9112,7 +9152,7 @@
                 py_mod_name,
                 doc_code,
                 code.error_goto_if_null(self.result(), self.pos)))
-        code.put_gotref(self.py_result())
+        self.generate_gotref(code)
 
 
 class ClassCellInjectorNode(ExprNode):
@@ -9131,7 +9171,7 @@
             '%s = PyList_New(0); %s' % (
                 self.result(),
                 code.error_goto_if_null(self.result(), self.pos)))
-        code.put_gotref(self.result())
+        self.generate_gotref(code)
 
     def generate_injection_code(self, code, classobj_cname):
         assert self.is_active
@@ -9173,7 +9213,6 @@
     #  from a PyMethodDef struct.
     #
     #  pymethdef_cname   string             PyMethodDef structure
-    #  self_object       ExprNode or None
     #  binding           bool
     #  def_node          DefNode            the Python function node
     #  module_name       EncodedString      Name of defining module
@@ -9182,7 +9221,6 @@
     subexprs = ['code_object', 'defaults_tuple', 'defaults_kwdict',
                 'annotations_dict']
 
-    self_object = None
     code_object = None
     binding = False
     def_node = None
@@ -9245,8 +9283,8 @@
                 else:
                     default_args.append(arg)
             if arg.annotation:
-                arg.annotation = self.analyse_annotation(env, arg.annotation)
-                annotations.append((arg.pos, arg.name, arg.annotation))
+                arg.annotation = arg.annotation.analyse_types(env)
+                annotations.append((arg.pos, arg.name, arg.annotation.string))
 
         for arg in (self.def_node.star_arg, self.def_node.starstar_arg):
             if arg and arg.annotation:
@@ -9250,8 +9288,8 @@
 
         for arg in (self.def_node.star_arg, self.def_node.starstar_arg):
             if arg and arg.annotation:
-                arg.annotation = self.analyse_annotation(env, arg.annotation)
-                annotations.append((arg.pos, arg.name, arg.annotation))
+                arg.annotation = arg.annotation.analyse_types(env)
+                annotations.append((arg.pos, arg.name, arg.annotation.string))
 
         annotation = self.def_node.return_type_annotation
         if annotation:
@@ -9255,9 +9293,9 @@
 
         annotation = self.def_node.return_type_annotation
         if annotation:
-            annotation = self.analyse_annotation(env, annotation)
-            self.def_node.return_type_annotation = annotation
-            annotations.append((annotation.pos, StringEncoding.EncodedString("return"), annotation))
+            self.def_node.return_type_annotation = annotation.analyse_types(env)
+            annotations.append((annotation.pos, StringEncoding.EncodedString("return"),
+                                annotation.string))
 
         if nonliteral_objects or nonliteral_other:
             module_scope = env.global_scope()
@@ -9265,7 +9303,10 @@
             scope = Symtab.StructOrUnionScope(cname)
             self.defaults = []
             for arg in nonliteral_objects:
-                entry = scope.declare_var(arg.name, arg.type, None,
+                type_ = arg.type
+                if type_.is_buffer:
+                    type_ = type_.base
+                entry = scope.declare_var(arg.name, type_, None,
                                           Naming.arg_prefix + arg.name,
                                           allow_pyobject=True)
                 self.defaults.append((arg, entry))
@@ -9297,7 +9338,8 @@
                             value=arg.default)
                         for arg in default_kwargs])
                     self.defaults_kwdict = defaults_kwdict.analyse_types(env)
-            else:
+            elif not self.specialized_cpdefs:
+                # Fused dispatch functions do not support (dynamic) default arguments, only the specialisations do.
                 if default_args:
                     defaults_tuple = DefaultsTupleNode(
                         self.pos, default_args, self.defaults_struct)
@@ -9334,22 +9376,8 @@
                 for pos, name, value in annotations])
             self.annotations_dict = annotations_dict.analyse_types(env)
 
-    def analyse_annotation(self, env, annotation):
-        if annotation is None:
-            return None
-        atype = annotation.analyse_as_type(env)
-        if atype is not None:
-            # Keep parsed types as strings as they might not be Python representable.
-            annotation = UnicodeNode(
-                annotation.pos,
-                value=StringEncoding.EncodedString(atype.declaration_code('', for_display=True)))
-        annotation = annotation.analyse_types(env)
-        if not annotation.type.is_pyobject:
-            annotation = annotation.coerce_to_pyobject(env)
-        return annotation
-
     def may_be_none(self):
         return False
 
     gil_message = "Constructing Python function"
 
@@ -9351,14 +9379,10 @@
     def may_be_none(self):
         return False
 
     gil_message = "Constructing Python function"
 
-    def self_result_code(self):
-        if self.self_object is None:
-            self_result = "NULL"
-        else:
-            self_result = self.self_object.py_result()
-        return self_result
+    def closure_result_code(self):
+        return "NULL"
 
     def generate_result_code(self, code):
         if self.binding:
@@ -9372,7 +9396,7 @@
             '%s = PyCFunction_NewEx(&%s, %s, %s); %s' % (
                 self.result(),
                 self.pymethdef_cname,
-                self.self_result_code(),
+                self.closure_result_code(),
                 py_mod_name,
                 code.error_goto_if_null(self.result(), self.pos)))
 
@@ -9376,7 +9400,7 @@
                 py_mod_name,
                 code.error_goto_if_null(self.result(), self.pos)))
 
-        code.put_gotref(self.py_result())
+        self.generate_gotref(code)
 
     def generate_cyfunction_code(self, code):
         if self.specialized_cpdefs:
@@ -9387,7 +9411,7 @@
         if self.specialized_cpdefs or self.is_specialization:
             code.globalstate.use_utility_code(
                 UtilityCode.load_cached("FusedFunction", "CythonFunction.c"))
-            constructor = "__pyx_FusedFunction_NewEx"
+            constructor = "__pyx_FusedFunction_New"
         else:
             code.globalstate.use_utility_code(
                 UtilityCode.load_cached("CythonFunction", "CythonFunction.c"))
@@ -9391,7 +9415,7 @@
         else:
             code.globalstate.use_utility_code(
                 UtilityCode.load_cached("CythonFunction", "CythonFunction.c"))
-            constructor = "__Pyx_CyFunction_NewEx"
+            constructor = "__Pyx_CyFunction_New"
 
         if self.code_object:
             code_object_result = self.code_object.py_result()
@@ -9412,4 +9436,17 @@
         else:
             flags = '0'
 
+        borrowed_moddict_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=False)
+        code.putln("#if CYTHON_COMPILING_IN_LIMITED_API")
+        code.putln('%s = PyModule_GetDict(%s); %s' % (
+            borrowed_moddict_temp,
+            Naming.module_cname,
+            code.error_goto_if_null(borrowed_moddict_temp, self.pos)))
+        code.putln("#else")
+        code.putln("%s = %s;  if ((1)); else %s;" % (
+            borrowed_moddict_temp,
+            Naming.moddict_cname,
+            code.error_goto(self.pos),
+        ))
+        code.putln("#endif")
         code.putln(
@@ -9415,7 +9452,7 @@
         code.putln(
-            '%s = %s(&%s, %s, %s, %s, %s, %s, %s); %s' % (
+            '%s = %s(&%s, %s, %s, %s, %s, %s, %s); %s = NULL; %s' % (
                 self.result(),
                 constructor,
                 self.pymethdef_cname,
                 flags,
                 self.get_py_qualified_name(code),
@@ -9417,7 +9454,7 @@
                 self.result(),
                 constructor,
                 self.pymethdef_cname,
                 flags,
                 self.get_py_qualified_name(code),
-                self.self_result_code(),
+                self.closure_result_code(),
                 self.get_py_mod_name(code),
@@ -9423,3 +9460,3 @@
                 self.get_py_mod_name(code),
-                Naming.moddict_cname,
+                borrowed_moddict_temp,
                 code_object_result,
@@ -9425,2 +9462,3 @@
                 code_object_result,
+                borrowed_moddict_temp,
                 code.error_goto_if_null(self.result(), self.pos)))
@@ -9426,6 +9464,7 @@
                 code.error_goto_if_null(self.result(), self.pos)))
-
-        code.put_gotref(self.py_result())
+        code.funcstate.release_temp(borrowed_moddict_temp)
+
+        self.generate_gotref(code)
 
         if def_node.requires_classobj:
             assert code.pyclass_stack, "pyclass_stack is empty"
@@ -9435,7 +9474,7 @@
                 'PyList_Append(%s, %s);' % (
                     class_node.class_cell.result(),
                     self.result()))
-            code.put_giveref(self.py_result())
+            self.generate_giveref(code)
 
         if self.defaults:
             code.putln(
@@ -9451,17 +9490,20 @@
         if self.defaults_tuple:
             code.putln('__Pyx_CyFunction_SetDefaultsTuple(%s, %s);' % (
                 self.result(), self.defaults_tuple.py_result()))
-        if self.defaults_kwdict:
-            code.putln('__Pyx_CyFunction_SetDefaultsKwDict(%s, %s);' % (
-                self.result(), self.defaults_kwdict.py_result()))
-        if def_node.defaults_getter and not self.specialized_cpdefs:
-            # Fused functions do not support dynamic defaults, only their specialisations can have them for now.
-            code.putln('__Pyx_CyFunction_SetDefaultsGetter(%s, %s);' % (
-                self.result(), def_node.defaults_getter.entry.pyfunc_cname))
-        if self.annotations_dict:
-            code.putln('__Pyx_CyFunction_SetAnnotationsDict(%s, %s);' % (
-                self.result(), self.annotations_dict.py_result()))
+        if not self.specialized_cpdefs:
+            # disable introspection functions for fused dispatcher function since the user never sees it
+            # TODO: this is mostly disabled because the attributes end up pointing to ones belonging
+            #  to the specializations - ideally this would be fixed instead
+            if self.defaults_kwdict:
+                code.putln('__Pyx_CyFunction_SetDefaultsKwDict(%s, %s);' % (
+                    self.result(), self.defaults_kwdict.py_result()))
+            if def_node.defaults_getter:
+                code.putln('__Pyx_CyFunction_SetDefaultsGetter(%s, %s);' % (
+                    self.result(), def_node.defaults_getter.entry.pyfunc_cname))
+            if self.annotations_dict:
+                code.putln('__Pyx_CyFunction_SetAnnotationsDict(%s, %s);' % (
+                    self.result(), self.annotations_dict.py_result()))
 
 
 class InnerFunctionNode(PyCFunctionNode):
     # Special PyCFunctionNode that depends on a closure class
@@ -9464,7 +9506,6 @@
 
 
 class InnerFunctionNode(PyCFunctionNode):
     # Special PyCFunctionNode that depends on a closure class
-    #
 
     binding = True
@@ -9469,9 +9510,9 @@
 
     binding = True
-    needs_self_code = True
-
-    def self_result_code(self):
-        if self.needs_self_code:
+    needs_closure_code = True
+
+    def closure_result_code(self):
+        if self.needs_closure_code:
             return "((PyObject*)%s)" % Naming.cur_scope_cname
         return "NULL"
 
@@ -9529,6 +9570,6 @@
         if self.def_node.starstar_arg:
             flags.append('CO_VARKEYWORDS')
 
-        code.putln("%s = (PyObject*)__Pyx_PyCode_New(%d, %d, %d, 0, %s, %s, %s, %s, %s, %s, %s, %s, %s, %d, %s); %s" % (
+        code.putln("%s = (PyObject*)__Pyx_PyCode_New(%d, %d, %d, %d, 0, %s, %s, %s, %s, %s, %s, %s, %s, %s, %d, %s); %s" % (
             self.result_code,
             len(func.args) - func.num_kwonly_args,  # argcount
@@ -9533,5 +9574,6 @@
             self.result_code,
             len(func.args) - func.num_kwonly_args,  # argcount
+            func.num_posonly_args,     # posonlyargcount (Py3.8+ only)
             func.num_kwonly_args,      # kwonlyargcount (Py3 only)
             len(self.varnames.args),   # nlocals
             '|'.join(flags) or '0',    # flags
@@ -9653,4 +9695,5 @@
         self.lambda_name = self.def_node.lambda_name = env.next_id('lambda')
         self.def_node.no_assignment_synthesis = True
         self.def_node.pymethdef_required = True
+        self.def_node.is_cyfunction = True
         self.def_node.analyse_declarations(env)
@@ -9656,5 +9699,4 @@
         self.def_node.analyse_declarations(env)
-        self.def_node.is_cyfunction = True
         self.pymethdef_cname = self.def_node.entry.pymethdef_cname
         env.add_lambda_def(self.def_node)
 
@@ -9693,5 +9735,5 @@
             '%s = %s(%s); %s' % (
                 self.result(),
                 self.def_node.entry.pyfunc_cname,
-                self.self_result_code(),
+                self.closure_result_code(),
                 code.error_goto_if_null(self.result(), self.pos)))
@@ -9697,5 +9739,5 @@
                 code.error_goto_if_null(self.result(), self.pos)))
-        code.put_gotref(self.py_result())
+        self.generate_gotref(code)
 
 
 class YieldExprNode(ExprNode):
@@ -9754,7 +9796,6 @@
         for cname, type, manage_ref in code.funcstate.temps_in_use():
             save_cname = code.funcstate.closure_temps.allocate_temp(type)
             saved.append((cname, save_cname, type))
-            if type.is_pyobject:
-                code.put_xgiveref(cname)
+            code.put_xgiveref(cname, type)
             code.putln('%s->%s = %s;' % (Naming.cur_scope_cname, save_cname, cname))
 
@@ -9759,6 +9800,6 @@
             code.putln('%s->%s = %s;' % (Naming.cur_scope_cname, save_cname, cname))
 
-        code.put_xgiveref(Naming.retval_cname)
+        code.put_xgiveref(Naming.retval_cname, py_object_type)
         profile = code.globalstate.directives['profile']
         linetrace = code.globalstate.directives['linetrace']
         if profile or linetrace:
@@ -9789,7 +9830,7 @@
             code.putln('%s = %s->%s;' % (cname, Naming.cur_scope_cname, save_cname))
             if type.is_pyobject:
                 code.putln('%s->%s = 0;' % (Naming.cur_scope_cname, save_cname))
-                code.put_xgotref(cname)
+                code.put_xgotref(cname, type)
         self.generate_sent_value_handling_code(code, Naming.sent_value_cname)
         if self.result_is_used:
             self.allocate_temp_result(code)
@@ -9817,7 +9858,7 @@
             self.arg.free_temps(code)
         elif decref_source:
             code.put_decref_clear(source_cname, py_object_type)
-        code.put_xgotref(Naming.retval_cname)
+        code.put_xgotref(Naming.retval_cname, py_object_type)
 
         code.putln("if (likely(%s)) {" % Naming.retval_cname)
         self.generate_yield_code(code)
@@ -9833,7 +9874,7 @@
         # YieldExprNode has allocated the result temp for us
         code.putln("%s = NULL;" % self.result())
         code.put_error_if_neg(self.pos, "__Pyx_PyGen_FetchStopIterationValue(&%s)" % self.result())
-        code.put_gotref(self.result())
+        self.generate_gotref(code)
 
     def handle_iteration_exception(self, code):
         code.putln("PyObject* exc_type = __Pyx_PyErr_Occurred();")
@@ -9925,7 +9966,7 @@
         code.putln('%s = __Pyx_Globals(); %s' % (
             self.result(),
             code.error_goto_if_null(self.result(), self.pos)))
-        code.put_gotref(self.result())
+        self.generate_gotref(code)
 
 
 class LocalsDictItemNode(DictItemNode):
@@ -10115,7 +10156,7 @@
                 function,
                 self.operand.py_result(),
                 code.error_goto_if_null(self.result(), self.pos)))
-        code.put_gotref(self.py_result())
+        self.generate_gotref(code)
 
     def type_error(self):
         if not self.operand.type.is_error:
@@ -10688,6 +10729,11 @@
             code.putln(code.error_goto(self.operand.pos))
             code.putln("}")
 
-        code.putln("%s = __pyx_format_from_typeinfo(&%s);" %
-                                                (format_temp, type_info))
+        code.putln("%s = __pyx_format_from_typeinfo(&%s); %s" % (
+            format_temp,
+            type_info,
+            code.error_goto_if_null(format_temp, self.pos),
+        ))
+        code.put_gotref(format_temp, py_object_type)
+
         buildvalue_fmt = " __PYX_BUILD_PY_SSIZE_T " * len(shapes)
@@ -10693,21 +10739,18 @@
         buildvalue_fmt = " __PYX_BUILD_PY_SSIZE_T " * len(shapes)
-        code.putln('%s = Py_BuildValue((char*) "(" %s ")", %s);' % (
-            shapes_temp, buildvalue_fmt, ", ".join(shapes)))
-
-        err = "!%s || !%s || !PyBytes_AsString(%s)" % (format_temp,
-                                                       shapes_temp,
-                                                       format_temp)
-        code.putln(code.error_goto_if(err, self.pos))
-        code.put_gotref(format_temp)
-        code.put_gotref(shapes_temp)
-
-        tup = (self.result(), shapes_temp, itemsize, format_temp,
-               self.mode, self.operand.result())
-        code.putln('%s = __pyx_array_new('
-                            '%s, %s, PyBytes_AS_STRING(%s), '
-                            '(char *) "%s", (char *) %s);' % tup)
-        code.putln(code.error_goto_if_null(self.result(), self.pos))
-        code.put_gotref(self.result())
+        code.putln('%s = Py_BuildValue((char*) "(" %s ")", %s); %s' % (
+            shapes_temp,
+            buildvalue_fmt,
+            ", ".join(shapes),
+            code.error_goto_if_null(shapes_temp, self.pos),
+        ))
+        code.put_gotref(shapes_temp, py_object_type)
+
+        code.putln('%s = __pyx_array_new(%s, %s, PyBytes_AS_STRING(%s), (char *) "%s", (char *) %s); %s' % (
+            self.result(),
+            shapes_temp, itemsize, format_temp, self.mode, self.operand.result(),
+            code.error_goto_if_null(self.result(), self.pos),
+        ))
+        self.generate_gotref(code)
 
         def dispose(temp):
             code.put_decref_clear(temp, py_object_type)
@@ -10859,7 +10902,7 @@
             self.error("The 'libcpp.typeinfo' module must be cimported to use the typeid() operator")
             return self
         self.type = type_info
-        as_type = self.operand.analyse_as_type(env)
+        as_type = self.operand.analyse_as_specialized_type(env)
         if as_type:
             self.arg_type = as_type
             self.is_type = True
@@ -11155,7 +11198,7 @@
                     self.operand2.py_result(),
                     extra_args,
                     code.error_goto_if_null(self.result(), self.pos)))
-            code.put_gotref(self.py_result())
+            self.generate_gotref(code)
         elif self.is_temp:
             # C++ overloaded operators with exception values are currently all
             # handled through temporaries.
@@ -11391,7 +11434,7 @@
 
     def py_operation_function(self, code):
         type1, type2 = self.operand1.type, self.operand2.type
-
+        func = None
         if type1 is unicode_type or type2 is unicode_type:
             if type1 in (unicode_type, str_type) and type2 in (unicode_type, str_type):
                 is_unicode_concat = True
@@ -11403,10 +11446,22 @@
                 is_unicode_concat = False
 
             if is_unicode_concat:
-                if self.operand1.may_be_none() or self.operand2.may_be_none():
-                    return '__Pyx_PyUnicode_ConcatSafe'
-                else:
-                    return '__Pyx_PyUnicode_Concat'
+                if self.inplace or self.operand1.is_temp:
+                    code.globalstate.use_utility_code(
+                        UtilityCode.load_cached("UnicodeConcatInPlace", "ObjectHandling.c"))
+                func = '__Pyx_PyUnicode_Concat'
+        elif type1 is str_type and type2 is str_type:
+            code.globalstate.use_utility_code(
+                    UtilityCode.load_cached("StrConcatInPlace", "ObjectHandling.c"))
+            func = '__Pyx_PyStr_Concat'
+
+        if func:
+            # any necessary utility code will be got by "NumberAdd" in generate_evaluation_code
+            if self.inplace or self.operand1.is_temp:
+                func += 'InPlace'  # upper case to indicate unintuitive macro
+            if self.operand1.may_be_none() or self.operand2.may_be_none():
+                func += 'Safe'
+            return func
 
         return super(AddNode, self).py_operation_function(code)
 
@@ -11578,7 +11633,7 @@
                         minus1_check = '(!(((%s)-1) > 0)) && unlikely(%s == (%s)-1)' % (
                             type_of_op2, self.operand2.result(), type_of_op2)
                     code.putln("else if (sizeof(%s) == sizeof(long) && %s "
-                               " && unlikely(UNARY_NEG_WOULD_OVERFLOW(%s))) {" % (
+                               " && unlikely(__Pyx_UNARY_NEG_WOULD_OVERFLOW(%s))) {" % (
                                self.type.empty_declaration_code(),
                                minus1_check,
                                self.operand1.result()))
@@ -11772,6 +11827,12 @@
             error(self.pos, "got unexpected types for C power operator: %s, %s" %
                             (self.operand1.type, self.operand2.type))
 
+    def compute_c_result_type(self, type1, type2):
+        c_result_type = super(PowNode, self).compute_c_result_type(type1, type2)
+        if isinstance(self.operand2.constant_result, _py_int_types) and self.operand2.constant_result < 0:
+            c_result_type = PyrexTypes.widest_numeric_type(c_result_type, PyrexTypes.c_double_type)
+        return c_result_type
+
     def calculate_result_code(self):
         # Work around MSVC overloading ambiguity.
         def typecast(operand):
@@ -12042,6 +12103,9 @@
             code.putln("}")
         self.arg.free_temps(code)
 
+    def analyse_types(self, env):
+        return self
+
 
 class CondExprNode(ExprNode):
     #  Short-circuiting conditional expression.
@@ -12988,5 +13052,5 @@
     exact_builtin_type = True
 
     def __init__(self, arg, dst_type, env, notnone=False):
-        #  The arg is know to be a Python object, and
+        #  The arg is known to be a Python object, and
         #  the dst_type is known to be an extension type.
@@ -12992,5 +13056,6 @@
         #  the dst_type is known to be an extension type.
-        assert dst_type.is_extension_type or dst_type.is_builtin_type, "PyTypeTest on non extension type"
+        assert dst_type.is_extension_type or dst_type.is_builtin_type, \
+            "PyTypeTest for %s against non extension type %s" % (arg.type, dst_type)
         CoercionNode.__init__(self, arg)
         self.type = dst_type
         self.result_ctype = arg.ctype()
@@ -13222,7 +13287,7 @@
                 self.target_type),
             code.error_goto_if_null(self.result(), self.pos)))
 
-        code.put_gotref(self.py_result())
+        self.generate_gotref(code)
 
 
 class CoerceIntToBytesNode(CoerceToPyTypeNode):
@@ -13262,7 +13327,7 @@
             code.error_goto_if_null(self.result(), self.pos)))
         if temp is not None:
             code.funcstate.release_temp(temp)
-        code.put_gotref(self.py_result())
+        self.generate_gotref(code)
 
 
 class CoerceFromPyTypeNode(CoercionNode):
@@ -13300,7 +13365,7 @@
         code.putln(self.type.from_py_call_code(
             self.arg.py_result(), self.result(), self.pos, code, from_py_function=from_py_function))
         if self.type.is_pyobject:
-            code.put_gotref(self.py_result())
+            self.generate_gotref(code)
 
     def nogil_check(self, env):
         error(self.pos, "Coercion from Python not allowed without the GIL")
@@ -13357,6 +13422,9 @@
                     self.arg.py_result(),
                     code.error_goto_if_neg(self.result(), self.pos)))
 
+    def analyse_types(self, env):
+        return self
+
 
 class CoerceToComplexNode(CoercionNode):
 
@@ -13382,6 +13450,9 @@
     def generate_result_code(self, code):
         pass
 
+    def analyse_types(self, env):
+        return self
+
 class CoerceToTempNode(CoercionNode):
     #  This node is used to force the result of another node
     #  to be stored in a temporary. It is only used if the
@@ -13415,5 +13486,5 @@
         code.putln("%s = %s;" % (
             self.result(), self.arg.result_as(self.ctype())))
         if self.use_managed_ref:
-            if self.type.is_pyobject:
+            if not self.type.is_memoryviewslice:
                 code.put_incref(self.result(), self.ctype())
@@ -13419,7 +13490,7 @@
                 code.put_incref(self.result(), self.ctype())
-            elif self.type.is_memoryviewslice:
-                code.put_incref_memoryviewslice(self.result(),
-                                                not self.in_nogil_context)
+            else:
+                code.put_incref_memoryviewslice(self.result(), self.type,
+                                            have_gil=not self.in_nogil_context)
 
 class ProxyNode(CoercionNode):
     """
@@ -13585,9 +13656,94 @@
             self.result(), self.body.result(),
             code.intern_identifier(StringEncoding.EncodedString("__doc__")),
             code.error_goto_if_null(self.result(), self.pos)))
-        code.put_gotref(self.result())
-
-
+        self.generate_gotref(code)
+
+class AnnotationNode(ExprNode):
+    # Deals with the two possible uses of an annotation.
+    # 1. The post PEP-563 use where an annotation is stored
+    #  as a string
+    # 2. The Cython use where the annotation can indicate an
+    #  object type
+    #
+    # Doesn't handle the pre PEP-563 version where the
+    # annotation is evaluated into a Python Object.
+
+    subexprs = []
+
+    # 'untyped' is set for fused specializations:
+    # Once a fused function has been created we don't want
+    # annotations to override an already set type.
+    untyped = False
+
+    def __init__(self, pos, expr, string=None):
+        """string is expected to already be a StringNode or None"""
+        ExprNode.__init__(self, pos)
+        if string is None:
+            # import doesn't work at top of file?
+            from .AutoDocTransforms import AnnotationWriter
+            string = StringEncoding.EncodedString(
+                AnnotationWriter(description="annotation").write(expr))
+            string = StringNode(pos, unicode_value=string, value=string.as_utf8_string())
+        self.string = string
+        self.expr = expr
+
+    def analyse_types(self, env):
+        return self # nothing needs doing
+
+    def analyse_as_type(self, env):
+        # for compatibility when used as a return_type_node, have this interface too
+        return self.analyse_type_annotation(env)[1]
+
+    def analyse_type_annotation(self, env, assigned_value=None):
+        if self.untyped:
+            # Already applied as a fused type, not re-evaluating it here.
+            return None, None
+        annotation = self.expr
+        base_type = None
+        is_ambiguous = False
+        explicit_pytype = explicit_ctype = False
+        if annotation.is_dict_literal:
+            warning(annotation.pos,
+                    "Dicts should no longer be used as type annotations. Use 'cython.int' etc. directly.", level=1)
+            for name, value in annotation.key_value_pairs:
+                if not name.is_string_literal:
+                    continue
+                if name.value in ('type', b'type'):
+                    explicit_pytype = True
+                    if not explicit_ctype:
+                        annotation = value
+                elif name.value in ('ctype', b'ctype'):
+                    explicit_ctype = True
+                    annotation = value
+            if explicit_pytype and explicit_ctype:
+                warning(annotation.pos, "Duplicate type declarations found in signature annotation", level=1)
+        arg_type = annotation.analyse_as_type(env)
+        if annotation.is_name and not annotation.cython_attribute and annotation.name in ('int', 'long', 'float'):
+            # Map builtin numeric Python types to C types in safe cases.
+            if assigned_value is not None and arg_type is not None and not arg_type.is_pyobject:
+                assigned_type = assigned_value.infer_type(env)
+                if assigned_type and assigned_type.is_pyobject:
+                    # C type seems unsafe, e.g. due to 'None' default value  => ignore annotation type
+                    is_ambiguous = True
+                    arg_type = None
+            # ignore 'int' and require 'cython.int' to avoid unsafe integer declarations
+            if arg_type in (PyrexTypes.c_long_type, PyrexTypes.c_int_type, PyrexTypes.c_float_type):
+                arg_type = PyrexTypes.c_double_type if annotation.name == 'float' else py_object_type
+        elif arg_type is not None and annotation.is_string_literal:
+            warning(annotation.pos,
+                    "Strings should no longer be used for type declarations. Use 'cython.int' etc. directly.",
+                    level=1)
+        if arg_type is not None:
+            if explicit_pytype and not explicit_ctype and not arg_type.is_pyobject:
+                warning(annotation.pos,
+                        "Python type declaration in signature annotation does not refer to a Python type")
+            base_type = Nodes.CAnalysedBaseTypeNode(
+                annotation.pos, type=arg_type, is_arg=True)
+        elif is_ambiguous:
+            warning(annotation.pos, "Ambiguous types in annotation, ignoring")
+        else:
+            warning(annotation.pos, "Unknown type declaration in annotation, ignoring")
+        return base_type, arg_type
 
 #------------------------------------------------------------------------------------
 #
diff --git a/Cython/Compiler/FlowControl.pxd b/Cython/Compiler/FlowControl.pxd
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL0Zsb3dDb250cm9sLnB4ZA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL0Zsb3dDb250cm9sLnB4ZA== 100644
--- a/Cython/Compiler/FlowControl.pxd
+++ b/Cython/Compiler/FlowControl.pxd
@@ -105,6 +105,7 @@
     cdef list stack
     cdef object env
     cdef ControlFlow flow
+    cdef object object_expr
     cdef bint in_inplace_assignment
 
     cpdef mark_assignment(self, lhs, rhs=*)
diff --git a/Cython/Compiler/FlowControl.py b/Cython/Compiler/FlowControl.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL0Zsb3dDb250cm9sLnB5..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL0Zsb3dDb250cm9sLnB5 100644
--- a/Cython/Compiler/FlowControl.py
+++ b/Cython/Compiler/FlowControl.py
@@ -1,5 +1,7 @@
+# cython: language_level=3str
+
 from __future__ import absolute_import
 
 import cython
 cython.declare(PyrexTypes=object, ExprNodes=object, Nodes=object,
                Builtin=object, InternalError=object, error=object, warning=object,
@@ -1,12 +3,11 @@
 from __future__ import absolute_import
 
 import cython
 cython.declare(PyrexTypes=object, ExprNodes=object, Nodes=object,
                Builtin=object, InternalError=object, error=object, warning=object,
-               py_object_type=object, unspecified_type=object,
-               object_expr=object, fake_rhs_expr=object, TypedExprNode=object)
+               fake_rhs_expr=object, TypedExprNode=object)
 
 from . import Builtin
 from . import ExprNodes
 from . import Nodes
 from . import Options
@@ -8,9 +9,8 @@
 
 from . import Builtin
 from . import ExprNodes
 from . import Nodes
 from . import Options
-from .PyrexTypes import py_object_type, unspecified_type
 from . import PyrexTypes
 
 from .Visitor import TreeVisitor, CythonTransform
@@ -28,5 +28,4 @@
     def may_be_none(self):
         return self._may_be_none != False
 
-object_expr = TypedExprNode(py_object_type, may_be_none=True)
 # Fake rhs to silence "unused variable" warning
@@ -32,5 +31,5 @@
 # Fake rhs to silence "unused variable" warning
-fake_rhs_expr = TypedExprNode(unspecified_type)
+fake_rhs_expr = TypedExprNode(PyrexTypes.unspecified_type)
 
 
 class ControlBlock(object):
@@ -373,9 +372,9 @@
 
     def infer_type(self):
         inferred_type = self.rhs.infer_type(self.entry.scope)
-        if (not inferred_type.is_pyobject and
-            inferred_type.can_coerce_to_pyobject(self.entry.scope)):
-            return py_object_type
+        if (not inferred_type.is_pyobject
+                and inferred_type.can_coerce_to_pyobject(self.entry.scope)):
+            return PyrexTypes.py_object_type
         self.inferred_type = inferred_type
         return inferred_type
 
@@ -674,7 +673,8 @@
 class ControlFlowAnalysis(CythonTransform):
 
     def visit_ModuleNode(self, node):
-        self.gv_ctx = GVContext()
+        dot_output = self.current_directives['control_flow.dot_output']
+        self.gv_ctx = GVContext() if dot_output else None
         self.constant_folder = ConstantFolding()
 
         # Set of NameNode reductions
@@ -685,7 +685,8 @@
         self.env = node.scope
         self.stack = []
         self.flow = ControlFlow()
+        self.object_expr = TypedExprNode(PyrexTypes.py_object_type, may_be_none=True)
         self.visitchildren(node)
 
         check_definitions(self.flow, self.current_directives)
 
@@ -688,7 +689,6 @@
         self.visitchildren(node)
 
         check_definitions(self.flow, self.current_directives)
 
-        dot_output = self.current_directives['control_flow.dot_output']
         if dot_output:
             annotate_defs = self.current_directives['control_flow.dot_annotate_defs']
@@ -693,5 +693,4 @@
         if dot_output:
             annotate_defs = self.current_directives['control_flow.dot_annotate_defs']
-            fp = open(dot_output, 'wt')
-            try:
+            with open(dot_output, 'wt') as fp:
                 self.gv_ctx.render(fp, 'module', annotate_defs=annotate_defs)
@@ -697,6 +696,4 @@
                 self.gv_ctx.render(fp, 'module', annotate_defs=annotate_defs)
-            finally:
-                fp.close()
         return node
 
     def visit_FuncDefNode(self, node):
@@ -744,7 +741,8 @@
         check_definitions(self.flow, self.current_directives)
         self.flow.blocks.add(self.flow.entry_point)
 
-        self.gv_ctx.add(GV(node.local_scope.name, self.flow))
+        if self.gv_ctx is not None:
+            self.gv_ctx.add(GV(node.local_scope.name, self.flow))
 
         self.flow = self.stack.pop()
         self.env = self.env_stack.pop()
@@ -769,7 +767,7 @@
             self.flow.nextblock()
 
         if not rhs:
-            rhs = object_expr
+            rhs = self.object_expr
         if lhs.is_name:
             if lhs.entry is not None:
                 entry = lhs.entry
@@ -910,6 +908,26 @@
             self.flow.block = None
         return node
 
+    def visit_AssertStatNode(self, node):
+        """Essentially an if-condition that wraps a RaiseStatNode.
+        """
+        self.mark_position(node)
+        next_block = self.flow.newblock()
+        parent = self.flow.block
+        # failure case
+        parent = self.flow.nextblock(parent)
+        self._visit(node.condition)
+        self.flow.nextblock()
+        self._visit(node.exception)
+        if self.flow.block:
+            self.flow.block.add_child(next_block)
+        parent.add_child(next_block)
+        if next_block.parents:
+            self.flow.block = next_block
+        else:
+            self.flow.block = None
+        return node
+
     def visit_WhileStatNode(self, node):
         condition_block = self.flow.nextblock()
         next_block = self.flow.newblock()
@@ -1296,7 +1314,7 @@
         self.visitchildren(node, ('dict', 'metaclass',
                                   'mkw', 'bases', 'class_result'))
         self.flow.mark_assignment(node.target, node.classobj,
-                                  self.env.lookup(node.name))
+                                  self.env.lookup(node.target.name))
         self.env_stack.append(self.env)
         self.env = node.scope
         self.flow.nextblock()
@@ -1300,6 +1318,8 @@
         self.env_stack.append(self.env)
         self.env = node.scope
         self.flow.nextblock()
+        if node.doc_node:
+            self.flow.mark_assignment(node.doc_node, fake_rhs_expr, node.doc_node.entry)
         self.visitchildren(node, ('body',))
         self.flow.nextblock()
         self.env = self.env_stack.pop()
diff --git a/Cython/Compiler/FusedNode.py b/Cython/Compiler/FusedNode.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL0Z1c2VkTm9kZS5weQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL0Z1c2VkTm9kZS5weQ== 100644
--- a/Cython/Compiler/FusedNode.py
+++ b/Cython/Compiler/FusedNode.py
@@ -220,6 +220,10 @@
                 arg.type = arg.type.specialize(fused_to_specific)
                 if arg.type.is_memoryviewslice:
                     arg.type.validate_memslice_dtype(arg.pos)
+                if arg.annotation:
+                    # TODO might be nice if annotations were specialized instead?
+                    # (Or might be hard to do reliably)
+                    arg.annotation.untyped = True
 
     def create_new_local_scope(self, node, env, f2s):
         """
@@ -580,6 +584,26 @@
                 {{endif}}
             """)
 
+    def _fused_signature_index(self, pyx_code):
+        """
+        Generate Cython code for constructing a persistent nested dictionary index of
+        fused type specialization signatures.
+        """
+        pyx_code.put_chunk(
+            u"""
+                if not _fused_sigindex:
+                    for sig in <dict>signatures:
+                        sigindex_node = _fused_sigindex
+                        *sig_series, last_type = sig.strip('()').split('|')
+                        for sig_type in sig_series:
+                            if sig_type not in sigindex_node:
+                                sigindex_node[sig_type] = sigindex_node = {}
+                            else:
+                                sigindex_node = sigindex_node[sig_type]
+                        sigindex_node[last_type] = sig
+            """
+        )
+
     def make_fused_cpdef(self, orig_py_func, env, is_def):
         """
         This creates the function that is indexable from Python and does
@@ -616,7 +640,7 @@
 
         pyx_code.put_chunk(
             u"""
-                def __pyx_fused_cpdef(signatures, args, kwargs, defaults):
+                def __pyx_fused_cpdef(signatures, args, kwargs, defaults, _fused_sigindex={}):
                     # FIXME: use a typed signature - currently fails badly because
                     #        default arguments inherit the types we specify here!
 
@@ -620,6 +644,10 @@
                     # FIXME: use a typed signature - currently fails badly because
                     #        default arguments inherit the types we specify here!
 
+                    cdef list search_list
+
+                    cdef dict sn, sigindex_node
+
                     dest_sig = [None] * {{n_fused}}
 
                     if kwargs is not None and not kwargs:
@@ -687,5 +715,7 @@
             env.use_utility_code(Code.UtilityCode.load_cached("Import", "ImportExport.c"))
             env.use_utility_code(Code.UtilityCode.load_cached("ImportNumPyArray", "ImportExport.c"))
 
+        self._fused_signature_index(pyx_code)
+
         pyx_code.put_chunk(
             u"""
@@ -690,15 +720,5 @@
         pyx_code.put_chunk(
             u"""
-                candidates = []
-                for sig in <dict>signatures:
-                    match_found = False
-                    src_sig = sig.strip('()').split('|')
-                    for i in range(len(dest_sig)):
-                        dst_type = dest_sig[i]
-                        if dst_type is not None:
-                            if src_sig[i] == dst_type:
-                                match_found = True
-                            else:
-                                match_found = False
-                                break
+                sigindex_matches = []
+                sigindex_candidates = [_fused_sigindex]
 
@@ -704,6 +724,27 @@
 
-                    if match_found:
-                        candidates.append(sig)
+                for dst_type in dest_sig:
+                    found_matches = []
+                    found_candidates = []
+                    # Make two seperate lists: One for signature sub-trees
+                    #        with at least one definite match, and another for
+                    #        signature sub-trees with only ambiguous matches
+                    #        (where `dest_sig[i] is None`).
+                    if dst_type is None:
+                        for sn in sigindex_matches:
+                            found_matches.extend(sn.values())
+                        for sn in sigindex_candidates:
+                            found_candidates.extend(sn.values())
+                    else:
+                        for search_list in (sigindex_matches, sigindex_candidates):
+                            for sn in search_list:
+                                if dst_type in sn:
+                                    found_matches.append(sn[dst_type])
+                    sigindex_matches = found_matches
+                    sigindex_candidates = found_candidates
+                    if not (found_matches or found_candidates):
+                        break
+
+                candidates = sigindex_matches
 
                 if not candidates:
                     raise TypeError("No matching signature found")
@@ -798,7 +839,8 @@
 
         for i, stat in enumerate(self.stats):
             stat = self.stats[i] = stat.analyse_expressions(env)
-            if isinstance(stat, FuncDefNode):
+            if isinstance(stat, FuncDefNode) and stat is not self.py_func:
+                # the dispatcher specifically doesn't want its defaults overriding
                 for arg, default in zip(stat.args, defaults):
                     if default is not None:
                         arg.default = CloneNode(default).coerce_to(arg.type, env)
@@ -829,6 +871,10 @@
         else:
             nodes = self.nodes
 
+        # For the moment, fused functions do not support METH_FASTCALL
+        for node in nodes:
+            node.entry.signature.use_fastcall = False
+
         signatures = [StringEncoding.EncodedString(node.specialized_signature_string)
                       for node in nodes]
         keys = [ExprNodes.StringNode(node.pos, value=sig)
@@ -877,7 +923,7 @@
                 "((__pyx_FusedFunctionObject *) %s)->__signatures__ = %s;" %
                                     (self.resulting_fused_function.result(),
                                      self.__signatures__.result()))
-            code.put_giveref(self.__signatures__.result())
+            self.__signatures__.generate_giveref(code)
 
             self.fused_func_assignment.generate_execution_code(code)
 
diff --git a/Cython/Compiler/Future.py b/Cython/Compiler/Future.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL0Z1dHVyZS5weQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL0Z1dHVyZS5weQ== 100644
--- a/Cython/Compiler/Future.py
+++ b/Cython/Compiler/Future.py
@@ -11,5 +11,6 @@
 nested_scopes = _get_feature("nested_scopes")  # dummy
 generators = _get_feature("generators")  # dummy
 generator_stop = _get_feature("generator_stop")
+annotations = _get_feature("annotations")
 
 del _get_feature
diff --git a/Cython/Compiler/Lexicon.py b/Cython/Compiler/Lexicon.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL0xleGljb24ucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL0xleGljb24ucHk= 100644
--- a/Cython/Compiler/Lexicon.py
+++ b/Cython/Compiler/Lexicon.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
 # cython: language_level=3, py2_import=True
 #
 #   Cython Scanner - Lexical Definitions
@@ -16,6 +17,5 @@
 def make_lexicon():
     from ..Plex import \
         Str, Any, AnyBut, AnyChar, Rep, Rep1, Opt, Bol, Eol, Eof, \
-        TEXT, IGNORE, State, Lexicon
-    from .Scanning import Method
+        TEXT, IGNORE, Method, State, Lexicon, Range
 
@@ -21,8 +21,8 @@
 
-    letter = Any("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_")
+    nonzero_digit = Any("123456789")
     digit = Any("0123456789")
     bindigit = Any("01")
     octdigit = Any("01234567")
     hexdigit = Any("0123456789ABCDEFabcdef")
     indentation = Bol + Rep(Any(" \t"))
 
@@ -23,9 +23,17 @@
     digit = Any("0123456789")
     bindigit = Any("01")
     octdigit = Any("01234567")
     hexdigit = Any("0123456789ABCDEFabcdef")
     indentation = Bol + Rep(Any(" \t"))
 
+    # The list of valid unicode identifier characters are pretty slow to generate at runtime,
+    # and require Python3, so are just included directly here
+    # (via the generated code block at the bottom of the file)
+    unicode_start_character = (Any(unicode_start_ch_any) | Range(unicode_start_ch_range))
+    unicode_continuation_character = (
+        unicode_start_character |
+        Any(unicode_continuation_ch_any) | Range(unicode_continuation_ch_range))
+
     def underscore_digits(d):
         return Rep1(d) + Rep(Str("_") + Rep1(d))
 
@@ -29,8 +37,11 @@
     def underscore_digits(d):
         return Rep1(d) + Rep(Str("_") + Rep1(d))
 
+    def prefixed_digits(prefix, digits):
+        return prefix + Opt(Str("_")) + underscore_digits(digits)
+
     decimal = underscore_digits(digit)
     dot = Str(".")
     exponent = Any("Ee") + Opt(Any("+-")) + decimal
     decimal_fract = (decimal + dot + Opt(decimal)) | (dot + decimal)
 
@@ -32,12 +43,17 @@
     decimal = underscore_digits(digit)
     dot = Str(".")
     exponent = Any("Ee") + Opt(Any("+-")) + decimal
     decimal_fract = (decimal + dot + Opt(decimal)) | (dot + decimal)
 
-    name = letter + Rep(letter | digit)
-    intconst = decimal | (Str("0") + ((Any("Xx") + underscore_digits(hexdigit)) |
-                                      (Any("Oo") + underscore_digits(octdigit)) |
-                                      (Any("Bb") + underscore_digits(bindigit)) ))
+    #name = letter + Rep(letter | digit)
+    name = unicode_start_character + Rep(unicode_continuation_character)
+    intconst = (prefixed_digits(nonzero_digit, digit) |  # decimal literals with underscores must not start with '0'
+                (Str("0") + (prefixed_digits(Any("Xx"), hexdigit) |
+                             prefixed_digits(Any("Oo"), octdigit) |
+                             prefixed_digits(Any("Bb"), bindigit) )) |
+                underscore_digits(Str('0'))  # 0_0_0_0... is allowed as a decimal literal
+                | Rep1(digit)  # FIXME: remove these Py2 style decimal/octal literals (PY_VERSION_HEX < 3)
+                )
     intsuffix = (Opt(Any("Uu")) + Opt(Any("Ll")) + Opt(Any("Ll"))) | (Opt(Any("Ll")) + Opt(Any("Ll")) + Opt(Any("Uu")))
     intliteral = intconst + intsuffix
     fltconst = (decimal_fract + Opt(exponent)) | (decimal + exponent)
@@ -69,7 +85,7 @@
     comment = Str("#") + Rep(AnyBut("\n"))
 
     return Lexicon([
-        (name, IDENT),
+        (name, Method('normalize_ident')),
         (intliteral, Method('strip_underscores', symbol='INT')),
         (fltconst, Method('strip_underscores', symbol='FLOAT')),
         (imagconst, Method('strip_underscores', symbol='IMAG')),
@@ -136,3 +152,48 @@
         #debug_file = scanner_dump_file
         )
 
+
+# BEGIN GENERATED CODE
+# generated with:
+# cpython 3.8.0b3+ (heads/3.8:ca9ae94a2a, Aug 23 2019, 17:18:38)
+
+unicode_start_ch_any = (
+    u"_ªµºˬˮͿΆΌՙەۿܐޱߺࠚࠤࠨऽॐলঽৎৼਫ਼ઽૐૹଽୱஃஜௐఽಀಽೞഽൎලาຄລາຽໆༀဿၡႎჇჍቘዀៗៜᢪᪧᳺὙ"
+    u"ὛὝιⁱⁿℂℇℕℤΩℨⅎⴧⴭⵯꣻꧏꩺꪱꫀꫂיִמּﹱﹳﹷﹹﹻﹽ𐠈𐠼𐨀𐼧𑅄𑅶𑇚𑇜𑊈𑌽𑍐𑑟𑓇𑙄𑚸𑣿𑧡𑧣𑨀𑨺𑩐𑪝𑱀𑵆𑶘𖽐𖿣𝒢𝒻𝕆𞅎"
+    u"𞥋𞸤𞸧𞸹𞸻𞹂𞹇𞹉𞹋𞹔𞹗𞹙𞹛𞹝𞹟𞹤𞹾"
+)
+unicode_start_ch_range = (
+    u"AZazÀÖØöøˁˆˑˠˤͰʹͶͷͻͽΈΊΎΡΣϵϷҁҊԯԱՖՠֈאתׯײؠيٮٯٱۓۥۦۮۯۺۼܒܯݍޥߊߪߴߵࠀࠕ"
+    u"ࡀࡘࡠࡪࢠࢴࢶࢽऄहक़ॡॱঀঅঌএঐওনপরশহড়ঢ়য়ৡৰৱਅਊਏਐਓਨਪਰਲਲ਼ਵਸ਼ਸਹਖ਼ੜੲੴઅઍએઑઓનપરલળવહ"
+    u"ૠૡଅଌଏଐଓନପରଲଳଵହଡ଼ଢ଼ୟୡஅஊஎஐஒகஙசஞடணதநபமஹఅఌఎఐఒనపహౘౚౠౡಅಌಎಐಒನಪಳವಹೠೡೱೲ"
+    u"അഌഎഐഒഺൔൖൟൡൺൿඅඖකනඳරවෆกะเๆກຂຆຊຌຣວະເໄໜໟཀཇཉཬྈྌကဪၐၕၚၝၥၦၮၰၵႁႠჅაჺჼቈ"
+    u"ቊቍቐቖቚቝበኈኊኍነኰኲኵኸኾዂዅወዖዘጐጒጕጘፚᎀᎏᎠᏵᏸᏽᐁᙬᙯᙿᚁᚚᚠᛪᛮᛸᜀᜌᜎᜑᜠᜱᝀᝑᝠᝬᝮᝰកឳᠠᡸᢀᢨ"
+    u"ᢰᣵᤀᤞᥐᥭᥰᥴᦀᦫᦰᧉᨀᨖᨠᩔᬅᬳᭅᭋᮃᮠᮮᮯᮺᯥᰀᰣᱍᱏᱚᱽᲀᲈᲐᲺᲽᲿᳩᳬᳮᳳᳵᳶᴀᶿḀἕἘἝἠὅὈὍὐὗὟώᾀᾴ"
+    u"ᾶᾼῂῄῆῌῐΐῖΊῠῬῲῴῶῼₐₜℊℓ℘ℝKℹℼℿⅅⅉⅠↈⰀⰮⰰⱞⱠⳤⳫⳮⳲⳳⴀⴥⴰⵧⶀⶖⶠⶦⶨⶮⶰⶶⶸⶾⷀⷆⷈⷎⷐⷖ"
+    u"ⷘⷞ々〇〡〩〱〵〸〼ぁゖゝゟァヺーヿㄅㄯㄱㆎㆠㆺㇰㇿ㐀䶵一鿯ꀀꒌꓐꓽꔀꘌꘐꘟꘪꘫꙀꙮꙿꚝꚠꛯꜗꜟꜢꞈꞋꞿꟂꟆꟷꠁꠃꠅꠇꠊ"
+    u"ꠌꠢꡀꡳꢂꢳꣲꣷꣽꣾꤊꤥꤰꥆꥠꥼꦄꦲꧠꧤꧦꧯꧺꧾꨀꨨꩀꩂꩄꩋꩠꩶꩾꪯꪵꪶꪹꪽꫛꫝꫠꫪꫲꫴꬁꬆꬉꬎꬑꬖꬠꬦꬨꬮꬰꭚꭜꭧꭰꯢ"
+    u"가힣ힰퟆퟋퟻ豈舘並龎ffstﬓﬗײַﬨשׁזּטּלּנּסּףּפּצּﮱﯓﱝﱤﴽﵐﶏﶒﷇﷰﷹﹿﻼAZazヲンᅠ하ᅦᅧᅬᅭᅲᅳᅵ𐀀𐀋𐀍𐀦𐀨𐀺"
+    u"𐀼𐀽𐀿𐁍𐁐𐁝𐂀𐃺𐅀𐅴𐊀𐊜𐊠𐋐𐌀𐌟𐌭𐍊𐍐𐍵𐎀𐎝𐎠𐏃𐏈𐏏𐏑𐏕𐐀𐒝𐒰𐓓𐓘𐓻𐔀𐔧𐔰𐕣𐘀𐜶𐝀𐝕𐝠𐝧𐠀𐠅𐠊𐠵𐠷𐠸𐠿𐡕𐡠𐡶𐢀𐢞𐣠𐣲𐣴𐣵"
+    u"𐤀𐤕𐤠𐤹𐦀𐦷𐦾𐦿𐨐𐨓𐨕𐨗𐨙𐨵𐩠𐩼𐪀𐪜𐫀𐫇𐫉𐫤𐬀𐬵𐭀𐭕𐭠𐭲𐮀𐮑𐰀𐱈𐲀𐲲𐳀𐳲𐴀𐴣𐼀𐼜𐼰𐽅𐿠𐿶𑀃𑀷𑂃𑂯𑃐𑃨𑄃𑄦𑅐𑅲𑆃𑆲𑇁𑇄𑈀𑈑"
+    u"𑈓𑈫𑊀𑊆𑊊𑊍𑊏𑊝𑊟𑊨𑊰𑋞𑌅𑌌𑌏𑌐𑌓𑌨𑌪𑌰𑌲𑌳𑌵𑌹𑍝𑍡𑐀𑐴𑑇𑑊𑒀𑒯𑓄𑓅𑖀𑖮𑗘𑗛𑘀𑘯𑚀𑚪𑜀𑜚𑠀𑠫𑢠𑣟𑦠𑦧𑦪𑧐𑨋𑨲𑩜𑪉𑫀𑫸𑰀𑰈"
+    u"𑰊𑰮𑱲𑲏𑴀𑴆𑴈𑴉𑴋𑴰𑵠𑵥𑵧𑵨𑵪𑶉𑻠𑻲𒀀𒎙𒐀𒑮𒒀𒕃𓀀𓐮𔐀𔙆𖠀𖨸𖩀𖩞𖫐𖫭𖬀𖬯𖭀𖭃𖭣𖭷𖭽𖮏𖹀𖹿𖼀𖽊𖾓𖾟𖿠𖿡𗀀𘟷𘠀𘫲𛀀𛄞𛅐𛅒𛅤𛅧"
+    u"𛅰𛋻𛰀𛱪𛱰𛱼𛲀𛲈𛲐𛲙𝐀𝑔𝑖𝒜𝒞𝒟𝒥𝒦𝒩𝒬𝒮𝒹𝒽𝓃𝓅𝔅𝔇𝔊𝔍𝔔𝔖𝔜𝔞𝔹𝔻𝔾𝕀𝕄𝕊𝕐𝕒𝚥𝚨𝛀𝛂𝛚𝛜𝛺𝛼𝜔𝜖𝜴𝜶𝝎𝝐𝝮𝝰𝞈𝞊𝞨"
+    u"𝞪𝟂𝟄𝟋𞄀𞄬𞄷𞄽𞋀𞋫𞠀𞣄𞤀𞥃𞸀𞸃𞸅𞸟𞸡𞸢𞸩𞸲𞸴𞸷𞹍𞹏𞹑𞹒𞹡𞹢𞹧𞹪𞹬𞹲𞹴𞹷𞹹𞹼𞺀𞺉𞺋𞺛𞺡𞺣𞺥𞺩𞺫𞺻𠀀𪛖𪜀𫜴𫝀𫠝𫠠𬺡𬺰𮯠"
+)
+unicode_continuation_ch_any = (
+    u"··়ׇֿٰܑ߽ৗ਼৾ੑੵ઼଼ஂௗ಼ൗ්ූัັ༹༵༷࿆᳭ᢩ៝᳴⁔⵿⃡꙯ꠂ꠆ꠋꧥꩃﬞꪰ꫁_𑅳𐨿𐇽𐋠𑈾𑍗𑑞𑧤𑩇𑴺𑵇𖽏𝩵𝪄"
+)
+unicode_continuation_ch_range = (
+    u"09ֽׁׂًؚ֑ׅ̀ͯ҃҇ׄؐ٩۪ۭۖۜ۟ۤۧۨ۰۹ܰ݊ަް߀߉࡙࡛࣓ࣣ߫߳ࠖ࠙ࠛࠣࠥࠧࠩ࠭࣡ःऺ़ाॏ॑ॗॢॣ०९ঁঃ"
+    u"াৄেৈো্ৢৣ০৯ਁਃਾੂੇੈੋ੍੦ੱઁઃાૅેૉો્ૢૣ૦૯ૺ૿ଁଃାୄେୈୋ୍ୖୗୢୣ୦୯ாூெைொ்௦௯ఀఄాౄ"
+    u"ెైొ్ౕౖౢౣ౦౯ಁಃಾೄೆೈೊ್ೕೖೢೣ೦೯ഀഃ഻഼ാൄെൈൊ്ൢൣ൦൯ංඃාුෘෟ෦෯ෲෳำฺ็๎๐๙ຳຼ່ໍ໐໙"
+    u"༘༙༠༩༾༿྄ཱ྆྇ྍྗྙྼါှ၀၉ၖၙၞၠၢၤၧၭၱၴႂႍႏႝ፝፟፩፱ᜒ᜔ᜲ᜴ᝒᝓᝲᝳ឴៓០៩᠋᠍᠐᠙ᤠᤫᤰ᤻᥆᥏᧐᧚"
+    u"ᨗᨛᩕᩞ᩠᩿᩼᪉᪐᪙᪽᪰ᬀᬄ᬴᭄᭐᭙᭫᭳ᮀᮂᮡᮭ᮰᮹᯦᯳ᰤ᰷᱀᱉᱐᱙᳔᳨᳐᳒᳷᷹᷿᳹᷀᷻‿⁀⃥゙゚〪〯⃐⃜⃰⳯⳱ⷠⷿ꘠꘩"
+    u"ꙴ꙽ꚞꚟ꛰꛱ꠣꠧꢀꢁꢴꣅ꣐꣙꣠꣱ꣿ꤉ꤦ꤭ꥇ꥓ꦀꦃ꦳꧀꧐꧙꧰꧹ꨩꨶꩌꩍ꩐꩙ꩻꩽꪴꪲꪷꪸꪾ꪿ꫫꫯꫵ꫶ꯣꯪ꯬꯭꯰꯹︀️︠︯︳︴"
+    u"﹍﹏09゙゚𐍶𐍺𐒠𐒩𐨁𐨃𐨅𐨆𐨌𐨺𐫦𐨏𐨸𐫥𐴤𐴧𐴰𐴹𐽆𐽐𑀀𑀂𑀸𑁆𑁦𑁯𑁿𑂂𑂰𑂺𑃰𑃹𑄀𑄂𑄧𑄴𑄶𑄿𑅅𑅆𑆀𑆂𑆳𑇀𑇉𑇌𑇐𑇙𑈬𑈷𑋟𑋪𑋰𑋹"
+    u"𑌀𑌃𑌻𑌼𑌾𑍄𑍇𑍈𑍋𑍍𑍢𑍣𑍦𑍬𑍰𑍴𑐵𑑆𑑐𑑙𑒰𑓃𑓐𑓙𑖯𑖵𑖸𑗀𑗜𑗝𑘰𑙀𑙐𑙙𑚫𑚷𑛀𑛉𑜝𑜫𑜰𑜹𑠬𑠺𑣠𑣩𑧑𑧗𑧚𑧠𑨁𑨊𑨳𑨹𑨻𑨾𑩑𑩛𑪊𑪙"
+    u"𑰯𑰶𑰸𑰿𑱐𑱙𑲒𑲧𑲩𑲶𑴱𑴶𑴼𑴽𑴿𑵅𑵐𑵙𑶊𑶎𑶐𑶑𑶓𑶗𑶠𑶩𑻳𑻶𖩠𖩩𖫰𖫴𖬰𖬶𖭐𖭙𖽑𖾇𖾏𖾒𛲝𛲞𝅩𝅥𝅲𝅻𝆂𝆋𝅭𝆅𝆪𝆭𝉂𝉄𝟎𝟿𝨀𝨶𝨻𝩬"
+    u"𝪛𝪟𝪡𝪯𞀀𞀆𞀈𞀘𞀛𞀡𞀣𞀤𞀦𞀪𞄰𞄶𞅀𞅉𞋬𞋹𞥊𞣐𞣖𞥄𞥐𞥙"
+)
+
+# END GENERATED CODE
diff --git a/Cython/Compiler/Main.py b/Cython/Compiler/Main.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL01haW4ucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL01haW4ucHk= 100644
--- a/Cython/Compiler/Main.py
+++ b/Cython/Compiler/Main.py
@@ -9,8 +9,8 @@
 import sys
 import io
 
-if sys.version_info[:2] < (2, 6) or (3, 0) <= sys.version_info[:2] < (3, 3):
-    sys.stderr.write("Sorry, Cython requires Python 2.6+ or 3.3+, found %d.%d\n" % tuple(sys.version_info[:2]))
+if sys.version_info[:2] < (2, 7) or (3, 0) <= sys.version_info[:2] < (3, 3):
+    sys.stderr.write("Sorry, Cython requires Python 2.7 or 3.3+, found %d.%d\n" % tuple(sys.version_info[:2]))
     sys.exit(1)
 
 try:
@@ -30,7 +30,8 @@
 from .Symtab import ModuleScope
 from .. import Utils
 from . import Options
-
-from . import Version  # legacy import needed by old PyTables versions
-version = Version.version  # legacy attribute - use "Cython.__version__" instead
+from .Options import CompilationOptions, default_options
+from .CmdLine import parse_command_line
+from .Lexicon import (unicode_start_ch_any, unicode_continuation_ch_any,
+                      unicode_start_ch_range, unicode_continuation_ch_range)
 
@@ -36,8 +37,2 @@
 
-module_name_pattern = re.compile(r"[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)*$")
-
-verbose = 0
-
-standard_include_path = os.path.abspath(os.path.join(os.path.dirname(__file__),
-                                        os.path.pardir, 'Includes'))
 
@@ -43,5 +38,7 @@
 
-class CompilationData(object):
-    #  Bundles the information that is passed from transform to transform.
-    #  (For now, this is only)
+def _make_range_re(chrs):
+    out = []
+    for i in range(0, len(chrs), 2):
+        out.append(u"{0}-{1}".format(chrs[i], chrs[i+1]))
+    return u"".join(out)
 
@@ -47,13 +44,14 @@
 
-    #  While Context contains every pxd ever loaded, path information etc.,
-    #  this only contains the data related to a single compilation pass
-    #
-    #  pyx                   ModuleNode              Main code tree of this compilation.
-    #  pxds                  {string : ModuleNode}   Trees for the pxds used in the pyx.
-    #  codewriter            CCodeWriter             Where to output final code.
-    #  options               CompilationOptions
-    #  result                CompilationResult
-    pass
+# py2 version looked like r"[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)*$"
+module_name_pattern = u"[{0}{1}][{0}{2}{1}{3}]*".format(
+    unicode_start_ch_any, _make_range_re(unicode_start_ch_range),
+    unicode_continuation_ch_any,
+    _make_range_re(unicode_continuation_ch_range))
+module_name_pattern = re.compile(u"{0}(\\.{0})*$".format(module_name_pattern))
+
+
+standard_include_path = os.path.abspath(
+    os.path.join(os.path.dirname(os.path.dirname(__file__)), 'Includes'))
 
 
 class Context(object):
@@ -95,4 +93,9 @@
 
         self.gdb_debug_outputwriter = None
 
+    @classmethod
+    def from_options(cls, options):
+        return cls(options.include_path, options.compiler_directives,
+                   options.cplus, options.language_level, options=options)
+
     def set_language_level(self, level):
@@ -98,5 +101,5 @@
     def set_language_level(self, level):
-        from .Future import print_function, unicode_literals, absolute_import, division
+        from .Future import print_function, unicode_literals, absolute_import, division, generator_stop
         future_directives = set()
         if level == '3str':
             level = 3
@@ -105,7 +108,7 @@
             if level >= 3:
                 future_directives.add(unicode_literals)
         if level >= 3:
-            future_directives.update([print_function, absolute_import, division])
+            future_directives.update([print_function, absolute_import, division, generator_stop])
         self.language_level = level
         self.future_directives = future_directives
         if level >= 3:
@@ -123,15 +126,6 @@
         self._interned[key] = value
         return value
 
-    def intern_value(self, value, *key):
-        key = (type(value), value) + key
-        try:
-            return self._interned[key]
-        except KeyError:
-            pass
-        self._interned[key] = value
-        return value
-
     # pipeline creation functions can now be found in Pipeline.py
 
     def process_pxd(self, source_desc, scope, module_name):
@@ -179,7 +173,7 @@
 
         if not module_name_pattern.match(qualified_name):
             raise CompileError(pos or (module_name, 0, 0),
-                               "'%s' is not a valid module name" % module_name)
+                               u"'%s' is not a valid module name" % module_name)
 
         if relative_to:
             if debug_find_module:
@@ -216,7 +210,7 @@
                     # look for the non-existing pxd file next time.
                     scope.pxd_file_loaded = True
                     package_pathname = self.search_include_directories(qualified_name, ".py", pos)
-                    if package_pathname and package_pathname.endswith('__init__.py'):
+                    if package_pathname and package_pathname.endswith(Utils.PACKAGE_FILES):
                         pass
                     else:
                         error(pos, "'%s.pxd' not found" % qualified_name.replace('.', os.sep))
@@ -248,25 +242,6 @@
         # for a dotted filename, and its containing package root
         # directory is searched first for a non-dotted filename.
         pxd = self.search_include_directories(qualified_name, ".pxd", pos, sys_path=sys_path)
-        if pxd is None: # XXX Keep this until Includes/Deprecated is removed
-            if (qualified_name.startswith('python') or
-                    qualified_name in ('stdlib', 'stdio', 'stl')):
-                standard_include_path = os.path.abspath(os.path.normpath(
-                        os.path.join(os.path.dirname(__file__), os.path.pardir, 'Includes')))
-                deprecated_include_path = os.path.join(standard_include_path, 'Deprecated')
-                self.include_directories.append(deprecated_include_path)
-                try:
-                    pxd = self.search_include_directories(qualified_name, ".pxd", pos)
-                finally:
-                    self.include_directories.pop()
-                if pxd:
-                    name = qualified_name
-                    if name.startswith('python'):
-                        warning(pos, "'%s' is deprecated, use 'cpython'" % name, 1)
-                    elif name in ('stdlib', 'stdio'):
-                        warning(pos, "'%s' is deprecated, use 'libc.%s'" % (name, name), 1)
-                    elif name in ('stl'):
-                        warning(pos, "'%s' is deprecated, use 'libcpp.*.*'" % name, 1)
         if pxd is None and Options.cimport_from_pyx:
             return self.find_pyx_file(qualified_name, pos)
         return pxd
@@ -473,6 +448,12 @@
 def run_pipeline(source, options, full_module_name=None, context=None):
     from . import Pipeline
 
+    # ensure that the inputs are unicode (for Python 2)
+    if sys.version_info[0] == 2:
+        source = Utils.decode_filename(source)
+        if full_module_name:
+            full_module_name = Utils.decode_filename(full_module_name)
+
     source_ext = os.path.splitext(source)[1]
     options.configure_language_defaults(source_ext[1:]) # py/pyx
     if context is None:
@@ -476,9 +457,9 @@
     source_ext = os.path.splitext(source)[1]
     options.configure_language_defaults(source_ext[1:]) # py/pyx
     if context is None:
-        context = options.create_context()
+        context = Context.from_options(options)
 
     # Set up source object
     cwd = os.getcwd()
     abs_path = os.path.abspath(source)
     full_module_name = full_module_name or context.extract_module_name(source, options)
@@ -480,8 +461,9 @@
 
     # Set up source object
     cwd = os.getcwd()
     abs_path = os.path.abspath(source)
     full_module_name = full_module_name or context.extract_module_name(source, options)
+    full_module_name = EncodedString(full_module_name)
 
     Utils.raise_error_if_module_name_forbidden(full_module_name)
 
@@ -512,6 +494,12 @@
         pipeline = Pipeline.create_pyx_pipeline(context, options, result)
 
     context.setup_errors(options, result)
+
+    if '.' in full_module_name and '.' in os.path.splitext(os.path.basename(abs_path))[0]:
+        warning((source_desc, 1, 0),
+                "Dotted filenames ('%s') are deprecated."
+                " Please use the normal Python package directory layout." % os.path.basename(abs_path), level=1)
+
     err, enddata = Pipeline.run_pipeline(pipeline, source)
     context.teardown_errors(err, options, result)
     return result
@@ -534,146 +522,6 @@
         self.cwd = cwd
 
 
-class CompilationOptions(object):
-    r"""
-    See default_options at the end of this module for a list of all possible
-    options and CmdLine.usage and CmdLine.parse_command_line() for their
-    meaning.
-    """
-    def __init__(self, defaults=None, **kw):
-        self.include_path = []
-        if defaults:
-            if isinstance(defaults, CompilationOptions):
-                defaults = defaults.__dict__
-        else:
-            defaults = default_options
-
-        options = dict(defaults)
-        options.update(kw)
-
-        # let's assume 'default_options' contains a value for most known compiler options
-        # and validate against them
-        unknown_options = set(options) - set(default_options)
-        # ignore valid options that are not in the defaults
-        unknown_options.difference_update(['include_path'])
-        if unknown_options:
-            message = "got unknown compilation option%s, please remove: %s" % (
-                's' if len(unknown_options) > 1 else '',
-                ', '.join(unknown_options))
-            raise ValueError(message)
-
-        directive_defaults = Options.get_directive_defaults()
-        directives = dict(options['compiler_directives'])  # copy mutable field
-        # check for invalid directives
-        unknown_directives = set(directives) - set(directive_defaults)
-        if unknown_directives:
-            message = "got unknown compiler directive%s: %s" % (
-                's' if len(unknown_directives) > 1 else '',
-                ', '.join(unknown_directives))
-            raise ValueError(message)
-        options['compiler_directives'] = directives
-        if directives.get('np_pythran', False) and not options['cplus']:
-            import warnings
-            warnings.warn("C++ mode forced when in Pythran mode!")
-            options['cplus'] = True
-        if 'language_level' in directives and 'language_level' not in kw:
-            options['language_level'] = directives['language_level']
-        elif not options.get('language_level'):
-            options['language_level'] = directive_defaults.get('language_level')
-        if 'formal_grammar' in directives and 'formal_grammar' not in kw:
-            options['formal_grammar'] = directives['formal_grammar']
-        if options['cache'] is True:
-            options['cache'] = os.path.join(Utils.get_cython_cache_dir(), 'compiler')
-
-        self.__dict__.update(options)
-
-    def configure_language_defaults(self, source_extension):
-        if source_extension == 'py':
-            if self.compiler_directives.get('binding') is None:
-                self.compiler_directives['binding'] = True
-
-    def create_context(self):
-        return Context(self.include_path, self.compiler_directives,
-                       self.cplus, self.language_level, options=self)
-
-    def get_fingerprint(self):
-        r"""
-        Return a string that contains all the options that are relevant for cache invalidation.
-        """
-        # Collect only the data that can affect the generated file(s).
-        data = {}
-
-        for key, value in self.__dict__.items():
-            if key in ['show_version', 'errors_to_stderr', 'verbose', 'quiet']:
-                # verbosity flags have no influence on the compilation result
-                continue
-            elif key in ['output_file', 'output_dir']:
-                # ignore the exact name of the output file
-                continue
-            elif key in ['timestamps']:
-                # the cache cares about the content of files, not about the timestamps of sources
-                continue
-            elif key in ['cache']:
-                # hopefully caching has no influence on the compilation result
-                continue
-            elif key in ['compiler_directives']:
-                # directives passed on to the C compiler do not influence the generated C code
-                continue
-            elif key in ['include_path']:
-                # this path changes which headers are tracked as dependencies,
-                # it has no influence on the generated C code
-                continue
-            elif key in ['working_path']:
-                # this path changes where modules and pxd files are found;
-                # their content is part of the fingerprint anyway, their
-                # absolute path does not matter
-                continue
-            elif key in ['create_extension']:
-                # create_extension() has already mangled the options, e.g.,
-                # embedded_metadata, when the fingerprint is computed so we
-                # ignore it here.
-                continue
-            elif key in ['build_dir']:
-                # the (temporary) directory where we collect dependencies
-                # has no influence on the C output
-                continue
-            elif key in ['use_listing_file', 'generate_pxi', 'annotate', 'annotate_coverage_xml']:
-                # all output files are contained in the cache so the types of
-                # files generated must be part of the fingerprint
-                data[key] = value
-            elif key in ['formal_grammar', 'evaluate_tree_assertions']:
-                # these bits can change whether compilation to C passes/fails
-                data[key] = value
-            elif key in ['embedded_metadata', 'emit_linenums', 'c_line_in_traceback', 'gdb_debug', 'relative_path_in_code_position_comments']:
-                # the generated code contains additional bits when these are set
-                data[key] = value
-            elif key in ['cplus', 'language_level', 'compile_time_env', 'np_pythran']:
-                # assorted bits that, e.g., influence the parser
-                data[key] = value
-            elif key == ['capi_reexport_cincludes']:
-                if self.capi_reexport_cincludes:
-                    # our caching implementation does not yet include fingerprints of all the header files
-                    raise NotImplementedError('capi_reexport_cincludes is not compatible with Cython caching')
-            elif key == ['common_utility_include_dir']:
-                if self.common_utility_include_dir:
-                    raise NotImplementedError('common_utility_include_dir is not compatible with Cython caching yet')
-            else:
-                # any unexpected option should go into the fingerprint; it's better
-                # to recompile than to return incorrect results from the cache.
-                data[key] = value
-
-        def to_fingerprint(item):
-            r"""
-            Recursively turn item into a string, turning dicts into lists with
-            deterministic ordering.
-            """
-            if isinstance(item, dict):
-                item = sorted([(repr(key), to_fingerprint(value)) for key, value in item.items()])
-            return repr(item)
-
-        return to_fingerprint(data)
-
-
 class CompilationResult(object):
     """
     Results from the Cython compiler:
@@ -736,7 +584,7 @@
     if these are specified in the options.
     """
     # run_pipeline creates the context
-    # context = options.create_context()
+    # context = Context.from_options(options)
     sources = [os.path.abspath(source) for source in sources]
     processed = set()
     results = CompilationResultSet()
@@ -747,7 +595,7 @@
     for source in sources:
         if source not in processed:
             if context is None:
-                context = options.create_context()
+                context = Context.from_options(options)
             output_filename = get_output_filename(source, cwd, options)
             out_of_date = context.c_file_out_of_date(source, output_filename)
             if (not timestamps) or out_of_date:
@@ -791,7 +639,6 @@
 
     The 'include' option will disable package dereferencing.
     """
-
     if pos:
         file_desc = pos[0]
         if not isinstance(file_desc, FileSourceDescriptor):
@@ -801,7 +648,8 @@
         else:
             dirs = (Utils.find_root_package_dir(file_desc.filename),) + dirs
 
+    # search for dotted filename e.g. <dir>/foo.bar.pxd
     dotted_filename = qualified_name
     if suffix:
         dotted_filename += suffix
 
@@ -804,5 +652,14 @@
     dotted_filename = qualified_name
     if suffix:
         dotted_filename += suffix
 
+    for dirname in dirs:
+        path = os.path.join(dirname, dotted_filename)
+        if os.path.exists(path):
+            if '.' in qualified_name and '.' in os.path.splitext(dotted_filename)[0]:
+                warning(pos, "Dotted filenames ('%s') are deprecated."
+                             " Please use the normal Python package directory layout." % dotted_filename, level=1)
+            return path
+
+    # search for filename in package structure e.g. <dir>/foo/bar.pxd or <dir>/foo/bar/__init__.pxd
     if not include:
@@ -808,7 +665,8 @@
     if not include:
+
         names = qualified_name.split('.')
         package_names = tuple(names[:-1])
         module_name = names[-1]
         module_filename = module_name + suffix
         package_filename = "__init__" + suffix
 
@@ -809,11 +667,12 @@
         names = qualified_name.split('.')
         package_names = tuple(names[:-1])
         module_name = names[-1]
         module_filename = module_name + suffix
         package_filename = "__init__" + suffix
 
-    for dirname in dirs:
-        path = os.path.join(dirname, dotted_filename)
-        if os.path.exists(path):
-            return path
+        # search for standard packages first - PEP420
+        namespace_dirs = []
+        for dirname in dirs:
+            package_dir, is_namespace = Utils.check_package_dir(dirname, package_names)
+            if package_dir is not None:
 
@@ -819,7 +678,9 @@
 
-        if not include:
-            package_dir = Utils.check_package_dir(dirname, package_names)
-            if package_dir is not None:
+                if is_namespace:
+                    namespace_dirs.append(package_dir)
+                    continue
+
+                # matches modules of the form: <dir>/foo/bar.pxd
                 path = os.path.join(package_dir, module_filename)
                 if os.path.exists(path):
                     return path
@@ -823,7 +684,8 @@
                 path = os.path.join(package_dir, module_filename)
                 if os.path.exists(path):
                     return path
-                path = os.path.join(package_dir, module_name,
-                                    package_filename)
+
+                # matches modules of the form: <dir>/foo/bar/__init__.pxd
+                path = os.path.join(package_dir, module_name, package_filename)
                 if os.path.exists(path):
                     return path
@@ -828,5 +690,18 @@
                 if os.path.exists(path):
                     return path
+
+        # search for namespaces second - PEP420
+        for package_dir in namespace_dirs:
+            # matches modules of the form: <dir>/foo/bar.pxd
+            path = os.path.join(package_dir, module_filename)
+            if os.path.exists(path):
+                return path
+
+            # matches modules of the form: <dir>/foo/bar/__init__.pxd
+            path = os.path.join(package_dir, module_name, package_filename)
+            if os.path.exists(path):
+                return path
+
     return None
 
 
@@ -844,10 +719,9 @@
     args = sys.argv[1:]
     any_failures = 0
     if command_line:
-        from .CmdLine import parse_command_line
         options, sources = parse_command_line(args)
     else:
         options = CompilationOptions(default_options)
         sources = args
 
     if options.show_version:
@@ -848,10 +722,11 @@
         options, sources = parse_command_line(args)
     else:
         options = CompilationOptions(default_options)
         sources = args
 
     if options.show_version:
-        sys.stderr.write("Cython version %s\n" % version)
+        from .. import __version__
+        sys.stderr.write("Cython version %s\n" % __version__)
     if options.working_path!="":
         os.chdir(options.working_path)
     try:
@@ -863,42 +738,3 @@
         any_failures = 1
     if any_failures:
         sys.exit(1)
-
-
-# ------------------------------------------------------------------------
-#
-#  Set the default options depending on the platform
-#
-# ------------------------------------------------------------------------
-
-default_options = dict(
-    show_version = 0,
-    use_listing_file = 0,
-    errors_to_stderr = 1,
-    cplus = 0,
-    output_file = None,
-    annotate = None,
-    annotate_coverage_xml = None,
-    generate_pxi = 0,
-    capi_reexport_cincludes = 0,
-    working_path = "",
-    timestamps = None,
-    verbose = 0,
-    quiet = 0,
-    compiler_directives = {},
-    embedded_metadata = {},
-    evaluate_tree_assertions = False,
-    emit_linenums = False,
-    relative_path_in_code_position_comments = True,
-    c_line_in_traceback = True,
-    language_level = None,  # warn but default to 2
-    formal_grammar = False,
-    gdb_debug = False,
-    compile_time_env = None,
-    common_utility_include_dir = None,
-    output_dir=None,
-    build_dir=None,
-    cache=None,
-    create_extension=None,
-    np_pythran=False
-)
diff --git a/Cython/Compiler/MemoryView.py b/Cython/Compiler/MemoryView.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL01lbW9yeVZpZXcucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL01lbW9yeVZpZXcucHk= 100644
--- a/Cython/Compiler/MemoryView.py
+++ b/Cython/Compiler/MemoryView.py
@@ -101,7 +101,8 @@
 def put_assign_to_memviewslice(lhs_cname, rhs, rhs_cname, memviewslicetype, code,
                                have_gil=False, first_assignment=False):
     if not first_assignment:
-        code.put_xdecref_memoryviewslice(lhs_cname, have_gil=have_gil)
+        code.put_xdecref(lhs_cname, memviewslicetype,
+                         have_gil=have_gil)
 
     if not rhs.result_in_temp():
         rhs.make_owned_memoryviewslice(code)
@@ -248,7 +249,7 @@
 
         return bufp
 
-    def generate_buffer_slice_code(self, code, indices, dst, have_gil,
+    def generate_buffer_slice_code(self, code, indices, dst, dst_type, have_gil,
                                    have_slices, directives):
         """
         Slice a memoryviewslice.
@@ -265,7 +266,7 @@
 
         code.putln("%(dst)s.data = %(src)s.data;" % locals())
         code.putln("%(dst)s.memview = %(src)s.memview;" % locals())
-        code.put_incref_memoryviewslice(dst)
+        code.put_incref_memoryviewslice(dst, dst_type, have_gil=have_gil)
 
         all_dimensions_direct = all(access == 'direct' for access, packing in self.type.axes)
         suboffset_dim_temp = []
@@ -402,8 +403,8 @@
     return utility
 
 
-def slice_iter(slice_type, slice_result, ndim, code):
-    if slice_type.is_c_contig or slice_type.is_f_contig:
+def slice_iter(slice_type, slice_result, ndim, code, force_strided=False):
+    if (slice_type.is_c_contig or slice_type.is_f_contig) and not force_strided:
         return ContigSliceIter(slice_type, slice_result, ndim, code)
     else:
         return StridedSliceIter(slice_type, slice_result, ndim, code)
@@ -487,7 +488,7 @@
 
 def get_copy_new_utility(pos, from_memview, to_memview):
     if (from_memview.dtype != to_memview.dtype and
-            not (from_memview.dtype.is_const and from_memview.dtype.const_base_type == to_memview.dtype)):
+            not (from_memview.dtype.is_cv_qualified and from_memview.dtype.cv_base_type == to_memview.dtype)):
         error(pos, "dtypes must be the same!")
         return
     if len(from_memview.axes) != len(to_memview.axes):
@@ -807,7 +808,7 @@
     'memview_struct_name': memview_objstruct_cname,
     'max_dims': Options.buffer_max_dims,
     'memviewslice_name': memviewslice_cname,
-    'memslice_init': memslice_entry_init,
+    'memslice_init': PyrexTypes.MemoryViewSliceType.default_value,
 }
 memviewslice_declare_code = load_memview_c_utility(
         "MemviewSliceStruct",
diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL01vZHVsZU5vZGUucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL01vZHVsZU5vZGUucHk= 100644
--- a/Cython/Compiler/ModuleNode.py
+++ b/Cython/Compiler/ModuleNode.py
@@ -14,6 +14,7 @@
 import operator
 import os
 import re
+import sys
 
 from .PyrexTypes import CPtrType
 from . import Future
@@ -30,6 +31,6 @@
 from .PyrexTypes import py_object_type
 from ..Utils import open_new_file, replace_suffix, decode_filename, build_hex_version
 from .Code import UtilityCode, IncludeCode
-from .StringEncoding import EncodedString
+from .StringEncoding import EncodedString, encoded_string_or_bytes_literal
 from .Pythran import has_np_pythran
 
@@ -34,5 +35,17 @@
 from .Pythran import has_np_pythran
 
+
+def replace_suffix_encoded(path, newsuf):
+    # calls replace suffix and returns a EncodedString or BytesLiteral with the encoding set
+    newpath = replace_suffix(path, newsuf)
+    return as_encoded_filename(newpath)
+
+def as_encoded_filename(path):
+    # wraps the path with either EncodedString or BytesLiteral (depending on its input type)
+    # and sets the encoding to the file system encoding
+    return encoded_string_or_bytes_literal(path, sys.getfilesystemencoding())
+
+
 def check_c_declarations_pxd(module_node):
     module_node.scope.check_c_classes_pxd()
     return module_node
@@ -50,6 +63,10 @@
     else:
         emit_linenums = options.emit_linenums
 
+    if hasattr(options, "emit_code_comments"):
+        print('Warning: option emit_code_comments is deprecated. '
+              'Instead, use compiler directive emit_code_comments.')
+
     return Code.CCodeConfig(
         emit_linenums=emit_linenums,
         emit_code_comments=env.directives['emit_code_comments'],
@@ -70,6 +87,7 @@
     child_attrs = ["body"]
     directives = None
 
+
     def merge_in(self, tree, scope, merge_scope=False):
         # Merges in the contents of another tree, and possibly scope. With the
         # current implementation below, this must be done right prior
@@ -162,8 +180,8 @@
         h_funcs = h_entries(env.cfunc_entries)
         h_extension_types = h_entries(env.c_class_entries)
         if h_types or  h_vars or h_funcs or h_extension_types:
-            result.h_file = replace_suffix(result.c_file, ".h")
+            result.h_file = replace_suffix_encoded(result.c_file, ".h")
             h_code = Code.CCodeWriter()
             c_code_config = generate_c_code_config(env, options)
             Code.GlobalState(h_code, self, c_code_config)
             if options.generate_pxi:
@@ -166,10 +184,10 @@
             h_code = Code.CCodeWriter()
             c_code_config = generate_c_code_config(env, options)
             Code.GlobalState(h_code, self, c_code_config)
             if options.generate_pxi:
-                result.i_file = replace_suffix(result.c_file, ".pxi")
+                result.i_file = replace_suffix_encoded(result.c_file, ".pxi")
                 i_code = Code.PyrexCodeWriter(result.i_file)
             else:
                 i_code = None
 
             h_code.put_generated_by()
@@ -171,9 +189,9 @@
                 i_code = Code.PyrexCodeWriter(result.i_file)
             else:
                 i_code = None
 
             h_code.put_generated_by()
-            h_guard = Naming.h_guard_prefix + self.api_name(env)
+            h_guard = self.api_name(Naming.h_guard_prefix, env)
             h_code.put_h_guard(h_guard)
             h_code.putln("")
             h_code.putln('#include "Python.h"')
@@ -181,7 +199,7 @@
             if options.capi_reexport_cincludes:
                 self.generate_includes(env, [], h_code)
             h_code.putln("")
-            api_guard = Naming.api_guard_prefix + self.api_name(env)
+            api_guard = self.api_name(Naming.api_guard_prefix, env)
             h_code.putln("#ifndef %s" % api_guard)
             h_code.putln("")
             self.generate_extern_c_macro_definition(h_code)
@@ -208,7 +226,12 @@
             h_code.putln("/* It now returns a PyModuleDef instance instead of a PyModule instance. */")
             h_code.putln("")
             h_code.putln("#if PY_MAJOR_VERSION < 3")
-            h_code.putln("PyMODINIT_FUNC init%s(void);" % env.module_name)
+            if env.module_name.isascii():
+                py2_mod_name = env.module_name
+            else:
+                py2_mod_name = env.module_name.encode("ascii", errors="ignore").decode("utf-8")
+                h_code.putln('#error "Unicode module names are not supported in Python 2";')
+            h_code.putln("PyMODINIT_FUNC init%s(void);" % py2_mod_name)
             h_code.putln("#else")
             h_code.putln("PyMODINIT_FUNC %s(void);" % self.mod_init_func_cname('PyInit', env))
             h_code.putln("#endif")
@@ -229,8 +252,9 @@
             i_code.putln("cdef extern %s" % (
                 entry.type.declaration_code(entry.cname, pyrex=1)))
 
-    def api_name(self, env):
-        return env.qualified_name.replace(".", "__")
+    def api_name(self, prefix, env):
+        api_name = self.punycode_module_name(prefix, env.qualified_name)
+        return api_name.replace(".", "__")
 
     def generate_api_code(self, env, options, result):
         def api_entries(entries, pxd=0):
@@ -240,8 +264,8 @@
         api_funcs = api_entries(env.cfunc_entries)
         api_extension_types = api_entries(env.c_class_entries)
         if api_vars or api_funcs or api_extension_types:
-            result.api_file = replace_suffix(result.c_file, "_api.h")
+            result.api_file = replace_suffix_encoded(result.c_file, "_api.h")
             h_code = Code.CCodeWriter()
             c_code_config = generate_c_code_config(env, options)
             Code.GlobalState(h_code, self, c_code_config)
             h_code.put_generated_by()
@@ -244,8 +268,8 @@
             h_code = Code.CCodeWriter()
             c_code_config = generate_c_code_config(env, options)
             Code.GlobalState(h_code, self, c_code_config)
             h_code.put_generated_by()
-            api_guard = Naming.api_guard_prefix + self.api_name(env)
+            api_guard = self.api_name(Naming.api_guard_prefix, env)
             h_code.put_h_guard(api_guard)
             # Work around https://bugs.python.org/issue4709
             h_code.putln('#ifdef __MINGW64__')
@@ -254,7 +278,9 @@
 
             h_code.putln('#include "Python.h"')
             if result.h_file:
-                h_code.putln('#include "%s"' % os.path.basename(result.h_file))
+                h_filename = os.path.basename(result.h_file)
+                h_filename = as_encoded_filename(h_filename)
+                h_code.putln('#include %s' % h_filename.as_c_string_literal())
             if api_extension_types:
                 h_code.putln("")
                 for entry in api_extension_types:
@@ -285,5 +311,5 @@
                 h_code.put(UtilityCode.load_as_string("TypeImport", "ImportExport.c")[0])
                 h_code.put(UtilityCode.load_as_string("TypeImport", "ImportExport.c")[1])
             h_code.putln("")
-            h_code.putln("static int import_%s(void) {" % self.api_name(env))
+            h_code.putln("static int %s(void) {" % self.api_name("import", env))
             h_code.putln("PyObject *module = 0;")
@@ -289,7 +315,7 @@
             h_code.putln("PyObject *module = 0;")
-            h_code.putln('module = PyImport_ImportModule("%s");' % env.qualified_name)
+            h_code.putln('module = PyImport_ImportModule(%s);' % env.qualified_name.as_c_string_literal())
             h_code.putln("if (!module) goto bad;")
             for entry in api_funcs:
                 cname = env.mangle(Naming.func_prefix_api, entry.name)
                 sig = entry.type.signature_string()
                 h_code.putln(
@@ -291,11 +317,11 @@
             h_code.putln("if (!module) goto bad;")
             for entry in api_funcs:
                 cname = env.mangle(Naming.func_prefix_api, entry.name)
                 sig = entry.type.signature_string()
                 h_code.putln(
-                    'if (__Pyx_ImportFunction(module, "%s", (void (**)(void))&%s, "%s") < 0) goto bad;'
-                    % (entry.name, cname, sig))
+                    'if (__Pyx_ImportFunction(module, %s, (void (**)(void))&%s, "%s") < 0) goto bad;'
+                    % (entry.name.as_c_string_literal(), cname, sig))
             for entry in api_vars:
                 cname = env.mangle(Naming.varptr_prefix_api, entry.name)
                 sig = entry.type.empty_declaration_code()
                 h_code.putln(
@@ -298,9 +324,9 @@
             for entry in api_vars:
                 cname = env.mangle(Naming.varptr_prefix_api, entry.name)
                 sig = entry.type.empty_declaration_code()
                 h_code.putln(
-                    'if (__Pyx_ImportVoidPtr(module, "%s", (void **)&%s, "%s") < 0) goto bad;'
-                    % (entry.name, cname, sig))
+                    'if (__Pyx_ImportVoidPtr(module, %s, (void **)&%s, "%s") < 0) goto bad;'
+                    % (entry.name.as_c_string_literal(), cname, sig))
             with ModuleImportGenerator(h_code, imported_modules={env.qualified_name: 'module'}) as import_generator:
                 for entry in api_extension_types:
                     self.generate_type_import_call(entry.type, h_code, import_generator, error_code="goto bad;")
@@ -342,7 +368,8 @@
         modules = self.referenced_modules
 
         if Options.annotate or options.annotate:
-            rootwriter = Annotate.AnnotationCCodeWriter()
+            show_entire_c_code = Options.annotate == "fullc" or options.annotate == "fullc"
+            rootwriter = Annotate.AnnotationCCodeWriter(show_entire_c_code=show_entire_c_code)
         else:
             rootwriter = Code.CCodeWriter()
 
@@ -364,8 +391,9 @@
         globalstate.use_utility_code(refnanny_utility_code)
 
         code = globalstate['before_global_var']
-        code.putln('#define __Pyx_MODULE_NAME "%s"' % self.full_module_name)
-        module_is_main = "%s%s" % (Naming.module_is_main, self.full_module_name.replace('.', '__'))
+        code.putln('#define __Pyx_MODULE_NAME %s' %
+                   self.full_module_name.as_c_string_literal())
+        module_is_main = self.is_main_module_flag_cname()
         code.putln("extern int %s;" % module_is_main)
         code.putln("int %s = 0;" % module_is_main)
         code.putln("")
@@ -369,6 +397,6 @@
         code.putln("extern int %s;" % module_is_main)
         code.putln("int %s = 0;" % module_is_main)
         code.putln("")
-        code.putln("/* Implementation of '%s' */" % env.qualified_name)
+        code.putln("/* Implementation of %s */" % env.qualified_name.as_c_string_literal())
 
         code = globalstate['late_includes']
@@ -373,5 +401,4 @@
 
         code = globalstate['late_includes']
-        code.putln("/* Late includes */")
         self.generate_includes(env, modules, code, early=False)
 
@@ -376,5 +403,5 @@
         self.generate_includes(env, modules, code, early=False)
 
-        code = globalstate['all_the_rest']
+        code = globalstate['module_code']
 
         self.generate_cached_builtins_decls(env, code)
@@ -379,4 +406,4 @@
 
         self.generate_cached_builtins_decls(env, code)
-        self.generate_lambda_definitions(env, code)
+
         # generate normal variable and function definitions
@@ -382,2 +409,3 @@
         # generate normal variable and function definitions
+        self.generate_lambda_definitions(env, code)
         self.generate_variable_definitions(env, code)
@@ -383,5 +411,4 @@
         self.generate_variable_definitions(env, code)
-
         self.body.generate_function_definitions(env, code)
 
         code.mark_pos(None)
@@ -389,8 +416,7 @@
         self.generate_method_table(env, code)
         if env.has_import_star:
             self.generate_import_star(env, code)
-        self.generate_pymoduledef_struct(env, code)
 
         # initialise the macro to reduce the code size of one-time functionality
         code.putln(UtilityCode.load_as_string("SmallCodeConfig", "ModuleSetupCode.c")[0].strip())
 
@@ -393,7 +419,12 @@
 
         # initialise the macro to reduce the code size of one-time functionality
         code.putln(UtilityCode.load_as_string("SmallCodeConfig", "ModuleSetupCode.c")[0].strip())
 
+        self.generate_module_state_start(env, globalstate['module_state'])
+        self.generate_module_state_defines(env, globalstate['module_state_defines'])
+        self.generate_module_state_clear(env, globalstate['module_state_clear'])
+        self.generate_module_state_traverse(env, globalstate['module_state_traverse'])
+
         # init_globals is inserted before this
         self.generate_module_init_func(modules[:-1], env, globalstate['init_module'])
         self.generate_module_cleanup_func(env, globalstate['cleanup_module'])
@@ -408,6 +439,8 @@
             globalstate.use_utility_code(utilcode)
         globalstate.finalize_main_c_code()
 
+        self.generate_module_state_end(env, modules, globalstate)
+
         f = open_new_file(result.c_file)
         try:
             rootwriter.copyto(f)
@@ -580,7 +613,7 @@
             definition = module is env
             type_entries = []
             for entry in module.type_entries:
-                if entry.type.is_ctuple:
+                if entry.type.is_ctuple and entry.used:
                     if entry.name not in ctuple_names:
                         ctuple_names.add(entry.name)
                         type_entries.append(entry)
@@ -615,8 +648,8 @@
         for module in modules:
             defined_here = module is env
             modulecode.putln("")
-            modulecode.putln("/* Module declarations from '%s' */" % module.qualified_name)
-            self.generate_c_class_declarations(module, modulecode, defined_here)
+            modulecode.putln("/* Module declarations from %s */" % module.qualified_name.as_c_string_literal())
+            self.generate_c_class_declarations(module, modulecode, defined_here, globalstate)
             self.generate_cvariable_declarations(module, modulecode, defined_here)
             self.generate_cfunction_declarations(module, modulecode, defined_here)
 
@@ -630,4 +663,5 @@
             code.putln(json.dumps(metadata, indent=4, sort_keys=True))
             code.putln("END: Cython Metadata */")
             code.putln("")
+
         code.putln("#define PY_SSIZE_T_CLEAN")
@@ -633,4 +667,5 @@
         code.putln("#define PY_SSIZE_T_CLEAN")
+        self._put_setup_code(code, "InitLimitedAPI")
 
         for inc in sorted(env.c_includes.values(), key=IncludeCode.sortkey):
             if inc.location == inc.INITIAL:
@@ -638,5 +673,5 @@
         code.putln("#ifndef Py_PYTHON_H")
         code.putln("    #error Python headers needed to compile C extensions, "
                    "please install development version of Python.")
-        code.putln("#elif PY_VERSION_HEX < 0x02060000 || "
+        code.putln("#elif PY_VERSION_HEX < 0x02070000 || "
                    "(0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000)")
@@ -642,5 +677,5 @@
                    "(0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000)")
-        code.putln("    #error Cython requires Python 2.6+ or Python 3.3+.")
+        code.putln("    #error Cython requires Python 2.7+ or Python 3.3+.")
         code.putln("#else")
         code.globalstate["end"].putln("#endif /* Py_PYTHON_H */")
 
@@ -658,4 +693,5 @@
         self._put_setup_code(code, "PythonCompatibility")
         self._put_setup_code(code, "MathInitCode")
 
+        # Using "(void)cname" to prevent "unused" warnings.
         if options.c_line_in_traceback:
@@ -661,4 +697,4 @@
         if options.c_line_in_traceback:
-            cinfo = "%s = %s; " % (Naming.clineno_cname, Naming.line_c_macro)
+            cinfo = "%s = %s; (void)%s; " % (Naming.clineno_cname, Naming.line_c_macro, Naming.clineno_cname)
         else:
             cinfo = ""
@@ -663,13 +699,15 @@
         else:
             cinfo = ""
-        code.put("""
-#define __PYX_ERR(f_index, lineno, Ln_error) \\
-{ \\
-  %s = %s[f_index]; %s = lineno; %sgoto Ln_error; \\
-}
-""" % (Naming.filename_cname, Naming.filetable_cname, Naming.lineno_cname, cinfo))
+        code.putln("#define __PYX_MARK_ERR_POS(f_index, lineno) \\")
+        code.putln("    { %s = %s[f_index]; (void)%s; %s = lineno; (void)%s; %s}" % (
+            Naming.filename_cname, Naming.filetable_cname, Naming.filename_cname,
+            Naming.lineno_cname, Naming.lineno_cname,
+            cinfo
+        ))
+        code.putln("#define __PYX_ERR(f_index, lineno, Ln_error) \\")
+        code.putln("    { __PYX_MARK_ERR_POS(f_index, lineno) goto Ln_error; }")
 
         code.putln("")
         self.generate_extern_c_macro_definition(code)
         code.putln("")
 
@@ -671,10 +709,10 @@
 
         code.putln("")
         self.generate_extern_c_macro_definition(code)
         code.putln("")
 
-        code.putln("#define %s" % Naming.h_guard_prefix + self.api_name(env))
-        code.putln("#define %s" % Naming.api_guard_prefix + self.api_name(env))
+        code.putln("#define %s" % self.api_name(Naming.h_guard_prefix, env))
+        code.putln("#define %s" % self.api_name(Naming.api_guard_prefix, env))
         code.putln("/* Early includes */")
         self.generate_includes(env, cimported_modules, code, late=False)
         code.putln("")
@@ -720,6 +758,7 @@
         code.put(Nodes.branch_prediction_macros)
         code.putln('static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; }')
         code.putln('')
+        code.putln('#if !CYTHON_COMPILING_IN_LIMITED_API')
         code.putln('static PyObject *%s = NULL;' % env.module_cname)
         code.putln('static PyObject *%s;' % env.module_dict_cname)
         code.putln('static PyObject *%s;' % Naming.builtins_cname)
@@ -729,5 +768,7 @@
         code.putln('static PyObject *%s;' % Naming.empty_unicode)
         if Options.pre_import is not None:
             code.putln('static PyObject *%s;' % Naming.preimport_cname)
+        code.putln('#endif')
+
         code.putln('static int %s;' % Naming.lineno_cname)
         code.putln('static int %s = 0;' % Naming.clineno_cname)
@@ -732,6 +773,6 @@
         code.putln('static int %s;' % Naming.lineno_cname)
         code.putln('static int %s = 0;' % Naming.clineno_cname)
-        code.putln('static const char * %s= %s;' % (Naming.cfilenm_cname, Naming.file_c_macro))
+        code.putln('static const char * %s = %s;' % (Naming.cfilenm_cname, Naming.file_c_macro))
         code.putln('static const char *%s;' % Naming.filename_cname)
 
         env.use_utility_code(UtilityCode.load_cached("FastTypeChecks", "ModuleSetupCode.c"))
@@ -754,7 +795,6 @@
         code.putln("#endif")
 
     def generate_includes(self, env, cimported_modules, code, early=True, late=True):
-        includes = []
         for inc in sorted(env.c_includes.values(), key=IncludeCode.sortkey):
             if inc.location == inc.EARLY:
                 if early:
@@ -775,7 +815,8 @@
                 if isabs(file_path):
                     file_path = basename(file_path)  # never include absolute paths
                 escaped_filename = file_path.replace("\\", "\\\\").replace('"', r'\"')
-                code.putln('"%s",' % escaped_filename)
+                escaped_filename = as_encoded_filename(escaped_filename)
+                code.putln('%s,' % escaped_filename.as_c_string_literal())
         else:
             # Some C compilers don't like an empty array
             code.putln("0")
@@ -950,7 +991,7 @@
                   if py_attrs:
                       code.put_ensure_gil()
                       for attr in py_attrs:
-                          code.put_init_var_to_py_none(attr, nanny=False);
+                          code.put_init_var_to_py_none(attr, nanny=False)
                   if constructor:
                       code.putln("%s(%s);" % (constructor.cname, ", ".join(arg_names)))
                   if py_attrs:
@@ -969,7 +1010,7 @@
                       code.putln("%s();" % destructor.cname)
                   if py_attrs:
                       for attr in py_attrs:
-                          code.put_var_xdecref(attr, nanny=False);
+                          code.put_var_xdecref(attr, nanny=False)
                       code.put_release_ensured_gil()
                   code.putln("}")
                 else:
@@ -990,7 +1031,7 @@
                   code.put_ensure_gil()
                   for attr in scope.var_entries:
                       if not attr.type.is_cfunction:
-                          code.put_var_xdecref(attr, nanny=False);
+                          code.put_var_xdecref(attr, nanny=False)
                           code.putln("%s = __Pyx_other.%s;" % (attr.cname, attr.cname))
                           code.put_var_incref(attr, nanny=False)
                   code.put_release_ensured_gil()
@@ -1145,8 +1186,13 @@
             # Only for exposing public typedef name.
             code.putln("typedef struct %s %s;" % (type.objstruct_cname, type.objtypedef_cname))
 
-    def generate_c_class_declarations(self, env, code, definition):
+    def generate_c_class_declarations(self, env, code, definition, globalstate):
+        module_state = globalstate['module_state']
+        module_state_defines = globalstate['module_state_defines']
+        module_state_clear = globalstate['module_state_clear']
+        module_state_traverse = globalstate['module_state_traverse']
+        code.putln("#if !CYTHON_COMPILING_IN_LIMITED_API")
         for entry in env.c_class_entries:
             if definition or entry.defined_in_pxd:
                 code.putln("static PyTypeObject *%s = 0;" % (
                     entry.type.typeptr_cname))
@@ -1149,7 +1195,31 @@
         for entry in env.c_class_entries:
             if definition or entry.defined_in_pxd:
                 code.putln("static PyTypeObject *%s = 0;" % (
                     entry.type.typeptr_cname))
+                module_state.putln("PyTypeObject *%s;" % entry.type.typeptr_cname)
+                module_state_defines.putln("#define %s %s->%s" % (
+                    entry.type.typeptr_cname,
+                    Naming.modulestateglobal_cname,
+                    entry.type.typeptr_cname))
+                module_state_clear.putln(
+                    "Py_CLEAR(clear_module_state->%s);" %
+                    entry.type.typeptr_cname)
+                module_state_traverse.putln(
+                    "Py_VISIT(traverse_module_state->%s);" %
+                    entry.type.typeptr_cname)
+                if entry.type.typeobj_cname is not None:
+                    module_state.putln("PyObject *%s;" % entry.type.typeobj_cname)
+                    module_state_defines.putln("#define %s %s->%s" % (
+                        entry.type.typeobj_cname,
+                        Naming.modulestateglobal_cname,
+                        entry.type.typeobj_cname))
+                    module_state_clear.putln(
+                        "Py_CLEAR(clear_module_state->%s);" % (
+                        entry.type.typeobj_cname))
+                    module_state_traverse.putln(
+                        "Py_VISIT(traverse_module_state->%s);" % (
+                        entry.type.typeobj_cname))
+        code.putln("#endif")
 
     def generate_cvariable_declarations(self, env, code, definition):
         if env.is_cython_builtin:
@@ -1255,4 +1325,7 @@
                     self.generate_property_accessors(scope, code)
                     self.generate_method_table(scope, code)
                     self.generate_getset_table(scope, code)
+                    code.putln("#if CYTHON_COMPILING_IN_LIMITED_API")
+                    self.generate_typeobj_spec(entry, code)
+                    code.putln("#else")
                     self.generate_typeobj_definition(full_module_name, entry, code)
@@ -1258,4 +1331,5 @@
                     self.generate_typeobj_definition(full_module_name, entry, code)
+                    code.putln("#endif")
 
     def generate_exttype_vtable(self, scope, code):
         # Generate the definition of an extension type's vtable.
@@ -1273,5 +1347,5 @@
                 type.empty_declaration_code()))
 
     def generate_new_function(self, scope, code, cclass_entry):
-        tp_slot = TypeSlots.ConstructorSlot("tp_new", '__new__')
+        tp_slot = TypeSlots.ConstructorSlot("tp_new", "__cinit__")
         slot_func = scope.mangle_internal("tp_new")
@@ -1277,4 +1351,7 @@
         slot_func = scope.mangle_internal("tp_new")
+        if tp_slot.slot_code(scope) != slot_func:
+            return  # never used
+
         type = scope.parent_type
         base_type = type.base_type
 
@@ -1287,9 +1364,11 @@
         cpp_class_attrs = [entry for entry in scope.var_entries
                            if entry.type.is_cpp_class]
 
-        new_func_entry = scope.lookup_here("__new__")
-        if base_type or (new_func_entry and new_func_entry.is_special
-                         and not new_func_entry.trivial_signature):
+        cinit_func_entry = scope.lookup_here("__cinit__")
+        if cinit_func_entry and not cinit_func_entry.is_special:
+            cinit_func_entry = None
+
+        if base_type or (cinit_func_entry and not cinit_func_entry.trivial_signature):
             unused_marker = ''
         else:
             unused_marker = 'CYTHON_UNUSED '
@@ -1321,7 +1400,12 @@
         if need_self_cast:
             code.putln("%s;" % scope.parent_type.declaration_code("p"))
         if base_type:
+            code.putln("#if CYTHON_COMPILING_IN_LIMITED_API")
+            code.putln("newfunc new_func = (newfunc)PyType_GetSlot(%s, Py_tp_new);" %
+                base_type.typeptr_cname)
+            code.putln("PyObject *o = new_func(t, a, k);")
+            code.putln("#else")
             tp_new = TypeSlots.get_base_slot_function(scope, tp_slot)
             if tp_new is None:
                 tp_new = "%s->tp_new" % base_type.typeptr_cname
             code.putln("PyObject *o = %s(t, a, k);" % tp_new)
@@ -1324,6 +1408,7 @@
             tp_new = TypeSlots.get_base_slot_function(scope, tp_slot)
             if tp_new is None:
                 tp_new = "%s->tp_new" % base_type.typeptr_cname
             code.putln("PyObject *o = %s(t, a, k);" % tp_new)
+            code.putln("#endif")
         else:
             code.putln("PyObject *o;")
@@ -1328,5 +1413,9 @@
         else:
             code.putln("PyObject *o;")
+            code.putln("#if CYTHON_COMPILING_IN_LIMITED_API")
+            code.putln("allocfunc alloc_func = (allocfunc)PyType_GetSlot(t, Py_tp_alloc);")
+            code.putln("o = alloc_func(t, 0);")
+            code.putln("#else")
             if freelist_size:
                 code.globalstate.use_utility_code(
                     UtilityCode.load_cached("IncludeStringH", "StringTools.c"))
@@ -1355,6 +1444,8 @@
         code.putln("if (unlikely(!o)) return 0;")
         if freelist_size and not base_type:
             code.putln('}')
+        if not base_type:
+            code.putln("#endif")
         if need_self_cast:
             code.putln("p = %s;" % type.cast_code("o"))
         #if need_self_cast:
@@ -1397,10 +1488,10 @@
         if cclass_entry.cname == '__pyx_memoryviewslice':
             code.putln("p->from_slice.memview = NULL;")
 
-        if new_func_entry and new_func_entry.is_special:
-            if new_func_entry.trivial_signature:
+        if cinit_func_entry:
+            if cinit_func_entry.trivial_signature:
                 cinit_args = "o, %s, NULL" % Naming.empty_tuple
             else:
                 cinit_args = "o, a, k"
             needs_error_cleanup = True
             code.putln("if (unlikely(%s(%s) < 0)) goto bad;" % (
@@ -1402,9 +1493,9 @@
                 cinit_args = "o, %s, NULL" % Naming.empty_tuple
             else:
                 cinit_args = "o, a, k"
             needs_error_cleanup = True
             code.putln("if (unlikely(%s(%s) < 0)) goto bad;" % (
-                new_func_entry.func_cname, cinit_args))
+                cinit_func_entry.func_cname, cinit_args))
 
         code.putln(
             "return o;")
@@ -1424,8 +1515,13 @@
 
         slot_func_cname = scope.mangle_internal("tp_dealloc")
         code.putln("")
+        cdealloc_func_entry = scope.lookup_here("__dealloc__")
+        if cdealloc_func_entry and not cdealloc_func_entry.is_special:
+            cdealloc_func_entry = None
+        if cdealloc_func_entry is None:
+            code.putln("#if !CYTHON_COMPILING_IN_LIMITED_API")
         code.putln(
             "static void %s(PyObject *o) {" % slot_func_cname)
 
         is_final_type = scope.parent_type.is_final_type
         needs_gc = scope.needs_gc()
@@ -1427,8 +1523,9 @@
         code.putln(
             "static void %s(PyObject *o) {" % slot_func_cname)
 
         is_final_type = scope.parent_type.is_final_type
         needs_gc = scope.needs_gc()
+        needs_trashcan = scope.needs_trashcan()
 
         weakref_slot = scope.lookup_here("__weakref__") if not scope.is_closure_class_scope else None
         if weakref_slot not in scope.var_entries:
@@ -1454,7 +1551,8 @@
                 finalised_check = (
                     '(!PyType_IS_GC(Py_TYPE(o)) || !_PyGC_FINALIZED(o))')
             code.putln(
-                "if (unlikely(PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE)"
+                "if (unlikely("
+                "(PY_VERSION_HEX >= 0x03080000 || PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE))"
                 " && Py_TYPE(o)->tp_finalize) && %s) {" % finalised_check)
             # if instance was resurrected by finaliser, return
             code.putln("if (PyObject_CallFinalizerFromDealloc(o)) return;")
@@ -1467,6 +1565,18 @@
             # running this destructor.
             code.putln("PyObject_GC_UnTrack(o);")
 
+        if needs_trashcan:
+            code.globalstate.use_utility_code(
+                UtilityCode.load_cached("PyTrashcan", "ExtensionTypes.c"))
+            code.putln("__Pyx_TRASHCAN_BEGIN(o, %s)" % slot_func_cname)
+
+        if weakref_slot:
+            # We must clean the weakreferences before calling the user's __dealloc__
+            # because if the __dealloc__ releases the GIL, a weakref can be
+            # dereferenced accessing the object in an inconsistent state or
+            # resurrecting it.
+            code.putln("if (p->__weakref__) PyObject_ClearWeakRefs(o);")
+
         # call the user's __dealloc__
         self.generate_usr_dealloc_call(scope, code)
 
@@ -1470,12 +1580,9 @@
         # call the user's __dealloc__
         self.generate_usr_dealloc_call(scope, code)
 
-        if weakref_slot:
-            code.putln("if (p->__weakref__) PyObject_ClearWeakRefs(o);")
-
         if dict_slot:
             code.putln("if (p->__dict__) PyDict_Clear(p->__dict__);")
 
         for entry in cpp_class_attrs:
             code.putln("__Pyx_call_destructor(p->%s);" % entry.cname)
 
@@ -1476,8 +1583,8 @@
         if dict_slot:
             code.putln("if (p->__dict__) PyDict_Clear(p->__dict__);")
 
         for entry in cpp_class_attrs:
             code.putln("__Pyx_call_destructor(p->%s);" % entry.cname)
 
-        for entry in py_attrs:
+        for entry in (py_attrs + memoryview_slices):
             code.put_xdecref_clear("p->%s" % entry.cname, entry.type, nanny=False,
@@ -1483,9 +1590,5 @@
             code.put_xdecref_clear("p->%s" % entry.cname, entry.type, nanny=False,
-                                   clear_before_decref=True)
-
-        for entry in memoryview_slices:
-            code.put_xdecref_memoryviewslice("p->%s" % entry.cname,
-                                             have_gil=True)
+                                   clear_before_decref=True, have_gil=True)
 
         if base_type:
             if needs_gc:
@@ -1540,5 +1643,9 @@
             code.putln("(*Py_TYPE(o)->tp_free)(o);")
             if freelist_size:
                 code.putln("}")
+
+        if needs_trashcan:
+            code.putln("__Pyx_TRASHCAN_END")
+
         code.putln(
             "}")
@@ -1543,5 +1650,7 @@
         code.putln(
             "}")
+        if cdealloc_func_entry is None:
+            code.putln("#endif")
 
     def generate_usr_dealloc_call(self, scope, code):
         entry = scope.lookup_here("__dealloc__")
@@ -1545,7 +1654,7 @@
 
     def generate_usr_dealloc_call(self, scope, code):
         entry = scope.lookup_here("__dealloc__")
-        if not entry:
+        if not entry or not entry.is_special:
             return
 
         code.putln("{")
@@ -2123,6 +2232,28 @@
         code.putln(
             "}")
 
+    def generate_typeobj_spec(self, entry, code):
+        ext_type = entry.type
+        scope = ext_type.scope
+        code.putln("static PyType_Slot %s_slots[] = {" % ext_type.typeobj_cname)
+        for slot in TypeSlots.slot_table:
+            slot.generate_spec(scope, code)
+        code.putln("{0, 0},")
+        code.putln("};")
+
+        if ext_type.typedef_flag:
+            objstruct = ext_type.objstruct_cname
+        else:
+            objstruct = "struct %s" % ext_type.objstruct_cname
+        classname = scope.class_name.as_c_string_literal()
+        code.putln("static PyType_Spec %s_spec = {" % ext_type.typeobj_cname)
+        code.putln('"%s.%s",' % (self.full_module_name, classname.replace('"', '')))
+        code.putln("sizeof(%s)," % objstruct)
+        code.putln("0,")
+        code.putln("%s," % TypeSlots.get_slot_by_name("tp_flags").slot_code(scope))
+        code.putln("%s_slots," % ext_type.typeobj_cname)
+        code.putln("};")
+
     def generate_typeobj_definition(self, modname, entry, code):
         type = entry.type
         scope = type.scope
@@ -2137,4 +2268,5 @@
         code.putln(header % type.typeobj_cname)
         code.putln(
             "PyVarObject_HEAD_INIT(0, 0)")
+        classname = scope.class_name.as_c_string_literal()
         code.putln(
@@ -2140,6 +2272,7 @@
         code.putln(
-            '"%s.%s", /*tp_name*/' % (
-                self.full_module_name, scope.class_name))
+            '"%s."%s, /*tp_name*/' % (
+                self.full_module_name,
+                classname))
         if type.typedef_flag:
             objstruct = type.objstruct_cname
         else:
@@ -2202,7 +2335,7 @@
                 if doc:
                     if doc.is_unicode:
                         doc = doc.as_utf8_string()
-                    doc_code = doc.as_c_string_literal()
+                    doc_code = "PyDoc_STR(%s)" % doc.as_c_string_literal()
                 else:
                     doc_code = "0"
                 code.putln(
@@ -2206,8 +2339,8 @@
                 else:
                     doc_code = "0"
                 code.putln(
-                    '{(char *)"%s", %s, %s, (char *)%s, 0},' % (
-                        entry.name,
+                    '{(char *)%s, %s, %s, (char *)%s, 0},' % (
+                        entry.name.as_c_string_literal(),
                         entry.getter_cname or "0",
                         entry.setter_cname or "0",
                         doc_code))
@@ -2283,7 +2416,7 @@
         if code.label_used(code.error_label):
             code.put_label(code.error_label)
             # This helps locate the offending name.
-            code.put_add_traceback(self.full_module_name)
+            code.put_add_traceback(EncodedString(self.full_module_name))
         code.error_label = old_error_label
         code.putln("bad:")
         code.putln("return -1;")
@@ -2292,4 +2425,150 @@
         code.putln(UtilityCode.load_as_string("ImportStar", "ImportExport.c")[1])
         code.exit_cfunc_scope()  # done with labels
 
+    def generate_module_state_start(self, env, code):
+        # TODO: Reactor LIMITED_API struct decl closer to the static decl
+        code.putln("#if CYTHON_COMPILING_IN_LIMITED_API")
+        code.putln('typedef struct {')
+        code.putln('PyObject *%s;' % Naming.builtins_cname)
+        code.putln('PyObject *%s;' % Naming.cython_runtime_cname)
+        code.putln('PyObject *%s;' % Naming.empty_tuple)
+        code.putln('PyObject *%s;' % Naming.empty_bytes)
+        code.putln('PyObject *%s;' % Naming.empty_unicode)
+        if Options.pre_import is not None:
+            code.putln('PyObject *%s;' % Naming.preimport_cname)
+        code.putln('#ifdef __Pyx_CyFunction_USED')
+        code.putln('PyTypeObject *%s;' % Naming.cyfunction_type_cname)
+        code.putln('#endif')
+        code.putln('#ifdef __Pyx_FusedFunction_USED')
+        code.putln('PyTypeObject *%s;' % Naming.fusedfunction_type_cname)
+        code.putln('#endif')
+
+    def generate_module_state_end(self, env, modules, globalstate):
+        module_state = globalstate['module_state']
+        module_state_defines = globalstate['module_state_defines']
+        module_state_clear = globalstate['module_state_clear']
+        module_state_traverse = globalstate['module_state_traverse']
+        module_state.putln('} %s;' % Naming.modulestate_cname)
+        module_state.putln('')
+        module_state.putln('#ifdef __cplusplus')
+        module_state.putln('namespace {')
+        module_state.putln('extern struct PyModuleDef %s;' % Naming.pymoduledef_cname)
+        module_state.putln('} /* anonymous namespace */')
+        module_state.putln('#else')
+        module_state.putln('static struct PyModuleDef %s;' % Naming.pymoduledef_cname)
+        module_state.putln('#endif')
+        module_state.putln('')
+        module_state.putln('#define %s(o) ((%s *)__Pyx_PyModule_GetState(o))' % (
+            Naming.modulestate_cname,
+            Naming.modulestate_cname))
+        module_state.putln('')
+        module_state.putln('#define %s (%s(PyState_FindModule(&%s)))' % (
+            Naming.modulestateglobal_cname,
+            Naming.modulestate_cname,
+            Naming.pymoduledef_cname))
+        module_state.putln('')
+        module_state.putln('#define %s (PyState_FindModule(&%s))' % (
+            env.module_cname,
+            Naming.pymoduledef_cname))
+        module_state.putln("#endif")
+        module_state_defines.putln("#endif")
+        module_state_clear.putln("return 0;")
+        module_state_clear.putln("}")
+        module_state_clear.putln("#endif")
+        module_state_traverse.putln("return 0;")
+        module_state_traverse.putln("}")
+        module_state_traverse.putln("#endif")
+
+    def generate_module_state_defines(self, env, code):
+        code.putln("#if CYTHON_COMPILING_IN_LIMITED_API")
+        code.putln('#define %s %s->%s' % (
+            Naming.builtins_cname,
+            Naming.modulestateglobal_cname,
+            Naming.builtins_cname))
+        code.putln('#define %s %s->%s' % (
+            Naming.cython_runtime_cname,
+            Naming.modulestateglobal_cname,
+            Naming.cython_runtime_cname))
+        code.putln('#define %s %s->%s' % (
+            Naming.empty_tuple,
+            Naming.modulestateglobal_cname,
+            Naming.empty_tuple))
+        code.putln('#define %s %s->%s' % (
+            Naming.empty_bytes,
+            Naming.modulestateglobal_cname,
+            Naming.empty_bytes))
+        code.putln('#define %s %s->%s' % (
+            Naming.empty_unicode,
+            Naming.modulestateglobal_cname,
+            Naming.empty_unicode))
+        if Options.pre_import is not None:
+            code.putln('#define %s %s->%s' % (
+                Naming.preimport_cname,
+                Naming.modulestateglobal_cname,
+                Naming.preimport_cname))
+        code.putln('#ifdef __Pyx_CyFunction_USED')
+        code.putln('#define %s %s->%s' % (
+            Naming.cyfunction_type_cname,
+            Naming.modulestateglobal_cname,
+            Naming.cyfunction_type_cname))
+        code.putln('#endif')
+        code.putln('#ifdef __Pyx_FusedFunction_USED')
+        code.putln('#define %s %s->%s' %
+            (Naming.fusedfunction_type_cname,
+            Naming.modulestateglobal_cname,
+            Naming.fusedfunction_type_cname))
+        code.putln('#endif')
+
+    def generate_module_state_clear(self, env, code):
+        code.putln("#if CYTHON_COMPILING_IN_LIMITED_API")
+        code.putln("static int %s_clear(PyObject *m) {" % Naming.module_cname)
+        code.putln("%s *clear_module_state = %s(m);" % (
+            Naming.modulestate_cname,
+            Naming.modulestate_cname))
+        code.putln("if (!clear_module_state) return 0;")
+        code.putln('Py_CLEAR(clear_module_state->%s);' %
+            Naming.builtins_cname)
+        code.putln('Py_CLEAR(clear_module_state->%s);' %
+            Naming.cython_runtime_cname)
+        code.putln('Py_CLEAR(clear_module_state->%s);' %
+            Naming.empty_tuple)
+        code.putln('Py_CLEAR(clear_module_state->%s);' %
+            Naming.empty_bytes)
+        code.putln('Py_CLEAR(clear_module_state->%s);' %
+            Naming.empty_unicode)
+        code.putln('#ifdef __Pyx_CyFunction_USED')
+        code.putln('Py_CLEAR(clear_module_state->%s);' %
+            Naming.cyfunction_type_cname)
+        code.putln('#endif')
+        code.putln('#ifdef __Pyx_FusedFunction_USED')
+        code.putln('Py_CLEAR(clear_module_state->%s);' %
+            Naming.fusedfunction_type_cname)
+        code.putln('#endif')
+
+    def generate_module_state_traverse(self, env, code):
+        code.putln("#if CYTHON_COMPILING_IN_LIMITED_API")
+        code.putln("static int %s_traverse(PyObject *m, visitproc visit, void *arg) {" % Naming.module_cname)
+        code.putln("%s *traverse_module_state = %s(m);" % (
+            Naming.modulestate_cname,
+            Naming.modulestate_cname))
+        code.putln("if (!traverse_module_state) return 0;")
+        code.putln('Py_VISIT(traverse_module_state->%s);' %
+            Naming.builtins_cname)
+        code.putln('Py_VISIT(traverse_module_state->%s);' %
+            Naming.cython_runtime_cname)
+        code.putln('Py_VISIT(traverse_module_state->%s);' %
+            Naming.empty_tuple)
+        code.putln('Py_VISIT(traverse_module_state->%s);' %
+            Naming.empty_bytes)
+        code.putln('Py_VISIT(traverse_module_state->%s);' %
+            Naming.empty_unicode)
+        code.putln('#ifdef __Pyx_CyFunction_USED')
+        code.putln('Py_VISIT(traverse_module_state->%s);' %
+            Naming.cyfunction_type_cname)
+        code.putln('#endif')
+        code.putln('#ifdef __Pyx_FusedFunction_USED')
+        code.putln('Py_VISIT(traverse_module_state->%s);' %
+            Naming.fusedfunction_type_cname)
+        code.putln('#endif')
+
     def generate_module_init_func(self, imported_modules, env, code):
@@ -2295,6 +2574,8 @@
     def generate_module_init_func(self, imported_modules, env, code):
-        subfunction = self.mod_init_subfunction(self.scope, code)
+        subfunction = self.mod_init_subfunction(self.pos, self.scope, code)
+
+        self.generate_pymoduledef_struct(env, code)
 
         code.enter_cfunc_scope(self.scope)
         code.putln("")
         code.putln(UtilityCode.load_as_string("PyModInitFuncType", "ModuleSetupCode.c")[0])
@@ -2297,6 +2578,14 @@
 
         code.enter_cfunc_scope(self.scope)
         code.putln("")
         code.putln(UtilityCode.load_as_string("PyModInitFuncType", "ModuleSetupCode.c")[0])
-        header2 = "__Pyx_PyMODINIT_FUNC init%s(void)" % env.module_name
+        if env.module_name.isascii():
+            py2_mod_name = env.module_name
+            fail_compilation_in_py2 = False
+        else:
+            fail_compilation_in_py2 = True
+            # at this point py2_mod_name is largely a placeholder and the value doesn't matter
+            py2_mod_name = env.module_name.encode("ascii", errors="ignore").decode("utf8")
+
+        header2 = "__Pyx_PyMODINIT_FUNC init%s(void)" % py2_mod_name
         header3 = "__Pyx_PyMODINIT_FUNC %s(void)" % self.mod_init_func_cname('PyInit', env)
@@ -2302,4 +2591,5 @@
         header3 = "__Pyx_PyMODINIT_FUNC %s(void)" % self.mod_init_func_cname('PyInit', env)
+        header3 = EncodedString(header3)
         code.putln("#if PY_MAJOR_VERSION < 3")
         # Optimise for small code size as the module init function is only executed once.
         code.putln("%s CYTHON_SMALL_CODE; /*proto*/" % header2)
@@ -2303,6 +2593,12 @@
         code.putln("#if PY_MAJOR_VERSION < 3")
         # Optimise for small code size as the module init function is only executed once.
         code.putln("%s CYTHON_SMALL_CODE; /*proto*/" % header2)
+        if fail_compilation_in_py2:
+            code.putln('#error "Unicode module names are not supported in Python 2";')
+        if self.scope.is_package:
+            code.putln("#if !defined(CYTHON_NO_PYINIT_EXPORT) && (defined(WIN32) || defined(MS_WINDOWS))")
+            code.putln("__Pyx_PyMODINIT_FUNC init__init__(void) { init%s(); }" % py2_mod_name)
+            code.putln("#endif")
         code.putln(header2)
         code.putln("#else")
         code.putln("%s CYTHON_SMALL_CODE; /*proto*/" % header3)
@@ -2306,6 +2602,11 @@
         code.putln(header2)
         code.putln("#else")
         code.putln("%s CYTHON_SMALL_CODE; /*proto*/" % header3)
+        if self.scope.is_package:
+            code.putln("#if !defined(CYTHON_NO_PYINIT_EXPORT) && (defined(WIN32) || defined(MS_WINDOWS))")
+            code.putln("__Pyx_PyMODINIT_FUNC PyInit___init__(void) { return %s(); }" % (
+                self.mod_init_func_cname('PyInit', env)))
+            code.putln("#endif")
         code.putln(header3)
 
         # CPython 3.5+ supports multi-phase module initialisation (gives access to __spec__, __file__, etc.)
@@ -2334,6 +2635,8 @@
         profile = code.globalstate.directives['profile']
         linetrace = code.globalstate.directives['linetrace']
         if profile or linetrace:
+            if linetrace:
+                code.use_fast_gil_utility_code()
             code.globalstate.use_utility_code(UtilityCode.load_cached("Profile", "Profile.c"))
 
         code.put_declare_refcount_context()
@@ -2348,7 +2651,7 @@
         ))
         code.putln('PyErr_SetString(PyExc_RuntimeError,'
                    ' "Module \'%s\' has already been imported. Re-initialisation is not supported.");' %
-                   env.module_name)
+                   env.module_name.as_c_string_literal()[1:-1])
         code.putln("return -1;")
         code.putln("}")
         code.putln("#elif PY_MAJOR_VERSION >= 3")
@@ -2359,6 +2662,9 @@
         ))
         code.putln("#endif")
 
+        code.putln("/*--- Module creation code ---*/")
+        self.generate_module_creation_code(env, code)
+
         if profile or linetrace:
             tempdecl_code.put_trace_declarations()
             code.put_trace_frame_init()
@@ -2390,7 +2696,6 @@
             code.put_error_if_neg(self.pos, "_import_array()")
 
         code.putln("/*--- Threads initialization code ---*/")
-        code.putln("#if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS")
-        code.putln("#ifdef WITH_THREAD /* Python build with threading support? */")
+        code.putln("#if defined(WITH_THREAD) && defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS")
         code.putln("PyEval_InitThreads();")
         code.putln("#endif")
@@ -2395,9 +2700,5 @@
         code.putln("PyEval_InitThreads();")
         code.putln("#endif")
-        code.putln("#endif")
-
-        code.putln("/*--- Module creation code ---*/")
-        self.generate_module_creation_code(env, code)
 
         code.putln("/*--- Initialize various global constants etc. ---*/")
         code.put_error_if_neg(self.pos, "__Pyx_InitGlobals()")
@@ -2407,7 +2708,7 @@
         code.put_error_if_neg(self.pos, "__Pyx_init_sys_getdefaultencoding_params()")
         code.putln("#endif")
 
-        code.putln("if (%s%s) {" % (Naming.module_is_main, self.full_module_name.replace('.', '__')))
+        code.putln("if (%s) {" % self.is_main_module_flag_cname())
         code.put_error_if_neg(self.pos, 'PyObject_SetAttr(%s, %s, %s)' % (
             env.module_cname,
             code.intern_identifier(EncodedString("__name__")),
@@ -2419,6 +2720,6 @@
 
         if Options.cache_builtins:
             code.putln("/*--- Builtin init code ---*/")
-            code.put_error_if_neg(None, "__Pyx_InitCachedBuiltins()")
+            code.put_error_if_neg(self.pos, "__Pyx_InitCachedBuiltins()")
 
         code.putln("/*--- Constants init code ---*/")
@@ -2423,6 +2724,6 @@
 
         code.putln("/*--- Constants init code ---*/")
-        code.put_error_if_neg(None, "__Pyx_InitCachedConstants()")
+        code.put_error_if_neg(self.pos, "__Pyx_InitCachedConstants()")
 
         code.putln("/*--- Global type/function init code ---*/")
 
@@ -2483,4 +2784,5 @@
         for cname, type in code.funcstate.all_managed_temps():
             code.put_xdecref(cname, type)
         code.putln('if (%s) {' % env.module_cname)
+        code.putln("#if !CYTHON_COMPILING_IN_LIMITED_API")
         code.putln('if (%s) {' % env.module_dict_cname)
@@ -2486,8 +2788,9 @@
         code.putln('if (%s) {' % env.module_dict_cname)
-        code.put_add_traceback("init %s" % env.qualified_name)
+        code.putln("#endif")
+        code.put_add_traceback(EncodedString("init %s" % env.qualified_name))
         code.globalstate.use_utility_code(Nodes.traceback_utility_code)
         # Module reference and module dict are in global variables which might still be needed
         # for cleanup, atexit code, etc., so leaking is better than crashing.
         # At least clearing the module dict here might be a good idea, but could still break
         # user code in atexit or other global registries.
         ##code.put_decref_clear(env.module_dict_cname, py_object_type, nanny=False)
@@ -2488,8 +2791,9 @@
         code.globalstate.use_utility_code(Nodes.traceback_utility_code)
         # Module reference and module dict are in global variables which might still be needed
         # for cleanup, atexit code, etc., so leaking is better than crashing.
         # At least clearing the module dict here might be a good idea, but could still break
         # user code in atexit or other global registries.
         ##code.put_decref_clear(env.module_dict_cname, py_object_type, nanny=False)
+        code.putln("#if !CYTHON_COMPILING_IN_LIMITED_API")
         code.putln('}')
         code.put_decref_clear(env.module_cname, py_object_type, nanny=False, clear_before_decref=True)
@@ -2494,3 +2798,4 @@
         code.putln('}')
         code.put_decref_clear(env.module_cname, py_object_type, nanny=False, clear_before_decref=True)
+        code.putln("#endif")
         code.putln('} else if (!PyErr_Occurred()) {')
@@ -2496,5 +2801,6 @@
         code.putln('} else if (!PyErr_Occurred()) {')
-        code.putln('PyErr_SetString(PyExc_ImportError, "init %s");' % env.qualified_name)
+        code.putln('PyErr_SetString(PyExc_ImportError, "init %s");' %
+                   env.qualified_name.as_c_string_literal()[1:-1])
         code.putln('}')
         code.put_label(code.return_label)
 
@@ -2513,7 +2819,7 @@
 
         code.exit_cfunc_scope()
 
-    def mod_init_subfunction(self, scope, orig_code):
+    def mod_init_subfunction(self, pos, scope, orig_code):
         """
         Return a context manager that allows deviating the module init code generation
         into a separate function and instead inserts a call to it.
@@ -2544,7 +2850,7 @@
                 code.putln("static int %s(void) {" % self.cfunc_name)
                 code.put_declare_refcount_context()
                 self.tempdecl_code = code.insertion_point()
-                code.put_setup_refcount_context(self.cfunc_name)
+                code.put_setup_refcount_context(EncodedString(self.cfunc_name))
                 # Leave a grepable marker that makes it easy to find the generator source.
                 code.putln("/*--- %s ---*/" % self.description)
                 return code
@@ -2569,9 +2875,8 @@
                 code.putln("")
 
                 if needs_error_handling:
-                    self.call_code.use_label(orig_code.error_label)
-                    self.call_code.putln("if (unlikely(%s() != 0)) goto %s;" % (
-                        self.cfunc_name, orig_code.error_label))
+                    self.call_code.putln(
+                        self.call_code.error_goto_if_neg("%s()" % self.cfunc_name, pos))
                 else:
                     self.call_code.putln("(void)%s();" % self.cfunc_name)
                 self.call_code = None
@@ -2602,7 +2907,7 @@
                         EncodedString(decode_filename(
                             os.path.dirname(module_path)))).cname,
                     code.error_goto_if_null(temp, self.pos)))
-                code.put_gotref(temp)
+                code.put_gotref(temp, py_object_type)
                 code.putln(
                     'if (PyObject_SetAttrString(%s, "__path__", %s) < 0) %s;' % (
                         env.module_cname, temp, code.error_goto(self.pos)))
@@ -2632,8 +2937,9 @@
         # CPython may not have put us into sys.modules yet, but relative imports and reimports require it
         fq_module_name = self.full_module_name
         if fq_module_name.endswith('.__init__'):
-            fq_module_name = fq_module_name[:-len('.__init__')]
+            fq_module_name = EncodedString(fq_module_name[:-len('.__init__')])
+        fq_module_name_cstring = fq_module_name.as_c_string_literal()
         code.putln("#if PY_MAJOR_VERSION >= 3")
         code.putln("{")
         code.putln("PyObject *modules = PyImport_GetModuleDict(); %s" %
                    code.error_goto_if_null("modules", self.pos))
@@ -2636,10 +2942,10 @@
         code.putln("#if PY_MAJOR_VERSION >= 3")
         code.putln("{")
         code.putln("PyObject *modules = PyImport_GetModuleDict(); %s" %
                    code.error_goto_if_null("modules", self.pos))
-        code.putln('if (!PyDict_GetItemString(modules, "%s")) {' % fq_module_name)
-        code.putln(code.error_goto_if_neg('PyDict_SetItemString(modules, "%s", %s)' % (
-            fq_module_name, env.module_cname), self.pos))
+        code.putln('if (!PyDict_GetItemString(modules, %s)) {' % fq_module_name_cstring)
+        code.putln(code.error_goto_if_neg('PyDict_SetItemString(modules, %s, %s)' % (
+            fq_module_name_cstring, env.module_cname), self.pos))
         code.putln("}")
         code.putln("}")
         code.putln("#endif")
@@ -2710,5 +3016,5 @@
         if Options.pre_import is not None:
             code.put_decref_clear(Naming.preimport_cname, py_object_type,
                                   nanny=False, clear_before_decref=True)
-        for cname in [env.module_dict_cname, Naming.cython_runtime_cname, Naming.builtins_cname]:
+        for cname in [Naming.cython_runtime_cname, Naming.builtins_cname]:
             code.put_decref_clear(cname, py_object_type, nanny=False, clear_before_decref=True)
@@ -2714,3 +3020,6 @@
             code.put_decref_clear(cname, py_object_type, nanny=False, clear_before_decref=True)
+        code.putln("#if !CYTHON_COMPILING_IN_LIMITED_API")
+        code.put_decref_clear(env.module_dict_cname, py_object_type, nanny=False, clear_before_decref=True)
+        code.putln("#endif")
 
     def generate_main_method(self, env, code):
@@ -2715,6 +3024,6 @@
 
     def generate_main_method(self, env, code):
-        module_is_main = "%s%s" % (Naming.module_is_main, self.full_module_name.replace('.', '__'))
+        module_is_main = self.is_main_module_flag_cname()
         if Options.embed == "main":
             wmain = "wmain"
         else:
@@ -2727,4 +3036,12 @@
                 main_method=Options.embed,
                 wmain_method=wmain))
 
+    def punycode_module_name(self, prefix, name):
+        # adapted from PEP483
+        try:
+            name = '_' + name.encode('ascii').decode('ascii')
+        except UnicodeEncodeError:
+            name = 'U_' + name.encode('punycode').replace(b'-', b'_').decode('ascii')
+        return "%s%s" % (prefix, name)
+
     def mod_init_func_cname(self, prefix, env):
@@ -2730,5 +3047,6 @@
     def mod_init_func_cname(self, prefix, env):
-        return '%s_%s' % (prefix, env.module_name)
+        # from PEP483
+        return self.punycode_module_name(prefix, env.module_name)
 
     def generate_pymoduledef_struct(self, env, code):
         if env.doc:
@@ -2753,6 +3071,10 @@
         code.putln("{Py_mod_exec, (void*)%s}," % exec_func_cname)
         code.putln("{0, NULL}")
         code.putln("};")
+        if not env.module_name.isascii():
+            code.putln("#else /* CYTHON_PEP489_MULTI_PHASE_INIT */")
+            code.putln('#error "Unicode module names are only supported with multi-phase init'
+                       ' as per PEP489"')
         code.putln("#endif")
 
         code.putln("")
@@ -2756,5 +3078,11 @@
         code.putln("#endif")
 
         code.putln("")
-        code.putln("static struct PyModuleDef %s = {" % Naming.pymoduledef_cname)
+        code.putln('#ifdef __cplusplus')
+        code.putln('namespace {')
+        code.putln("struct PyModuleDef %s =" % Naming.pymoduledef_cname)
+        code.putln('#else')
+        code.putln("static struct PyModuleDef %s =" % Naming.pymoduledef_cname)
+        code.putln('#endif')
+        code.putln('{')
         code.putln("  PyModuleDef_HEAD_INIT,")
@@ -2760,5 +3088,5 @@
         code.putln("  PyModuleDef_HEAD_INIT,")
-        code.putln('  "%s",' % env.module_name)
+        code.putln('  %s,' % env.module_name.as_c_string_literal())
         code.putln("  %s, /* m_doc */" % doc)
         code.putln("#if CYTHON_PEP489_MULTI_PHASE_INIT")
         code.putln("  0, /* m_size */")
@@ -2762,6 +3090,8 @@
         code.putln("  %s, /* m_doc */" % doc)
         code.putln("#if CYTHON_PEP489_MULTI_PHASE_INIT")
         code.putln("  0, /* m_size */")
+        code.putln("#elif CYTHON_COMPILING_IN_LIMITED_API")
+        code.putln("  sizeof(%s), /* m_size */" % Naming.modulestate_cname)
         code.putln("#else")
         code.putln("  -1, /* m_size */")
         code.putln("#endif")
@@ -2771,6 +3101,11 @@
         code.putln("#else")
         code.putln("  NULL, /* m_reload */")
         code.putln("#endif")
+        code.putln("#if CYTHON_COMPILING_IN_LIMITED_API")
+        code.putln("  %s_traverse, /* m_traverse */" % Naming.module_cname)
+        code.putln("  %s_clear, /* m_clear */" % Naming.module_cname)
+        code.putln("  %s /* m_free */" % cleanup_func)
+        code.putln("#else")
         code.putln("  NULL, /* m_traverse */")
         code.putln("  NULL, /* m_clear */")
         code.putln("  %s /* m_free */" % cleanup_func)
@@ -2774,4 +3109,5 @@
         code.putln("  NULL, /* m_traverse */")
         code.putln("  NULL, /* m_clear */")
         code.putln("  %s /* m_free */" % cleanup_func)
+        code.putln("#endif")
         code.putln("};")
@@ -2777,4 +3113,7 @@
         code.putln("};")
+        code.putln('#ifdef __cplusplus')
+        code.putln('} /* anonymous namespace */')
+        code.putln('#endif')
         code.putln("#endif")
 
     def generate_module_creation_code(self, env, code):
@@ -2793,5 +3132,5 @@
         code.putln("#else")
         code.putln("#if PY_MAJOR_VERSION < 3")
         code.putln(
-            '%s = Py_InitModule4("%s", %s, %s, 0, PYTHON_API_VERSION); Py_XINCREF(%s);' % (
+            '%s = Py_InitModule4(%s, %s, %s, 0, PYTHON_API_VERSION); Py_XINCREF(%s);' % (
                 env.module_cname,
@@ -2797,5 +3136,5 @@
                 env.module_cname,
-                env.module_name,
+                env.module_name.as_c_string_literal(),
                 env.method_table_cname,
                 doc,
                 env.module_cname))
@@ -2799,8 +3138,21 @@
                 env.method_table_cname,
                 doc,
                 env.module_cname))
-        code.putln("#else")
+        code.putln(code.error_goto_if_null(env.module_cname, self.pos))
+        code.putln("#elif CYTHON_COMPILING_IN_LIMITED_API")
+        module_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
+        code.putln(
+            "%s = PyModule_Create(&%s); %s" % (
+                module_temp,
+                Naming.pymoduledef_cname,
+                code.error_goto_if_null(module_temp, self.pos)))
+        code.put_gotref(module_temp, py_object_type)
+        code.putln(code.error_goto_if_neg("PyState_AddModule(%s, &%s)" % (
+            module_temp, Naming.pymoduledef_cname), self.pos))
+        code.put_decref_clear(module_temp, type=py_object_type)
+        code.funcstate.release_temp(module_temp)
+        code.putln('#else')
         code.putln(
             "%s = PyModule_Create(&%s);" % (
                 env.module_cname,
                 Naming.pymoduledef_cname))
@@ -2803,5 +3155,6 @@
         code.putln(
             "%s = PyModule_Create(&%s);" % (
                 env.module_cname,
                 Naming.pymoduledef_cname))
+        code.putln(code.error_goto_if_null(env.module_cname, self.pos))
         code.putln("#endif")
@@ -2807,4 +3160,3 @@
         code.putln("#endif")
-        code.putln(code.error_goto_if_null(env.module_cname, self.pos))
         code.putln("#endif")  # CYTHON_PEP489_MULTI_PHASE_INIT
 
@@ -2809,7 +3161,8 @@
         code.putln("#endif")  # CYTHON_PEP489_MULTI_PHASE_INIT
 
+        code.putln("#if !CYTHON_COMPILING_IN_LIMITED_API")
         code.putln(
             "%s = PyModule_GetDict(%s); %s" % (
                 env.module_dict_cname, env.module_cname,
                 code.error_goto_if_null(env.module_dict_cname, self.pos)))
         code.put_incref(env.module_dict_cname, py_object_type, nanny=False)
@@ -2811,8 +3164,9 @@
         code.putln(
             "%s = PyModule_GetDict(%s); %s" % (
                 env.module_dict_cname, env.module_cname,
                 code.error_goto_if_null(env.module_dict_cname, self.pos)))
         code.put_incref(env.module_dict_cname, py_object_type, nanny=False)
+        code.putln("#endif")
 
         code.putln(
             '%s = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); %s' % (
@@ -2896,8 +3250,8 @@
             # investigation shows that the resulting binary is smaller with repeated functions calls.
             for entry in entries:
                 signature = entry.type.signature_string()
-                code.putln('if (__Pyx_ExportFunction("%s", (void (*)(void))%s, "%s") < 0) %s' % (
-                    entry.name,
+                code.putln('if (__Pyx_ExportFunction(%s, (void (*)(void))%s, "%s") < 0) %s' % (
+                    entry.name.as_c_string_literal(),
                     entry.cname,
                     signature,
                     code.error_goto(self.pos)))
@@ -2969,5 +3323,5 @@
                     code.error_goto(self.pos)))
             for entry in entries:
                 code.putln(
-                    'if (__Pyx_ImportFunction(%s, "%s", (void (**)(void))&%s, "%s") < 0) %s' % (
+                    'if (__Pyx_ImportFunction(%s, %s, (void (**)(void))&%s, "%s") < 0) %s' % (
                         temp,
@@ -2973,5 +3327,5 @@
                         temp,
-                        entry.name,
+                        entry.name.as_c_string_literal(),
                         entry.cname,
                         entry.type.signature_string(),
                         code.error_goto(self.pos)))
@@ -2993,7 +3347,8 @@
     def generate_base_type_import_code(self, env, entry, code, import_generator):
         base_type = entry.type.base_type
         if (base_type and base_type.module_name != env.qualified_name and not
-                base_type.is_builtin_type and not entry.utility_code_definition):
+                (base_type.is_builtin_type or base_type.is_cython_builtin_type)
+                 and not entry.utility_code_definition):
             self.generate_type_import_code(env, base_type, self.pos, code, import_generator)
 
     def generate_type_import_code(self, env, type, pos, code, import_generator):
@@ -3010,7 +3365,7 @@
         if type.vtabptr_cname:
             code.globalstate.use_utility_code(
                 UtilityCode.load_cached('GetVTable', 'ImportExport.c'))
-            code.putln("%s = (struct %s*)__Pyx_GetVtable(%s->tp_dict); %s" % (
+            code.putln("%s = (struct %s*)__Pyx_GetVtable(%s); %s" % (
                 type.vtabptr_cname,
                 type.vtabstruct_cname,
                 type.typeptr_cname,
@@ -3050,8 +3405,10 @@
             module,
             module_name))
 
+        type_name = type.name.as_c_string_literal()
+
         if condition and replacement:
             code.putln("")  # start in new line
             code.putln("#if %s" % condition)
             code.putln('"%s",' % replacement)
             code.putln("#else")
@@ -3053,8 +3410,8 @@
         if condition and replacement:
             code.putln("")  # start in new line
             code.putln("#if %s" % condition)
             code.putln('"%s",' % replacement)
             code.putln("#else")
-            code.putln('"%s",' % type.name)
+            code.putln('%s,' % type_name)
             code.putln("#endif")
         else:
@@ -3059,9 +3416,9 @@
             code.putln("#endif")
         else:
-            code.put(' "%s", ' % type.name)
+            code.put(' %s, ' % type_name)
 
         if sizeof_objstruct != objstruct:
             if not condition:
                 code.putln("")  # start in new line
             code.putln("#if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x050B0000")
             code.putln('sizeof(%s),' % objstruct)
@@ -3062,9 +3419,11 @@
 
         if sizeof_objstruct != objstruct:
             if not condition:
                 code.putln("")  # start in new line
             code.putln("#if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x050B0000")
             code.putln('sizeof(%s),' % objstruct)
+            code.putln("#elif CYTHON_COMPILING_IN_LIMITED_API")
+            code.putln('sizeof(%s),' % objstruct)
             code.putln("#else")
             code.putln('sizeof(%s),' % sizeof_objstruct)
             code.putln("#endif")
@@ -3086,6 +3445,10 @@
     def generate_type_ready_code(self, entry, code):
         Nodes.CClassDefNode.generate_type_ready_code(entry, code)
 
+    def is_main_module_flag_cname(self):
+        full_module_name = self.full_module_name.replace('.', '__')
+        return self.punycode_module_name(Naming.module_is_main, full_module_name)
+
     def generate_exttype_vtable_init_code(self, entry, code):
         # Generate code to initialise the C method table of an
         # extension type.
@@ -3138,7 +3501,7 @@
         self.temps.append(temp)
         code.putln('%s = PyImport_ImportModule(%s); if (unlikely(!%s)) %s' % (
             temp, module_name_string, temp, error_code))
-        code.put_gotref(temp)
+        code.put_gotref(temp, py_object_type)
         self.imported[module_name_string] = temp
         return temp
 
@@ -3199,4 +3562,4 @@
 #endif
 """, impl="", proto_block='utility_code_proto_before_types')
 
-capsule_utility_code = UtilityCode.load("Capsule")
+capsule_utility_code = UtilityCode.load("Capsule", "Capsule.c")
diff --git a/Cython/Compiler/Naming.py b/Cython/Compiler/Naming.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL05hbWluZy5weQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL05hbWluZy5weQ== 100644
--- a/Cython/Compiler/Naming.py
+++ b/Cython/Compiler/Naming.py
@@ -13,6 +13,8 @@
 
 temp_prefix       = u"__cyt_"
 
+pyunicode_identifier_prefix = pyrex_prefix + 'U'
+
 builtin_prefix    = pyrex_prefix + "builtin_"
 arg_prefix        = pyrex_prefix + "arg_"
 funcdoc_prefix    = pyrex_prefix + "doc_"
@@ -45,8 +47,15 @@
 vtable_prefix     = pyrex_prefix + "vtable_"
 vtabptr_prefix    = pyrex_prefix + "vtabptr_"
 vtabstruct_prefix = pyrex_prefix + "vtabstruct_"
+unicode_vtabentry_prefix  = pyrex_prefix + "Uvtabentry_"
+ # vtab entries aren't  normally manged,
+ # but punycode names sometimes start with numbers leading
+ # to a C syntax error
+unicode_structmember_prefix = pyrex_prefix + "Umember_"
+ # as above -
+ # not normally manged but punycode names cause specific problems
 opt_arg_prefix    = pyrex_prefix + "opt_args_"
 convert_func_prefix = pyrex_prefix + "convert_"
 closure_scope_prefix = pyrex_prefix + "scope_"
 closure_class_prefix = pyrex_prefix + "scope_struct_"
 lambda_func_prefix = pyrex_prefix + "lambda_"
@@ -48,9 +57,9 @@
 opt_arg_prefix    = pyrex_prefix + "opt_args_"
 convert_func_prefix = pyrex_prefix + "convert_"
 closure_scope_prefix = pyrex_prefix + "scope_"
 closure_class_prefix = pyrex_prefix + "scope_struct_"
 lambda_func_prefix = pyrex_prefix + "lambda_"
-module_is_main   = pyrex_prefix + "module_is_main_"
+module_is_main   = pyrex_prefix + "module_is_main"
 defaults_struct_prefix = pyrex_prefix + "defaults"
 dynamic_args_cname = pyrex_prefix + "dynamic_args"
 
@@ -67,6 +76,8 @@
 
 ctuple_type_prefix = pyrex_prefix + "ctuple_"
 args_cname       = pyrex_prefix + "args"
+nargs_cname      = pyrex_prefix + "nargs"
+kwvalues_cname   = pyrex_prefix + "kwvalues"
 generator_cname  = pyrex_prefix + "generator"
 sent_value_cname = pyrex_prefix + "sent_value"
 pykwdlist_cname  = pyrex_prefix + "pyargnames"
@@ -85,6 +96,8 @@
 cfilenm_cname    = pyrex_prefix + "cfilenm"
 local_tstate_cname = pyrex_prefix + "tstate"
 module_cname     = pyrex_prefix + "m"
+modulestate_cname = pyrex_prefix + "mstate"
+modulestateglobal_cname = pyrex_prefix + "mstate_global"
 moddoc_cname     = pyrex_prefix + "mdoc"
 methtable_cname  = pyrex_prefix + "methods"
 retval_cname     = pyrex_prefix + "r"
@@ -121,6 +134,8 @@
 obj_dict_version_temp = pyrex_prefix + "obj_dict_version"
 type_dict_guard_temp = pyrex_prefix + "type_dict_guard"
 cython_runtime_cname   = pyrex_prefix + "cython_runtime"
+cyfunction_type_cname = pyrex_prefix + "CyFunctionType"
+fusedfunction_type_cname = pyrex_prefix + "FusedFunctionType"
 
 global_code_object_cache_find = pyrex_prefix + 'find_code_object'
 global_code_object_cache_insert = pyrex_prefix + 'insert_code_object'
@@ -152,8 +167,11 @@
 
 api_name        = pyrex_prefix + "capi__"
 
-h_guard_prefix   = "__PYX_HAVE__"
-api_guard_prefix = "__PYX_HAVE_API__"
+# the h and api guards get changed to:
+#  __PYX_HAVE__FILENAME (for ascii filenames)
+#  __PYX_HAVE_U_PUNYCODEFILENAME (for non-ascii filenames)
+h_guard_prefix   = "__PYX_HAVE_"
+api_guard_prefix = "__PYX_HAVE_API_"
 api_func_guard   = "__PYX_HAVE_API_FUNC_"
 
 PYX_NAN          = "__PYX_NAN()"
diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL05vZGVzLnB5..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL05vZGVzLnB5 100644
--- a/Cython/Compiler/Nodes.py
+++ b/Cython/Compiler/Nodes.py
@@ -22,7 +22,8 @@
 from . import TypeSlots
 from .PyrexTypes import py_object_type, error_type
 from .Symtab import (ModuleScope, LocalScope, ClosureScope,
-                     StructOrUnionScope, PyClassScope, CppClassScope, TemplateScope)
+                     StructOrUnionScope, PyClassScope, CppClassScope, TemplateScope,
+                     punycodify_name)
 from .Code import UtilityCode
 from .StringEncoding import EncodedString
 from . import Future
@@ -38,6 +39,9 @@
     _py_int_types = (int, long)
 
 
+IMPLICIT_CLASSMETHODS = {"__init_subclass__", "__class_getitem__"}
+
+
 def relative_position(pos):
     return (pos[0].get_filenametable_entry(), pos[1])
 
@@ -67,54 +71,6 @@
     doc.encoding = encoding
     return doc
 
-
-def analyse_type_annotation(annotation, env, assigned_value=None):
-    base_type = None
-    is_ambiguous = False
-    explicit_pytype = explicit_ctype = False
-    if annotation.is_dict_literal:
-        warning(annotation.pos,
-                "Dicts should no longer be used as type annotations. Use 'cython.int' etc. directly.")
-        for name, value in annotation.key_value_pairs:
-            if not name.is_string_literal:
-                continue
-            if name.value in ('type', b'type'):
-                explicit_pytype = True
-                if not explicit_ctype:
-                    annotation = value
-            elif name.value in ('ctype', b'ctype'):
-                explicit_ctype = True
-                annotation = value
-        if explicit_pytype and explicit_ctype:
-            warning(annotation.pos, "Duplicate type declarations found in signature annotation")
-    arg_type = annotation.analyse_as_type(env)
-    if annotation.is_name and not annotation.cython_attribute and annotation.name in ('int', 'long', 'float'):
-        # Map builtin numeric Python types to C types in safe cases.
-        if assigned_value is not None and arg_type is not None and not arg_type.is_pyobject:
-            assigned_type = assigned_value.infer_type(env)
-            if assigned_type and assigned_type.is_pyobject:
-                # C type seems unsafe, e.g. due to 'None' default value  => ignore annotation type
-                is_ambiguous = True
-                arg_type = None
-        # ignore 'int' and require 'cython.int' to avoid unsafe integer declarations
-        if arg_type in (PyrexTypes.c_long_type, PyrexTypes.c_int_type, PyrexTypes.c_float_type):
-            arg_type = PyrexTypes.c_double_type if annotation.name == 'float' else py_object_type
-    elif arg_type is not None and annotation.is_string_literal:
-        warning(annotation.pos,
-                "Strings should no longer be used for type declarations. Use 'cython.int' etc. directly.")
-    if arg_type is not None:
-        if explicit_pytype and not explicit_ctype and not arg_type.is_pyobject:
-            warning(annotation.pos,
-                    "Python type declaration in signature annotation does not refer to a Python type")
-        base_type = CAnalysedBaseTypeNode(
-            annotation.pos, type=arg_type, is_arg=True)
-    elif is_ambiguous:
-        warning(annotation.pos, "Ambiguous types in annotation, ignoring")
-    else:
-        warning(annotation.pos, "Unknown type declaration in annotation, ignoring")
-    return base_type, arg_type
-
-
 def write_func_call(func, codewriter_class):
     def f(*args, **kwds):
         if len(args) > 1 and isinstance(args[1], codewriter_class):
@@ -734,5 +690,4 @@
                         self.exception_value = ConstNode(
                             self.pos, value=return_type.exception_value, type=return_type)
             if self.exception_value:
-                self.exception_value = self.exception_value.analyse_const_expression(env)
                 if self.exception_check == '+':
@@ -738,4 +693,5 @@
                 if self.exception_check == '+':
+                    self.exception_value = self.exception_value.analyse_const_expression(env)
                     exc_val_type = self.exception_value.type
                     if (not exc_val_type.is_error
                             and not exc_val_type.is_pyobject
@@ -748,7 +704,7 @@
                               "Exception value must be a Python exception or cdef function with no arguments or *.")
                     exc_val = self.exception_value
                 else:
-                    self.exception_value = self.exception_value.coerce_to(
+                    self.exception_value = self.exception_value.analyse_types(env).coerce_to(
                         return_type, env).analyse_const_expression(env)
                     exc_val = self.exception_value.get_constant_c_result_code()
                     if exc_val is None:
@@ -752,9 +708,7 @@
                         return_type, env).analyse_const_expression(env)
                     exc_val = self.exception_value.get_constant_c_result_code()
                     if exc_val is None:
-                        raise InternalError(
-                            "get_constant_c_result_code not implemented for %s" %
-                            self.exception_value.__class__.__name__)
+                        error(self.exception_value.pos, "Exception value must be constant")
                     if not return_type.assignable_from(self.exception_value.type):
                         error(self.exception_value.pos,
                               "Exception value incompatible with function return type")
@@ -758,6 +712,17 @@
                     if not return_type.assignable_from(self.exception_value.type):
                         error(self.exception_value.pos,
                               "Exception value incompatible with function return type")
+                    if (visibility != 'extern'
+                            and (return_type.is_int or return_type.is_float)
+                            and self.exception_value.has_constant_result()):
+                        try:
+                            type_default_value = float(return_type.default_value)
+                        except ValueError:
+                            pass
+                        else:
+                            if self.exception_value.constant_result == type_default_value:
+                                warning(self.pos, "Ambiguous exception value, same as default return value: %r" %
+                                        self.exception_value.constant_result)
             exc_check = self.exception_check
         if return_type.is_cfunction:
             error(self.pos, "Function cannot return a function")
@@ -850,5 +815,5 @@
     # annotation     ExprNode or None   Py3 function arg annotation
     # is_self_arg    boolean            Is the "self" arg of an extension type method
     # is_type_arg    boolean            Is the "class" arg of an extension type classmethod
-    # is_kw_only     boolean            Is a keyword-only argument
+    # kw_only        boolean            Is a keyword-only argument
     # is_dynamic     boolean            Non-literal arg stored inside CyFunction
@@ -854,4 +819,8 @@
     # is_dynamic     boolean            Non-literal arg stored inside CyFunction
+    # pos_only       boolean            Is a positional-only argument
+    #
+    # name_cstring                         property that converts the name to a cstring taking care of unicode
+    #                                      and quoting it
 
     child_attrs = ["base_type", "declarator", "default", "annotation"]
     outer_attrs = ["default", "annotation"]
@@ -860,6 +829,7 @@
     is_type_arg = 0
     is_generic = 1
     kw_only = 0
+    pos_only = 0
     not_none = 0
     or_none = 0
     type = None
@@ -868,6 +838,20 @@
     annotation = None
     is_dynamic = 0
 
+    @property
+    def name_cstring(self):
+        return self.name.as_c_string_literal()
+
+    @property
+    def hdr_cname(self):
+        # done lazily - needs self.entry to be set to get the class-mangled
+        # name, which means it has to be generated relatively late
+        if self.needs_conversion:
+            return punycodify_name(Naming.arg_prefix + self.entry.name)
+        else:
+            return punycodify_name(Naming.var_prefix + self.entry.name)
+
+
     def analyse(self, env, nonempty=0, is_self_arg=False):
         if is_self_arg:
             self.base_type.is_self_arg = self.is_self_arg = True
@@ -906,7 +890,10 @@
 
             # inject type declaration from annotations
             # this is called without 'env' by AdjustDefByDirectives transform before declaration analysis
-            if self.annotation and env and env.directives['annotation_typing'] and self.base_type.name is None:
+            if (self.annotation and env and env.directives['annotation_typing']
+                    # CSimpleBaseTypeNode has a name attribute; CAnalysedBaseTypeNode
+                    # (and maybe other options) doesn't
+                    and getattr(self.base_type, "name", None) is None):
                 arg_type = self.inject_type_from_annotations(env)
                 if arg_type is not None:
                     base_type = arg_type
@@ -918,7 +905,7 @@
         annotation = self.annotation
         if not annotation:
             return None
-        base_type, arg_type = analyse_type_annotation(annotation, env, assigned_value=self.default)
+        base_type, arg_type = annotation.analyse_type_annotation(env, assigned_value=self.default)
         if base_type is not None:
             self.base_type = base_type
         return arg_type
@@ -947,8 +934,7 @@
         default.make_owned_reference(code)
         result = default.result() if overloaded_assignment else default.result_as(self.type)
         code.putln("%s = %s;" % (target, result))
-        if self.type.is_pyobject:
-            code.put_giveref(default.result())
+        code.put_giveref(default.result(), self.type)
         default.generate_post_assignment_code(code)
         default.free_temps(code)
 
@@ -1273,5 +1259,5 @@
         return PyrexTypes.FusedType(types, name=self.name)
 
 
-class CConstTypeNode(CBaseTypeNode):
+class CConstOrVolatileTypeNode(CBaseTypeNode):
     # base_type     CBaseTypeNode
@@ -1277,4 +1263,6 @@
     # base_type     CBaseTypeNode
+    # is_const      boolean
+    # is_volatile   boolean
 
     child_attrs = ["base_type"]
 
@@ -1282,8 +1270,8 @@
         base = self.base_type.analyse(env, could_be_name)
         if base.is_pyobject:
             error(self.pos,
-                  "Const base type cannot be a Python object")
-        return PyrexTypes.c_const_type(base)
+                  "Const/volatile base type cannot be a Python object")
+        return PyrexTypes.c_const_or_volatile_type(base, self.is_const, self.is_volatile)
 
 
 class CVarDefNode(StatNode):
@@ -1564,7 +1552,7 @@
                     temp,
                     item.cname,
                     code.error_goto_if_null(temp, item.pos)))
-                code.put_gotref(temp)
+                code.put_gotref(temp, PyrexTypes.py_object_type)
                 code.putln('if (PyDict_SetItemString(%s, "%s", %s) < 0) %s' % (
                     Naming.moddict_cname,
                     item.name,
@@ -1664,6 +1652,7 @@
     starstar_arg = None
     is_cyfunction = False
     code_object = None
+    return_type_annotation = None
 
     def analyse_default_values(self, env):
         default_seen = 0
@@ -1681,14 +1670,6 @@
             elif default_seen:
                 error(arg.pos, "Non-default argument following default argument")
 
-    def analyse_annotation(self, env, annotation):
-        # Annotations can not only contain valid Python expressions but arbitrary type references.
-        if annotation is None:
-            return None
-        if not env.directives['annotation_typing'] or annotation.analyse_as_type(env) is None:
-            annotation = annotation.analyse_types(env)
-        return annotation
-
     def analyse_annotations(self, env):
         for arg in self.args:
             if arg.annotation:
@@ -1692,7 +1673,9 @@
     def analyse_annotations(self, env):
         for arg in self.args:
             if arg.annotation:
-                arg.annotation = self.analyse_annotation(env, arg.annotation)
+                arg.annotation = arg.annotation.analyse_types(env)
+        if self.return_type_annotation:
+            self.return_type_annotation = self.return_type_annotation.analyse_types(env)
 
     def align_argument_type(self, env, arg):
         # @cython.locals()
@@ -1746,8 +1729,10 @@
 
     def generate_function_definitions(self, env, code):
         from . import Buffer
-        if self.return_type.is_memoryviewslice:
-            from . import MemoryView
+
+        if self.entry.is_cgetter:
+            # no code to generate
+            return
 
         lenv = self.local_scope
         if lenv.is_closure_scope and not lenv.is_passthrough:
@@ -1775,6 +1760,8 @@
         profile = code.globalstate.directives['profile']
         linetrace = code.globalstate.directives['linetrace']
         if profile or linetrace:
+            if linetrace:
+                code.use_fast_gil_utility_code()
             code.globalstate.use_utility_code(
                 UtilityCode.load_cached("Profile", "Profile.c"))
 
@@ -1820,6 +1807,7 @@
 
         # Initialize the return variable __pyx_r
         init = ""
-        if not self.return_type.is_void:
-            if self.return_type.is_pyobject:
+        return_type = self.return_type
+        if not return_type.is_void:
+            if return_type.is_pyobject:
                 init = " = NULL"
@@ -1825,5 +1813,5 @@
                 init = " = NULL"
-            elif self.return_type.is_memoryviewslice:
-                init = ' = ' + MemoryView.memslice_entry_init
+            elif return_type.is_memoryviewslice:
+                init = ' = ' + return_type.literal_code(return_type.default_value)
 
             code.putln("%s%s;" % (
@@ -1828,6 +1816,6 @@
 
             code.putln("%s%s;" % (
-                self.return_type.declaration_code(Naming.retval_cname),
+                return_type.declaration_code(Naming.retval_cname),
                 init))
 
         tempvardecl_code = code.insertion_point()
@@ -1859,6 +1847,7 @@
 
         use_refnanny = not lenv.nogil or lenv.has_with_gil_block
 
+        gilstate_decl = None
         if acquire_gil or acquire_gil_for_var_decls_only:
             code.put_ensure_gil()
             code.funcstate.gil_owned = True
@@ -1862,8 +1851,8 @@
         if acquire_gil or acquire_gil_for_var_decls_only:
             code.put_ensure_gil()
             code.funcstate.gil_owned = True
-        elif lenv.nogil and lenv.has_with_gil_block:
-            code.declare_gilstate()
+        else:
+            gilstate_decl = code.insertion_point()
 
         if profile or linetrace:
             if not self.is_generator:
@@ -1905,7 +1894,7 @@
             code.put_incref("Py_None", py_object_type)
             code.putln(code.error_goto(self.pos))
             code.putln("} else {")
-            code.put_gotref(Naming.cur_scope_cname)
+            code.put_gotref(Naming.cur_scope_cname, lenv.scope_class.type)
             code.putln("}")
             # Note that it is unsafe to decref the scope at this point.
         if self.needs_outer_scope:
@@ -1924,7 +1913,7 @@
             elif self.needs_closure:
                 # inner closures own a reference to their outer parent
                 code.put_incref(outer_scope_cname, cenv.scope_class.type)
-                code.put_giveref(outer_scope_cname)
+                code.put_giveref(outer_scope_cname, cenv.scope_class.type)
         # ----- Trace function call
         if profile or linetrace:
             # this looks a bit late, but if we don't get here due to a
@@ -1944,6 +1933,6 @@
         # incref it to properly keep track of refcounts.
         is_cdef = isinstance(self, CFuncDefNode)
         for entry in lenv.arg_entries:
-            if entry.type.is_pyobject:
-                if (acquire_gil or len(entry.cf_assignments) > 1) and not entry.in_closure:
+            if not entry.type.is_memoryviewslice:
+                if (acquire_gil or entry.cf_is_reassigned) and not entry.in_closure:
                     code.put_var_incref(entry)
@@ -1949,6 +1938,5 @@
                     code.put_var_incref(entry)
-
             # Note: defaults are always incref-ed. For def functions, we
             #       we acquire arguments from object conversion, so we have
             #       new references. If we are a cdef function, we need to
             #       incref our arguments
@@ -1951,7 +1939,8 @@
             # Note: defaults are always incref-ed. For def functions, we
             #       we acquire arguments from object conversion, so we have
             #       new references. If we are a cdef function, we need to
             #       incref our arguments
-            elif is_cdef and entry.type.is_memoryviewslice and len(entry.cf_assignments) > 1:
-                code.put_incref_memoryviewslice(entry.cname, have_gil=code.funcstate.gil_owned)
+            elif is_cdef and entry.cf_is_reassigned:
+                code.put_var_incref_memoryviewslice(entry,
+                                    have_gil=code.funcstate.gil_owned)
         for entry in lenv.var_entries:
@@ -1957,5 +1946,5 @@
         for entry in lenv.var_entries:
-            if entry.is_arg and len(entry.cf_assignments) > 1 and not entry.in_closure:
+            if entry.is_arg and entry.cf_is_reassigned and not entry.in_closure:
                 if entry.xdecref_cleanup:
                     code.put_var_xincref(entry)
                 else:
@@ -1986,4 +1975,17 @@
         code.putln("")
         code.putln("/* function exit code */")
 
+        gil_owned = {
+            'success': code.funcstate.gil_owned,
+            'error': code.funcstate.gil_owned,
+            'gil_state_declared': gilstate_decl is None,
+        }
+        def assure_gil(code_path, code=code):
+            if not gil_owned[code_path]:
+                if not gil_owned['gil_state_declared']:
+                    gilstate_decl.declare_gilstate()
+                    gil_owned['gil_state_declared'] = True
+                code.put_ensure_gil(declare_gilstate=False)
+                gil_owned[code_path] = True
+
         # ----- Default return value
@@ -1989,2 +1991,3 @@
         # ----- Default return value
+        return_type = self.return_type
         if not self.body.is_terminator:
@@ -1990,6 +1993,6 @@
         if not self.body.is_terminator:
-            if self.return_type.is_pyobject:
-                #if self.return_type.is_extension_type:
+            if return_type.is_pyobject:
+                #if return_type.is_extension_type:
                 #    lhs = "(PyObject *)%s" % Naming.retval_cname
                 #else:
                 lhs = Naming.retval_cname
@@ -1993,8 +1996,10 @@
                 #    lhs = "(PyObject *)%s" % Naming.retval_cname
                 #else:
                 lhs = Naming.retval_cname
-                code.put_init_to_py_none(lhs, self.return_type)
-            else:
-                val = self.return_type.default_value
+                assure_gil('success')
+                code.put_init_to_py_none(lhs, return_type)
+            elif not return_type.is_memoryviewslice:
+                # memory view structs receive their default value on initialisation
+                val = return_type.default_value
                 if val:
                     code.putln("%s = %s;" % (Naming.retval_cname, val))
@@ -1999,6 +2004,6 @@
                 if val:
                     code.putln("%s = %s;" % (Naming.retval_cname, val))
-                elif not self.return_type.is_void:
+                elif not return_type.is_void:
                     code.putln("__Pyx_pretend_to_initialize(&%s);" % Naming.retval_cname)
         # ----- Error cleanup
         if code.error_label in code.labels_used:
@@ -2006,6 +2011,7 @@
                 code.put_goto(code.return_label)
             code.put_label(code.error_label)
             for cname, type in code.funcstate.all_managed_temps():
+                assure_gil('error')
                 code.put_xdecref(cname, type, have_gil=not lenv.nogil)
 
             # Clean up buffers -- this calls a Python function
@@ -2016,6 +2022,7 @@
                 code.globalstate.use_utility_code(restore_exception_utility_code)
                 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
                 code.putln("__Pyx_PyThreadState_declare")
+                assure_gil('error')
                 code.putln("__Pyx_PyThreadState_assign")
                 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
                 for entry in used_buffer_entries:
@@ -2023,7 +2030,8 @@
                     #code.putln("%s = 0;" % entry.cname)
                 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
 
-            if self.return_type.is_memoryviewslice:
+            if return_type.is_memoryviewslice:
+                from . import MemoryView
                 MemoryView.put_init_entry(Naming.retval_cname, code)
                 err_val = Naming.retval_cname
             else:
@@ -2035,8 +2043,5 @@
                 # code.globalstate.use_utility_code(get_exception_tuple_utility_code)
                 # code.put_trace_exception()
 
-                if lenv.nogil and not lenv.has_with_gil_block:
-                    code.putln("{")
-                    code.put_ensure_gil()
-
+                assure_gil('error')
                 code.put_add_traceback(self.entry.qualified_name)
@@ -2042,9 +2047,5 @@
                 code.put_add_traceback(self.entry.qualified_name)
-
-                if lenv.nogil and not lenv.has_with_gil_block:
-                    code.put_release_ensured_gil()
-                    code.putln("}")
             else:
                 warning(self.entry.pos,
                         "Unraisable exception in function '%s'." %
                         self.entry.qualified_name, 0)
@@ -2047,11 +2048,12 @@
             else:
                 warning(self.entry.pos,
                         "Unraisable exception in function '%s'." %
                         self.entry.qualified_name, 0)
-                code.put_unraisable(self.entry.qualified_name, lenv.nogil)
-            default_retval = self.return_type.default_value
+                assure_gil('error')
+                code.put_unraisable(self.entry.qualified_name)
+            default_retval = return_type.default_value
             if err_val is None and default_retval:
                 err_val = default_retval
             if err_val is not None:
                 if err_val != Naming.retval_cname:
                     code.putln("%s = %s;" % (Naming.retval_cname, err_val))
@@ -2053,9 +2055,9 @@
             if err_val is None and default_retval:
                 err_val = default_retval
             if err_val is not None:
                 if err_val != Naming.retval_cname:
                     code.putln("%s = %s;" % (Naming.retval_cname, err_val))
-            elif not self.return_type.is_void:
+            elif not return_type.is_void:
                 code.putln("__Pyx_pretend_to_initialize(&%s);" % Naming.retval_cname)
 
             if is_getbuffer_slot:
@@ -2059,5 +2061,6 @@
                 code.putln("__Pyx_pretend_to_initialize(&%s);" % Naming.retval_cname)
 
             if is_getbuffer_slot:
+                assure_gil('error')
                 self.getbuffer_error_cleanup(code)
 
@@ -2062,5 +2065,15 @@
                 self.getbuffer_error_cleanup(code)
 
+            def align_error_path_gil_to_success_path(code=code.insertion_point()):
+                # align error and success GIL state when both join
+                if gil_owned['success']:
+                    assure_gil('error', code=code)
+                elif gil_owned['error']:
+                    code.put_release_ensured_gil()
+                    gil_owned['error'] = False
+                assert gil_owned['error'] == gil_owned['success'], "%s: error path %s != success path %s" % (
+                    self.pos, gil_owned['error'], gil_owned['success'])
+
             # If we are using the non-error cleanup section we should
             # jump past it if we have an error. The if-test below determine
             # whether this section is used.
@@ -2064,5 +2077,7 @@
             # If we are using the non-error cleanup section we should
             # jump past it if we have an error. The if-test below determine
             # whether this section is used.
-            if buffers_present or is_getbuffer_slot or self.return_type.is_memoryviewslice:
+            if buffers_present or is_getbuffer_slot or return_type.is_memoryviewslice:
+                # In the buffer cases, we already called assure_gil('error') and own the GIL.
+                assert gil_owned['error'] or return_type.is_memoryviewslice
                 code.put_goto(code.return_from_error_cleanup_label)
@@ -2068,4 +2083,10 @@
                 code.put_goto(code.return_from_error_cleanup_label)
+            else:
+                # Adapt the GIL state to the success path right now.
+                align_error_path_gil_to_success_path()
+        else:
+            # No error path, no need to adapt the GIL state.
+            def align_error_path_gil_to_success_path(): pass
 
         # ----- Non-error return cleanup
         code.put_label(code.return_label)
@@ -2069,4 +2090,5 @@
 
         # ----- Non-error return cleanup
         code.put_label(code.return_label)
+
         for entry in used_buffer_entries:
@@ -2072,3 +2094,4 @@
         for entry in used_buffer_entries:
+            assure_gil('success')
             Buffer.put_release_buffer_code(code, entry)
         if is_getbuffer_slot:
@@ -2073,4 +2096,5 @@
             Buffer.put_release_buffer_code(code, entry)
         if is_getbuffer_slot:
+            assure_gil('success')
             self.getbuffer_normal_cleanup(code)
 
@@ -2075,6 +2099,6 @@
             self.getbuffer_normal_cleanup(code)
 
-        if self.return_type.is_memoryviewslice:
+        if return_type.is_memoryviewslice:
             # See if our return value is uninitialized on non-error return
             # from . import MemoryView
             # MemoryView.err_if_nogil_initialized_check(self.pos, env)
@@ -2078,6 +2102,6 @@
             # See if our return value is uninitialized on non-error return
             # from . import MemoryView
             # MemoryView.err_if_nogil_initialized_check(self.pos, env)
-            cond = code.unlikely(self.return_type.error_condition(Naming.retval_cname))
+            cond = code.unlikely(return_type.error_condition(Naming.retval_cname))
             code.putln(
                 'if (%s) {' % cond)
@@ -2082,6 +2106,6 @@
             code.putln(
                 'if (%s) {' % cond)
-            if env.nogil:
+            if not gil_owned['success']:
                 code.put_ensure_gil()
             code.putln(
                 'PyErr_SetString(PyExc_TypeError, "Memoryview return value is not initialized");')
@@ -2085,9 +2109,9 @@
                 code.put_ensure_gil()
             code.putln(
                 'PyErr_SetString(PyExc_TypeError, "Memoryview return value is not initialized");')
-            if env.nogil:
+            if not gil_owned['success']:
                 code.put_release_ensured_gil()
             code.putln(
                 '}')
 
         # ----- Return cleanup for both error and no-error return
@@ -2089,11 +2113,13 @@
                 code.put_release_ensured_gil()
             code.putln(
                 '}')
 
         # ----- Return cleanup for both error and no-error return
-        code.put_label(code.return_from_error_cleanup_label)
+        if code.label_used(code.return_from_error_cleanup_label):
+            align_error_path_gil_to_success_path()
+            code.put_label(code.return_from_error_cleanup_label)
 
         for entry in lenv.var_entries:
             if not entry.used or entry.in_closure:
                 continue
 
@@ -2095,16 +2121,13 @@
 
         for entry in lenv.var_entries:
             if not entry.used or entry.in_closure:
                 continue
 
-            if entry.type.is_memoryviewslice:
-                code.put_xdecref_memoryviewslice(entry.cname, have_gil=not lenv.nogil)
-            elif entry.type.is_pyobject:
-                if not entry.is_arg or len(entry.cf_assignments) > 1:
-                    if entry.xdecref_cleanup:
-                        code.put_var_xdecref(entry)
-                    else:
-                        code.put_var_decref(entry)
+            if entry.type.is_pyobject:
+                if entry.is_arg and not entry.cf_is_reassigned:
+                    continue
+            # FIXME ideally use entry.xdecref_cleanup but this currently isn't reliable
+            code.put_var_xdecref(entry, have_gil=not lenv.nogil)
 
         # Decref any increfed args
         for entry in lenv.arg_entries:
@@ -2108,10 +2131,6 @@
 
         # Decref any increfed args
         for entry in lenv.arg_entries:
-            if entry.type.is_pyobject:
-                if (acquire_gil or len(entry.cf_assignments) > 1) and not entry.in_closure:
-                    code.put_var_decref(entry)
-            elif (entry.type.is_memoryviewslice and
-                  (not is_cdef or len(entry.cf_assignments) > 1)):
+            if entry.type.is_memoryviewslice:
                 # decref slices of def functions and acquired slices from cdef
                 # functions, but not borrowed slices from cdef functions.
@@ -2116,5 +2135,13 @@
                 # decref slices of def functions and acquired slices from cdef
                 # functions, but not borrowed slices from cdef functions.
-                code.put_xdecref_memoryviewslice(entry.cname,
-                                                 have_gil=not lenv.nogil)
+                if is_cdef and not entry.cf_is_reassigned:
+                    continue
+            else:
+                if entry.in_closure:
+                    continue
+                if not acquire_gil and not entry.cf_is_reassigned:
+                    continue
+
+            # FIXME use entry.xdecref_cleanup - del arg seems to be the problem
+            code.put_var_xdecref(entry, have_gil=not lenv.nogil)
         if self.needs_closure:
@@ -2120,6 +2147,7 @@
         if self.needs_closure:
+            assure_gil('success')
             code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type)
 
         # ----- Return
         # This code is duplicated in ModuleNode.generate_module_init_func
         if not lenv.nogil:
@@ -2121,9 +2149,9 @@
             code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type)
 
         # ----- Return
         # This code is duplicated in ModuleNode.generate_module_init_func
         if not lenv.nogil:
-            default_retval = self.return_type.default_value
+            default_retval = return_type.default_value
             err_val = self.error_value()
             if err_val is None and default_retval:
                 err_val = default_retval  # FIXME: why is err_val not used?
@@ -2127,9 +2155,8 @@
             err_val = self.error_value()
             if err_val is None and default_retval:
                 err_val = default_retval  # FIXME: why is err_val not used?
-            if self.return_type.is_pyobject:
-                code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
+            code.put_xgiveref(Naming.retval_cname, return_type)
 
         if self.entry.is_special and self.entry.name == "__hash__":
             # Returning -1 for __hash__ is supposed to signal an error
             # We do as Python instances and coerce -1 into -2.
@@ -2132,7 +2159,8 @@
 
         if self.entry.is_special and self.entry.name == "__hash__":
             # Returning -1 for __hash__ is supposed to signal an error
             # We do as Python instances and coerce -1 into -2.
+            assure_gil('success')
             code.putln("if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;" % (
                 Naming.retval_cname, Naming.retval_cname))
 
@@ -2140,5 +2168,5 @@
             code.funcstate.can_trace = False
             if not self.is_generator:
                 # generators are traced when iterated, not at creation
-                if self.return_type.is_pyobject:
+                if return_type.is_pyobject:
                     code.put_trace_return(
@@ -2144,4 +2172,4 @@
                     code.put_trace_return(
-                        Naming.retval_cname, nogil=not code.funcstate.gil_owned)
+                        Naming.retval_cname, nogil=not gil_owned['success'])
                 else:
                     code.put_trace_return(
@@ -2146,13 +2174,12 @@
                 else:
                     code.put_trace_return(
-                        "Py_None", nogil=not code.funcstate.gil_owned)
-
-        if not lenv.nogil:
-            # GIL holding function
-            code.put_finish_refcount_context()
-
-        if acquire_gil or (lenv.nogil and lenv.has_with_gil_block):
+                        "Py_None", nogil=not gil_owned['success'])
+
+        if use_refnanny:
+            code.put_finish_refcount_context(nogil=not gil_owned['success'])
+
+        if acquire_gil or (lenv.nogil and gil_owned['success']):
             # release the GIL (note that with-gil blocks acquire it on exit in their EnsureGILNode)
             code.put_release_ensured_gil()
             code.funcstate.gil_owned = False
 
@@ -2155,8 +2182,8 @@
             # release the GIL (note that with-gil blocks acquire it on exit in their EnsureGILNode)
             code.put_release_ensured_gil()
             code.funcstate.gil_owned = False
 
-        if not self.return_type.is_void:
+        if not return_type.is_void:
             code.putln("return %s;" % Naming.retval_cname)
 
         code.putln("}")
@@ -2180,7 +2207,7 @@
             error(arg.pos, "Argument type '%s' is incomplete" % arg.type)
         entry = env.declare_arg(arg.name, arg.type, arg.pos)
         if arg.annotation:
-            entry.annotation = arg.annotation
+            entry.annotation = arg.annotation.expr
         return entry
 
     def generate_arg_type_test(self, arg, code):
@@ -2191,7 +2218,7 @@
             typeptr_cname = arg.type.typeptr_cname
             arg_code = "((PyObject *)%s)" % arg.entry.cname
             code.putln(
-                'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
+                'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, %s, %s))) %s' % (
                     arg_code,
                     typeptr_cname,
                     arg.accept_none,
@@ -2195,7 +2222,7 @@
                     arg_code,
                     typeptr_cname,
                     arg.accept_none,
-                    arg.name,
+                    arg.name_cstring,
                     arg.type.is_builtin_type and arg.type.require_exact,
                     code.error_goto(arg.pos)))
         else:
@@ -2209,8 +2236,8 @@
             cname = arg.entry.cname
 
         code.putln('if (unlikely(((PyObject *)%s) == Py_None)) {' % cname)
-        code.putln('''PyErr_Format(PyExc_TypeError, "Argument '%%.%ds' must not be None", "%s"); %s''' % (
-            max(200, len(arg.name)), arg.name,
+        code.putln('''PyErr_Format(PyExc_TypeError, "Argument '%%.%ds' must not be None", %s); %s''' % (
+            max(200, len(arg.name_cstring)), arg.name_cstring,
             code.error_goto(arg.pos)))
         code.putln('}')
 
@@ -2246,7 +2273,7 @@
     def getbuffer_check(self, code):
         py_buffer, _ = self._get_py_buffer_info()
         view = py_buffer.cname
-        code.putln("if (%s == NULL) {" % view)
+        code.putln("if (unlikely(%s == NULL)) {" % view)
         code.putln("PyErr_SetString(PyExc_BufferError, "
                    "\"PyObject_GetBuffer: view==NULL argument is obsolete\");")
         code.putln("return -1;")
@@ -2257,7 +2284,7 @@
         view = py_buffer.cname
         if obj_type and obj_type.is_pyobject:
             code.put_init_to_py_none("%s->obj" % view, obj_type)
-            code.put_giveref("%s->obj" % view) # Do not refnanny object within structs
+            code.put_giveref("%s->obj" % view, obj_type) # Do not refnanny object within structs
         else:
             code.putln("%s->obj = NULL;" % view)
 
@@ -2266,7 +2293,7 @@
         view = py_buffer.cname
         if obj_type and obj_type.is_pyobject:
             code.putln("if (%s->obj != NULL) {" % view)
-            code.put_gotref("%s->obj" % view)
+            code.put_gotref("%s->obj" % view, obj_type)
             code.put_decref_clear("%s->obj" % view, obj_type)
             code.putln("}")
         else:
@@ -2277,7 +2304,7 @@
         view = py_buffer.cname
         if obj_type and obj_type.is_pyobject:
             code.putln("if (%s->obj == Py_None) {" % view)
-            code.put_gotref("%s->obj" % view)
+            code.put_gotref("%s->obj" % view, obj_type)
             code.put_decref_clear("%s->obj" % view, obj_type)
             code.putln("}")
 
@@ -2319,7 +2346,8 @@
     #  is_static_method whether this is a static method
     #  is_c_class_method whether this is a cclass method
 
-    child_attrs = ["base_type", "declarator", "body", "py_func_stat"]
+    child_attrs = ["base_type", "declarator", "body", "py_func_stat", "decorators"]
+    outer_attrs = ["decorators", "py_func_stat"]
 
     inline_in_pxd = False
     decorators = None
@@ -2339,6 +2367,21 @@
         return self.py_func.code_object if self.py_func else None
 
     def analyse_declarations(self, env):
+        is_property = 0
+        if self.decorators:
+            for decorator in self.decorators:
+                func = decorator.decorator
+                if func.is_name:
+                    if func.name == 'property':
+                        is_property = 1
+                    elif func.name == 'staticmethod':
+                        pass
+                    else:
+                        error(self.pos, "Cannot handle %s decorators yet" % func.name)
+                else:
+                    error(self.pos,
+                          "Cannot handle %s decorators yet" % type(func).__name__)
+
         self.is_c_class_method = env.is_c_class_scope
         if self.directive_locals is None:
             self.directive_locals = {}
@@ -2353,7 +2396,7 @@
         self.is_static_method = 'staticmethod' in env.directives and not env.lookup_here('staticmethod')
         # The 2 here is because we need both function and argument names.
         if isinstance(self.declarator, CFuncDeclaratorNode):
-            name_declarator, type = self.declarator.analyse(
+            name_declarator, typ = self.declarator.analyse(
                 base_type, env, nonempty=2 * (self.body is not None),
                 directive_locals=self.directive_locals, visibility=self.visibility)
         else:
@@ -2357,5 +2400,5 @@
                 base_type, env, nonempty=2 * (self.body is not None),
                 directive_locals=self.directive_locals, visibility=self.visibility)
         else:
-            name_declarator, type = self.declarator.analyse(
+            name_declarator, typ = self.declarator.analyse(
                 base_type, env, nonempty=2 * (self.body is not None), visibility=self.visibility)
@@ -2361,7 +2404,7 @@
                 base_type, env, nonempty=2 * (self.body is not None), visibility=self.visibility)
-        if not type.is_cfunction:
+        if not typ.is_cfunction:
             error(self.pos, "Suite attached to non-function declaration")
         # Remember the actual type according to the function header
         # written here, because the type in the symbol table entry
         # may be different if we're overriding a C method inherited
         # from the base type of an extension type.
@@ -2363,10 +2406,10 @@
             error(self.pos, "Suite attached to non-function declaration")
         # Remember the actual type according to the function header
         # written here, because the type in the symbol table entry
         # may be different if we're overriding a C method inherited
         # from the base type of an extension type.
-        self.type = type
-        type.is_overridable = self.overridable
+        self.type = typ
+        typ.is_overridable = self.overridable
         declarator = self.declarator
         while not hasattr(declarator, 'args'):
             declarator = declarator.base
@@ -2379,7 +2422,7 @@
             error(self.cfunc_declarator.pos,
                   "Function with optional arguments may not be declared public or api")
 
-        if type.exception_check == '+' and self.visibility != 'extern':
+        if typ.exception_check == '+' and self.visibility != 'extern':
             warning(self.cfunc_declarator.pos,
                     "Only extern functions can throw C++ exceptions.")
 
@@ -2383,7 +2426,7 @@
             warning(self.cfunc_declarator.pos,
                     "Only extern functions can throw C++ exceptions.")
 
-        for formal_arg, type_arg in zip(self.args, type.args):
+        for formal_arg, type_arg in zip(self.args, typ.args):
             self.align_argument_type(env, type_arg)
             formal_arg.type = type_arg.type
             formal_arg.name = type_arg.name
@@ -2404,8 +2447,8 @@
                 elif 'inline' in self.modifiers:
                     warning(formal_arg.pos, "Buffer unpacking not optimized away.", 1)
 
-        self._validate_type_visibility(type.return_type, self.pos, env)
+        self._validate_type_visibility(typ.return_type, self.pos, env)
 
         name = name_declarator.name
         cname = name_declarator.cname
 
@@ -2408,7 +2451,8 @@
 
         name = name_declarator.name
         cname = name_declarator.cname
 
-        type.is_const_method = self.is_const_method
-        type.is_static_method = self.is_static_method
+        typ.is_const_method = self.is_const_method
+        typ.is_static_method = self.is_static_method
+
         self.entry = env.declare_cfunction(
@@ -2414,5 +2458,5 @@
         self.entry = env.declare_cfunction(
-            name, type, self.pos,
+            name, typ, self.pos,
             cname=cname, visibility=self.visibility, api=self.api,
             defining=self.body is not None, modifiers=self.modifiers,
             overridable=self.overridable)
@@ -2416,4 +2460,8 @@
             cname=cname, visibility=self.visibility, api=self.api,
             defining=self.body is not None, modifiers=self.modifiers,
             overridable=self.overridable)
+        if is_property:
+            self.entry.is_property = 1
+            env.property_entries.append(self.entry)
+            env.cfunc_entries.remove(self.entry)
         self.entry.inline_func_in_pxd = self.inline_in_pxd
@@ -2419,5 +2467,5 @@
         self.entry.inline_func_in_pxd = self.inline_in_pxd
-        self.return_type = type.return_type
+        self.return_type = typ.return_type
         if self.return_type.is_array and self.visibility != 'extern':
             error(self.pos, "Function cannot return an array")
         if self.return_type.is_cpp_class:
@@ -2440,7 +2488,7 @@
             py_func_body = self.call_self_node(is_module_scope=env.is_module_scope)
             if self.is_static_method:
                 from .ExprNodes import NameNode
-                decorators = [DecoratorNode(self.pos, decorator=NameNode(self.pos, name='staticmethod'))]
+                decorators = [DecoratorNode(self.pos, decorator=NameNode(self.pos, name=EncodedString('staticmethod')))]
                 decorators[0].decorator.analyse_types(env)
             else:
                 decorators = []
@@ -2776,5 +2824,5 @@
 
     def __init__(self, pos, **kwds):
         FuncDefNode.__init__(self, pos, **kwds)
-        k = rk = r = 0
+        p = k = rk = r = 0
         for arg in self.args:
@@ -2780,7 +2828,9 @@
         for arg in self.args:
+            if arg.pos_only:
+                p += 1
             if arg.kw_only:
                 k += 1
                 if not arg.default:
                     rk += 1
             if not arg.default:
                 r += 1
@@ -2781,9 +2831,10 @@
             if arg.kw_only:
                 k += 1
                 if not arg.default:
                     rk += 1
             if not arg.default:
                 r += 1
+        self.num_posonly_args = p
         self.num_kwonly_args = k
         self.num_required_kw_args = rk
         self.num_required_args = r
@@ -2881,8 +2932,16 @@
             # staticmethod() was overridden - not much we can do here ...
             self.is_staticmethod = False
 
-        if self.name == '__new__' and env.is_py_class_scope:
-            self.is_staticmethod = 1
+        if env.is_py_class_scope:
+            if self.name == '__new__':
+                self.is_staticmethod = True
+            elif not self.is_classmethod and self.name in IMPLICIT_CLASSMETHODS:
+                self.is_classmethod = True
+                # TODO: remove the need to generate a real decorator here, is_classmethod=True should suffice.
+                from .ExprNodes import NameNode
+                self.decorators = self.decorators or []
+                self.decorators.insert(0, DecoratorNode(
+                    self.pos, decorator=NameNode(self.pos, name=EncodedString('classmethod'))))
 
         self.analyse_argument_types(env)
         if self.name == '<lambda>':
@@ -2895,7 +2954,7 @@
         # if a signature annotation provides a more specific return object type, use it
         if self.return_type is py_object_type and self.return_type_annotation:
             if env.directives['annotation_typing'] and not self.entry.is_special:
-                _, return_type = analyse_type_annotation(self.return_type_annotation, env)
+                _, return_type = self.return_type_annotation.analyse_type_annotation(env)
                 if return_type and return_type.is_pyobject:
                     self.return_type = return_type
 
@@ -2935,9 +2994,6 @@
                 arg.name = name_declarator.name
                 arg.type = type
 
-                if type.is_fused:
-                    self.has_fused_arguments = True
-
             self.align_argument_type(env, arg)
             if name_declarator and name_declarator.cname:
                 error(self.pos, "Python function argument cannot have C name specification")
@@ -2968,6 +3024,9 @@
                     error(arg.pos, "Only Python type arguments can have 'not None'")
                 if arg.or_none:
                     error(arg.pos, "Only Python type arguments can have 'or None'")
+
+            if arg.type.is_fused:
+                self.has_fused_arguments = True
         env.fused_to_specific = f2s
 
         if has_np_pythran(env):
@@ -2980,8 +3039,10 @@
             if self.decorators:
                 error(self.pos, "special functions of cdef classes cannot have decorators")
             self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
-        elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
-            # Use the simpler calling signature for zero- and one-argument functions.
+        elif not (self.star_arg or self.starstar_arg) and (
+                not env.directives['always_allow_keywords']
+                or all([arg.pos_only for arg in self.args])):
+            # Use the simpler calling signature for zero- and one-argument pos-only functions.
             if self.entry.signature is TypeSlots.pyfunction_signature:
                 if len(self.args) == 0:
                     self.entry.signature = TypeSlots.pyfunction_noargs
@@ -3037,10 +3098,6 @@
                         arg.needs_type_test = 1
                     else:
                         arg.needs_conversion = 1
-            if arg.needs_conversion:
-                arg.hdr_cname = Naming.arg_prefix + arg.name
-            else:
-                arg.hdr_cname = Naming.var_prefix + arg.name
 
         if nfixed > len(self.args):
             self.bad_signature()
@@ -3052,6 +3109,31 @@
                 if arg.is_generic and (arg.type.is_extension_type or arg.type.is_builtin_type):
                     arg.needs_type_test = 1
 
+        # Decide whether to use METH_FASTCALL
+        # 1. If we use METH_NOARGS or METH_O, keep that. We can only change
+        #    METH_VARARGS to METH_FASTCALL
+        # 2. Special methods like __call__ always use the METH_VARGARGS
+        #    calling convention
+        mf = sig.method_flags()
+        if mf and TypeSlots.method_varargs in mf and not self.entry.is_special:
+            # 3. If the function uses the full args tuple, it's more
+            #    efficient to use METH_VARARGS. This happens when the function
+            #    takes *args but no other positional arguments (apart from
+            #    possibly self). We don't do the analogous check for keyword
+            #    arguments since the kwargs dict is copied anyway.
+            if self.star_arg:
+                uses_args_tuple = True
+                for arg in self.args:
+                    if (arg.is_generic and not arg.kw_only and
+                            not arg.is_self_arg and not arg.is_type_arg):
+                        # Other positional argument
+                        uses_args_tuple = False
+            else:
+                uses_args_tuple = False
+
+            if not uses_args_tuple:
+                sig = self.entry.signature = sig.with_fastcall()
+
     def bad_signature(self):
         sig = self.entry.signature
         expected_str = "%d" % sig.num_fixed_args()
@@ -3077,6 +3159,6 @@
         entry = env.declare_pyfunction(name, self.pos, allow_redefine=not self.is_wrapper)
         self.entry = entry
         prefix = env.next_id(env.scope_prefix)
-        self.entry.pyfunc_cname = Naming.pyfunc_prefix + prefix + name
+        self.entry.pyfunc_cname = punycodify_name(Naming.pyfunc_prefix + prefix + name)
         if Options.docstrings:
             entry.doc = embed_position(self.pos, self.doc)
@@ -3081,8 +3163,8 @@
         if Options.docstrings:
             entry.doc = embed_position(self.pos, self.doc)
-            entry.doc_cname = Naming.funcdoc_prefix + prefix + name
+            entry.doc_cname = punycodify_name(Naming.funcdoc_prefix + prefix + name)
             if entry.is_special:
                 if entry.name in TypeSlots.invisible or not entry.doc or (
                         entry.name in '__getattr__' and env.directives['fast_getattr']):
                     entry.wrapperbase_cname = None
                 else:
@@ -3084,9 +3166,9 @@
             if entry.is_special:
                 if entry.name in TypeSlots.invisible or not entry.doc or (
                         entry.name in '__getattr__' and env.directives['fast_getattr']):
                     entry.wrapperbase_cname = None
                 else:
-                    entry.wrapperbase_cname = Naming.wrapperbase_prefix + prefix + name
+                    entry.wrapperbase_cname = punycodify_name(Naming.wrapperbase_prefix + prefix + name)
         else:
             entry.doc = None
 
@@ -3129,8 +3211,6 @@
         self.local_scope.directives = env.directives
         self.analyse_default_values(env)
         self.analyse_annotations(env)
-        if self.return_type_annotation:
-            self.return_type_annotation = self.analyse_annotation(env, self.return_type_annotation)
 
         if not self.needs_assignment_synthesis(env) and self.decorators:
             for decorator in self.decorators[::-1]:
@@ -3258,6 +3338,7 @@
 
     def __init__(self, *args, **kwargs):
         FuncDefNode.__init__(self, *args, **kwargs)
+        self.num_posonly_args = self.target.num_posonly_args
         self.num_kwonly_args = self.target.num_kwonly_args
         self.num_required_kw_args = self.target.num_required_kw_args
         self.num_required_args = self.target.num_required_args
@@ -3268,8 +3349,8 @@
         target_entry = self.target.entry
         name = self.name
         prefix = env.next_id(env.scope_prefix)
-        target_entry.func_cname = Naming.pywrap_prefix + prefix + name
-        target_entry.pymethdef_cname = Naming.pymethdef_prefix + prefix + name
+        target_entry.func_cname = punycodify_name(Naming.pywrap_prefix + prefix + name)
+        target_entry.pymethdef_cname = punycodify_name(Naming.pymethdef_prefix + prefix + name)
 
         self.signature = target_entry.signature
 
@@ -3313,7 +3394,13 @@
         if self.signature.has_dummy_arg:
             args.append(Naming.self_cname)
         for arg in self.args:
-            if arg.hdr_type and not (arg.type.is_memoryviewslice or
+            if arg.hdr_type and arg.type.is_cpp_class:
+                # it's safe to move converted C++ types because they aren't
+                # used again afterwards
+                code.globalstate.use_utility_code(
+                    UtilityCode.load_cached("MoveIfSupported", "CppSupport.cpp"))
+                args.append("__PYX_STD_MOVE_IF_SUPPORTED(%s)" % arg.entry.cname)
+            elif arg.hdr_type and not (arg.type.is_memoryviewslice or
                                      arg.type.is_struct or
                                      arg.type.is_complex):
                 args.append(arg.type.cast_code(arg.entry.cname))
@@ -3357,7 +3444,7 @@
                 self.return_type.declaration_code(Naming.retval_cname),
                 retval_init))
         code.put_declare_refcount_context()
-        code.put_setup_refcount_context('%s (wrapper)' % self.name)
+        code.put_setup_refcount_context(EncodedString('%s (wrapper)' % self.name))
 
         self.generate_argument_parsing_code(lenv, code)
         self.generate_argument_type_tests(code)
@@ -3384,7 +3471,10 @@
         code.put_label(code.return_label)
         for entry in lenv.var_entries:
             if entry.is_arg and entry.type.is_pyobject:
-                code.put_var_decref(entry)
+                if entry.xdecref_cleanup:
+                    code.put_var_xdecref(entry)
+                else:
+                    code.put_var_decref(entry)
 
         code.put_finish_refcount_context()
         if not self.return_type.is_void:
@@ -3417,9 +3507,16 @@
         if entry.scope.is_c_class_scope and entry.name == "__ipow__":
             arg_code_list.append("CYTHON_UNUSED PyObject *unused")
         if sig.has_generic_args:
-            arg_code_list.append(
-                "PyObject *%s, PyObject *%s" % (
-                    Naming.args_cname, Naming.kwds_cname))
+            varargs_args = "PyObject *%s, PyObject *%s" % (
+                    Naming.args_cname, Naming.kwds_cname)
+            if sig.use_fastcall:
+                fastcall_args = "PyObject *const *%s, Py_ssize_t %s, PyObject *%s" % (
+                        Naming.args_cname, Naming.nargs_cname, Naming.kwds_cname)
+                arg_code_list.append(
+                    "\n#if CYTHON_METH_FASTCALL\n%s\n#else\n%s\n#endif\n" % (
+                        fastcall_args, varargs_args))
+            else:
+                arg_code_list.append(varargs_args)
         arg_code = ", ".join(arg_code_list)
 
         # Prevent warning: unused function '__pyx_pw_5numpy_7ndarray_1__getbuffer__'
@@ -3453,7 +3550,7 @@
                 docstr = docstr.as_utf8_string()
 
             if not (entry.is_special and entry.name in ('__getbuffer__', '__releasebuffer__')):
-                code.putln('static char %s[] = %s;' % (
+                code.putln('PyDoc_STRVAR(%s, %s);' % (
                     entry.doc_cname,
                     docstr.as_c_string_literal()))
 
@@ -3480,6 +3577,23 @@
             if entry.is_arg:
                 code.put_var_declaration(entry)
 
+        # Assign nargs variable as len(args), but avoid an "unused" warning in the few cases where we don't need it.
+        if self.signature_has_generic_args():
+            nargs_code = "CYTHON_UNUSED const Py_ssize_t %s = PyTuple_GET_SIZE(%s);" % (
+                        Naming.nargs_cname, Naming.args_cname)
+            if self.signature.use_fastcall:
+                code.putln("#if !CYTHON_METH_FASTCALL")
+                code.putln(nargs_code)
+                code.putln("#endif")
+            else:
+                code.putln(nargs_code)
+
+        # Array containing the values of keyword arguments when using METH_FASTCALL.
+        code.globalstate.use_utility_code(
+            UtilityCode.load_cached("fastcall", "FunctionArguments.c"))
+        code.putln('CYTHON_UNUSED PyObject *const *%s = __Pyx_KwValues_%s(%s, %s);' % (
+            Naming.kwvalues_cname, self.signature.fastvar, Naming.args_cname, Naming.nargs_cname))
+
     def generate_argument_parsing_code(self, env, code):
         # Generate fast equivalent of PyArg_ParseTuple call for
         # generic arguments, if any, including args/kwargs
@@ -3503,6 +3617,8 @@
 
         elif not self.signature_has_nongeneric_args():
             # func(*args) or func(**kw) or func(*args, **kw)
+            # possibly with a "self" argument but no other non-star
+            # arguments
             self.generate_stararg_copy_code(code)
 
         else:
@@ -3538,10 +3654,9 @@
         if not self.star_arg:
             code.globalstate.use_utility_code(
                 UtilityCode.load_cached("RaiseArgTupleInvalid", "FunctionArguments.c"))
-            code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
-                       Naming.args_cname)
-            code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
-                self.name, Naming.args_cname, self.error_value()))
+            code.putln("if (unlikely(%s > 0)) {" % Naming.nargs_cname)
+            code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, %s); return %s;' % (
+                self.name, Naming.nargs_cname, self.error_value()))
             code.putln("}")
 
         if self.starstar_arg:
@@ -3550,8 +3665,8 @@
             else:
                 kwarg_check = "%s" % Naming.kwds_cname
         else:
-            kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
-                Naming.kwds_cname, Naming.kwds_cname)
+            kwarg_check = "unlikely(%s) && __Pyx_NumKwargs_%s(%s)" % (
+                Naming.kwds_cname, self.signature.fastvar, Naming.kwds_cname)
         code.globalstate.use_utility_code(
             UtilityCode.load_cached("KeywordStringCheck", "FunctionArguments.c"))
         code.putln(
@@ -3560,13 +3675,16 @@
                 bool(self.starstar_arg), self.error_value()))
 
         if self.starstar_arg and self.starstar_arg.entry.cf_used:
-            if all(ref.node.allow_null for ref in self.starstar_arg.entry.cf_references):
-                code.putln("if (%s) {" % kwarg_check)
-                code.putln("%s = PyDict_Copy(%s); if (unlikely(!%s)) return %s;" % (
-                    self.starstar_arg.entry.cname,
-                    Naming.kwds_cname,
-                    self.starstar_arg.entry.cname,
-                    self.error_value()))
-                code.put_gotref(self.starstar_arg.entry.cname)
-                code.putln("} else {")
+            code.putln("if (%s) {" % kwarg_check)
+            code.putln("%s = __Pyx_KwargsAsDict_%s(%s, %s);" % (
+                self.starstar_arg.entry.cname,
+                self.signature.fastvar,
+                Naming.kwds_cname,
+                Naming.kwvalues_cname))
+            code.putln("if (unlikely(!%s)) return %s;" % (
+                self.starstar_arg.entry.cname, self.error_value()))
+            code.put_gotref(self.starstar_arg.entry.cname, py_object_type)
+            code.putln("} else {")
+            allow_null = all(ref.node.allow_null for ref in self.starstar_arg.entry.cf_references)
+            if allow_null:
                 code.putln("%s = NULL;" % (self.starstar_arg.entry.cname,))
@@ -3572,4 +3690,2 @@
                 code.putln("%s = NULL;" % (self.starstar_arg.entry.cname,))
-                code.putln("}")
-                self.starstar_arg.entry.xdecref_cleanup = 1
             else:
@@ -3575,7 +3691,4 @@
             else:
-                code.put("%s = (%s) ? PyDict_Copy(%s) : PyDict_New(); " % (
-                    self.starstar_arg.entry.cname,
-                    Naming.kwds_cname,
-                    Naming.kwds_cname))
+                code.putln("%s = PyDict_New();" % (self.starstar_arg.entry.cname,))
                 code.putln("if (unlikely(!%s)) return %s;" % (
                     self.starstar_arg.entry.cname, self.error_value()))
@@ -3580,6 +3693,7 @@
                 code.putln("if (unlikely(!%s)) return %s;" % (
                     self.starstar_arg.entry.cname, self.error_value()))
-                self.starstar_arg.entry.xdecref_cleanup = 0
-                code.put_gotref(self.starstar_arg.entry.cname)
+                code.put_var_gotref(self.starstar_arg.entry)
+            self.starstar_arg.entry.xdecref_cleanup = allow_null
+            code.putln("}")
 
         if self.self_in_stararg and not self.target.is_staticmethod:
@@ -3584,3 +3698,4 @@
 
         if self.self_in_stararg and not self.target.is_staticmethod:
+            assert not self.signature.use_fastcall
             # need to create a new tuple with 'self' inserted as first item
@@ -3586,3 +3701,3 @@
             # need to create a new tuple with 'self' inserted as first item
-            code.put("%s = PyTuple_New(PyTuple_GET_SIZE(%s)+1); if (unlikely(!%s)) " % (
+            code.put("%s = PyTuple_New(%s + 1); if (unlikely(!%s)) " % (
                 self.star_arg.entry.cname,
@@ -3588,5 +3703,5 @@
                 self.star_arg.entry.cname,
-                Naming.args_cname,
+                Naming.nargs_cname,
                 self.star_arg.entry.cname))
             if self.starstar_arg and self.starstar_arg.entry.cf_used:
                 code.putln("{")
@@ -3590,8 +3705,8 @@
                 self.star_arg.entry.cname))
             if self.starstar_arg and self.starstar_arg.entry.cf_used:
                 code.putln("{")
-                code.put_xdecref_clear(self.starstar_arg.entry.cname, py_object_type)
+                code.put_var_xdecref_clear(self.starstar_arg.entry)
                 code.putln("return %s;" % self.error_value())
                 code.putln("}")
             else:
                 code.putln("return %s;" % self.error_value())
@@ -3594,6 +3709,6 @@
                 code.putln("return %s;" % self.error_value())
                 code.putln("}")
             else:
                 code.putln("return %s;" % self.error_value())
-            code.put_gotref(self.star_arg.entry.cname)
+            code.put_var_gotref(self.star_arg.entry)
             code.put_incref(Naming.self_cname, py_object_type)
@@ -3599,5 +3714,5 @@
             code.put_incref(Naming.self_cname, py_object_type)
-            code.put_giveref(Naming.self_cname)
+            code.put_giveref(Naming.self_cname, py_object_type)
             code.putln("PyTuple_SET_ITEM(%s, 0, %s);" % (
                 self.star_arg.entry.cname, Naming.self_cname))
             temp = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
@@ -3601,8 +3716,8 @@
             code.putln("PyTuple_SET_ITEM(%s, 0, %s);" % (
                 self.star_arg.entry.cname, Naming.self_cname))
             temp = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
-            code.putln("for (%s=0; %s < PyTuple_GET_SIZE(%s); %s++) {" % (
-                temp, temp, Naming.args_cname, temp))
+            code.putln("for (%s=0; %s < %s; %s++) {" % (
+                temp, temp, Naming.nargs_cname, temp))
             code.putln("PyObject* item = PyTuple_GET_ITEM(%s, %s);" % (
                 Naming.args_cname, temp))
             code.put_incref("item", py_object_type)
@@ -3606,10 +3721,10 @@
             code.putln("PyObject* item = PyTuple_GET_ITEM(%s, %s);" % (
                 Naming.args_cname, temp))
             code.put_incref("item", py_object_type)
-            code.put_giveref("item")
+            code.put_giveref("item", py_object_type)
             code.putln("PyTuple_SET_ITEM(%s, %s+1, item);" % (
                 self.star_arg.entry.cname, temp))
             code.putln("}")
             code.funcstate.release_temp(temp)
             self.star_arg.entry.xdecref_cleanup = 0
         elif self.star_arg:
@@ -3610,9 +3725,10 @@
             code.putln("PyTuple_SET_ITEM(%s, %s+1, item);" % (
                 self.star_arg.entry.cname, temp))
             code.putln("}")
             code.funcstate.release_temp(temp)
             self.star_arg.entry.xdecref_cleanup = 0
         elif self.star_arg:
+            assert not self.signature.use_fastcall
             code.put_incref(Naming.args_cname, py_object_type)
             code.putln("%s = %s;" % (
                 self.star_arg.entry.cname,
@@ -3620,8 +3736,13 @@
             self.star_arg.entry.xdecref_cleanup = 0
 
     def generate_tuple_and_keyword_parsing_code(self, args, success_label, code):
+        code.globalstate.use_utility_code(
+            UtilityCode.load_cached("fastcall", "FunctionArguments.c"))
+
+        self_name_csafe = self.name.as_c_string_literal()
+
         argtuple_error_label = code.new_label("argtuple_error")
 
         positional_args = []
         required_kw_only_args = []
         optional_kw_only_args = []
@@ -3623,8 +3744,9 @@
         argtuple_error_label = code.new_label("argtuple_error")
 
         positional_args = []
         required_kw_only_args = []
         optional_kw_only_args = []
+        num_pos_only_args = 0
         for arg in args:
             if arg.is_generic:
                 if arg.default:
@@ -3637,6 +3759,8 @@
                     required_kw_only_args.append(arg)
                 elif not arg.is_self_arg and not arg.is_type_arg:
                     positional_args.append(arg)
+                if arg.pos_only:
+                    num_pos_only_args += 1
 
         # sort required kw-only args before optional ones to avoid special
         # cases in the unpacking code
@@ -3655,5 +3779,9 @@
 
         code.putln('{')
         all_args = tuple(positional_args) + tuple(kw_only_args)
-        code.putln("static PyObject **%s[] = {%s,0};" % (
+        non_posonly_args = [arg for arg in all_args if not arg.pos_only]
+        non_pos_args_id = ','.join(
+            ['&%s' % code.intern_identifier(arg.entry.name) for arg in non_posonly_args] + ['0'])
+        code.putln("#if CYTHON_COMPILING_IN_LIMITED_API")
+        code.putln("PyObject **%s[] = {%s};" % (
             Naming.pykwdlist_cname,
@@ -3659,6 +3787,10 @@
             Naming.pykwdlist_cname,
-            ','.join(['&%s' % code.intern_identifier(arg.name)
-                      for arg in all_args])))
+            non_pos_args_id))
+        code.putln("#else")
+        code.putln("static PyObject **%s[] = {%s};" % (
+            Naming.pykwdlist_cname,
+            non_pos_args_id))
+        code.putln("#endif")
 
         # Before being converted and assigned to the target variables,
         # borrowed references to all unpacked argument values are
@@ -3670,4 +3802,19 @@
         # was passed for them.
         self.generate_argument_values_setup_code(all_args, code)
 
+        # If all args are positional-only, we can raise an error
+        # straight away if we receive a non-empty kw-dict.
+        # This requires a PyDict_Size call.  This call is wasteful
+        # for functions which do accept kw-args, so we do not generate
+        # the PyDict_Size call unless all args are positional-only.
+        accept_kwd_args = non_posonly_args or self.starstar_arg
+        if accept_kwd_args:
+            kw_unpacking_condition = Naming.kwds_cname
+        else:
+            kw_unpacking_condition = "%s && __Pyx_NumKwargs_%s(%s) > 0" % (
+                Naming.kwds_cname, self.signature.fastvar, Naming.kwds_cname)
+
+        if self.num_required_kw_args > 0:
+            kw_unpacking_condition = "likely(%s)" % kw_unpacking_condition
+
         # --- optimised code when we receive keyword arguments
@@ -3673,11 +3820,25 @@
         # --- optimised code when we receive keyword arguments
-        code.putln("if (%s(%s)) {" % (
-            (self.num_required_kw_args > 0) and "likely" or "unlikely",
-            Naming.kwds_cname))
-        self.generate_keyword_unpacking_code(
-            min_positional_args, max_positional_args,
-            has_fixed_positional_count, has_kw_only_args,
-            all_args, argtuple_error_label, code)
+        code.putln("if (%s) {" % kw_unpacking_condition)
+
+        if accept_kwd_args:
+            self.generate_keyword_unpacking_code(
+                min_positional_args, max_positional_args,
+                has_fixed_positional_count, has_kw_only_args, all_args, argtuple_error_label, code)
+        else:
+            # Here we do not accept kw-args but we are passed a non-empty kw-dict.
+            # We call ParseOptionalKeywords which will raise an appropriate error if
+            # the kw-args dict passed is non-empty (which it will be, since kw_unpacking_condition is true)
+            code.globalstate.use_utility_code(
+                UtilityCode.load_cached("ParseKeywords", "FunctionArguments.c"))
+            code.putln('if (likely(__Pyx_ParseOptionalKeywords(%s, %s, %s, %s, %s, %s, %s) < 0)) %s' % (
+                Naming.kwds_cname,
+                Naming.kwvalues_cname,
+                Naming.pykwdlist_cname,
+                self.starstar_arg.entry.cname if self.starstar_arg else 0,
+                'values',
+                0,
+                self_name_csafe,
+                code.error_goto(self.pos)))
 
         # --- optimised code when we do not receive any keyword arguments
         if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
@@ -3687,10 +3848,10 @@
                 compare = '!='
             else:
                 compare = '<'
-            code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
-                Naming.args_cname, compare, min_positional_args))
+            code.putln('} else if (unlikely(%s %s %d)) {' % (
+                Naming.nargs_cname, compare, min_positional_args))
             code.put_goto(argtuple_error_label)
 
         if self.num_required_kw_args:
             # pure error case: keywords required but not passed
             if max_positional_args > min_positional_args and not self.star_arg:
@@ -3692,11 +3853,11 @@
             code.put_goto(argtuple_error_label)
 
         if self.num_required_kw_args:
             # pure error case: keywords required but not passed
             if max_positional_args > min_positional_args and not self.star_arg:
-                code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
-                    Naming.args_cname, max_positional_args))
+                code.putln('} else if (unlikely(%s > %d)) {' % (
+                    Naming.nargs_cname, max_positional_args))
                 code.put_goto(argtuple_error_label)
             code.putln('} else {')
             for i, arg in enumerate(kw_only_args):
                 if not arg.default:
@@ -3699,8 +3860,8 @@
                 code.put_goto(argtuple_error_label)
             code.putln('} else {')
             for i, arg in enumerate(kw_only_args):
                 if not arg.default:
-                    pystring_cname = code.intern_identifier(arg.name)
+                    pystring_cname = code.intern_identifier(arg.entry.name)
                     # required keyword-only argument missing
                     code.globalstate.use_utility_code(
                         UtilityCode.load_cached("RaiseKeywordRequired", "FunctionArguments.c"))
@@ -3717,7 +3878,8 @@
                 # parse the exact number of positional arguments from
                 # the args tuple
                 for i, arg in enumerate(positional_args):
-                    code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (i, Naming.args_cname, i))
+                    code.putln("values[%d] = __Pyx_Arg_%s(%s, %d);" % (
+                            i, self.signature.fastvar, Naming.args_cname, i))
             else:
                 # parse the positional arguments from the variable length
                 # args tuple and reject illegal argument tuple sizes
@@ -3721,7 +3883,7 @@
             else:
                 # parse the positional arguments from the variable length
                 # args tuple and reject illegal argument tuple sizes
-                code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
+                code.putln('switch (%s) {' % Naming.nargs_cname)
                 if self.star_arg:
                     code.putln('default:')
                 reversed_args = list(enumerate(positional_args))[::-1]
@@ -3730,7 +3892,8 @@
                         if i != reversed_args[0][0]:
                             code.putln('CYTHON_FALLTHROUGH;')
                         code.put('case %2d: ' % (i+1))
-                    code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (i, Naming.args_cname, i))
+                    code.putln("values[%d] = __Pyx_Arg_%s(%s, %d);" % (
+                            i, self.signature.fastvar, Naming.args_cname, i))
                 if min_positional_args == 0:
                     code.putln('CYTHON_FALLTHROUGH;')
                     code.put('case  0: ')
@@ -3760,6 +3923,6 @@
             code.put_label(argtuple_error_label)
             code.globalstate.use_utility_code(
                 UtilityCode.load_cached("RaiseArgTupleInvalid", "FunctionArguments.c"))
-            code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
-                self.name, has_fixed_positional_count,
+            code.put('__Pyx_RaiseArgtupleInvalid(%s, %d, %d, %d, %s); ' % (
+                self_name_csafe, has_fixed_positional_count,
                 min_positional_args, max_positional_args,
@@ -3765,5 +3928,5 @@
                 min_positional_args, max_positional_args,
-                Naming.args_cname))
+                Naming.nargs_cname))
             code.putln(code.error_goto(self.pos))
 
     def generate_arg_assignment(self, arg, item, code):
@@ -3786,8 +3949,7 @@
                         arg.entry.cname,
                         arg.calculate_default_value_code(code)))
                     if arg.type.is_memoryviewslice:
-                        code.put_incref_memoryviewslice(arg.entry.cname,
-                                                        have_gil=True)
+                        code.put_var_incref_memoryviewslice(arg.entry, have_gil=True)
                     code.putln('}')
             else:
                 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
@@ -3799,6 +3961,6 @@
                 self.starstar_arg.entry.cname,
                 self.starstar_arg.entry.cname,
                 self.error_value()))
-            code.put_gotref(self.starstar_arg.entry.cname)
+            code.put_var_gotref(self.starstar_arg.entry)
         if self.star_arg:
             self.star_arg.entry.xdecref_cleanup = 0
@@ -3803,22 +3965,26 @@
         if self.star_arg:
             self.star_arg.entry.xdecref_cleanup = 0
-            code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
-                Naming.args_cname,
-                max_positional_args))
-            code.putln('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s));' % (
-                self.star_arg.entry.cname, Naming.args_cname,
-                max_positional_args, Naming.args_cname))
-            code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
-            if self.starstar_arg:
-                code.put_decref_clear(self.starstar_arg.entry.cname, py_object_type)
-            code.put_finish_refcount_context()
-            code.putln('return %s;' % self.error_value())
-            code.putln('}')
-            code.put_gotref(self.star_arg.entry.cname)
-            code.putln('} else {')
-            code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
-            code.put_incref(Naming.empty_tuple, py_object_type)
-            code.putln('}')
+            if max_positional_args == 0:
+                # If there are no positional arguments, use the args tuple
+                # directly
+                assert not self.signature.use_fastcall
+                code.put_incref(Naming.args_cname, py_object_type)
+                code.putln("%s = %s;" % (self.star_arg.entry.cname, Naming.args_cname))
+            else:
+                # It is possible that this is a slice of "negative" length,
+                # as in args[5:3]. That's not a problem, the function below
+                # handles that efficiently and returns the empty tuple.
+                code.putln('%s = __Pyx_ArgsSlice_%s(%s, %d, %s);' % (
+                    self.star_arg.entry.cname, self.signature.fastvar,
+                    Naming.args_cname, max_positional_args, Naming.nargs_cname))
+                code.putln("if (unlikely(!%s)) {" %
+                           self.star_arg.entry.type.nullcheck_string(self.star_arg.entry.cname))
+                if self.starstar_arg:
+                    code.put_var_decref_clear(self.starstar_arg.entry)
+                code.put_finish_refcount_context()
+                code.putln('return %s;' % self.error_value())
+                code.putln('}')
+                code.put_var_gotref(self.star_arg.entry)
 
     def generate_argument_values_setup_code(self, args, code):
         max_args = len(args)
@@ -3840,6 +4006,14 @@
                 code.putln('values[%d] = %s;' % (i, arg.type.as_pyobject(default_value)))
 
     def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
-                                        has_fixed_positional_count, has_kw_only_args,
-                                        all_args, argtuple_error_label, code):
+                                        has_fixed_positional_count,
+                                        has_kw_only_args, all_args, argtuple_error_label, code):
+        # First we count how many arguments must be passed as positional
+        num_required_posonly_args = num_pos_only_args = 0
+        for i, arg in enumerate(all_args):
+            if arg.pos_only:
+                num_pos_only_args += 1
+                if not arg.default:
+                    num_required_posonly_args += 1
+
         code.putln('Py_ssize_t kw_args;')
@@ -3845,3 +4019,2 @@
         code.putln('Py_ssize_t kw_args;')
-        code.putln('const Py_ssize_t pos_args = PyTuple_GET_SIZE(%s);' % Naming.args_cname)
         # copy the values from the args tuple and check that it's not too long
@@ -3847,4 +4020,4 @@
         # copy the values from the args tuple and check that it's not too long
-        code.putln('switch (pos_args) {')
+        code.putln('switch (%s) {' % Naming.nargs_cname)
         if self.star_arg:
             code.putln('default:')
@@ -3849,4 +4022,5 @@
         if self.star_arg:
             code.putln('default:')
-        for i in range(max_positional_args-1, -1, -1):
+
+        for i in range(max_positional_args-1, num_required_posonly_args-1, -1):
             code.put('case %2d: ' % (i+1))
@@ -3852,4 +4026,4 @@
             code.put('case %2d: ' % (i+1))
-            code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
-                i, Naming.args_cname, i))
+            code.putln("values[%d] = __Pyx_Arg_%s(%s, %d);" % (
+                i, self.signature.fastvar, Naming.args_cname, i))
             code.putln('CYTHON_FALLTHROUGH;')
@@ -3855,5 +4029,20 @@
             code.putln('CYTHON_FALLTHROUGH;')
-        code.putln('case  0: break;')
+        if num_required_posonly_args > 0:
+            code.put('case %2d: ' % num_required_posonly_args)
+            for i in range(num_required_posonly_args-1, -1, -1):
+                code.putln("values[%d] = __Pyx_Arg_%s(%s, %d);" % (
+                    i, self.signature.fastvar, Naming.args_cname, i))
+            code.putln('break;')
+        for i in range(num_required_posonly_args-2, -1, -1):
+            code.put('case %2d: ' % (i+1))
+            code.putln('CYTHON_FALLTHROUGH;')
+
+        code.put('case  0: ')
+        if num_required_posonly_args == 0:
+            code.putln('break;')
+        else:
+            # catch-all for not enough pos-only args passed
+            code.put_goto(argtuple_error_label)
         if not self.star_arg:
             code.put('default: ') # more arguments than allowed
             code.put_goto(argtuple_error_label)
@@ -3868,7 +4057,10 @@
 
         # If we received kwargs, fill up the positional/required
         # arguments with values from the kw dict
-        code.putln('kw_args = PyDict_Size(%s);' % Naming.kwds_cname)
+        self_name_csafe = self.name.as_c_string_literal()
+
+        code.putln('kw_args = __Pyx_NumKwargs_%s(%s);' % (
+                self.signature.fastvar, Naming.kwds_cname))
         if self.num_required_args or max_positional_args > 0:
             last_required_arg = -1
             for i, arg in enumerate(all_args):
@@ -3876,13 +4068,13 @@
                     last_required_arg = i
             if last_required_arg < max_positional_args:
                 last_required_arg = max_positional_args-1
-            if max_positional_args > 0:
-                code.putln('switch (pos_args) {')
-            for i, arg in enumerate(all_args[:last_required_arg+1]):
-                if max_positional_args > 0 and i <= max_positional_args:
-                    if i != 0:
+            if max_positional_args > num_pos_only_args:
+                code.putln('switch (%s) {' % Naming.nargs_cname)
+            for i, arg in enumerate(all_args[num_pos_only_args:last_required_arg+1], num_pos_only_args):
+                if max_positional_args > num_pos_only_args and i <= max_positional_args:
+                    if i != num_pos_only_args:
                         code.putln('CYTHON_FALLTHROUGH;')
                     if self.star_arg and i == max_positional_args:
                         code.putln('default:')
                     else:
                         code.putln('case %2d:' % i)
@@ -3884,12 +4076,12 @@
                         code.putln('CYTHON_FALLTHROUGH;')
                     if self.star_arg and i == max_positional_args:
                         code.putln('default:')
                     else:
                         code.putln('case %2d:' % i)
-                pystring_cname = code.intern_identifier(arg.name)
+                pystring_cname = code.intern_identifier(arg.entry.name)
                 if arg.default:
                     if arg.kw_only:
                         # optional kw-only args are handled separately below
                         continue
                     code.putln('if (kw_args > 0) {')
                     # don't overwrite default argument
@@ -3890,9 +4082,9 @@
                 if arg.default:
                     if arg.kw_only:
                         # optional kw-only args are handled separately below
                         continue
                     code.putln('if (kw_args > 0) {')
                     # don't overwrite default argument
-                    code.putln('PyObject* value = __Pyx_PyDict_GetItemStr(%s, %s);' % (
-                        Naming.kwds_cname, pystring_cname))
+                    code.putln('PyObject* value = __Pyx_GetKwValue_%s(%s, %s, %s);' % (
+                        self.signature.fastvar, Naming.kwds_cname, Naming.kwvalues_cname, pystring_cname))
                     code.putln('if (value) { values[%d] = value; kw_args--; }' % i)
@@ -3898,3 +4090,4 @@
                     code.putln('if (value) { values[%d] = value; kw_args--; }' % i)
+                    code.putln('else if (unlikely(PyErr_Occurred())) %s' % code.error_goto(self.pos))
                     code.putln('}')
                 else:
@@ -3899,7 +4092,8 @@
                     code.putln('}')
                 else:
-                    code.putln('if (likely((values[%d] = __Pyx_PyDict_GetItemStr(%s, %s)) != 0)) kw_args--;' % (
-                        i, Naming.kwds_cname, pystring_cname))
+                    code.putln('if (likely((values[%d] = __Pyx_GetKwValue_%s(%s, %s, %s)) != 0)) kw_args--;' % (
+                        i, self.signature.fastvar, Naming.kwds_cname, Naming.kwvalues_cname, pystring_cname))
+                    code.putln('else if (unlikely(PyErr_Occurred())) %s' % code.error_goto(self.pos))
                     if i < min_positional_args:
                         if i == 0:
                             # special case: we know arg 0 is missing
@@ -3912,8 +4106,8 @@
                             code.putln('else {')
                             code.globalstate.use_utility_code(
                                 UtilityCode.load_cached("RaiseArgTupleInvalid", "FunctionArguments.c"))
-                            code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
-                                self.name, has_fixed_positional_count,
+                            code.put('__Pyx_RaiseArgtupleInvalid(%s, %d, %d, %d, %d); ' % (
+                                self_name_csafe, has_fixed_positional_count,
                                 min_positional_args, max_positional_args, i))
                             code.putln(code.error_goto(self.pos))
                             code.putln('}')
@@ -3921,7 +4115,7 @@
                         code.putln('else {')
                         code.globalstate.use_utility_code(
                             UtilityCode.load_cached("RaiseKeywordRequired", "FunctionArguments.c"))
-                        code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
-                            self.name, pystring_cname))
+                        code.put('__Pyx_RaiseKeywordRequired(%s, %s); ' % (
+                            self_name_csafe, pystring_cname))
                         code.putln(code.error_goto(self.pos))
                         code.putln('}')
@@ -3926,6 +4120,6 @@
                         code.putln(code.error_goto(self.pos))
                         code.putln('}')
-            if max_positional_args > 0:
+            if max_positional_args > num_pos_only_args:
                 code.putln('}')
 
         if has_kw_only_args:
@@ -3941,6 +4135,23 @@
         # arguments, this will always do the right thing for unpacking
         # keyword arguments, so that we can concentrate on optimising
         # common cases above.
+        #
+        # ParseOptionalKeywords() needs to know how many of the arguments
+        # that could be passed as keywords have in fact been passed as
+        # positional args.
+        if num_pos_only_args > 0:
+            # There are positional-only arguments which we don't want to count,
+            # since they cannot be keyword arguments.  Subtract the number of
+            # pos-only arguments from the number of positional arguments we got.
+            # If we get a negative number then none of the keyword arguments were
+            # passed as positional args.
+            code.putln('const Py_ssize_t kwd_pos_args = (unlikely(%s < %d)) ? 0 : %s - %d;' % (
+                Naming.nargs_cname, num_pos_only_args,
+                Naming.nargs_cname, num_pos_only_args,
+            ))
+        elif max_positional_args > 0:
+            code.putln('const Py_ssize_t kwd_pos_args = %s;' % Naming.nargs_cname)
+
         if max_positional_args == 0:
             pos_arg_count = "0"
         elif self.star_arg:
@@ -3944,7 +4155,12 @@
         if max_positional_args == 0:
             pos_arg_count = "0"
         elif self.star_arg:
-            code.putln("const Py_ssize_t used_pos_args = (pos_args < %d) ? pos_args : %d;" % (
-                max_positional_args, max_positional_args))
+            # If there is a *arg, the number of used positional args could be larger than
+            # the number of possible keyword arguments.  But ParseOptionalKeywords() uses the
+            # number of positional args as an index into the keyword argument name array,
+            # if this is larger than the number of kwd args we get a segfault.  So round
+            # this down to max_positional_args - num_pos_only_args (= num possible kwd args).
+            code.putln("const Py_ssize_t used_pos_args = (kwd_pos_args < %d) ? kwd_pos_args : %d;" % (
+                max_positional_args - num_pos_only_args, max_positional_args - num_pos_only_args))
             pos_arg_count = "used_pos_args"
         else:
@@ -3949,5 +4165,9 @@
             pos_arg_count = "used_pos_args"
         else:
-            pos_arg_count = "pos_args"
+            pos_arg_count = "kwd_pos_args"
+        if num_pos_only_args < len(all_args):
+            values_array = 'values + %d' % num_pos_only_args
+        else:
+            values_array = 'values'
         code.globalstate.use_utility_code(
             UtilityCode.load_cached("ParseKeywords", "FunctionArguments.c"))
@@ -3952,4 +4172,4 @@
         code.globalstate.use_utility_code(
             UtilityCode.load_cached("ParseKeywords", "FunctionArguments.c"))
-        code.putln('if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) %s' % (
+        code.putln('if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, %s, %s, %s, %s) < 0)) %s' % (
             Naming.kwds_cname,
@@ -3955,3 +4175,4 @@
             Naming.kwds_cname,
+            Naming.kwvalues_cname,
             Naming.pykwdlist_cname,
             self.starstar_arg and self.starstar_arg.entry.cname or '0',
@@ -3956,3 +4177,4 @@
             Naming.pykwdlist_cname,
             self.starstar_arg and self.starstar_arg.entry.cname or '0',
+            values_array,
             pos_arg_count,
@@ -3958,8 +4180,8 @@
             pos_arg_count,
-            self.name,
+            self_name_csafe,
             code.error_goto(self.pos)))
         code.putln('}')
 
     def generate_optional_kwonly_args_unpacking_code(self, all_args, code):
         optional_args = []
         first_optional_arg = -1
@@ -3960,7 +4182,8 @@
             code.error_goto(self.pos)))
         code.putln('}')
 
     def generate_optional_kwonly_args_unpacking_code(self, all_args, code):
         optional_args = []
         first_optional_arg = -1
+        num_posonly_args = 0
         for i, arg in enumerate(all_args):
@@ -3966,6 +4189,8 @@
         for i, arg in enumerate(all_args):
+            if arg.pos_only:
+                num_posonly_args += 1
             if not arg.kw_only or not arg.default:
                 continue
             if not optional_args:
                 first_optional_arg = i
             optional_args.append(arg.name)
@@ -3967,8 +4192,12 @@
             if not arg.kw_only or not arg.default:
                 continue
             if not optional_args:
                 first_optional_arg = i
             optional_args.append(arg.name)
+        if num_posonly_args > 0:
+            posonly_correction = '-%d' % num_posonly_args
+        else:
+            posonly_correction = ''
         if optional_args:
             if len(optional_args) > 1:
                 # if we receive more than the named kwargs, we either have **kwargs
@@ -3984,6 +4213,10 @@
             else:
                 code.putln('if (kw_args == 1) {')
                 code.putln('const Py_ssize_t index = %d;' % first_optional_arg)
-            code.putln('PyObject* value = __Pyx_PyDict_GetItemStr(%s, *%s[index]);' % (
-                Naming.kwds_cname, Naming.pykwdlist_cname))
+            code.putln('PyObject* value = __Pyx_GetKwValue_%s(%s, %s, *%s[index%s]);' % (
+                self.signature.fastvar,
+                Naming.kwds_cname,
+                Naming.kwvalues_cname,
+                Naming.pykwdlist_cname,
+                posonly_correction))
             code.putln('if (value) { values[index] = value; kw_args--; }')
@@ -3989,4 +4222,5 @@
             code.putln('if (value) { values[index] = value; kw_args--; }')
+            code.putln('else if (unlikely(PyErr_Occurred())) %s' % code.error_goto(self.pos))
             if len(optional_args) > 1:
                 code.putln('}')
             code.putln('}')
@@ -4104,7 +4338,7 @@
             code.putln('%s = __Pyx_CyFunction_GetClassObj(%s);' % (
                 classobj_cname, Naming.self_cname))
             code.put_incref(classobj_cname, py_object_type)
-            code.put_giveref(classobj_cname)
+            code.put_giveref(classobj_cname, py_object_type)
         code.put_finish_refcount_context()
         code.putln('return (PyObject *) gen;')
         code.putln('}')
@@ -4224,7 +4458,7 @@
             code.putln("%s = %s; %s" % (
                 Naming.retval_cname, comp_init,
                 code.error_goto_if_null(Naming.retval_cname, self.pos)))
-            code.put_gotref(Naming.retval_cname)
+            code.put_gotref(Naming.retval_cname, py_object_type)
 
         # ----- Function body
         self.generate_function_body(env, code)
@@ -4270,7 +4504,7 @@
         # ----- Non-error return cleanup
         code.put_label(code.return_label)
         if self.is_inlined:
-            code.put_xgiveref(Naming.retval_cname)
+            code.put_xgiveref(Naming.retval_cname, py_object_type)
         else:
             code.put_xdecref_clear(Naming.retval_cname, py_object_type)
         # For Py3.7, clearing is already done below.
@@ -4386,7 +4620,7 @@
         err = code.error_goto_if_null(func_node_temp, self.pos)
         code.putln("%s = __Pyx_PyObject_GetAttrStr(%s, %s); %s" % (
             func_node_temp, self_arg, interned_attr_cname, err))
-        code.put_gotref(func_node_temp)
+        code.put_gotref(func_node_temp, py_object_type)
 
         is_builtin_function_or_method = "PyCFunction_Check(%s)" % func_node_temp
         is_overridden = "(PyCFunction_GET_FUNCTION(%s) != (PyCFunction)(void*)%s)" % (
@@ -4433,7 +4667,7 @@
     #  A Python class definition.
     #
     #  name     EncodedString   Name of the class
-    #  doc      string or None
+    #  doc      string or None  The class docstring
     #  body     StatNode        Attribute definition code
     #  entry    Symtab.Entry
     #  scope    PyClassScope
@@ -4441,7 +4675,8 @@
     #
     #  The following subnodes are constructed internally:
     #
+    #  doc_node NameNode   '__doc__' name that is made available to the class body
     #  dict     DictNode   Class dictionary or Py3 namespace
     #  classobj ClassNode  Class object
     #  target   NameNode   Variable to assign class object to
 
@@ -4444,11 +4679,11 @@
     #  dict     DictNode   Class dictionary or Py3 namespace
     #  classobj ClassNode  Class object
     #  target   NameNode   Variable to assign class object to
 
-    child_attrs = ["body", "dict", "metaclass", "mkw", "bases", "class_result",
+    child_attrs = ["doc_node", "body", "dict", "metaclass", "mkw", "bases", "class_result",
                    "target", "class_cell", "decorators"]
     decorators = None
     class_result = None
     is_py3_style_class = False  # Python3 style class (kwargs)
     metaclass = None
     mkw = None
@@ -4449,9 +4684,10 @@
                    "target", "class_cell", "decorators"]
     decorators = None
     class_result = None
     is_py3_style_class = False  # Python3 style class (kwargs)
     metaclass = None
     mkw = None
+    doc_node = None
 
     def __init__(self, pos, name, bases, doc, body, decorators=None,
                  keyword_args=None, force_py3_semantics=False):
@@ -4465,6 +4701,7 @@
         if self.doc and Options.docstrings:
             doc = embed_position(self.pos, self.doc)
             doc_node = ExprNodes.StringNode(pos, value=doc)
+            self.doc_node = ExprNodes.NameNode(name=EncodedString('__doc__'), type=py_object_type, pos=pos)
         else:
             doc_node = None
 
@@ -4513,7 +4750,9 @@
             self.classobj = ExprNodes.Py3ClassNode(
                 pos, name=name, class_def_node=self, doc=doc_node,
                 calculate_metaclass=needs_metaclass_calculation,
-                allow_py2_metaclass=allow_py2_metaclass)
+                allow_py2_metaclass=allow_py2_metaclass,
+                force_type=force_py3_semantics,
+            )
         else:
             # no bases, no metaclass => old style class creation
             self.dict = ExprNodes.DictNode(pos, key_value_pairs=[])
@@ -4569,6 +4808,8 @@
         cenv = self.create_scope(env)
         cenv.directives = env.directives
         cenv.class_obj_cname = self.target.entry.cname
+        if self.doc_node:
+            self.doc_node.analyse_target_declaration(cenv)
         self.body.analyse_declarations(cenv)
 
     def analyse_expressions(self, env):
@@ -4667,6 +4908,10 @@
     decorators = None
     shadow = False
 
+    @property
+    def punycode_class_name(self):
+        return punycodify_name(self.class_name)
+
     def buffer_defaults(self, env):
         if not hasattr(self, '_buffer_defaults'):
             from . import Buffer
@@ -4858,8 +5103,6 @@
         # This is needed to generate evaluation code for
         # default values of method arguments.
         code.mark_pos(self.pos)
-        if self.body:
-            self.body.generate_execution_code(code)
         if not self.entry.type.early_init:
             if self.type_init_args:
                 self.type_init_args.generate_evaluation_code(code)
@@ -4870,7 +5113,7 @@
                 code.putln("%s = PyType_Type.tp_new(&PyType_Type, %s, NULL);" % (
                     trial_type, self.type_init_args.result()))
                 code.putln(code.error_goto_if_null(trial_type, self.pos))
-                code.put_gotref(trial_type)
+                code.put_gotref(trial_type, py_object_type)
                 code.putln("if (((PyTypeObject*) %s)->tp_base != %s) {" % (
                     trial_type, first_base))
                 code.putln("PyErr_Format(PyExc_TypeError, \"best base '%s' must be equal to first base '%s'\",")
@@ -4880,10 +5123,10 @@
                 code.putln("}")
                 code.funcstate.release_temp(trial_type)
                 code.put_incref(bases, PyrexTypes.py_object_type)
-                code.put_giveref(bases)
+                code.put_giveref(bases, py_object_type)
                 code.putln("%s.tp_bases = %s;" % (self.entry.type.typeobj_cname, bases))
                 code.put_decref_clear(trial_type, PyrexTypes.py_object_type)
                 self.type_init_args.generate_disposal_code(code)
                 self.type_init_args.free_temps(code)
 
             self.generate_type_ready_code(self.entry, code, True)
@@ -4884,9 +5127,11 @@
                 code.putln("%s.tp_bases = %s;" % (self.entry.type.typeobj_cname, bases))
                 code.put_decref_clear(trial_type, PyrexTypes.py_object_type)
                 self.type_init_args.generate_disposal_code(code)
                 self.type_init_args.free_temps(code)
 
             self.generate_type_ready_code(self.entry, code, True)
+        if self.body:
+            self.body.generate_execution_code(code)
 
     # Also called from ModuleNode for early init types.
     @staticmethod
@@ -4899,6 +5144,31 @@
         if not scope:  # could be None if there was an error
             return
         if entry.visibility != 'extern':
+            code.putln("#if CYTHON_COMPILING_IN_LIMITED_API")
+            tuple_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
+            base_type = scope.parent_type.base_type
+            if base_type:
+                code.putln(
+                    "%s = PyTuple_Pack(1, (PyObject *)%s); %s" % (
+                    tuple_temp,
+                    base_type.typeptr_cname,
+                    code.error_goto_if_null(tuple_temp, entry.pos)))
+                code.put_gotref(tuple_temp, py_object_type)
+                code.putln(
+                    "%s = PyType_FromSpecWithBases(&%s_spec, %s); %s" % (
+                        typeobj_cname,
+                        typeobj_cname,
+                        tuple_temp,
+                        code.error_goto_if_null(typeobj_cname, entry.pos)))
+                code.put_xdecref_clear(tuple_temp, type=py_object_type)
+                code.funcstate.release_temp(tuple_temp)
+            else:
+                code.putln(
+                    "%s = PyType_FromSpec(&%s_spec); %s" % (
+                        typeobj_cname,
+                        typeobj_cname,
+                        code.error_goto_if_null(typeobj_cname, entry.pos)))
+            code.putln("#else")
             for slot in TypeSlots.slot_table:
                 slot.generate_dynamic_init_code(scope, code)
             if heap_type_bases:
@@ -4912,6 +5182,6 @@
                     readyfunc,
                     typeobj_cname,
                     code.error_goto(entry.pos)))
-            # Don't inherit tp_print from builtin types, restoring the
+            # Don't inherit tp_print from builtin types in Python 2, restoring the
             # behavior of using tp_repr or tp_str instead.
             # ("tp_print" was renamed to "tp_vectorcall_offset" in Py3.8b1)
@@ -4916,6 +5186,6 @@
             # behavior of using tp_repr or tp_str instead.
             # ("tp_print" was renamed to "tp_vectorcall_offset" in Py3.8b1)
-            code.putln("#if PY_VERSION_HEX < 0x030800B1")
+            code.putln("#if PY_MAJOR_VERSION < 3")
             code.putln("%s.tp_print = 0;" % typeobj_cname)
             code.putln("#endif")
 
@@ -4937,6 +5207,7 @@
                 code.putln("%s.tp_getattro = %s;" % (
                     typeobj_cname, py_cfunc))
                 code.putln("}")
+            code.putln("#endif")
 
             # Fix special method docstrings. This is a bit of a hack, but
             # unless we let PyType_Ready create the slot wrappers we have
@@ -4957,7 +5228,7 @@
                             func.name,
                             code.error_goto_if_null('wrapper', entry.pos)))
                     code.putln(
-                        "if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) {")
+                        "if (__Pyx_IS_TYPE(wrapper, &PyWrapperDescr_Type)) {")
                     code.putln(
                         "%s = *((PyWrapperDescrObject *)wrapper)->d_base;" % (
                             func.wrapperbase_cname))
@@ -4974,8 +5245,15 @@
             if type.vtable_cname:
                 code.globalstate.use_utility_code(
                     UtilityCode.load_cached('SetVTable', 'ImportExport.c'))
+                code.putln("#if CYTHON_COMPILING_IN_LIMITED_API")
+                code.putln(
+                    "if (__Pyx_SetVtable(%s, %s) < 0) %s" % (
+                        typeobj_cname,
+                        type.vtabptr_cname,
+                        code.error_goto(entry.pos)))
+                code.putln("#else")
                 code.putln(
                     "if (__Pyx_SetVtable(%s.tp_dict, %s) < 0) %s" % (
                         typeobj_cname,
                         type.vtabptr_cname,
                         code.error_goto(entry.pos)))
@@ -4977,8 +5255,9 @@
                 code.putln(
                     "if (__Pyx_SetVtable(%s.tp_dict, %s) < 0) %s" % (
                         typeobj_cname,
                         type.vtabptr_cname,
                         code.error_goto(entry.pos)))
+                code.putln("#endif")
                 if heap_type_bases:
                     code.globalstate.use_utility_code(
                         UtilityCode.load_cached('MergeVTables', 'ImportExport.c'))
@@ -4989,9 +5268,17 @@
                 # scope.is_internal is set for types defined by
                 # Cython (such as closures), the 'internal'
                 # directive is set by users
+                code.putln("#if CYTHON_COMPILING_IN_LIMITED_API")
+                code.putln(
+                    'if (PyObject_SetAttr(%s, %s, %s) < 0) %s' % (
+                        Naming.module_cname,
+                        code.intern_identifier(scope.class_name),
+                        typeobj_cname,
+                        code.error_goto(entry.pos)))
+                code.putln("#else")
                 code.putln(
                     'if (PyObject_SetAttr(%s, %s, (PyObject *)&%s) < 0) %s' % (
                         Naming.module_cname,
                         code.intern_identifier(scope.class_name),
                         typeobj_cname,
                         code.error_goto(entry.pos)))
@@ -4992,9 +5279,10 @@
                 code.putln(
                     'if (PyObject_SetAttr(%s, %s, (PyObject *)&%s) < 0) %s' % (
                         Naming.module_cname,
                         code.intern_identifier(scope.class_name),
                         typeobj_cname,
                         code.error_goto(entry.pos)))
+                code.putln("#endif")
             weakref_entry = scope.lookup_here("__weakref__") if not scope.is_closure_class_scope else None
             if weakref_entry:
                 if weakref_entry.type is py_object_type:
@@ -5016,6 +5304,7 @@
                 # do so at runtime.
                 code.globalstate.use_utility_code(
                     UtilityCode.load_cached('SetupReduce', 'ExtensionTypes.c'))
+                code.putln("#if !CYTHON_COMPILING_IN_LIMITED_API")
                 code.putln('if (__Pyx_setup_reduce((PyObject*)&%s) < 0) %s' % (
                               typeobj_cname,
                               code.error_goto(entry.pos)))
@@ -5019,6 +5308,7 @@
                 code.putln('if (__Pyx_setup_reduce((PyObject*)&%s) < 0) %s' % (
                               typeobj_cname,
                               code.error_goto(entry.pos)))
+                code.putln("#endif")
         # Generate code to initialise the typeptr of an extension
         # type defined in this module to point to its type object.
         if type.typeobj_cname:
@@ -5022,6 +5312,11 @@
         # Generate code to initialise the typeptr of an extension
         # type defined in this module to point to its type object.
         if type.typeobj_cname:
+            code.putln("#if CYTHON_COMPILING_IN_LIMITED_API")
+            code.putln(
+                "%s = (PyTypeObject *)%s;" % (
+                    type.typeptr_cname, type.typeobj_cname))
+            code.putln("#else")
             code.putln(
                 "%s = &%s;" % (
                     type.typeptr_cname, type.typeobj_cname))
@@ -5025,6 +5320,7 @@
             code.putln(
                 "%s = &%s;" % (
                     type.typeptr_cname, type.typeobj_cname))
+            code.putln("#endif")
 
     def annotate(self, code):
         if self.type_init_args:
@@ -5811,7 +6107,7 @@
             arg.free_temps(code)
         code.putln(
             code.error_goto_if_null(temp_result, self.pos))
-        code.put_gotref(temp_result)
+        code.put_gotref(temp_result, py_object_type)
         code.put_decref_clear(temp_result, py_object_type)
         code.funcstate.release_temp(temp_result)
 
@@ -6054,6 +6350,8 @@
 
     child_attrs = ["exc_type", "exc_value", "exc_tb", "cause"]
     is_terminator = True
+    builtin_exc_name = None
+    wrap_tuple_value = False
 
     def analyse_expressions(self, env):
         if self.exc_type:
@@ -6061,6 +6359,12 @@
             self.exc_type = exc_type.coerce_to_pyobject(env)
         if self.exc_value:
             exc_value = self.exc_value.analyse_types(env)
+            if self.wrap_tuple_value:
+                if exc_value.type is Builtin.tuple_type or not exc_value.type.is_builtin_type:
+                    # prevent tuple values from being interpreted as argument value tuples
+                    from .ExprNodes import TupleNode
+                    exc_value = TupleNode(exc_value.pos, args=[exc_value.coerce_to_pyobject(env)], slow=True)
+                    exc_value = exc_value.analyse_types(env, skip_children=True)
             self.exc_value = exc_value.coerce_to_pyobject(env)
         if self.exc_tb:
             exc_tb = self.exc_tb.analyse_types(env)
@@ -6069,7 +6373,6 @@
             cause = self.cause.analyse_types(env)
             self.cause = cause.coerce_to_pyobject(env)
         # special cases for builtin exceptions
-        self.builtin_exc_name = None
         if self.exc_type and not self.exc_value and not self.exc_tb:
             exc = self.exc_type
             from . import ExprNodes
@@ -6164,6 +6467,6 @@
         vars = code.funcstate.exc_vars
         if vars:
             code.globalstate.use_utility_code(restore_exception_utility_code)
-            code.put_giveref(vars[0])
-            code.put_giveref(vars[1])
+            code.put_giveref(vars[0], py_object_type)
+            code.put_giveref(vars[1], py_object_type)
             # fresh exceptions may not have a traceback yet (-> finally!)
@@ -6169,5 +6472,5 @@
             # fresh exceptions may not have a traceback yet (-> finally!)
-            code.put_xgiveref(vars[2])
+            code.put_xgiveref(vars[2], py_object_type)
             code.putln("__Pyx_ErrRestoreWithState(%s, %s, %s);" % tuple(vars))
             for varname in vars:
                 code.put("%s = 0; " % varname)
@@ -6178,6 +6481,7 @@
                 UtilityCode.load_cached("ReRaiseException", "Exceptions.c"))
             code.putln("__Pyx_ReraiseException(); %s" % code.error_goto(self.pos))
 
+
 class AssertStatNode(StatNode):
     #  assert statement
     #
@@ -6181,9 +6485,16 @@
 class AssertStatNode(StatNode):
     #  assert statement
     #
-    #  cond    ExprNode
-    #  value   ExprNode or None
-
-    child_attrs = ["cond", "value"]
+    #  condition    ExprNode
+    #  value        ExprNode or None
+    #  exception    (Raise/GIL)StatNode   created from 'value' in PostParse transform
+
+    child_attrs = ["condition", "value", "exception"]
+    exception = None
+
+    def analyse_declarations(self, env):
+        assert self.value is None, "Message should have been replaced in PostParse()"
+        assert self.exception is not None, "Message should have been replaced in PostParse()"
+        self.exception.analyse_declarations(env)
 
     def analyse_expressions(self, env):
@@ -6188,14 +6499,6 @@
 
     def analyse_expressions(self, env):
-        self.cond = self.cond.analyse_boolean_expression(env)
-        if self.value:
-            value = self.value.analyse_types(env)
-            if value.type is Builtin.tuple_type or not value.type.is_builtin_type:
-                # prevent tuple values from being interpreted as argument value tuples
-                from .ExprNodes import TupleNode
-                value = TupleNode(value.pos, args=[value], slow=True)
-                self.value = value.analyse_types(env, skip_children=True).coerce_to_pyobject(env)
-            else:
-                self.value = value.coerce_to_pyobject(env)
+        self.condition = self.condition.analyse_temp_boolean_expression(env)
+        self.exception = self.exception.analyse_expressions(env)
         return self
 
@@ -6200,9 +6503,6 @@
         return self
 
-    nogil_check = Node.gil_error
-    gil_message = "Raising exception"
-
     def generate_execution_code(self, code):
         code.putln("#ifndef CYTHON_WITHOUT_ASSERTIONS")
         code.putln("if (unlikely(!Py_OptimizeFlag)) {")
         code.mark_pos(self.pos)
@@ -6205,6 +6505,6 @@
     def generate_execution_code(self, code):
         code.putln("#ifndef CYTHON_WITHOUT_ASSERTIONS")
         code.putln("if (unlikely(!Py_OptimizeFlag)) {")
         code.mark_pos(self.pos)
-        self.cond.generate_evaluation_code(code)
+        self.condition.generate_evaluation_code(code)
         code.putln(
@@ -6210,15 +6510,5 @@
         code.putln(
-            "if (unlikely(!%s)) {" % self.cond.result())
-        if self.value:
-            self.value.generate_evaluation_code(code)
-            code.putln(
-                "PyErr_SetObject(PyExc_AssertionError, %s);" % self.value.py_result())
-            self.value.generate_disposal_code(code)
-            self.value.free_temps(code)
-        else:
-            code.putln(
-                "PyErr_SetNone(PyExc_AssertionError);")
-        code.putln(
-            code.error_goto(self.pos))
+            "if (unlikely(!%s)) {" % self.condition.result())
+        self.exception.generate_execution_code(code)
         code.putln(
             "}")
@@ -6223,6 +6513,6 @@
         code.putln(
             "}")
-        self.cond.generate_disposal_code(code)
-        self.cond.free_temps(code)
+        self.condition.generate_disposal_code(code)
+        self.condition.free_temps(code)
         code.putln(
             "}")
@@ -6227,5 +6517,8 @@
         code.putln(
             "}")
+        code.putln("#else")
+        # avoid unused labels etc.
+        code.putln("if ((1)); else %s" % code.error_goto(self.pos, used=False))
         code.putln("#endif")
 
     def generate_function_definitions(self, env, code):
@@ -6229,8 +6522,7 @@
         code.putln("#endif")
 
     def generate_function_definitions(self, env, code):
-        self.cond.generate_function_definitions(env, code)
-        if self.value is not None:
-            self.value.generate_function_definitions(env, code)
+        self.condition.generate_function_definitions(env, code)
+        self.exception.generate_function_definitions(env, code)
 
     def annotate(self, code):
@@ -6235,8 +6527,7 @@
 
     def annotate(self, code):
-        self.cond.annotate(code)
-        if self.value:
-            self.value.annotate(code)
+        self.condition.annotate(code)
+        self.exception.annotate(code)
 
 
 class IfStatNode(StatNode):
@@ -6263,9 +6554,6 @@
         code.mark_pos(self.pos)
         end_label = code.new_label()
         last = len(self.if_clauses)
-        if self.else_clause:
-            # If the 'else' clause is 'unlikely', then set the preceding 'if' clause to 'likely' to reflect that.
-            self._set_branch_hint(self.if_clauses[-1], self.else_clause, inverse=True)
-        else:
+        if not self.else_clause:
             last -= 1  # avoid redundant goto at end of last if-clause
         for i, if_clause in enumerate(self.if_clauses):
@@ -6270,6 +6558,5 @@
             last -= 1  # avoid redundant goto at end of last if-clause
         for i, if_clause in enumerate(self.if_clauses):
-            self._set_branch_hint(if_clause, if_clause.body)
             if_clause.generate_execution_code(code, end_label, is_last=i == last)
         if self.else_clause:
             code.mark_pos(self.else_clause.pos)
@@ -6278,21 +6565,6 @@
             code.putln("}")
         code.put_label(end_label)
 
-    def _set_branch_hint(self, clause, statements_node, inverse=False):
-        if not statements_node.is_terminator:
-            return
-        if not isinstance(statements_node, StatListNode) or not statements_node.stats:
-            return
-        # Anything that unconditionally raises exceptions should be considered unlikely.
-        if isinstance(statements_node.stats[-1], (RaiseStatNode, ReraiseStatNode)):
-            if len(statements_node.stats) > 1:
-                # Allow simple statements before the 'raise', but no conditions, loops, etc.
-                non_branch_nodes = (ExprStatNode, AssignmentNode, DelStatNode, GlobalNode, NonlocalNode)
-                for node in statements_node.stats[:-1]:
-                    if not isinstance(node, non_branch_nodes):
-                        return
-            clause.branch_hint = 'likely' if inverse else 'unlikely'
-
     def generate_function_definitions(self, env, code):
         for clause in self.if_clauses:
             clause.generate_function_definitions(env, code)
@@ -6576,7 +6848,7 @@
 
         # evaluate all coercions before the assignments
         for var, result, target in assignments:
-            code.put_gotref(var.result())
+            var.generate_gotref(code)
         for var, result, target in assignments:
             result.generate_evaluation_code(code)
         for var, result, target in assignments:
@@ -6638,7 +6910,7 @@
         code.funcstate.release_temp(result_temp)
 
         # evaluate all coercions before the assignments
-        code.put_gotref(value_ref.result())
+        value_ref.generate_gotref(code)
         self.coerced_value_var.generate_evaluation_code(code)
         self.value_target.generate_assignment_code(self.coerced_value_var, code)
         value_ref.release(code)
@@ -6951,7 +7223,7 @@
                     target_node.result(),
                     interned_cname,
                     code.error_goto_if_null(target_node.result(), self.target.pos)))
-                code.put_gotref(target_node.result())
+                target_node.generate_gotref(code)
             else:
                 target_node = self.target
             from_py_node = ExprNodes.CoerceFromPyTypeNode(
@@ -7087,7 +7359,7 @@
             code.intern_identifier(EncodedString('__aexit__' if self.is_async else '__exit__')),
             code.error_goto_if_null(self.exit_var, self.pos),
             ))
-        code.put_gotref(self.exit_var)
+        code.put_gotref(self.exit_var, py_object_type)
 
         # need to free exit_var in the face of exceptions during setup
         old_error_label = code.new_error_label()
@@ -7231,7 +7503,7 @@
             save_exc.putln("__Pyx_ExceptionSave(%s);" % (
                 ', '.join(['&%s' % var for var in exc_save_vars])))
             for var in exc_save_vars:
-                save_exc.put_xgotref(var)
+                save_exc.put_xgotref(var, py_object_type)
 
             def restore_saved_exception():
                 for name in exc_save_vars:
@@ -7235,7 +7507,7 @@
 
             def restore_saved_exception():
                 for name in exc_save_vars:
-                    code.put_xgiveref(name)
+                    code.put_xgiveref(name, py_object_type)
                 code.putln("__Pyx_ExceptionReset(%s);" %
                            ', '.join(exc_save_vars))
         else:
@@ -7437,7 +7709,7 @@
         code.putln("if (__Pyx_GetException(%s) < 0) %s" % (
             exc_args, code.error_goto(self.pos)))
         for var in exc_vars:
-            code.put_gotref(var)
+            code.put_gotref(var, py_object_type)
         if self.target:
             self.exc_value.set_var(exc_vars[1])
             self.exc_value.generate_evaluation_code(code)
@@ -7716,7 +7988,7 @@
                    " unlikely(__Pyx_GetException(&%s, &%s, &%s) < 0)) "
                    "__Pyx_ErrFetch(&%s, &%s, &%s);" % (exc_vars[:3] * 2))
         for var in exc_vars:
-            code.put_xgotref(var)
+            code.put_xgotref(var, py_object_type)
         if exc_lineno_cnames:
             code.putln("%s = %s; %s = %s; %s = %s;" % (
                 exc_lineno_cnames[0], Naming.lineno_cname,
@@ -7737,7 +8009,7 @@
         # unused utility functions and/or temps
         code.putln("if (PY_MAJOR_VERSION >= 3) {")
         for var in exc_vars[3:]:
-            code.put_xgiveref(var)
+            code.put_xgiveref(var, py_object_type)
         code.putln("__Pyx_ExceptionReset(%s, %s, %s);" % exc_vars[3:])
         code.putln("}")
         for var in exc_vars[:3]:
@@ -7741,7 +8013,7 @@
         code.putln("__Pyx_ExceptionReset(%s, %s, %s);" % exc_vars[3:])
         code.putln("}")
         for var in exc_vars[:3]:
-            code.put_xgiveref(var)
+            code.put_xgiveref(var, py_object_type)
         code.putln("__Pyx_ErrRestore(%s, %s, %s);" % exc_vars[:3])
 
         if self.is_try_finally_in_nogil:
@@ -7763,7 +8035,7 @@
         # unused utility functions and/or temps
         code.putln("if (PY_MAJOR_VERSION >= 3) {")
         for var in exc_vars[3:]:
-            code.put_xgiveref(var)
+            code.put_xgiveref(var, py_object_type)
         code.putln("__Pyx_ExceptionReset(%s, %s, %s);" % exc_vars[3:])
         code.putln("}")
         for var in exc_vars[:3]:
@@ -7791,5 +8063,6 @@
     #
     #   state   string   'gil' or 'nogil'
 
+    child_attrs = ["condition"] + NogilTryFinallyStatNode.child_attrs
     state_temp = None
 
@@ -7794,4 +8067,4 @@
     state_temp = None
 
-    def __init__(self, pos, state, body):
+    def __init__(self, pos, state, body, condition=None):
         self.state = state
@@ -7797,4 +8070,5 @@
         self.state = state
+        self.condition = condition
         self.create_state_temp_if_needed(pos, state, body)
         TryFinallyStatNode.__init__(
             self, pos,
@@ -7821,8 +8095,11 @@
         if self.state == 'gil':
             env.has_with_gil_block = True
 
+        if self.condition is not None:
+            self.condition.analyse_declarations(env)
+
         return super(GILStatNode, self).analyse_declarations(env)
 
     def analyse_expressions(self, env):
         env.use_utility_code(
             UtilityCode.load_cached("ForceInitThreads", "ModuleSetupCode.c"))
@@ -7824,8 +8101,12 @@
         return super(GILStatNode, self).analyse_declarations(env)
 
     def analyse_expressions(self, env):
         env.use_utility_code(
             UtilityCode.load_cached("ForceInitThreads", "ModuleSetupCode.c"))
+
+        if self.condition is not None:
+            self.condition = self.condition.analyse_expressions(env)
+
         was_nogil = env.nogil
         env.nogil = self.state == 'nogil'
         node = TryFinallyStatNode.analyse_expressions(self, env)
@@ -7912,6 +8193,33 @@
     'inspect': ("__Pyx_patch_inspect", "PatchInspect", "Coroutine.c"),
 }
 
+def cimport_numpy_check(node, code):
+    # shared code between CImportStatNode and FromCImportStatNode
+    # check to ensure that import_array is called
+    for mod in code.globalstate.module_node.scope.cimported_modules:
+        if mod.name != node.module_name:
+            continue
+        # there are sometimes several cimported modules with the same name
+        # so complete the loop if necessary
+        import_array = mod.lookup_here("import_array")
+        _import_array = mod.lookup_here("_import_array")
+        # at least one entry used
+        used = (import_array and import_array.used) or (_import_array and _import_array.used)
+        if ((import_array or _import_array) # at least one entry found
+                and not used):
+            # sanity check that this is actually numpy and not a user pxd called "numpy"
+            if _import_array and _import_array.type.is_cfunction:
+                # warning is mainly for the sake of testing
+                warning(node.pos, "'numpy.import_array()' has been added automatically "
+                        "since 'numpy' was cimported but 'numpy.import_array' was not called.", 0)
+                from .Code import TempitaUtilityCode
+                code.globalstate.use_utility_code(
+                         TempitaUtilityCode.load_cached("NumpyImportArray", "NumpyImportArray.c",
+                                            context = {'err_goto': code.error_goto(node.pos)})
+                    )
+                return # no need to continue once the utility code is added
+
+
 
 class CImportStatNode(StatNode):
     #  cimport statement
@@ -7953,7 +8261,8 @@
         return self
 
     def generate_execution_code(self, code):
-        pass
+        if self.module_name == "numpy":
+            cimport_numpy_check(self, code)
 
 
 class FromCImportStatNode(StatNode):
@@ -8032,7 +8341,8 @@
         return self
 
     def generate_execution_code(self, code):
-        pass
+        if self.module_name == "numpy":
+            cimport_numpy_check(self, code)
 
 
 class FromImportStatNode(StatNode):
@@ -8114,7 +8424,7 @@
                     self.module.py_result(),
                     code.intern_identifier(name),
                     code.error_goto_if_null(item_temp, self.pos)))
-            code.put_gotref(item_temp)
+            code.put_gotref(item_temp, py_object_type)
             if coerced_item is None:
                 target.generate_assignment_code(self.item, code)
             else:
@@ -8491,11 +8801,7 @@
         if self.is_parallel and not self.is_nested_prange:
             code.putln("/* Clean up any temporaries */")
             for temp, type in sorted(self.temps):
-                if type.is_memoryviewslice:
-                    code.put_xdecref_memoryviewslice(temp, have_gil=False)
-                elif type.is_pyobject:
-                    code.put_xdecref(temp, type)
-                    code.putln("%s = NULL;" % temp)
+                code.put_xdecref_clear(temp, type, have_gil=False)
 
     def setup_parallel_control_flow_block(self, code):
         """
@@ -8726,7 +9032,7 @@
         pos_info = chain(*zip(self.parallel_pos_info, self.pos_info))
         code.funcstate.uses_error_indicator = True
         code.putln("%s = %s; %s = %s; %s = %s;" % tuple(pos_info))
-        code.put_gotref(Naming.parallel_exc_type)
+        code.put_gotref(Naming.parallel_exc_type, py_object_type)
 
         code.putln(
             "}")
@@ -8739,7 +9045,7 @@
         code.begin_block()
         code.put_ensure_gil(declare_gilstate=True)
 
-        code.put_giveref(Naming.parallel_exc_type)
+        code.put_giveref(Naming.parallel_exc_type, py_object_type)
         code.putln("__Pyx_ErrRestoreWithState(%s, %s, %s);" % self.parallel_exc)
         pos_info = chain(*zip(self.pos_info, self.parallel_pos_info))
         code.putln("%s = %s; %s = %s; %s = %s;" % tuple(pos_info))
diff --git a/Cython/Compiler/Optimize.py b/Cython/Compiler/Optimize.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL09wdGltaXplLnB5..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL09wdGltaXplLnB5 100644
--- a/Cython/Compiler/Optimize.py
+++ b/Cython/Compiler/Optimize.py
@@ -1753,7 +1753,11 @@
             # Interestingly, PySequence_List works on a lot of non-sequence
             # things as well.
             list_node = loop_node = ExprNodes.PythonCapiCallNode(
-                node.pos, "PySequence_List", self.PySequence_List_func_type,
+                node.pos,
+                "__Pyx_PySequence_ListKeepNew"
+                    if arg.is_temp and arg.type in (PyrexTypes.py_object_type, Builtin.list_type)
+                    else "PySequence_List",
+                self.PySequence_List_func_type,
                 args=pos_args, is_temp=True)
 
         result_node = UtilNodes.ResultRefNode(
@@ -2312,6 +2316,38 @@
         return ExprNodes.CachedBuiltinMethodCallNode(
             node, function.obj, attr_name, arg_list)
 
+    PyObject_String_func_type = PyrexTypes.CFuncType(
+        PyrexTypes.py_object_type, [  # Change this to Builtin.str_type when removing Py2 support.
+            PyrexTypes.CFuncTypeArg("obj", PyrexTypes.py_object_type, None)
+            ])
+
+    def _handle_simple_function_str(self, node, function, pos_args):
+        """Optimize single argument calls to str().
+        """
+        if len(pos_args) != 1:
+            if len(pos_args) == 0:
+                return ExprNodes.StringNode(node.pos, value=EncodedString(), constant_result='')
+            return node
+        arg = pos_args[0]
+
+        if arg.type is Builtin.str_type:
+            if not arg.may_be_none():
+                return arg
+
+            cname = "__Pyx_PyStr_Str"
+            utility_code = UtilityCode.load_cached('PyStr_Str', 'StringTools.c')
+        else:
+            cname = '__Pyx_PyObject_Str'
+            utility_code = UtilityCode.load_cached('PyObject_Str', 'StringTools.c')
+
+        return ExprNodes.PythonCapiCallNode(
+            node.pos, cname, self.PyObject_String_func_type,
+            args=pos_args,
+            is_temp=node.is_temp,
+            utility_code=utility_code,
+            py_name="str"
+        )
+
     PyObject_Unicode_func_type = PyrexTypes.CFuncType(
         Builtin.unicode_type, [
             PyrexTypes.CFuncTypeArg("obj", PyrexTypes.py_object_type, None)
@@ -2383,8 +2419,14 @@
             return node
         arg = pos_args[0]
         return ExprNodes.PythonCapiCallNode(
-            node.pos, "PySequence_List", self.PySequence_List_func_type,
-            args=pos_args, is_temp=node.is_temp)
+            node.pos,
+            "__Pyx_PySequence_ListKeepNew"
+                if node.is_temp and arg.is_temp and arg.type in (PyrexTypes.py_object_type, Builtin.list_type)
+                else "PySequence_List",
+            self.PySequence_List_func_type,
+            args=pos_args,
+            is_temp=node.is_temp,
+        )
 
     PyList_AsTuple_func_type = PyrexTypes.CFuncType(
         Builtin.tuple_type, [
@@ -2557,6 +2599,13 @@
     Pyx_strlen_func_type = PyrexTypes.CFuncType(
         PyrexTypes.c_size_t_type, [
             PyrexTypes.CFuncTypeArg("bytes", PyrexTypes.c_const_char_ptr_type, None)
-        ])
+        ],
+        nogil=True)
+
+    Pyx_ssize_strlen_func_type = PyrexTypes.CFuncType(
+        PyrexTypes.c_py_ssize_t_type, [
+            PyrexTypes.CFuncTypeArg("bytes", PyrexTypes.c_const_char_ptr_type, None)
+        ],
+        exception_value="-1")
 
     Pyx_Py_UNICODE_strlen_func_type = PyrexTypes.CFuncType(
@@ -2561,4 +2610,4 @@
 
     Pyx_Py_UNICODE_strlen_func_type = PyrexTypes.CFuncType(
-        PyrexTypes.c_size_t_type, [
+        PyrexTypes.c_py_ssize_t_type, [
             PyrexTypes.CFuncTypeArg("unicode", PyrexTypes.c_const_py_unicode_ptr_type, None)
@@ -2564,5 +2613,6 @@
             PyrexTypes.CFuncTypeArg("unicode", PyrexTypes.c_const_py_unicode_ptr_type, None)
-        ])
+        ],
+        exception_value="-1")
 
     PyObject_Size_func_type = PyrexTypes.CFuncType(
         PyrexTypes.c_py_ssize_t_type, [
@@ -2596,6 +2646,6 @@
             arg = arg.arg
         if arg.type.is_string:
             new_node = ExprNodes.PythonCapiCallNode(
-                node.pos, "strlen", self.Pyx_strlen_func_type,
+                node.pos, "__Pyx_ssize_strlen", self.Pyx_ssize_strlen_func_type,
                 args = [arg],
                 is_temp = node.is_temp,
@@ -2600,5 +2650,5 @@
                 args = [arg],
                 is_temp = node.is_temp,
-                utility_code = UtilityCode.load_cached("IncludeStringH", "StringTools.c"))
+                utility_code = UtilityCode.load_cached("ssize_strlen", "StringTools.c"))
         elif arg.type.is_pyunicode_ptr:
             new_node = ExprNodes.PythonCapiCallNode(
@@ -2603,4 +2653,4 @@
         elif arg.type.is_pyunicode_ptr:
             new_node = ExprNodes.PythonCapiCallNode(
-                node.pos, "__Pyx_Py_UNICODE_strlen", self.Pyx_Py_UNICODE_strlen_func_type,
+                node.pos, "__Pyx_Py_UNICODE_ssize_strlen", self.Pyx_Py_UNICODE_strlen_func_type,
                 args = [arg],
@@ -2606,4 +2656,5 @@
                 args = [arg],
-                is_temp = node.is_temp)
+                is_temp = node.is_temp,
+                utility_code = UtilityCode.load_cached("ssize_pyunicode_strlen", "StringTools.c"))
         elif arg.type.is_memoryviewslice:
             func_type = PyrexTypes.CFuncType(
@@ -2608,6 +2659,6 @@
         elif arg.type.is_memoryviewslice:
             func_type = PyrexTypes.CFuncType(
-                PyrexTypes.c_size_t_type, [
+                PyrexTypes.c_py_ssize_t_type, [
                     PyrexTypes.CFuncTypeArg("memoryviewslice", arg.type, None)
                 ], nogil=True)
             new_node = ExprNodes.PythonCapiCallNode(
@@ -2777,6 +2828,5 @@
             return node
         type_arg = args[0]
         if not obj.is_name or not type_arg.is_name:
-            # play safe
-            return node
+            return node  # not a simple case
         if obj.type != Builtin.type_type or type_arg.type != Builtin.type_type:
@@ -2782,6 +2832,5 @@
         if obj.type != Builtin.type_type or type_arg.type != Builtin.type_type:
-            # not a known type, play safe
-            return node
+            return node  # not a known type
         if not type_arg.type_entry or not obj.type_entry:
             if obj.name != type_arg.name:
                 return node
@@ -3178,6 +3227,9 @@
     def _handle_simple_method_object___sub__(self, node, function, args, is_unbound_method):
         return self._optimise_num_binop('Subtract', node, function, args, is_unbound_method)
 
+    def _handle_simple_method_object___mul__(self, node, function, args, is_unbound_method):
+        return self._optimise_num_binop('Multiply', node, function, args, is_unbound_method)
+
     def _handle_simple_method_object___eq__(self, node, function, args, is_unbound_method):
         return self._optimise_num_binop('Eq', node, function, args, is_unbound_method)
 
@@ -3385,6 +3437,8 @@
             PyrexTypes.CFuncTypeArg("uchar", PyrexTypes.c_py_ucs4_type, None),
             ])
 
+    # DISABLED: Return value can only be one character, which is not correct.
+    '''
     def _inject_unicode_character_conversion(self, node, function, args, is_unbound_method):
         if is_unbound_method or len(args) != 1:
             return node
@@ -3403,9 +3457,10 @@
             func_call = func_call.coerce_to_pyobject(self.current_env)
         return func_call
 
-    _handle_simple_method_unicode_lower = _inject_unicode_character_conversion
-    _handle_simple_method_unicode_upper = _inject_unicode_character_conversion
-    _handle_simple_method_unicode_title = _inject_unicode_character_conversion
+    #_handle_simple_method_unicode_lower = _inject_unicode_character_conversion
+    #_handle_simple_method_unicode_upper = _inject_unicode_character_conversion
+    #_handle_simple_method_unicode_title = _inject_unicode_character_conversion
+    '''
 
     PyUnicode_Splitlines_func_type = PyrexTypes.CFuncType(
         Builtin.list_type, [
@@ -4418,5 +4473,5 @@
         args = []
         items = []
 
-        def add(arg):
+        def add(parent, arg):
             if arg.is_dict_literal:
@@ -4422,5 +4477,5 @@
             if arg.is_dict_literal:
-                if items:
-                    items[0].key_value_pairs.extend(arg.key_value_pairs)
+                if items and items[-1].reject_duplicates == arg.reject_duplicates:
+                    items[-1].key_value_pairs.extend(arg.key_value_pairs)
                 else:
                     items.append(arg)
@@ -4425,4 +4480,4 @@
                 else:
                     items.append(arg)
-            elif isinstance(arg, ExprNodes.MergedDictNode):
+            elif isinstance(arg, ExprNodes.MergedDictNode) and parent.reject_duplicates == arg.reject_duplicates:
                 for child_arg in arg.keyword_args:
@@ -4428,4 +4483,4 @@
                 for child_arg in arg.keyword_args:
-                    add(child_arg)
+                    add(arg, child_arg)
             else:
                 if items:
@@ -4430,7 +4485,7 @@
             else:
                 if items:
-                    args.append(items[0])
+                    args.extend(items)
                     del items[:]
                 args.append(arg)
 
         for arg in node.keyword_args:
@@ -4433,6 +4488,6 @@
                     del items[:]
                 args.append(arg)
 
         for arg in node.keyword_args:
-            add(arg)
+            add(node, arg)
         if items:
@@ -4438,5 +4493,5 @@
         if items:
-            args.append(items[0])
+            args.extend(items)
 
         if len(args) == 1:
             arg = args[0]
@@ -4525,8 +4580,9 @@
         cascades = [[node.operand1]]
         final_false_result = []
 
-        def split_cascades(cmp_node):
+        cmp_node = node
+        while cmp_node is not None:
             if cmp_node.has_constant_result():
                 if not cmp_node.constant_result:
                     # False => short-circuit
                     final_false_result.append(self._bool_node(cmp_node, False))
@@ -4529,11 +4585,11 @@
             if cmp_node.has_constant_result():
                 if not cmp_node.constant_result:
                     # False => short-circuit
                     final_false_result.append(self._bool_node(cmp_node, False))
-                    return
+                    break
                 else:
                     # True => discard and start new cascade
                     cascades.append([cmp_node.operand2])
             else:
                 # not constant => append to current cascade
                 cascades[-1].append(cmp_node)
@@ -4534,13 +4590,10 @@
                 else:
                     # True => discard and start new cascade
                     cascades.append([cmp_node.operand2])
             else:
                 # not constant => append to current cascade
                 cascades[-1].append(cmp_node)
-            if cmp_node.cascade:
-                split_cascades(cmp_node.cascade)
-
-        split_cascades(node)
+            cmp_node = cmp_node.cascade
 
         cmp_nodes = []
         for cascade in cascades:
@@ -4686,6 +4739,30 @@
             return None
         return node
 
+    def visit_GILStatNode(self, node):
+        self.visitchildren(node)
+        if node.condition is None:
+            return node
+
+        if node.condition.has_constant_result():
+            # Condition is True - Modify node to be a normal
+            # GILStatNode with condition=None
+            if node.condition.constant_result:
+                node.condition = None
+
+            # Condition is False - the body of the GILStatNode
+            # should run without changing the state of the gil
+            # return the body of the GILStatNode
+            else:
+                return node.body
+
+        # If condition is not constant we keep the GILStatNode as it is.
+        # Either it will later become constant (e.g. a `numeric is int`
+        # expression in a fused type function) and then when ConstantFolding
+        # runs again it will be handled or a later transform (i.e. GilCheck)
+        # will raise an error
+        return node
+
     # in the future, other nodes can have their own handler method here
     # that can replace them with a constant result node
 
@@ -4702,6 +4779,7 @@
         - isinstance -> typecheck for cdef types
         - eliminate checks for None and/or types that became redundant after tree changes
         - eliminate useless string formatting steps
+        - inject branch hints for unlikely if-cases that only raise exceptions
         - replace Python function calls that look like method calls by a faster PyMethodCallNode
     """
     in_loop = False
@@ -4800,6 +4878,48 @@
         self.in_loop = old_val
         return node
 
+    def visit_IfStatNode(self, node):
+        """Assign 'unlikely' branch hints to if-clauses that only raise exceptions.
+        """
+        self.visitchildren(node)
+        last_non_unlikely_clause = None
+        for i, if_clause in enumerate(node.if_clauses):
+            self._set_ifclause_branch_hint(if_clause, if_clause.body)
+            if not if_clause.branch_hint:
+                last_non_unlikely_clause = if_clause
+        if node.else_clause and last_non_unlikely_clause:
+            # If the 'else' clause is 'unlikely', then set the preceding 'if' clause to 'likely' to reflect that.
+            self._set_ifclause_branch_hint(last_non_unlikely_clause, node.else_clause, inverse=True)
+        return node
+
+    def _set_ifclause_branch_hint(self, clause, statements_node, inverse=False):
+        """Inject a branch hint if the if-clause unconditionally leads to a 'raise' statement.
+        """
+        if not statements_node.is_terminator:
+            return
+        # Allow simple statements, but no conditions, loops, etc.
+        non_branch_nodes = (
+            Nodes.ExprStatNode,
+            Nodes.AssignmentNode,
+            Nodes.AssertStatNode,
+            Nodes.DelStatNode,
+            Nodes.GlobalNode,
+            Nodes.NonlocalNode,
+        )
+        statements = [statements_node]
+        for next_node_pos, node in enumerate(statements, 1):
+            if isinstance(node, Nodes.GILStatNode):
+                statements.insert(next_node_pos, node.body)
+                continue
+            if isinstance(node, Nodes.StatListNode):
+                statements[next_node_pos:next_node_pos] = node.stats
+                continue
+            if not isinstance(node, non_branch_nodes):
+                if next_node_pos == len(statements) and isinstance(node, (Nodes.RaiseStatNode, Nodes.ReraiseStatNode)):
+                    # Anything that unconditionally raises exceptions at the end should be considered unlikely.
+                    clause.branch_hint = 'likely' if inverse else 'unlikely'
+                break
+
 
 class ConsolidateOverflowCheck(Visitor.CythonTransform):
     """
diff --git a/Cython/Compiler/Options.py b/Cython/Compiler/Options.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL09wdGlvbnMucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL09wdGlvbnMucHk= 100644
--- a/Cython/Compiler/Options.py
+++ b/Cython/Compiler/Options.py
@@ -4,6 +4,10 @@
 
 from __future__ import absolute_import
 
+import os
+
+from Cython import Utils
+
 
 class ShouldBeFromDirective(object):
 
@@ -33,7 +37,7 @@
 """
 The members of this module are documented using autodata in
 Cython/docs/src/reference/compilation.rst.
-See http://www.sphinx-doc.org/en/master/ext/autodoc.html#directive-autoattribute
+See https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#directive-autoattribute
 for how autodata works.
 Descriptions of those members should start with a #:
 Donc forget to keep the docs in sync by removing and adding
@@ -48,11 +52,6 @@
 #: Embed the source code position in the docstrings of functions and classes.
 embed_pos_in_docstring = False
 
-#: Copy the original source code line by line into C code comments
-#: in the generated code file to help with understanding the output.
-#: This is also required for coverage analysis.
-emit_code_comments = True
-
 # undocumented
 pre_import = None
 
@@ -170,6 +169,7 @@
 
 # Declare compiler directives
 _directive_defaults = {
+    'binding': True,
     'boundscheck' : True,
     'nonecheck' : False,
     'initializedcheck' : True,
@@ -238,8 +238,6 @@
     'test_fail_if_path_exists' : [],
 
 # experimental, subject to change
-    'binding': None,
-
     'formal_grammar': False,
 }
 
@@ -317,6 +315,7 @@
     'freelist': int,
     'c_string_type': one_of('bytes', 'bytearray', 'str', 'unicode'),
     'c_string_encoding': normalise_encoding_name,
+    'trashcan': bool,
 }
 
 for key, val in _directive_defaults.items():
@@ -359,6 +358,7 @@
     'np_pythran': ('module',),
     'fast_gil': ('module',),
     'iterable_coroutine': ('module', 'function'),
+    'trashcan' : ('cclass',),
 }
 
 
@@ -547,3 +547,184 @@
         name, value = [s.strip() for s in item.split('=', 1)]
         result[name] = parse_variable_value(value)
     return result
+
+
+# ------------------------------------------------------------------------
+# CompilationOptions are constructed from user input and are the `option`
+#  object passed throughout the compilation pipeline.
+
+class CompilationOptions(object):
+    r"""
+    See default_options at the end of this module for a list of all possible
+    options and CmdLine.usage and CmdLine.parse_command_line() for their
+    meaning.
+    """
+    def __init__(self, defaults=None, **kw):
+        self.include_path = []
+        if defaults:
+            if isinstance(defaults, CompilationOptions):
+                defaults = defaults.__dict__
+        else:
+            defaults = default_options
+
+        options = dict(defaults)
+        options.update(kw)
+
+        # let's assume 'default_options' contains a value for most known compiler options
+        # and validate against them
+        unknown_options = set(options) - set(default_options)
+        # ignore valid options that are not in the defaults
+        unknown_options.difference_update(['include_path'])
+        if unknown_options:
+            message = "got unknown compilation option%s, please remove: %s" % (
+                's' if len(unknown_options) > 1 else '',
+                ', '.join(unknown_options))
+            raise ValueError(message)
+
+        directive_defaults = get_directive_defaults()
+        directives = dict(options['compiler_directives'])  # copy mutable field
+        # check for invalid directives
+        unknown_directives = set(directives) - set(directive_defaults)
+        if unknown_directives:
+            message = "got unknown compiler directive%s: %s" % (
+                's' if len(unknown_directives) > 1 else '',
+                ', '.join(unknown_directives))
+            raise ValueError(message)
+        options['compiler_directives'] = directives
+        if directives.get('np_pythran', False) and not options['cplus']:
+            import warnings
+            warnings.warn("C++ mode forced when in Pythran mode!")
+            options['cplus'] = True
+        if 'language_level' in directives and 'language_level' not in kw:
+            options['language_level'] = directives['language_level']
+        elif not options.get('language_level'):
+            options['language_level'] = directive_defaults.get('language_level')
+        if 'formal_grammar' in directives and 'formal_grammar' not in kw:
+            options['formal_grammar'] = directives['formal_grammar']
+        if options['cache'] is True:
+            options['cache'] = os.path.join(Utils.get_cython_cache_dir(), 'compiler')
+
+        self.__dict__.update(options)
+
+    def configure_language_defaults(self, source_extension):
+        if source_extension == 'py':
+            if self.compiler_directives.get('binding') is None:
+                self.compiler_directives['binding'] = True
+
+    def get_fingerprint(self):
+        r"""
+        Return a string that contains all the options that are relevant for cache invalidation.
+        """
+        # Collect only the data that can affect the generated file(s).
+        data = {}
+
+        for key, value in self.__dict__.items():
+            if key in ['show_version', 'errors_to_stderr', 'verbose', 'quiet']:
+                # verbosity flags have no influence on the compilation result
+                continue
+            elif key in ['output_file', 'output_dir']:
+                # ignore the exact name of the output file
+                continue
+            elif key in ['timestamps']:
+                # the cache cares about the content of files, not about the timestamps of sources
+                continue
+            elif key in ['cache']:
+                # hopefully caching has no influence on the compilation result
+                continue
+            elif key in ['compiler_directives']:
+                # directives passed on to the C compiler do not influence the generated C code
+                continue
+            elif key in ['include_path']:
+                # this path changes which headers are tracked as dependencies,
+                # it has no influence on the generated C code
+                continue
+            elif key in ['working_path']:
+                # this path changes where modules and pxd files are found;
+                # their content is part of the fingerprint anyway, their
+                # absolute path does not matter
+                continue
+            elif key in ['create_extension']:
+                # create_extension() has already mangled the options, e.g.,
+                # embedded_metadata, when the fingerprint is computed so we
+                # ignore it here.
+                continue
+            elif key in ['build_dir']:
+                # the (temporary) directory where we collect dependencies
+                # has no influence on the C output
+                continue
+            elif key in ['use_listing_file', 'generate_pxi', 'annotate', 'annotate_coverage_xml']:
+                # all output files are contained in the cache so the types of
+                # files generated must be part of the fingerprint
+                data[key] = value
+            elif key in ['formal_grammar', 'evaluate_tree_assertions']:
+                # these bits can change whether compilation to C passes/fails
+                data[key] = value
+            elif key in ['embedded_metadata', 'emit_linenums',
+                         'c_line_in_traceback', 'gdb_debug',
+                         'relative_path_in_code_position_comments']:
+                # the generated code contains additional bits when these are set
+                data[key] = value
+            elif key in ['cplus', 'language_level', 'compile_time_env', 'np_pythran']:
+                # assorted bits that, e.g., influence the parser
+                data[key] = value
+            elif key == ['capi_reexport_cincludes']:
+                if self.capi_reexport_cincludes:
+                    # our caching implementation does not yet include fingerprints of all the header files
+                    raise NotImplementedError('capi_reexport_cincludes is not compatible with Cython caching')
+            elif key == ['common_utility_include_dir']:
+                if self.common_utility_include_dir:
+                    raise NotImplementedError('common_utility_include_dir is not compatible with Cython caching yet')
+            else:
+                # any unexpected option should go into the fingerprint; it's better
+                # to recompile than to return incorrect results from the cache.
+                data[key] = value
+
+        def to_fingerprint(item):
+            r"""
+            Recursively turn item into a string, turning dicts into lists with
+            deterministic ordering.
+            """
+            if isinstance(item, dict):
+                item = sorted([(repr(key), to_fingerprint(value)) for key, value in item.items()])
+            return repr(item)
+
+        return to_fingerprint(data)
+
+
+# ------------------------------------------------------------------------
+#
+#  Set the default options depending on the platform
+#
+# ------------------------------------------------------------------------
+
+default_options = dict(
+    show_version=0,
+    use_listing_file=0,
+    errors_to_stderr=1,
+    cplus=0,
+    output_file=None,
+    annotate=None,
+    annotate_coverage_xml=None,
+    generate_pxi=0,
+    capi_reexport_cincludes=0,
+    working_path="",
+    timestamps=None,
+    verbose=0,
+    quiet=0,
+    compiler_directives={},
+    embedded_metadata={},
+    evaluate_tree_assertions=False,
+    emit_linenums=False,
+    relative_path_in_code_position_comments=True,
+    c_line_in_traceback=True,
+    language_level=None,  # warn but default to 2
+    formal_grammar=False,
+    gdb_debug=False,
+    compile_time_env=None,
+    common_utility_include_dir=None,
+    output_dir=None,
+    build_dir=None,
+    cache=None,
+    create_extension=None,
+    np_pythran=False
+)
diff --git a/Cython/Compiler/ParseTreeTransforms.py b/Cython/Compiler/ParseTreeTransforms.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL1BhcnNlVHJlZVRyYW5zZm9ybXMucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL1BhcnNlVHJlZVRyYW5zZm9ybXMucHk= 100644
--- a/Cython/Compiler/ParseTreeTransforms.py
+++ b/Cython/Compiler/ParseTreeTransforms.py
@@ -169,7 +169,6 @@
     reorganization that can be refactored into this transform
     if a more pure Abstract Syntax Tree is wanted.
     """
-
     def __init__(self, context):
         super(PostParse, self).__init__(context)
         self.specialattribute_handlers = {
@@ -347,6 +346,23 @@
         self.visitchildren(node)
         return node
 
+    def visit_AssertStatNode(self, node):
+        """Extract the exception raising into a RaiseStatNode to simplify GIL handling.
+        """
+        if node.exception is None:
+            node.exception = Nodes.RaiseStatNode(
+                node.pos,
+                exc_type=ExprNodes.NameNode(node.pos, name=EncodedString("AssertionError")),
+                exc_value=node.value,
+                exc_tb=None,
+                cause=None,
+                builtin_exc_name="AssertionError",
+                wrap_tuple_value=True,
+            )
+            node.value = None
+        self.visitchildren(node)
+        return node
+
 
 def eliminate_rhs_duplicates(expr_list_list, ref_node_sequence):
     """Replace rhs items by LetRefNodes if they appear more than once.
@@ -581,7 +597,9 @@
             err = None # allow these slots
 
         if isinstance(node, Nodes.CFuncDefNode):
-            if (u'inline' in node.modifiers and
+            if node.decorators and self.scope_type == 'cclass':
+                err = None
+            elif (u'inline' in node.modifiers and
                 self.scope_type in ('pxd', 'cclass')):
                 node.inline_in_pxd = True
                 if node.visibility != 'private':
@@ -628,6 +646,9 @@
     - Command-line arguments overriding these
     - @cython.directivename decorators
     - with cython.directivename: statements
+    - replaces "cython.compiled" with BoolNode(value=True)
+      allowing unreachable blocks to be removed at a fairly early stage
+      before cython typing rules are forced on applied
 
     This transform is responsible for interpreting these various sources
     and store the directive in two ways:
@@ -844,6 +865,16 @@
             directive = self.directive_names.get(node.name)
             if directive is not None:
                 node.cython_attribute = directive
+        if node.as_cython_attribute() == "compiled":
+            return ExprNodes.BoolNode(node.pos, value=True)  # replace early so unused branches can be dropped
+                # before they have a chance to cause compile-errors
+        return node
+
+    def visit_AttributeNode(self, node):
+        self.visitchildren(node)
+        if node.as_cython_attribute() == "compiled":
+            return ExprNodes.BoolNode(node.pos, value=True)  # replace early so unused branches can be dropped
+                # before they have a chance to cause compile-errors
         return node
 
     def visit_NewExprNode(self, node):
@@ -1031,7 +1062,7 @@
             else:
                 realdecs.append(dec)
         if realdecs and (scope_name == 'cclass' or
-                         isinstance(node, (Nodes.CFuncDefNode, Nodes.CClassDefNode, Nodes.CVarDefNode))):
+                         isinstance(node, (Nodes.CClassDefNode, Nodes.CVarDefNode))):
             raise PostParseError(realdecs[0].pos, "Cdef functions/classes cannot take arbitrary decorators.")
         node.decorators = realdecs[::-1] + both[::-1]
         # merge or override repeated directives
@@ -1325,9 +1356,9 @@
     _properties = None
 
     _map_property_attribute = {
-        'getter': '__get__',
-        'setter': '__set__',
-        'deleter': '__del__',
+        'getter': EncodedString('__get__'),
+        'setter': EncodedString('__set__'),
+        'deleter': EncodedString('__del__'),
     }.get
 
     def visit_CClassDefNode(self, node):
@@ -1496,6 +1527,10 @@
 
 
 class ForwardDeclareTypes(CythonTransform):
+    """
+    Declare all global cdef names that we allow referencing in other places,
+    before declaring everything (else) in source code order.
+    """
 
     def visit_CompilerDirectivesNode(self, node):
         env = self.module_scope
@@ -1539,6 +1574,14 @@
                     entry.type.get_all_specialized_function_types()
         return node
 
+    def visit_FuncDefNode(self, node):
+        # no traversal needed
+        return node
+
+    def visit_PyClassDefNode(self, node):
+        # no traversal needed
+        return node
+
 
 class AnalyseDeclarationsTransform(EnvTransform):
 
@@ -1572,7 +1615,7 @@
         count = 0
         INIT_ASSIGNMENTS
         if IS_UNION and count > 1:
-            raise ValueError, "At most one union member should be specified."
+            raise ValueError("At most one union member should be specified.")
     def __str__(self):
         return STR_FORMAT % MEMBER_TUPLE
     def __repr__(self):
@@ -1700,8 +1743,8 @@
                     e.type.create_to_py_utility_code(env)
                     e.type.create_from_py_utility_code(env)
             all_members_names = sorted([e.name for e in all_members])
-            checksum = '0x%s' % hashlib.md5(' '.join(all_members_names).encode('utf-8')).hexdigest()[:7]
-            unpickle_func_name = '__pyx_unpickle_%s' % node.class_name
+            checksum = '0x%s' % hashlib.sha1(' '.join(all_members_names).encode('utf-8')).hexdigest()[:7]
+            unpickle_func_name = '__pyx_unpickle_%s' % node.punycode_class_name
 
             # TODO(robertwb): Move the state into the third argument
             # so it can be pickled *after* self is memoized.
@@ -1800,6 +1843,8 @@
         node.stats.insert(0, node.py_func)
         node.py_func = self.visit(node.py_func)
         node.update_fused_defnode_entry(env)
+        # For the moment, fused functions do not support METH_FASTCALL
+        node.py_func.entry.signature.use_fastcall = False
         pycfunc = ExprNodes.PyCFunctionNode.from_defnode(node.py_func, binding=True)
         pycfunc = ExprNodes.ProxyNode(pycfunc.coerce_to_temp(env))
         node.resulting_fused_function = pycfunc
@@ -1842,19 +1887,6 @@
 
         return node
 
-    def _handle_nogil_cleanup(self, lenv, node):
-        "Handle cleanup for 'with gil' blocks in nogil functions."
-        if lenv.nogil and lenv.has_with_gil_block:
-            # Acquire the GIL for cleanup in 'nogil' functions, by wrapping
-            # the entire function body in try/finally.
-            # The corresponding release will be taken care of by
-            # Nodes.FuncDefNode.generate_function_definitions()
-            node.body = Nodes.NogilTryFinallyStatNode(
-                node.body.pos,
-                body=node.body,
-                finally_clause=Nodes.EnsureGILNode(node.body.pos),
-                finally_except_clause=Nodes.EnsureGILNode(node.body.pos))
-
     def _handle_fused(self, node):
         if node.is_generator and node.has_fused_arguments:
             node.has_fused_arguments = False
@@ -1886,6 +1918,8 @@
         for var, type_node in node.directive_locals.items():
             if not lenv.lookup_here(var):   # don't redeclare args
                 type = type_node.analyse_as_type(lenv)
+                if type and type.is_fused and lenv.fused_to_specific:
+                    type = type.specialize(lenv.fused_to_specific)
                 if type:
                     lenv.declare_var(var, type, type_node.pos)
                 else:
@@ -1895,7 +1929,6 @@
             node = self._create_fused_function(env, node)
         else:
             node.body.analyse_declarations(lenv)
-            self._handle_nogil_cleanup(lenv, node)
             self._super_visit_FuncDefNode(node)
 
         self.seen_vars_stack.pop()
@@ -2197,7 +2230,7 @@
     def visit_ClassDefNode(self, node):
         orig_qualified_name = self.qualified_name[:]
         entry = (getattr(node, 'entry', None) or             # PyClass
-                 self.current_env().lookup_here(node.name))  # CClass
+                 self.current_env().lookup_here(node.target.name))  # CClass
         self._append_entry(entry)
         self._super_visit_ClassDefNode(node)
         self.qualified_name = orig_qualified_name
@@ -2241,6 +2274,29 @@
             node = node.base
         return node
 
+class ReplacePropertyNode(CythonTransform):
+    def visit_CFuncDefNode(self, node):
+        if not node.decorators:
+            return node
+        decorator = self.find_first_decorator(node, 'property')
+        if decorator:
+            # transform class functions into c-getters
+            if len(node.decorators) > 1:
+                # raises
+                self._reject_decorated_property(node, decorator_node)
+            node.entry.is_cgetter = True
+            # Add a func_cname to be output instead of the attribute
+            node.entry.func_cname = node.body.stats[0].value.function.name
+            node.decorators.remove(decorator)
+        return node
+
+    def find_first_decorator(self, node, name):
+        for decorator_node in node.decorators[::-1]:
+            decorator = decorator_node.decorator
+            if decorator.is_name and decorator.name == name:
+                return decorator_node
+        return None
+
 
 class FindInvalidUseOfFusedTypes(CythonTransform):
 
@@ -2704,7 +2760,7 @@
                 if not node.py_cfunc_node:
                     raise InternalError("DefNode does not have assignment node")
                 inner_node = node.py_cfunc_node
-            inner_node.needs_self_code = False
+            inner_node.needs_closure_code = False
             node.needs_outer_scope = False
 
         if node.is_generator:
@@ -2723,6 +2779,7 @@
         as_name = '%s_%s' % (
             target_module_scope.next_id(Naming.closure_class_prefix),
             node.entry.cname.replace('.','__'))
+        as_name = EncodedString(as_name)
 
         entry = target_module_scope.declare_c_class(
             name=as_name, pos=node.pos, defining=True,
@@ -2802,9 +2859,7 @@
     Must run before the AnalyseDeclarationsTransform to make sure the GILStatNodes get
     set up, parallel sections know that the GIL is acquired inside of them, etc.
     """
-    def __call__(self, root):
-        self.nogil = False
-        return super(InjectGilHandling, self).__call__(root)
+    nogil = False
 
     # special node handling
 
@@ -2808,9 +2863,9 @@
 
     # special node handling
 
-    def visit_RaiseStatNode(self, node):
-        """Allow raising exceptions in nogil sections by wrapping them in a 'with gil' block."""
+    def _inject_gil_in_nogil(self, node):
+        """Allow the (Python statement) node in nogil sections by wrapping it in a 'with gil' block."""
         if self.nogil:
             node = Nodes.GILStatNode(node.pos, state='gil', body=node)
         return node
 
@@ -2813,5 +2868,8 @@
         if self.nogil:
             node = Nodes.GILStatNode(node.pos, state='gil', body=node)
         return node
 
+    visit_RaiseStatNode = _inject_gil_in_nogil
+    visit_PrintStatNode = _inject_gil_in_nogil  # sadly, not the function
+
     # further candidates:
@@ -2817,5 +2875,4 @@
     # further candidates:
-    # def visit_AssertStatNode(self, node):
     # def visit_ReraiseStatNode(self, node):
 
     # nogil tracking
@@ -2898,6 +2955,12 @@
         return node
 
     def visit_GILStatNode(self, node):
+        if node.condition is not None:
+            error(node.condition.pos,
+                  "Non-constant condition in a "
+                  "`with %s(<condition>)` statement" % node.state)
+            return node
+
         if self.nogil and node.nogil_check:
             node.nogil_check()
 
@@ -2995,9 +3058,7 @@
     def visit_cython_attribute(self, node):
         attribute = node.as_cython_attribute()
         if attribute:
-            if attribute == u'compiled':
-                node = ExprNodes.BoolNode(node.pos, value=True)
-            elif attribute == u'__version__':
+            if attribute == u'__version__':
                 from .. import __version__ as version
                 node = ExprNodes.StringNode(node.pos, value=EncodedString(version))
             elif attribute == u'NULL':
@@ -3079,8 +3140,8 @@
 
     def _inject_eval(self, node, func_name):
         lenv = self.current_env()
-        entry = lenv.lookup_here(func_name)
-        if entry or len(node.args) != 1:
+        entry = lenv.lookup(func_name)
+        if len(node.args) != 1 or (entry and not entry.is_builtin):
             return node
         # Inject globals and locals
         node.args.append(ExprNodes.GlobalsExprNode(node.pos))
@@ -3237,6 +3298,13 @@
         self.visitchildren(node)
         return self.transform(node)
 
+    def visit_GILStatNode(self, node):
+        """
+        Fold constant condition of GILStatNode.
+        """
+        self.visitchildren(node)
+        return self.transform(node)
+
     def visit_PrimaryCmpNode(self, node):
         with Errors.local_errors(ignore=True):
           type1 = node.operand1.analyse_as_type(self.local_scope)
diff --git a/Cython/Compiler/Parsing.pxd b/Cython/Compiler/Parsing.pxd
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL1BhcnNpbmcucHhk..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL1BhcnNpbmcucHhk 100644
--- a/Cython/Compiler/Parsing.pxd
+++ b/Cython/Compiler/Parsing.pxd
@@ -196,3 +196,4 @@
 cdef p_template_definition(PyrexScanner s)
 cdef p_cpp_class_definition(PyrexScanner s, pos, ctx)
 cdef p_cpp_class_attribute(PyrexScanner s, ctx)
+cdef p_annotation(PyrexScanner s)
diff --git a/Cython/Compiler/Parsing.py b/Cython/Compiler/Parsing.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL1BhcnNpbmcucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL1BhcnNpbmcucHk= 100644
--- a/Cython/Compiler/Parsing.py
+++ b/Cython/Compiler/Parsing.py
@@ -65,7 +65,7 @@
 
 def p_ident(s, message="Expected an identifier"):
     if s.sy == 'IDENT':
-        name = s.systring
+        name = s.context.intern_ustring(s.systring)
         s.next()
         return name
     else:
@@ -74,7 +74,7 @@
 def p_ident_list(s):
     names = []
     while s.sy == 'IDENT':
-        names.append(s.systring)
+        names.append(s.context.intern_ustring(s.systring))
         s.next()
         if s.sy != ',':
             break
@@ -317,9 +317,8 @@
     base_type = p_c_base_type(s)
     is_memslice = isinstance(base_type, Nodes.MemoryViewSliceTypeNode)
     is_template = isinstance(base_type, Nodes.TemplatedTypeNode)
-    is_const = isinstance(base_type, Nodes.CConstTypeNode)
-    if (not is_memslice and not is_template and not is_const
-        and base_type.name is None):
+    is_const_volatile = isinstance(base_type, Nodes.CConstOrVolatileTypeNode)
+    if not is_memslice and not is_template and not is_const_volatile and base_type.name is None:
         s.error("Unknown type")
     declarator = p_c_declarator(s, empty = 1)
     if s.sy == '?':
@@ -330,8 +329,7 @@
     s.expect(">")
     operand = p_factor(s)
     if is_memslice:
-        return ExprNodes.CythonArrayNode(pos, base_type_node=base_type,
-                                         operand=operand)
+        return ExprNodes.CythonArrayNode(pos, base_type_node=base_type, operand=operand)
 
     return ExprNodes.TypecastNode(pos,
         base_type = base_type,
@@ -1495,7 +1493,7 @@
     expr = p_testlist_star_expr(s)
     if s.sy == ':' and (expr.is_name or expr.is_subscript or expr.is_attribute):
         s.next()
-        expr.annotation = p_test(s)
+        expr.annotation = p_annotation(s)
     if s.sy == '=' and expr.is_starred:
         # This is a common enough error to make when learning Cython to let
         # it fail as early as possible and give a very clear error message.
@@ -1678,11 +1676,6 @@
                 as_name=as_name,
                 is_absolute=is_absolute)
         else:
-            if as_name and "." in dotted_name:
-                name_list = ExprNodes.ListNode(pos, args=[
-                    ExprNodes.IdentifierStringNode(pos, value=s.context.intern_ustring("*"))])
-            else:
-                name_list = None
             stat = Nodes.SingleAssignmentNode(
                 pos,
                 lhs=ExprNodes.NameNode(pos, name=as_name or target_name),
@@ -1690,7 +1683,8 @@
                     pos,
                     module_name=ExprNodes.IdentifierStringNode(pos, value=dotted_name),
                     level=0 if is_absolute else None,
-                    name_list=name_list))
+                    get_top_level_module='.' in dotted_name and as_name is None,
+                    name_list=None))
         stats.append(stat)
     return Nodes.StatListNode(pos, stats=stats)
 
@@ -1820,7 +1814,7 @@
         value = p_test(s)
     else:
         value = None
-    return Nodes.AssertStatNode(pos, cond = cond, value = value)
+    return Nodes.AssertStatNode(pos, condition=cond, value=value)
 
 
 statement_terminators = cython.declare(set, set([';', 'NEWLINE', 'EOF']))
@@ -2058,8 +2052,16 @@
             s.error("with gil/nogil cannot be async")
         state = s.systring
         s.next()
+
+        # support conditional gil/nogil
+        condition = None
+        if s.sy == '(':
+            s.next()
+            condition = p_test(s)
+            s.expect(')')
+
         if s.sy == ',':
             s.next()
             body = p_with_items(s)
         else:
             body = p_suite(s)
@@ -2061,9 +2063,9 @@
         if s.sy == ',':
             s.next()
             body = p_with_items(s)
         else:
             body = p_suite(s)
-        return Nodes.GILStatNode(pos, state=state, body=body)
+        return Nodes.GILStatNode(pos, state=state, body=body, condition=condition)
     else:
         manager = p_test(s)
         target = None
@@ -2480,7 +2482,16 @@
     complex = 0
     module_path = []
     pos = s.position()
-    if not s.sy == 'IDENT':
-        error(pos, "Expected an identifier, found '%s'" % s.sy)
-    if s.systring == 'const':
+
+    # Handle const/volatile
+    is_const = is_volatile = 0
+    while s.sy == 'IDENT':
+        if s.systring == 'const':
+            if is_const: error(pos, "Duplicate 'const'")
+            is_const = 1
+        elif s.systring == 'volatile':
+            if is_volatile: error(pos, "Duplicate 'volatile'")
+            is_volatile = 1
+        else:
+            break
         s.next()
@@ -2486,4 +2497,5 @@
         s.next()
+    if is_const or is_volatile:
         base_type = p_c_base_type(s, self_flag=self_flag, nonempty=nonempty, templates=templates)
         if isinstance(base_type, Nodes.MemoryViewSliceTypeNode):
             # reverse order to avoid having to write "(const int)[:]"
@@ -2487,5 +2499,6 @@
         base_type = p_c_base_type(s, self_flag=self_flag, nonempty=nonempty, templates=templates)
         if isinstance(base_type, Nodes.MemoryViewSliceTypeNode):
             # reverse order to avoid having to write "(const int)[:]"
-            base_type.base_type_node = Nodes.CConstTypeNode(pos, base_type=base_type.base_type_node)
+            base_type.base_type_node = Nodes.CConstOrVolatileTypeNode(pos,
+                base_type=base_type.base_type_node, is_const=is_const, is_volatile=is_volatile)
             return base_type
@@ -2491,5 +2504,9 @@
             return base_type
-        return Nodes.CConstTypeNode(pos, base_type=base_type)
+        return Nodes.CConstOrVolatileTypeNode(pos,
+            base_type=base_type, is_const=is_const, is_volatile=is_volatile)
+
+    if s.sy != 'IDENT':
+        error(pos, "Expected an identifier, found '%s'" % s.sy)
     if looking_at_base_type(s):
         #print "p_c_simple_base_type: looking_at_base_type at", s.position()
         is_basic = 1
@@ -2948,7 +2965,7 @@
             exc_val = p_test(s)
     return exc_val, exc_check
 
-c_arg_list_terminators = cython.declare(set, set(['*', '**', '.', ')', ':']))
+c_arg_list_terminators = cython.declare(set, set(['*', '**', '.', ')', ':', '/']))
 
 def p_c_arg_list(s, ctx = Ctx(), in_pyfunc = 0, cmethod_flag = 0,
                  nonempty_declarators = 0, kw_only = 0, annotated = 1):
@@ -3002,7 +3019,7 @@
         not_none = kind == 'not'
     if annotated and s.sy == ':':
         s.next()
-        annotation = p_test(s)
+        annotation = p_annotation(s)
     if s.sy == '=':
         s.next()
         if 'pxd' in ctx.level:
@@ -3172,6 +3189,4 @@
     attributes = None
     if s.sy == ':':
         s.next()
-        s.expect('NEWLINE')
-        s.expect_indent()
         attributes = []
@@ -3177,13 +3192,19 @@
         attributes = []
-        body_ctx = Ctx()
-        while s.sy != 'DEDENT':
-            if s.sy != 'pass':
-                attributes.append(
-                    p_c_func_or_var_declaration(s, s.position(), body_ctx))
-            else:
-                s.next()
-                s.expect_newline("Expected a newline")
-        s.expect_dedent()
+        if s.sy == 'pass':
+            s.next()
+            s.expect_newline("Expected a newline", ignore_semicolon=True)
+        else:
+            s.expect('NEWLINE')
+            s.expect_indent()
+            body_ctx = Ctx()
+            while s.sy != 'DEDENT':
+                if s.sy != 'pass':
+                    attributes.append(
+                        p_c_func_or_var_declaration(s, s.position(), body_ctx))
+                else:
+                    s.next()
+                    s.expect_newline("Expected a newline")
+            s.expect_dedent()
     else:
         s.expect_newline("Syntax error in struct or union definition")
     return Nodes.CStructOrUnionDefNode(pos,
@@ -3368,7 +3389,7 @@
 
 def p_def_statement(s, decorators=None, is_async_def=False):
     # s.sy == 'def'
-    pos = s.position()
+    pos = decorators[0].pos if decorators else s.position()
     # PEP 492 switches the async/await keywords on in "async def" functions
     if is_async_def:
         s.enter_async()
@@ -3385,7 +3406,7 @@
     return_type_annotation = None
     if s.sy == '->':
         s.next()
-        return_type_annotation = p_test(s)
+        return_type_annotation = p_annotation(s)
         _reject_cdef_modifier_in_py(s, s.systring)
 
     doc, body = p_suite_with_docstring(s, Ctx(level='function'))
@@ -3403,6 +3424,20 @@
                         annotated = annotated)
     star_arg = None
     starstar_arg = None
+    if s.sy == '/':
+        if len(args) == 0:
+            s.error("Got zero positional-only arguments despite presence of "
+                    "positional-only specifier '/'")
+        s.next()
+        # Mark all args to the left as pos only
+        for arg in args:
+            arg.pos_only = 1
+        if s.sy == ',':
+            s.next()
+            args.extend(p_c_arg_list(s, in_pyfunc = 1,
+                nonempty_declarators = 1, annotated = annotated))
+        elif s.sy != terminator:
+            s.error("Syntax error in Python function argument list")
     if s.sy == '*':
         s.next()
         if s.sy == 'IDENT':
@@ -3426,7 +3461,7 @@
     annotation = None
     if annotated and s.sy == ':':
         s.next()
-        annotation = p_test(s)
+        annotation = p_annotation(s)
     return Nodes.PyArgDeclNode(pos, name = name, annotation = annotation)
 
 
@@ -3676,7 +3711,7 @@
     s.parse_comments = False
 
     if s.context.language_level is None:
-        s.context.set_language_level(2)
+        s.context.set_language_level('3str')
         if pos[0].filename:
             import warnings
             warnings.warn(
@@ -3680,9 +3715,9 @@
         if pos[0].filename:
             import warnings
             warnings.warn(
-                "Cython directive 'language_level' not set, using 2 for now (Py2). "
-                "This will change in a later release! File: %s" % pos[0].filename,
+                "Cython directive 'language_level' not set, using '3str' for now (Py3). "
+                "This has changed from earlier releases! File: %s" % pos[0].filename,
                 FutureWarning,
                 stacklevel=1 if cython.compiled else 2,
             )
 
@@ -3685,5 +3720,6 @@
                 FutureWarning,
                 stacklevel=1 if cython.compiled else 2,
             )
 
+    level = 'module_pxd' if pxd else 'module'
     doc = p_doc_string(s)
@@ -3689,9 +3725,4 @@
     doc = p_doc_string(s)
-    if pxd:
-        level = 'module_pxd'
-    else:
-        level = 'module'
-
     body = p_statement_list(s, ctx(level=level), first_statement = 1)
     if s.sy != 'EOF':
         s.error("Syntax error in statement [%s,%s]" % (
@@ -3747,6 +3778,10 @@
         s.next()
         s.expect('NEWLINE')
         s.expect_indent()
+        # Allow a cppclass to have docstrings. It will be discarded as comment.
+        # The goal of this is consistency: we can make docstrings inside cppclass methods,
+        # so why not on the cppclass itself ?
+        p_doc_string(s)
         attributes = []
         body_ctx = Ctx(visibility = ctx.visibility, level='cpp_class', nogil=nogil or ctx.nogil)
         body_ctx.templates = template_names
@@ -3830,3 +3865,14 @@
             f.write("%s]\n" % ind)
             return
     f.write("%s%s\n" % (ind, node))
+
+def p_annotation(s):
+    """An annotation just has the "test" syntax, but also stores the string it came from
+
+    Note that the string is *allowed* to be changed/processed (although isn't here)
+    so may not exactly match the string generated by Python, and if it doesn't
+    then it is not a bug.
+    """
+    pos = s.position()
+    expr = p_test(s)
+    return ExprNodes.AnnotationNode(pos, expr=expr)
diff --git a/Cython/Compiler/Pipeline.py b/Cython/Compiler/Pipeline.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL1BpcGVsaW5lLnB5..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL1BpcGVsaW5lLnB5 100644
--- a/Cython/Compiler/Pipeline.py
+++ b/Cython/Compiler/Pipeline.py
@@ -146,7 +146,7 @@
     from .ParseTreeTransforms import CreateClosureClasses, MarkClosureVisitor, DecoratorTransform
     from .ParseTreeTransforms import TrackNumpyAttributes, InterpretCompilerDirectives, TransformBuiltinMethods
     from .ParseTreeTransforms import ExpandInplaceOperators, ParallelRangeTransform
-    from .ParseTreeTransforms import CalculateQualifiedNamesTransform
+    from .ParseTreeTransforms import CalculateQualifiedNamesTransform, ReplacePropertyNode
     from .TypeInference import MarkParallelAssignments, MarkOverflowingArithmetic
     from .ParseTreeTransforms import AdjustDefByDirectives, AlignFunctionDefinitions
     from .ParseTreeTransforms import RemoveUnreachableCode, GilCheck
@@ -198,6 +198,7 @@
         AnalyseDeclarationsTransform(context),
         AutoTestDictTransform(context),
         EmbedSignature(context),
+        ReplacePropertyNode(context),
         EarlyReplaceBuiltinCalls(context),  ## Necessary?
         TransformBuiltinMethods(context),
         MarkParallelAssignments(context),
diff --git a/Cython/Compiler/PyrexTypes.py b/Cython/Compiler/PyrexTypes.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL1B5cmV4VHlwZXMucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL1B5cmV4VHlwZXMucHk= 100644
--- a/Cython/Compiler/PyrexTypes.py
+++ b/Cython/Compiler/PyrexTypes.py
@@ -4,7 +4,6 @@
 
 from __future__ import absolute_import
 
-import collections
 import copy
 import re
 
@@ -115,7 +114,7 @@
         Deduce any template params in this (argument) type given the actual
         argument type.
 
-        http://en.cppreference.com/w/cpp/language/function_template#Template_argument_deduction
+        https://en.cppreference.com/w/cpp/language/function_template#Template_argument_deduction
         """
         return {}
 
@@ -176,7 +175,9 @@
     #  is_ptr                boolean     Is a C pointer type
     #  is_null_ptr           boolean     Is the type of NULL
     #  is_reference          boolean     Is a C reference type
-    #  is_const              boolean     Is a C const type.
+    #  is_const              boolean     Is a C const type
+    #  is_volatile           boolean     Is a C volatile type
+    #  is_cv_qualified       boolean     Is a C const or volatile type
     #  is_cfunction          boolean     Is a C function type
     #  is_struct_or_union    boolean     Is a C struct or union type
     #  is_struct             boolean     Is a C struct type
@@ -192,6 +193,8 @@
     #  is_pythran_expr       boolean     Is Pythran expr
     #  is_numpy_buffer       boolean     Is Numpy array buffer
     #  has_attributes        boolean     Has C dot-selectable attributes
+    #  needs_refcounting          boolean     Needs code to be generated similar to incref/gotref/decref.
+    #                                    Largely used internally.
     #  default_value         string      Initial value that can be assigned before first user assignment.
     #  declaration_value     string      The value statically assigned on declaration (if any).
     #  entry                 Entry       The Entry for this type
@@ -226,6 +229,7 @@
     is_extension_type = 0
     is_final_type = 0
     is_builtin_type = 0
+    is_cython_builtin_type = 0
     is_numeric = 0
     is_int = 0
     is_float = 0
@@ -236,6 +240,8 @@
     is_null_ptr = 0
     is_reference = 0
     is_const = 0
+    is_volatile = 0
+    is_cv_qualified = 0
     is_cfunction = 0
     is_struct_or_union = 0
     is_cpp_class = 0
@@ -254,6 +260,7 @@
     is_pythran_expr = 0
     is_numpy_buffer = 0
     has_attributes = 0
+    needs_refcounting = 0
     default_value = ""
     declaration_value = ""
 
@@ -331,6 +338,31 @@
             convert_call,
             code.error_goto_if(error_condition or self.error_condition(result_code), error_pos))
 
+    def _generate_dummy_refcounting(self, code, *ignored_args, **ignored_kwds):
+        if self.needs_refcounting:
+            raise NotImplementedError("Ref-counting operation not yet implemented for type %s" %
+                                      self)
+
+    def _generate_dummy_refcounting_assignment(self, code, cname, rhs_cname, *ignored_args, **ignored_kwds):
+        if self.needs_refcounting:
+            raise NotImplementedError("Ref-counting operation not yet implemented for type %s" %
+                                      self)
+        code.putln("%s = %s" % (cname, rhs_cname))
+
+    generate_incref = generate_xincref = generate_decref = generate_xdecref \
+        = generate_decref_clear = generate_xdecref_clear \
+        = generate_gotref = generate_xgotref = generate_giveref = generate_xgiveref \
+            = _generate_dummy_refcounting
+
+    generate_decref_set = generate_xdecref_set = _generate_dummy_refcounting_assignment
+
+    def nullcheck_string(self, code, cname):
+        if self.needs_refcounting:
+            raise NotImplementedError("Ref-counting operation not yet implemented for type %s" %
+                                      self)
+        code.putln("1")
+
+
 
 def public_decl(base_code, dll_linkage):
     if dll_linkage:
@@ -561,5 +593,6 @@
 class MemoryViewSliceType(PyrexType):
 
     is_memoryviewslice = 1
+    default_value = "{ 0, 0, { 0 }, { 0 }, { 0 } }"
 
     has_attributes = 1
@@ -564,5 +597,9 @@
 
     has_attributes = 1
+    needs_refcounting = 1  # Ideally this would be true and reference counting for
+        # memoryview and pyobject code could be generated in the same way.
+        # However, memoryviews are sufficiently specialized that this doesn't
+        # seem practical. Implement a limited version of it for now
     scope = None
 
     # These are special cased in Defnode
@@ -591,7 +628,7 @@
         'ptr' -- Pointer stored in this dimension.
         'full' -- Check along this dimension, don't assume either.
 
-        the packing specifiers specify how the array elements are layed-out
+        the packing specifiers specify how the array elements are laid-out
         in memory.
 
         'contig' -- The data is contiguous in memory along this dimension.
@@ -653,7 +690,8 @@
         assert not pyrex
         assert not dll_linkage
         from . import MemoryView
-        base_code = str(self) if for_display else MemoryView.memviewslice_cname
+        base_code = StringEncoding.EncodedString(
+                        (str(self)) if for_display else MemoryView.memviewslice_cname)
         return self.base_declaration_code(
                 base_code,
                 entity_code)
@@ -713,8 +751,8 @@
             to_axes_f = contig_dim + follow_dim * (ndim -1)
 
             dtype = self.dtype
-            if dtype.is_const:
-                dtype = dtype.const_base_type
+            if dtype.is_cv_qualified:
+                dtype = dtype.cv_base_type
 
             to_memview_c = MemoryViewSliceType(dtype, to_axes_c)
             to_memview_f = MemoryViewSliceType(dtype, to_axes_f)
@@ -791,15 +829,18 @@
         #    return False
 
         src_dtype, dst_dtype = src.dtype, dst.dtype
-        if dst_dtype.is_const:
-            # Requesting read-only views is always ok => consider only the non-const base type.
-            dst_dtype = dst_dtype.const_base_type
-            if src_dtype.is_const:
-                # When assigning between read-only views, compare only the non-const base types.
-                src_dtype = src_dtype.const_base_type
-        elif copying and src_dtype.is_const:
-            # Copying by value => ignore const on source.
-            src_dtype = src_dtype.const_base_type
+        # We can add but not remove const/volatile modifiers
+        # (except if we are copying by value, then anything is fine)
+        if not copying:
+            if src_dtype.is_const and not dst_dtype.is_const:
+                return False
+            if src_dtype.is_volatile and not dst_dtype.is_volatile:
+                return False
+        # const/volatile checks are done, remove those qualifiers
+        if src_dtype.is_cv_qualified:
+            src_dtype = src_dtype.cv_base_type
+        if dst_dtype.is_cv_qualified:
+            dst_dtype = dst_dtype.cv_base_type
 
         if src_dtype != dst_dtype:
             return False
@@ -1032,6 +1073,36 @@
     def cast_code(self, expr_code):
         return expr_code
 
+    # When memoryviews are increfed currently seems heavily special-cased.
+    # Therefore, use our own function for now
+    def generate_incref(self, code, name, **kwds):
+        pass
+
+    def generate_incref_memoryviewslice(self, code, slice_cname, have_gil):
+        # TODO ideally would be done separately
+        code.putln("__PYX_INC_MEMVIEW(&%s, %d);" % (slice_cname, int(have_gil)))
+
+    # decref however did look to always apply for memoryview slices
+    # with "have_gil" set to True by default
+    def generate_xdecref(self, code, cname, nanny, have_gil):
+        code.putln("__PYX_XDEC_MEMVIEW(&%s, %d);" % (cname, int(have_gil)))
+
+    def generate_decref(self, code, cname, nanny, have_gil):
+        # Fall back to xdecref since we don't care to have a separate decref version for this.
+        self.generate_xdecref(code, cname, nanny, have_gil)
+
+    def generate_xdecref_clear(self, code, cname, clear_before_decref, **kwds):
+        self.generate_xdecref(code, cname, **kwds)
+        code.putln("%s.memview = NULL; %s.data = NULL;" % (cname, cname))
+
+    def generate_decref_clear(self, code, cname, **kwds):
+        # memoryviews don't currently distinguish between xdecref and decref
+        self.generate_xdecref_clear(code, cname, **kwds)
+
+    # memoryviews don't participate in giveref/gotref
+    generate_gotref = generate_xgotref = generate_xgiveref = generate_giveref = lambda *args: None
+
+
 
 class BufferType(BaseType):
     #
@@ -1129,6 +1200,8 @@
     is_extern = False
     is_subclassed = False
     is_gc_simple = False
+    builtin_trashcan = False  # builtin type using trashcan
+    needs_refcounting = True
 
     def __str__(self):
         return "Python object"
@@ -1181,5 +1254,75 @@
     def check_for_null_code(self, cname):
         return cname
 
+    def generate_incref(self, code, cname, nanny):
+        if nanny:
+            code.putln("__Pyx_INCREF(%s);" % self.as_pyobject(cname))
+        else:
+            code.putln("Py_INCREF(%s);" % self.as_pyobject(cname))
+
+    def generate_xincref(self, code, cname, nanny):
+        if nanny:
+            code.putln("__Pyx_XINCREF(%s);" % self.as_pyobject(cname))
+        else:
+            code.putln("Py_XINCREF(%s);" % self.as_pyobject(cname))
+
+    def generate_decref(self, code, cname, nanny, have_gil):
+        # have_gil is for the benefit of memoryviewslice - it's ignored here
+        assert have_gil
+        self._generate_decref(code, cname, nanny, null_check=False, clear=False)
+
+    def generate_xdecref(self, code, cname, nanny, have_gil):
+        # in this (and other) PyObjectType functions, have_gil is being
+        # passed to provide a common interface with MemoryviewSlice.
+        # It's ignored here
+        self._generate_decref(code, cname, nanny, null_check=True,
+                         clear=False)
+
+    def generate_decref_clear(self, code, cname, clear_before_decref, nanny, have_gil):
+        self._generate_decref(code, cname, nanny, null_check=False,
+                         clear=True, clear_before_decref=clear_before_decref)
+
+    def generate_xdecref_clear(self, code, cname, clear_before_decref=False, nanny=True, have_gil=None):
+        self._generate_decref(code, cname, nanny, null_check=True,
+                         clear=True, clear_before_decref=clear_before_decref)
+
+    def generate_gotref(self, code, cname):
+        code.putln("__Pyx_GOTREF(%s);" % self.as_pyobject(cname))
+
+    def generate_xgotref(self, code, cname):
+        code.putln("__Pyx_XGOTREF(%s);" % self.as_pyobject(cname))
+
+    def generate_giveref(self, code, cname):
+        code.putln("__Pyx_GIVEREF(%s);" % self.as_pyobject(cname))
+
+    def generate_xgiveref(self, code, cname):
+        code.putln("__Pyx_XGIVEREF(%s);" % self.as_pyobject(cname))
+
+    def generate_decref_set(self, code, cname, rhs_cname):
+        code.putln("__Pyx_DECREF_SET(%s, %s);" % (cname, rhs_cname))
+
+    def generate_xdecref_set(self, code, cname, rhs_cname):
+        code.putln("__Pyx_XDECREF_SET(%s, %s);" % (cname, rhs_cname))
+
+    def _generate_decref(self, code, cname, nanny, null_check=False,
+                    clear=False, clear_before_decref=False):
+        prefix = '__Pyx' if nanny else 'Py'
+        X = 'X' if null_check else ''
+
+        if clear:
+            if clear_before_decref:
+                if not nanny:
+                    X = ''  # CPython doesn't have a Py_XCLEAR()
+                code.putln("%s_%sCLEAR(%s);" % (prefix, X, cname))
+            else:
+                code.putln("%s_%sDECREF(%s); %s = 0;" % (
+                    prefix, X, self.as_pyobject(cname), cname))
+        else:
+            code.putln("%s_%sDECREF(%s);" % (
+                prefix, X, self.as_pyobject(cname)))
+
+    def nullcheck_string(self, cname):
+        return cname
+
 
 builtin_types_that_cannot_create_refcycles = set([
@@ -1184,6 +1327,6 @@
 
 builtin_types_that_cannot_create_refcycles = set([
-    'bool', 'int', 'long', 'float', 'complex',
+    'object', 'bool', 'int', 'long', 'float', 'complex',
     'bytearray', 'bytes', 'unicode', 'str', 'basestring'
 ])
 
@@ -1187,6 +1330,10 @@
     'bytearray', 'bytes', 'unicode', 'str', 'basestring'
 ])
 
+builtin_types_with_trashcan = set([
+    'dict', 'list', 'set', 'frozenset', 'tuple', 'type',
+])
+
 
 class BuiltinObjectType(PyObjectType):
     #  objstruct_cname  string           Name of PyObject struct
@@ -1211,6 +1358,7 @@
         self.typeptr_cname = "(&%s)" % cname
         self.objstruct_cname = objstruct_cname
         self.is_gc_simple = name in builtin_types_that_cannot_create_refcycles
+        self.builtin_trashcan = name in builtin_types_with_trashcan
         if name == 'type':
             # Special case the type type, as many C API calls (and other
             # libraries) actually expect a PyTypeObject* for type arguments.
@@ -1297,7 +1445,7 @@
             name = '"%s"' % self.name
             # avoid wasting too much space but limit number of different format strings
             space_for_name = (len(self.name) // 16 + 1) * 16
-        error = '(PyErr_Format(PyExc_TypeError, "Expected %%.%ds, got %%.200s", %s, Py_TYPE(%s)->tp_name), 0)' % (
+        error = '(PyErr_Format(PyExc_TypeError, "Expected %%.%ds, got %%.200s", %s, __Pyx_PyType_Name(Py_TYPE(%s))), 0)' % (
             space_for_name, name, arg)
         return check + '||' + error
 
@@ -1543,8 +1691,14 @@
             self.scope = scope = Symtab.CClassScope('', None, visibility="extern")
             scope.parent_type = self
             scope.directives = {}
-            scope.declare_var("shape", CPtrType(c_long_type), None, cname="_shape", is_cdef=True)
-            scope.declare_var("ndim", c_long_type, None, cname="value", is_cdef=True)
+            scope.declare_cgetter(
+                "shape",
+                CPtrType(c_long_type),
+                pos=None,
+                cname="__Pyx_PythranShapeAccessor",
+                visibility="extern",
+                nogil=True)
+            scope.declare_var("ndim", c_long_type, pos=None, cname="value", is_cdef=True)
 
         return True
 
@@ -1558,14 +1712,27 @@
         return hash(self.pythran_type)
 
 
-class CConstType(BaseType):
-
-    is_const = 1
-
-    def __init__(self, const_base_type):
-        self.const_base_type = const_base_type
-        if const_base_type.has_attributes and const_base_type.scope is not None:
-            from . import Symtab
-            self.scope = Symtab.CConstScope(const_base_type.scope)
+class CConstOrVolatileType(BaseType):
+    "A C const or volatile type"
+
+    subtypes = ['cv_base_type']
+
+    is_cv_qualified = 1
+
+    def __init__(self, base_type, is_const=0, is_volatile=0):
+        self.cv_base_type = base_type
+        self.is_const = is_const
+        self.is_volatile = is_volatile
+        if base_type.has_attributes and base_type.scope is not None:
+            from .Symtab import CConstOrVolatileScope
+            self.scope = CConstOrVolatileScope(base_type.scope, is_const, is_volatile)
+
+    def cv_string(self):
+        cvstring = ""
+        if self.is_const:
+            cvstring = "const " + cvstring
+        if self.is_volatile:
+            cvstring = "volatile " + cvstring
+        return cvstring
 
     def __repr__(self):
@@ -1570,9 +1737,9 @@
 
     def __repr__(self):
-        return "<CConstType %s>" % repr(self.const_base_type)
+        return "<CConstOrVolatileType %s%r>" % (self.cv_string(), self.cv_base_type)
 
     def __str__(self):
         return self.declaration_code("", for_display=1)
 
     def declaration_code(self, entity_code,
             for_display = 0, dll_linkage = None, pyrex = 0):
@@ -1573,7 +1740,8 @@
 
     def __str__(self):
         return self.declaration_code("", for_display=1)
 
     def declaration_code(self, entity_code,
             for_display = 0, dll_linkage = None, pyrex = 0):
+        cv = self.cv_string()
         if for_display or pyrex:
@@ -1579,3 +1747,3 @@
         if for_display or pyrex:
-            return "const " + self.const_base_type.declaration_code(entity_code, for_display, dll_linkage, pyrex)
+            return cv + self.cv_base_type.declaration_code(entity_code, for_display, dll_linkage, pyrex)
         else:
@@ -1581,4 +1749,4 @@
         else:
-            return self.const_base_type.declaration_code("const %s" % entity_code, for_display, dll_linkage, pyrex)
+            return self.cv_base_type.declaration_code(cv + entity_code, for_display, dll_linkage, pyrex)
 
     def specialize(self, values):
@@ -1583,5 +1751,5 @@
 
     def specialize(self, values):
-        base_type = self.const_base_type.specialize(values)
-        if base_type == self.const_base_type:
+        base_type = self.cv_base_type.specialize(values)
+        if base_type == self.cv_base_type:
             return self
@@ -1587,5 +1755,5 @@
             return self
-        else:
-            return CConstType(base_type)
+        return CConstOrVolatileType(base_type,
+                self.is_const, self.is_volatile)
 
     def deduce_template_params(self, actual):
@@ -1590,5 +1758,5 @@
 
     def deduce_template_params(self, actual):
-        return self.const_base_type.deduce_template_params(actual)
+        return self.cv_base_type.deduce_template_params(actual)
 
     def can_coerce_to_pyobject(self, env):
@@ -1593,5 +1761,5 @@
 
     def can_coerce_to_pyobject(self, env):
-        return self.const_base_type.can_coerce_to_pyobject(env)
+        return self.cv_base_type.can_coerce_to_pyobject(env)
 
     def can_coerce_from_pyobject(self, env):
@@ -1596,5 +1764,5 @@
 
     def can_coerce_from_pyobject(self, env):
-        return self.const_base_type.can_coerce_from_pyobject(env)
+        return self.cv_base_type.can_coerce_from_pyobject(env)
 
     def create_to_py_utility_code(self, env):
@@ -1599,7 +1767,7 @@
 
     def create_to_py_utility_code(self, env):
-        if self.const_base_type.create_to_py_utility_code(env):
-            self.to_py_function = self.const_base_type.to_py_function
+        if self.cv_base_type.create_to_py_utility_code(env):
+            self.to_py_function = self.cv_base_type.to_py_function
             return True
 
     def same_as_resolved_type(self, other_type):
@@ -1603,9 +1771,9 @@
             return True
 
     def same_as_resolved_type(self, other_type):
-        if other_type.is_const:
-            return self.const_base_type.same_as_resolved_type(other_type.const_base_type)
-        # Accept const LHS <- non-const RHS.
-        return self.const_base_type.same_as_resolved_type(other_type)
+        if other_type.is_cv_qualified:
+            return self.cv_base_type.same_as_resolved_type(other_type.cv_base_type)
+        # Accept cv LHS <- non-cv RHS.
+        return self.cv_base_type.same_as_resolved_type(other_type)
 
     def __getattr__(self, name):
@@ -1610,6 +1778,10 @@
 
     def __getattr__(self, name):
-        return getattr(self.const_base_type, name)
+        return getattr(self.cv_base_type, name)
+
+
+def CConstType(base_type):
+    return CConstOrVolatileType(base_type, is_const=1)
 
 
 class FusedType(CType):
@@ -1737,6 +1909,7 @@
             base_code = type_name.replace('PY_LONG_LONG', 'long long')
         else:
             base_code = public_decl(type_name, dll_linkage)
+        base_code = StringEncoding.EncodedString(base_code)
         return self.base_declaration_code(base_code, entity_code)
 
     def attributes_known(self):
@@ -2302,8 +2475,8 @@
 
     def __init__(self, base_type):
         self.base_type = base_type
-        if base_type.is_const:
-            base_type = base_type.const_base_type
+        if base_type.is_cv_qualified:
+            base_type = base_type.cv_base_type
         for char_type in (c_char_type, c_uchar_type, c_schar_type):
             if base_type.same_as(char_type):
                 self.is_string = 1
@@ -2527,8 +2700,8 @@
             return 1
         if other_type.is_null_ptr:
             return 1
-        if self.base_type.is_const:
-            self = CPtrType(self.base_type.const_base_type)
+        if self.base_type.is_cv_qualified:
+            self = CPtrType(self.base_type.cv_base_type)
         if self.base_type.is_cfunction:
             if other_type.is_ptr:
                 other_type = other_type.base_type.resolve()
@@ -3709,8 +3882,8 @@
         return specialized
 
     def deduce_template_params(self, actual):
-        if actual.is_const:
-            actual = actual.const_base_type
+        if actual.is_cv_qualified:
+            actual = actual.cv_base_type
         if actual.is_reference:
             actual = actual.ref_base_type
         if self == actual:
@@ -4452,10 +4625,10 @@
         type1 = type1.ref_base_type
     if type2.is_reference:
         type2 = type2.ref_base_type
-    if type1.is_const:
-        type1 = type1.const_base_type
-    if type2.is_const:
-        type2 = type2.const_base_type
+    if type1.is_cv_qualified:
+        type1 = type1.cv_base_type
+    if type2.is_cv_qualified:
+        type2 = type2.cv_base_type
     if type1 == type2:
         widest_type = type1
     elif type1.is_complex or type2.is_complex:
@@ -4675,6 +4848,13 @@
     else:
         return CConstType(base_type)
 
+def c_const_or_volatile_type(base_type, is_const, is_volatile):
+    # Construct a C const/volatile type.
+    if base_type is error_type:
+        return error_type
+    else:
+        return CConstOrVolatileType(base_type, is_const, is_volatile)
+
 def same_type(type1, type2):
     return type1.same_as(type2)
 
diff --git a/Cython/Compiler/Scanning.pxd b/Cython/Compiler/Scanning.pxd
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL1NjYW5uaW5nLnB4ZA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL1NjYW5uaW5nLnB4ZA== 100644
--- a/Cython/Compiler/Scanning.pxd
+++ b/Cython/Compiler/Scanning.pxd
@@ -9,11 +9,6 @@
 cdef get_lexicon()
 cdef initial_compile_time_env()
 
-cdef class Method:
-    cdef object name
-    cdef dict kwargs
-    cdef readonly object __name__  # for tracing the scanner
-
 ## methods commented with '##' out are used by Parsing.py when compiled.
 
 @cython.final
diff --git a/Cython/Compiler/Scanning.py b/Cython/Compiler/Scanning.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL1NjYW5uaW5nLnB5..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL1NjYW5uaW5nLnB5 100644
--- a/Cython/Compiler/Scanning.py
+++ b/Cython/Compiler/Scanning.py
@@ -1,4 +1,4 @@
-# cython: infer_types=True, language_level=3, py2_import=True, auto_pickle=False
+# cython: infer_types=True, language_level=3, auto_pickle=False
 #
 #   Cython Scanner
 #
@@ -12,6 +12,7 @@
 
 import os
 import platform
+from unicodedata import normalize
 
 from .. import Utils
 from ..Plex.Scanners import Scanner
@@ -41,8 +42,8 @@
     "global", "nonlocal", "def", "class", "print", "del", "pass", "break",
     "continue", "return", "raise", "import", "exec", "try",
     "except", "finally", "while", "if", "elif", "else", "for",
-    "in", "assert", "and", "or", "not", "is", "in", "lambda",
-    "from", "yield", "with", "nonlocal",
+    "in", "assert", "and", "or", "not", "is", "lambda",
+    "from", "yield", "with",
 ]
 
 pyx_reserved_words = py_reserved_words + [
@@ -51,25 +52,6 @@
 ]
 
 
-class Method(object):
-
-    def __init__(self, name, **kwargs):
-        self.name = name
-        self.kwargs = kwargs or None
-        self.__name__ = name  # for Plex tracing
-
-    def __call__(self, stream, text):
-        method = getattr(stream, self.name)
-        # self.kwargs is almost always unused => avoid call overhead
-        return method(text, **self.kwargs) if self.kwargs is not None else method(text)
-
-    def __copy__(self):
-        return self  # immutable, no need to copy
-
-    def __deepcopy__(self, memo):
-        return self  # immutable, no need to copy
-
-
 #------------------------------------------------------------------
 
 class CompileTimeScope(object):
@@ -360,6 +342,13 @@
         self.sy = ''
         self.next()
 
+    def normalize_ident(self, text):
+        try:
+            text.encode('ascii') # really just name.isascii but supports Python 2 and 3
+        except UnicodeEncodeError:
+            text = normalize('NFKC', text)
+        self.produce(IDENT, text)
+
     def commentline(self, text):
         if self.parse_comments:
             self.produce('commentline', text)
diff --git a/Cython/Compiler/StringEncoding.py b/Cython/Compiler/StringEncoding.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL1N0cmluZ0VuY29kaW5nLnB5..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL1N0cmluZ0VuY29kaW5nLnB5 100644
--- a/Cython/Compiler/StringEncoding.py
+++ b/Cython/Compiler/StringEncoding.py
@@ -138,6 +138,24 @@
     def as_utf8_string(self):
         return bytes_literal(self.utf8encode(), 'utf8')
 
+    def as_c_string_literal(self):
+        # first encodes the string then produces a c string literal
+        if self.encoding is None:
+            s = self.as_utf8_string()
+        else:
+            s = bytes_literal(self.byteencode(), self.encoding)
+        return s.as_c_string_literal()
+
+    if not hasattr(_unicode, "isascii"):
+        def isascii(self):
+            # not defined for Python3.7+ since the class already has it
+            try:
+                self.encode("ascii")
+            except UnicodeEncodeError:
+                return False
+            else:
+                return True
+
 
 def string_contains_surrogates(ustring):
     """
@@ -183,6 +201,11 @@
         value = split_string_literal(escape_byte_string(self))
         return '"%s"' % value
 
+    if not hasattr(_bytes, "isascii"):
+        def isascii(self):
+            # already defined for Python3.7+
+            return True
+
 
 def bytes_literal(s, encoding):
     assert isinstance(s, bytes)
@@ -198,6 +221,12 @@
         s.encoding = encoding
     return s
 
+def encoded_string_or_bytes_literal(s, encoding):
+    if isinstance(s, bytes):
+        return bytes_literal(s, encoding)
+    else:
+        return encoded_string(s, encoding)
+
 
 char_from_escape_sequence = {
     r'\a' : u'\a',
diff --git a/Cython/Compiler/Symtab.py b/Cython/Compiler/Symtab.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL1N5bXRhYi5weQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL1N5bXRhYi5weQ== 100644
--- a/Cython/Compiler/Symtab.py
+++ b/Cython/Compiler/Symtab.py
@@ -42,6 +42,28 @@
         cname = Naming.pyrex_prefix + cname
     return cname
 
+def punycodify_name(cname, mangle_with=None):
+    # if passed the mangle_with should be a byte string
+    # modified from  PEP489
+    try:
+        cname.encode('ascii')
+    except UnicodeEncodeError:
+        cname = cname.encode('punycode').replace(b'-', b'_').decode('ascii')
+        if mangle_with:
+            # sometimes it necessary to mangle unicode names alone where
+            # they'll be inserted directly into C, because the punycode
+            # transformation can turn them into invalid identifiers
+            cname = "%s_%s" % (mangle_with, cname)
+        elif cname.startswith(Naming.pyrex_prefix):
+            # a punycode name could also be a valid ascii variable name so
+            # change the prefix to distinguish
+            cname = cname.replace(Naming.pyrex_prefix,
+                                  Naming.pyunicode_identifier_prefix, 1)
+
+    return cname
+
+
+
 
 class BufferAux(object):
     writable_needed = False
@@ -134,6 +156,7 @@
     # cf_used          boolean    Entry is used
     # is_fused_specialized boolean Whether this entry of a cdef or def function
     #                              is a specialization
+    # is_cgetter       boolean    Is a c-level getter function
 
     # TODO: utility_code and utility_code_definition serves the same purpose...
 
@@ -203,6 +226,7 @@
     error_on_uninitialized = False
     cf_used = True
     outer_entry = None
+    is_cgetter = False
 
     def __init__(self, name, cname, type, pos = None, init = None):
         self.name = name
@@ -238,6 +262,10 @@
         else:
             return NotImplemented
 
+    @property
+    def cf_is_reassigned(self):
+        return len(self.cf_assignments) > 1
+
 
 class InnerEntry(Entry):
     """
@@ -347,7 +375,6 @@
         self.defined_c_classes = []
         self.imported_c_classes = {}
         self.cname_to_entry = {}
-        self.string_to_entry = {}
         self.identifier_to_entry = {}
         self.num_to_entry = {}
         self.obj_to_entry = {}
@@ -390,7 +417,7 @@
 
     def mangle(self, prefix, name = None):
         if name:
-            return "%s%s%s" % (prefix, self.scope_prefix, name)
+            return punycodify_name("%s%s%s" % (prefix, self.scope_prefix, name))
         else:
             return self.parent_scope.mangle(prefix, self.name)
 
@@ -443,5 +470,5 @@
         if type.is_buffer and not isinstance(self, LocalScope): # and not is_type:
             error(pos, 'Buffer types only allowed as function local variables')
         if not self.in_cinclude and cname and re.match("^_[_A-Z]+$", cname):
-            # See http://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html#Reserved-Names
+            # See https://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html#Reserved-Names
             warning(pos, "'%s' is a reserved name in C." % cname, -1)
@@ -447,4 +474,5 @@
             warning(pos, "'%s' is a reserved name in C." % cname, -1)
+
         entries = self.entries
         if name and name in entries and not shadow:
             old_entry = entries[name]
@@ -487,8 +515,7 @@
                 entries[name] = entry
 
         if type.is_memoryviewslice:
-            from . import MemoryView
-            entry.init = MemoryView.memslice_entry_init
+            entry.init = type.default_value
 
         entry.scope = self
         entry.visibility = visibility
@@ -698,6 +725,7 @@
         return entry
 
     def declare_builtin(self, name, pos):
+        name = self.mangle_class_private_name(name)
         return self.outer_scope.declare_builtin(name, pos)
 
     def _declare_pyfunction(self, name, pos, visibility='extern', entry=None):
@@ -736,7 +764,7 @@
         qualified_name = self.qualify_name(lambda_name)
 
         entry = self.declare(None, func_cname, py_object_type, pos, 'private')
-        entry.name = lambda_name
+        entry.name = EncodedString(lambda_name)
         entry.qualified_name = qualified_name
         entry.pymethdef_cname = pymethdef_cname
         entry.func_cname = func_cname
@@ -769,7 +797,8 @@
                 entry.cname = cname
                 entry.func_cname = cname
             if visibility != 'private' and visibility != entry.visibility:
-                warning(pos, "Function '%s' previously declared as '%s', now as '%s'" % (name, entry.visibility, visibility), 1)
+                warning(pos, "Function '%s' previously declared as '%s', now as '%s'" % (
+                    name, entry.visibility, visibility), 1)
             if overridable != entry.is_overridable:
                 warning(pos, "Function '%s' previously declared as '%s'" % (
                     name, 'cpdef' if overridable else 'cdef'), 1)
@@ -822,6 +851,7 @@
         if overridable:
             # names of cpdef functions can be used as variables and can be assigned to
             var_entry = Entry(name, cname, py_object_type)   # FIXME: cname?
+            var_entry.qualified_name = self.qualify_name(name)
             var_entry.is_variable = 1
             var_entry.is_pyglobal = 1
             var_entry.scope = entry.scope
@@ -829,7 +859,25 @@
         type.entry = entry
         return entry
 
-    def add_cfunction(self, name, type, pos, cname, visibility, modifiers, inherited=False):
+    def declare_cgetter(self, name, return_type, pos=None, cname=None,
+                        visibility="private", modifiers=(), defining=False, **cfunc_type_config):
+        assert all(
+            k in ('exception_value', 'exception_check', 'nogil', 'with_gil', 'is_const_method', 'is_static_method')
+            for k in cfunc_type_config
+        )
+        cfunc_type = PyrexTypes.CFuncType(
+            return_type,
+            [PyrexTypes.CFuncTypeArg("self", self.parent_type, None)],
+            **cfunc_type_config)
+        entry = self.declare_cfunction(
+            name, cfunc_type, pos, cname=None, visibility=visibility, modifiers=modifiers, defining=defining)
+        entry.is_cgetter = True
+        if cname is not None:
+            entry.func_cname = cname
+        return entry
+
+    def add_cfunction(self, name, type, pos, cname, visibility, modifiers,
+                      inherited=False):
         # Add a C function entry without giving it a func_cname.
         entry = self.declare(name, cname, type, pos, visibility)
         entry.is_cfunction = 1
@@ -874,9 +922,20 @@
     def lookup(self, name):
         # Look up name in this scope or an enclosing one.
         # Return None if not found.
-        return (self.lookup_here(name)
-            or (self.outer_scope and self.outer_scope.lookup(name))
-            or None)
+
+        mangled_name = self.mangle_class_private_name(name)
+        entry = (self.lookup_here(name)  # lookup here also does mangling
+                or (self.outer_scope and self.outer_scope.lookup(mangled_name))
+                or None)
+        if entry:
+            return entry
+
+        # look up the original name in the outer scope
+        # Not strictly Python behaviour but see https://github.com/cython/cython/issues/3544
+        entry = (self.outer_scope and self.outer_scope.lookup(name)) or None
+        if entry and entry.is_pyglobal:
+            self._emit_class_private_warning(entry.pos, name)
+        return entry
 
     def lookup_here(self, name):
         # Look up in this scope only, return None if not found.
@@ -880,6 +939,16 @@
 
     def lookup_here(self, name):
         # Look up in this scope only, return None if not found.
+
+        entry = self.entries.get(self.mangle_class_private_name(name), None)
+        if entry:
+            return entry
+        # Also check the unmangled name in the current scope
+        # (even if mangling should give us something else).
+        # This is to support things like global __foo which makes a declaration for __foo
+        return self.entries.get(name, None)
+
+    def lookup_here_unmangled(self, name):
         return self.entries.get(name, None)
 
     def lookup_target(self, name):
@@ -887,6 +956,10 @@
         # variable if not found.
         entry = self.lookup_here(name)
         if not entry:
+            entry = self.lookup_here_unmangled(name)
+            if entry and entry.is_pyglobal:
+                self._emit_class_private_warning(entry.pos, name)
+        if not entry:
             entry = self.declare_var(name, py_object_type, None)
         return entry
 
@@ -903,8 +976,7 @@
             method = obj_type.scope.lookup("operator%s" % operator)
             if method is not None:
                 arg_types = [arg.type for arg in operands[1:]]
-                res = PyrexTypes.best_match([arg.type for arg in operands[1:]],
-                                            method.all_alternatives())
+                res = PyrexTypes.best_match(arg_types, method.all_alternatives())
                 if res is not None:
                     return res
         function = self.lookup("operator%s" % operator)
@@ -938,6 +1010,11 @@
         operands = [FakeOperand(pos, type=type) for type in types]
         return self.lookup_operator(operator, operands)
 
+    def _emit_class_private_warning(self, pos, name):
+        warning(pos, "Global name %s matched from within class scope "
+                            "in contradiction to to Python 'class private name' rules. "
+                            "This may change in a future release." % name, 1)
+
     def use_utility_code(self, new_code):
         self.global_scope().use_utility_code(new_code)
 
@@ -1026,11 +1103,10 @@
         # If python_equiv == "*", the Python equivalent has the same name
         # as the entry, otherwise it has the name specified by python_equiv.
         name = EncodedString(name)
-        entry = self.declare_cfunction(name, type, None, cname, visibility='extern',
-                                       utility_code=utility_code)
+        entry = self.declare_cfunction(name, type, None, cname, visibility='extern', utility_code=utility_code)
         if python_equiv:
             if python_equiv == "*":
                 python_equiv = name
             else:
                 python_equiv = EncodedString(python_equiv)
             var_entry = Entry(python_equiv, python_equiv, py_object_type)
@@ -1031,9 +1107,10 @@
         if python_equiv:
             if python_equiv == "*":
                 python_equiv = name
             else:
                 python_equiv = EncodedString(python_equiv)
             var_entry = Entry(python_equiv, python_equiv, py_object_type)
+            var_entry.qualified_name = self.qualify_name(name)
             var_entry.is_variable = 1
             var_entry.is_builtin = 1
             var_entry.utility_code = utility_code
@@ -1057,6 +1134,7 @@
             type = self.lookup('type').type, # make sure "type" is the first type declared...
             pos = entry.pos,
             cname = entry.type.typeptr_cname)
+        var_entry.qualified_name = self.qualify_name(name)
         var_entry.is_variable = 1
         var_entry.is_cglobal = 1
         var_entry.is_readonly = 1
@@ -1113,7 +1191,6 @@
     # utility_code_list    [UtilityCode]      Queuing utility codes for forwarding to Code.py
     # c_includes           {key: IncludeCode} C headers or verbatim code to be generated
     #                                         See process_include() for more documentation
-    # string_to_entry      {string : Entry}   Map string const to entry
     # identifier_to_entry  {string : Entry}   Map identifier string const to entry
     # context              Context
     # parent_module        Scope              Parent in the import namespace
@@ -1244,6 +1321,7 @@
         else:
             entry.is_builtin = 1
             entry.name = name
+        entry.qualified_name = self.builtin_scope().qualify_name(name)
         return entry
 
     def find_module(self, module_name, pos, relative_level=-1):
@@ -1707,6 +1785,7 @@
             type = Builtin.type_type,
             pos = entry.pos,
             cname = entry.type.typeptr_cname)
+        var_entry.qualified_name = entry.qualified_name
         var_entry.is_variable = 1
         var_entry.is_cglobal = 1
         var_entry.is_readonly = 1
@@ -1735,7 +1814,7 @@
         Scope.__init__(self, name, outer_scope, parent_scope)
 
     def mangle(self, prefix, name):
-        return prefix + name
+        return punycodify_name(prefix + name)
 
     def declare_arg(self, name, type, pos):
         # Add an entry for an argument of a function.
@@ -1739,6 +1818,7 @@
 
     def declare_arg(self, name, type, pos):
         # Add an entry for an argument of a function.
+        name = self.mangle_class_private_name(name)
         cname = self.mangle(Naming.var_prefix, name)
         entry = self.declare(name, cname, type, pos, 'private')
         entry.is_variable = 1
@@ -1752,6 +1832,7 @@
     def declare_var(self, name, type, pos,
                     cname = None, visibility = 'private',
                     api = 0, in_pxd = 0, is_cdef = 0):
+        name = self.mangle_class_private_name(name)
         # Add an entry for a local variable.
         if visibility in ('public', 'readonly'):
             error(pos, "Local variable cannot be declared %s" % visibility)
@@ -1788,6 +1869,7 @@
     def lookup(self, name):
         # Look up name in this scope or an enclosing one.
         # Return None if not found.
+
         entry = Scope.lookup(self, name)
         if entry is not None:
             entry_scope = entry.scope
@@ -1949,6 +2031,14 @@
     #                          declared in the class
     #  doc    string or None   Doc string
 
+    def mangle_class_private_name(self, name):
+        # a few utilitycode names need to specifically be ignored
+        if name and name.lower().startswith("__pyx_"):
+            return name
+        if name and name.startswith('__') and not name.endswith('__'):
+            name = EncodedString('_%s%s' % (self.class_name.lstrip('_'), name))
+        return name
+
     def __init__(self, name, outer_scope):
         Scope.__init__(self, name, outer_scope, outer_scope)
         self.class_name = name
@@ -1982,18 +2072,6 @@
 
     is_py_class_scope = 1
 
-    def mangle_class_private_name(self, name):
-        return self.mangle_special_name(name)
-
-    def mangle_special_name(self, name):
-        if name and name.startswith('__') and not name.endswith('__'):
-            name = EncodedString('_%s%s' % (self.class_name.lstrip('_'), name))
-        return name
-
-    def lookup_here(self, name):
-        name = self.mangle_special_name(name)
-        return ClassScope.lookup_here(self, name)
-
     def declare_var(self, name, type, pos,
                     cname = None, visibility = 'private',
                     api = 0, in_pxd = 0, is_cdef = 0):
@@ -1997,7 +2075,7 @@
     def declare_var(self, name, type, pos,
                     cname = None, visibility = 'private',
                     api = 0, in_pxd = 0, is_cdef = 0):
-        name = self.mangle_special_name(name)
+        name = self.mangle_class_private_name(name)
         if type is unspecified_type:
             type = py_object_type
         # Add an entry for a class attribute.
@@ -2038,7 +2116,7 @@
 class CClassScope(ClassScope):
     #  Namespace of an extension type.
     #
-    #  parent_type           CClassType
+    #  parent_type           PyExtensionType
     #  #typeobj_cname        string or None
     #  #objstruct_cname      string
     #  method_table_cname    string
@@ -2082,6 +2160,22 @@
             return not self.parent_type.is_gc_simple
         return False
 
+    def needs_trashcan(self):
+        # If the trashcan directive is explicitly set to False,
+        # unconditionally disable the trashcan.
+        directive = self.directives.get('trashcan')
+        if directive is False:
+            return False
+        # If the directive is set to True and the class has Python-valued
+        # C attributes, then it should use the trashcan in tp_dealloc.
+        if directive and self.has_cyclic_pyobject_attrs:
+            return True
+        # Use the trashcan if the base class uses it
+        base_type = self.parent_type.base_type
+        if base_type and base_type.scope is not None:
+            return base_type.scope.needs_trashcan()
+        return self.parent_type.builtin_trashcan
+
     def needs_tp_clear(self):
         """
         Do we need to generate an implementation for the tp_clear slot? Can
@@ -2111,6 +2205,7 @@
     def declare_var(self, name, type, pos,
                     cname = None, visibility = 'private',
                     api = 0, in_pxd = 0, is_cdef = 0):
+        name = self.mangle_class_private_name(name)
         if is_cdef:
             # Add an entry for an attribute.
             if self.defined:
@@ -2125,6 +2220,7 @@
                 cname = name
                 if visibility == 'private':
                     cname = c_safe_identifier(cname)
+                cname = punycodify_name(cname, Naming.unicode_structmember_prefix)
             if type.is_cpp_class and visibility != 'extern':
                 type.check_nullary_constructor(pos)
                 self.use_utility_code(Code.UtilityCode("#include <new>"))
@@ -2168,6 +2264,7 @@
                                   # I keep it in for now. is_member should be enough
                                   # later on
             self.namespace_cname = "(PyObject *)%s" % self.parent_type.typeptr_cname
+
             return entry
 
     def declare_pyfunction(self, name, pos, allow_redefine=False):
@@ -2215,6 +2312,7 @@
     def declare_cfunction(self, name, type, pos,
                           cname=None, visibility='private', api=0, in_pxd=0,
                           defining=0, modifiers=(), utility_code=None, overridable=False):
+        name = self.mangle_class_private_name(name)
         if get_special_method_signature(name) and not self.parent_type.is_builtin_type:
             error(pos, "Special methods must be declared with 'def', not 'cdef'")
         args = type.args
@@ -2226,7 +2324,7 @@
                       (args[0].type, name, self.parent_type))
         entry = self.lookup_here(name)
         if cname is None:
-            cname = c_safe_identifier(name)
+            cname = punycodify_name(c_safe_identifier(name), Naming.unicode_vtabentry_prefix)
         if entry:
             if not entry.is_cfunction:
                 warning(pos, "'%s' redeclared  " % name, 0)
@@ -2258,7 +2356,8 @@
                 error(pos,
                     "C method '%s' not previously declared in definition part of"
                     " extension type '%s'" % (name, self.class_name))
-            entry = self.add_cfunction(name, type, pos, cname, visibility, modifiers)
+            entry = self.add_cfunction(name, type, pos, cname, visibility,
+                                                 modifiers)
         if defining:
             entry.func_cname = self.mangle(Naming.func_prefix, name)
         entry.utility_code = utility_code
@@ -2274,7 +2373,8 @@
 
         return entry
 
-    def add_cfunction(self, name, type, pos, cname, visibility, modifiers, inherited=False):
+    def add_cfunction(self, name, type, pos, cname, visibility, modifiers,
+                                             inherited=False):
         # Add a cfunction entry without giving it a func_cname.
         prev_entry = self.lookup_here(name)
         entry = ClassScope.add_cfunction(self, name, type, pos, cname,
@@ -2278,7 +2378,8 @@
         # Add a cfunction entry without giving it a func_cname.
         prev_entry = self.lookup_here(name)
         entry = ClassScope.add_cfunction(self, name, type, pos, cname,
-                                         visibility, modifiers, inherited=inherited)
+                                    visibility, modifiers,
+                                    inherited=inherited)
         entry.is_cmethod = 1
         entry.prev_entry = prev_entry
         return entry
@@ -2287,6 +2388,6 @@
         # overridden methods of builtin types still have their Python
         # equivalent that must be accessible to support bound methods
         name = EncodedString(name)
-        entry = self.declare_cfunction(name, type, None, cname, visibility='extern',
-                                       utility_code=utility_code)
+        entry = self.declare_cfunction(
+            name, type, pos=None, cname=cname, visibility='extern', utility_code=utility_code)
         var_entry = Entry(name, name, py_object_type)
@@ -2292,4 +2393,5 @@
         var_entry = Entry(name, name, py_object_type)
+        var_entry.qualified_name = name
         var_entry.is_variable = 1
         var_entry.is_builtin = 1
         var_entry.utility_code = utility_code
@@ -2403,7 +2505,7 @@
         class_name = self.name.split('::')[-1]
         if name in (class_name, '__init__') and cname is None:
             cname = "%s__init__%s" % (Naming.func_prefix, class_name)
-            name = '<init>'
+            name = EncodedString('<init>')
             type.return_type = PyrexTypes.CVoidType()
             # This is called by the actual constructor, but need to support
             # arguments that cannot by called by value.
@@ -2417,7 +2519,7 @@
             type.args = [maybe_ref(arg) for arg in type.args]
         elif name == '__dealloc__' and cname is None:
             cname = "%s__dealloc__%s" % (Naming.func_prefix, class_name)
-            name = '<del>'
+            name = EncodedString('<del>')
             type.return_type = PyrexTypes.CVoidType()
         if name in ('<init>', '<del>') and type.nogil:
             for base in self.type.base_classes:
@@ -2523,5 +2625,5 @@
             return None
 
 
-class CConstScope(Scope):
+class CConstOrVolatileScope(Scope):
 
@@ -2527,4 +2629,4 @@
 
-    def __init__(self, const_base_type_scope):
+    def __init__(self, base_type_scope, is_const=0, is_volatile=0):
         Scope.__init__(
             self,
@@ -2529,8 +2631,10 @@
         Scope.__init__(
             self,
-            'const_' + const_base_type_scope.name,
-            const_base_type_scope.outer_scope,
-            const_base_type_scope.parent_scope)
-        self.const_base_type_scope = const_base_type_scope
+            'cv_' + base_type_scope.name,
+            base_type_scope.outer_scope,
+            base_type_scope.parent_scope)
+        self.base_type_scope = base_type_scope
+        self.is_const = is_const
+        self.is_volatile = is_volatile
 
     def lookup_here(self, name):
@@ -2535,5 +2639,5 @@
 
     def lookup_here(self, name):
-        entry = self.const_base_type_scope.lookup_here(name)
+        entry = self.base_type_scope.lookup_here(name)
         if entry is not None:
             entry = copy.copy(entry)
@@ -2538,5 +2642,6 @@
         if entry is not None:
             entry = copy.copy(entry)
-            entry.type = PyrexTypes.c_const_type(entry.type)
+            entry.type = PyrexTypes.c_const_or_volatile_type(
+                    entry.type, self.is_const, self.is_volatile)
             return entry
 
@@ -2541,5 +2646,6 @@
             return entry
 
+
 class TemplateScope(Scope):
     def __init__(self, name, outer_scope):
         Scope.__init__(self, name, outer_scope, None)
diff --git a/Cython/Compiler/Tests/TestBuffer.py b/Cython/Compiler/Tests/TestBuffer.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL1Rlc3RzL1Rlc3RCdWZmZXIucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL1Rlc3RzL1Rlc3RCdWZmZXIucHk= 100644
--- a/Cython/Compiler/Tests/TestBuffer.py
+++ b/Cython/Compiler/Tests/TestBuffer.py
@@ -21,7 +21,7 @@
     def test_basic(self):
         t = self.parse(u"cdef object[float, 4, ndim=2, foo=foo] x")
         bufnode = t.stats[0].base_type
-        self.assert_(isinstance(bufnode, TemplatedTypeNode))
+        self.assertTrue(isinstance(bufnode, TemplatedTypeNode))
         self.assertEqual(2, len(bufnode.positional_args))
 #        print bufnode.dump()
         # should put more here...
@@ -46,7 +46,7 @@
     def nonfatal_error(self, error):
         # We're passing self as context to transform to trap this
         self.error = error
-        self.assert_(self.expect_error)
+        self.assertTrue(self.expect_error)
 
     def parse_opts(self, opts, expect_error=False):
         assert opts != ""
@@ -57,8 +57,8 @@
             vardef = root.stats[0].body.stats[0]
             assert isinstance(vardef, CVarDefNode) # use normal assert as this is to validate the test code
             buftype = vardef.base_type
-            self.assert_(isinstance(buftype, TemplatedTypeNode))
-            self.assert_(isinstance(buftype.base_type_node, CSimpleBaseTypeNode))
+            self.assertTrue(isinstance(buftype, TemplatedTypeNode))
+            self.assertTrue(isinstance(buftype.base_type_node, CSimpleBaseTypeNode))
             self.assertEqual(u"object", buftype.base_type_node.name)
             return buftype
         else:
@@ -62,7 +62,7 @@
             self.assertEqual(u"object", buftype.base_type_node.name)
             return buftype
         else:
-            self.assert_(len(root.stats[0].body.stats) == 0)
+            self.assertTrue(len(root.stats[0].body.stats) == 0)
 
     def non_parse(self, expected_err, opts):
         self.parse_opts(opts, expect_error=True)
@@ -71,9 +71,9 @@
 
     def __test_basic(self):
         buf = self.parse_opts(u"unsigned short int, 3")
-        self.assert_(isinstance(buf.dtype_node, CSimpleBaseTypeNode))
-        self.assert_(buf.dtype_node.signed == 0 and buf.dtype_node.longness == -1)
+        self.assertTrue(isinstance(buf.dtype_node, CSimpleBaseTypeNode))
+        self.assertTrue(buf.dtype_node.signed == 0 and buf.dtype_node.longness == -1)
         self.assertEqual(3, buf.ndim)
 
     def __test_dict(self):
         buf = self.parse_opts(u"ndim=3, dtype=unsigned short int")
@@ -76,9 +76,9 @@
         self.assertEqual(3, buf.ndim)
 
     def __test_dict(self):
         buf = self.parse_opts(u"ndim=3, dtype=unsigned short int")
-        self.assert_(isinstance(buf.dtype_node, CSimpleBaseTypeNode))
-        self.assert_(buf.dtype_node.signed == 0 and buf.dtype_node.longness == -1)
+        self.assertTrue(isinstance(buf.dtype_node, CSimpleBaseTypeNode))
+        self.assertTrue(buf.dtype_node.signed == 0 and buf.dtype_node.longness == -1)
         self.assertEqual(3, buf.ndim)
 
     def __test_ndim(self):
@@ -94,8 +94,8 @@
             cdef object[ndim=ndim, dtype=int] y
         """, pipeline=[NormalizeTree(self), PostParse(self)]).root
         stats = t.stats[0].body.stats
-        self.assert_(stats[0].base_type.ndim == 3)
-        self.assert_(stats[1].base_type.ndim == 3)
+        self.assertTrue(stats[0].base_type.ndim == 3)
+        self.assertTrue(stats[1].base_type.ndim == 3)
 
     # add exotic and impossible combinations as they come along...
 
diff --git a/Cython/Compiler/Tests/TestCmdLine.py b/Cython/Compiler/Tests/TestCmdLine.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL1Rlc3RzL1Rlc3RDbWRMaW5lLnB5..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL1Rlc3RzL1Rlc3RDbWRMaW5lLnB5 100644
--- a/Cython/Compiler/Tests/TestCmdLine.py
+++ b/Cython/Compiler/Tests/TestCmdLine.py
@@ -1,4 +1,4 @@
-
+import os
 import sys
 from unittest import TestCase
 try:
@@ -9,6 +9,8 @@
 from .. import Options
 from ..CmdLine import parse_command_line
 
+from .Utils import backup_Options, restore_Options, check_global_options
+
 
 class CmdLineParserTest(TestCase):
     def setUp(self):
@@ -12,9 +14,6 @@
 
 class CmdLineParserTest(TestCase):
     def setUp(self):
-        backup = {}
-        for name, value in vars(Options).items():
-            backup[name] = value
-        self._options_backup = backup
+        self._options_backup = backup_Options()
 
     def tearDown(self):
@@ -19,3 +18,10 @@
 
     def tearDown(self):
+        restore_Options(self._options_backup)
+
+    def check_default_global_options(self, white_list=[]):
+        self.assertEqual(check_global_options(self._options_backup, white_list), "")
+
+    def check_default_options(self, options, white_list=[]):
+        default_options = Options.CompilationOptions(Options.default_options)
         no_value = object()
@@ -21,7 +27,7 @@
         no_value = object()
-        for name, orig_value in self._options_backup.items():
-            if getattr(Options, name, no_value) != orig_value:
-                setattr(Options, name, orig_value)
+        for name in default_options.__dict__.keys():
+            if name not in white_list:
+               self.assertEqual(getattr(options, name, no_value), getattr(default_options, name), msg="error in option " + name)
 
     def test_short_options(self):
         options, sources = parse_command_line([
@@ -97,6 +103,397 @@
         self.assertEqual(Options.annotate_coverage_xml, 'cov.xml')
         self.assertTrue(options.gdb_debug)
         self.assertEqual(options.output_dir, '/gdb/outdir')
+        self.assertEqual(options.compiler_directives['wraparound'], False)
+
+    def test_embed_before_positional(self):
+        options, sources = parse_command_line([
+            '--embed',
+            'source.pyx',
+        ])
+        self.assertEqual(sources, ['source.pyx'])
+        self.assertEqual(Options.embed, 'main')
+
+    def test_two_embeds(self):
+        options, sources = parse_command_line([
+            '--embed', '--embed=huhu',
+            'source.pyx',
+        ])
+        self.assertEqual(sources, ['source.pyx'])
+        self.assertEqual(Options.embed, 'huhu')
+
+    def test_two_embeds2(self):
+        options, sources = parse_command_line([
+            '--embed=huhu', '--embed',
+            'source.pyx',
+        ])
+        self.assertEqual(sources, ['source.pyx'])
+        self.assertEqual(Options.embed, 'main')
+
+    def test_no_annotate(self):
+        options, sources = parse_command_line([
+            '--embed=huhu', 'source.pyx'
+        ])
+        self.assertFalse(Options.annotate)
+
+    def test_annotate_short(self):
+        options, sources = parse_command_line([
+            '-a',
+            'source.pyx',
+        ])
+        self.assertEqual(Options.annotate, 'default')
+
+    def test_annotate_long(self):
+        options, sources = parse_command_line([
+            '--annotate',
+            'source.pyx',
+        ])
+        self.assertEqual(Options.annotate, 'default')
+
+    def test_annotate_fullc(self):
+        options, sources = parse_command_line([
+            '--annotate-fullc',
+            'source.pyx',
+        ])
+        self.assertEqual(Options.annotate, 'fullc')
+
+    def test_short_w(self):
+       options, sources = parse_command_line([
+                '-w', 'my_working_path',
+                'source.pyx'
+       ])
+       self.assertEqual(options.working_path, 'my_working_path')
+       self.check_default_global_options()
+       self.check_default_options(options, ['working_path'])
+
+    def test_short_o(self):
+       options, sources = parse_command_line([
+                '-o', 'my_output',
+                'source.pyx'
+       ])
+       self.assertEqual(options.output_file, 'my_output')
+       self.check_default_global_options()
+       self.check_default_options(options, ['output_file'])
+
+    def test_short_z(self):
+       options, sources = parse_command_line([
+                '-z', 'my_preimport',
+                'source.pyx'
+       ])
+       self.assertEqual(Options.pre_import, 'my_preimport')
+       self.check_default_global_options(['pre_import'])
+       self.check_default_options(options)
+
+    def test_convert_range(self):
+       options, sources = parse_command_line([
+                '--convert-range',
+                'source.pyx'
+       ])
+       self.assertEqual(Options.convert_range, True)
+       self.check_default_global_options(['convert_range'])
+       self.check_default_options(options)
+
+    def test_line_directives(self):
+       options, sources = parse_command_line([
+                '--line-directives',
+                'source.pyx'
+       ])
+       self.assertEqual(options.emit_linenums, True)
+       self.check_default_global_options()
+       self.check_default_options(options, ['emit_linenums'])
+
+    def test_no_c_in_traceback(self):
+       options, sources = parse_command_line([
+                '--no-c-in-traceback',
+                'source.pyx'
+       ])
+       self.assertEqual(options.c_line_in_traceback, False)
+       self.check_default_global_options()
+       self.check_default_options(options, ['c_line_in_traceback'])
+
+    def test_gdb(self):
+       options, sources = parse_command_line([
+                '--gdb',
+                'source.pyx'
+       ])
+       self.assertEqual(options.gdb_debug, True)
+       self.assertEqual(options.output_dir, os.curdir)
+       self.check_default_global_options()
+       self.check_default_options(options, ['gdb_debug', 'output_dir'])
+
+    def test_3str(self):
+       options, sources = parse_command_line([
+                '--3str',
+                'source.pyx'
+       ])
+       self.assertEqual(options.language_level, '3str')
+       self.check_default_global_options()
+       self.check_default_options(options, ['language_level'])
+
+    def test_capi_reexport_cincludes(self):
+       options, sources = parse_command_line([
+                '--capi-reexport-cincludes',
+                'source.pyx'
+       ])
+       self.assertEqual(options.capi_reexport_cincludes, True)
+       self.check_default_global_options()
+       self.check_default_options(options, ['capi_reexport_cincludes'])
+
+    def test_fast_fail(self):
+       options, sources = parse_command_line([
+                '--fast-fail',
+                'source.pyx'
+       ])
+       self.assertEqual(Options.fast_fail, True)
+       self.check_default_global_options(['fast_fail'])
+       self.check_default_options(options)
+
+    def test_cimport_from_pyx(self):
+       options, sources = parse_command_line([
+                '--cimport-from-pyx',
+                'source.pyx'
+       ])
+       self.assertEqual(Options.cimport_from_pyx, True)
+       self.check_default_global_options(['cimport_from_pyx'])
+       self.check_default_options(options)
+
+    def test_Werror(self):
+       options, sources = parse_command_line([
+                '-Werror',
+                'source.pyx'
+       ])
+       self.assertEqual(Options.warning_errors, True)
+       self.check_default_global_options(['warning_errors'])
+       self.check_default_options(options)
+
+    def test_warning_errors(self):
+       options, sources = parse_command_line([
+                '--warning-errors',
+                'source.pyx'
+       ])
+       self.assertEqual(Options.warning_errors, True)
+       self.check_default_global_options(['warning_errors'])
+       self.check_default_options(options)
+
+    def test_Wextra(self):
+       options, sources = parse_command_line([
+                '-Wextra',
+                'source.pyx'
+       ])
+       self.assertEqual(options.compiler_directives, Options.extra_warnings)
+       self.check_default_global_options()
+       self.check_default_options(options, ['compiler_directives'])
+
+    def test_warning_extra(self):
+       options, sources = parse_command_line([
+                '--warning-extra',
+                'source.pyx'
+       ])
+       self.assertEqual(options.compiler_directives, Options.extra_warnings)
+       self.check_default_global_options()
+       self.check_default_options(options, ['compiler_directives'])
+
+    def test_old_style_globals(self):
+       options, sources = parse_command_line([
+                '--old-style-globals',
+                'source.pyx'
+       ])
+       self.assertEqual(Options.old_style_globals, True)
+       self.check_default_global_options(['old_style_globals'])
+       self.check_default_options(options)
+
+    def test_directive_multiple(self):
+        options, source = parse_command_line([
+               '-X', 'cdivision=True',
+               '-X', 'c_string_type=bytes',
+               'source.pyx'
+        ])
+        self.assertEqual(options.compiler_directives['cdivision'], True)
+        self.assertEqual(options.compiler_directives['c_string_type'], 'bytes')
+        self.check_default_global_options()
+        self.check_default_options(options, ['compiler_directives'])
+
+    def test_directive_multiple_v2(self):
+        options, source = parse_command_line([
+               '-X', 'cdivision=True,c_string_type=bytes',
+               'source.pyx'
+        ])
+        self.assertEqual(options.compiler_directives['cdivision'], True)
+        self.assertEqual(options.compiler_directives['c_string_type'], 'bytes')
+        self.check_default_global_options()
+        self.check_default_options(options, ['compiler_directives'])
+
+    def test_directive_value_yes(self):
+        options, source = parse_command_line([
+               '-X', 'cdivision=YeS',
+               'source.pyx'
+        ])
+        self.assertEqual(options.compiler_directives['cdivision'], True)
+        self.check_default_global_options()
+        self.check_default_options(options, ['compiler_directives'])
+
+    def test_directive_value_no(self):
+        options, source = parse_command_line([
+               '-X', 'cdivision=no',
+               'source.pyx'
+        ])
+        self.assertEqual(options.compiler_directives['cdivision'], False)
+        self.check_default_global_options()
+        self.check_default_options(options, ['compiler_directives'])
+
+    def test_directive_value_invalid(self):
+        self.assertRaises(ValueError, parse_command_line, [
+               '-X', 'cdivision=sadfasd',
+               'source.pyx'
+        ])
+
+    def test_directive_key_invalid(self):
+        self.assertRaises(ValueError, parse_command_line, [
+               '-X', 'abracadabra',
+               'source.pyx'
+        ])
+
+    def test_directive_no_value(self):
+        self.assertRaises(ValueError, parse_command_line, [
+               '-X', 'cdivision',
+               'source.pyx'
+        ])
+
+    def test_compile_time_env_short(self):
+        options, source = parse_command_line([
+               '-E', 'MYSIZE=10',
+               'source.pyx'
+        ])
+        self.assertEqual(options.compile_time_env['MYSIZE'], 10)
+        self.check_default_global_options()
+        self.check_default_options(options, ['compile_time_env'])
+
+    def test_compile_time_env_long(self):
+        options, source = parse_command_line([
+               '--compile-time-env', 'MYSIZE=10',
+               'source.pyx'
+        ])
+        self.assertEqual(options.compile_time_env['MYSIZE'], 10)
+        self.check_default_global_options()
+        self.check_default_options(options, ['compile_time_env'])
+
+    def test_compile_time_env_multiple(self):
+        options, source = parse_command_line([
+               '-E', 'MYSIZE=10', '-E', 'ARRSIZE=11',
+               'source.pyx'
+        ])
+        self.assertEqual(options.compile_time_env['MYSIZE'], 10)
+        self.assertEqual(options.compile_time_env['ARRSIZE'], 11)
+        self.check_default_global_options()
+        self.check_default_options(options, ['compile_time_env'])
+
+    def test_compile_time_env_multiple_v2(self):
+        options, source = parse_command_line([
+               '-E', 'MYSIZE=10,ARRSIZE=11',
+               'source.pyx'
+        ])
+        self.assertEqual(options.compile_time_env['MYSIZE'], 10)
+        self.assertEqual(options.compile_time_env['ARRSIZE'], 11)
+        self.check_default_global_options()
+        self.check_default_options(options, ['compile_time_env'])
+
+    def test_option_first(self):
+        options, sources = parse_command_line(['-V', 'file.pyx'])
+        self.assertEqual(sources, ['file.pyx'])
+
+    def test_file_inbetween(self):
+        options, sources = parse_command_line(['-V', 'file.pyx', '-a'])
+        self.assertEqual(sources, ['file.pyx'])
+
+    def test_option_trailing(self):
+        options, sources = parse_command_line(['file.pyx', '-V'])
+        self.assertEqual(sources, ['file.pyx'])
+
+    def test_multiple_files(self):
+        options, sources = parse_command_line([
+             'file1.pyx', '-V',
+             'file2.pyx', '-a',
+             'file3.pyx'
+        ])
+        self.assertEqual(sources, ['file1.pyx', 'file2.pyx', 'file3.pyx'])
+
+    def test_debug_flags(self):
+        options, sources = parse_command_line([
+             '--debug-disposal-code', '--debug-coercion',
+             'file3.pyx'
+        ])
+        from Cython.Compiler import DebugFlags
+        for name in ['debug_disposal_code', 'debug_temp_alloc', 'debug_coercion']:
+            self.assertEqual(getattr(DebugFlags, name), name in ['debug_disposal_code', 'debug_coercion'])
+            setattr(DebugFlags, name, 0)  # restore original value
+
+    def test_gdb_overwrites_gdb_outdir(self):
+        options, sources = parse_command_line([
+            '--gdb-outdir=my_dir', '--gdb',
+            'file3.pyx'
+        ])
+        self.assertEqual(options.gdb_debug, True)
+        self.assertEqual(options.output_dir, os.curdir)
+        self.check_default_global_options()
+        self.check_default_options(options, ['gdb_debug', 'output_dir'])
+
+    def test_gdb_first(self):
+        options, sources = parse_command_line([
+            '--gdb', '--gdb-outdir=my_dir',
+            'file3.pyx'
+        ])
+        self.assertEqual(options.gdb_debug, True)
+        self.assertEqual(options.output_dir, 'my_dir')
+        self.check_default_global_options()
+        self.check_default_options(options, ['gdb_debug', 'output_dir'])
+
+    def test_coverage_overwrites_annotation(self):
+        options, sources = parse_command_line([
+            '--annotate-fullc', '--annotate-coverage=my.xml',
+            'file3.pyx'
+        ])
+        self.assertEqual(Options.annotate, True)
+        self.assertEqual(Options.annotate_coverage_xml, 'my.xml')
+        self.check_default_global_options(['annotate', 'annotate_coverage_xml'])
+        self.check_default_options(options)
+
+    def test_coverage_first(self):
+        options, sources = parse_command_line([
+            '--annotate-coverage=my.xml', '--annotate-fullc',
+            'file3.pyx'
+        ])
+        self.assertEqual(Options.annotate, 'fullc')
+        self.assertEqual(Options.annotate_coverage_xml, 'my.xml')
+        self.check_default_global_options(['annotate', 'annotate_coverage_xml'])
+        self.check_default_options(options)
+
+    def test_annotate_first_fullc_second(self):
+        options, sources = parse_command_line([
+            '--annotate', '--annotate-fullc',
+            'file3.pyx'
+        ])
+        self.assertEqual(Options.annotate, 'fullc')
+        self.check_default_global_options(['annotate'])
+        self.check_default_options(options)
+
+    def test_annotate_fullc_first(self):
+        options, sources = parse_command_line([
+            '--annotate-fullc', '--annotate',
+            'file3.pyx'
+        ])
+        self.assertEqual(Options.annotate, 'default')
+        self.check_default_global_options(['annotate'])
+        self.check_default_options(options)
+
+    def test_warning_extra_dont_overwrite(self):
+       options, sources = parse_command_line([
+                '-X', 'cdivision=True',
+                '--warning-extra',
+                '-X', 'c_string_type=bytes',
+                'source.pyx'
+       ])
+       self.assertTrue(len(options.compiler_directives), len(Options.extra_warnings) + 1)
+       self.check_default_global_options()
+       self.check_default_options(options, ['compiler_directives'])
 
     def test_errors(self):
         def error(*args):
@@ -116,3 +513,4 @@
         error('--verbose=1')
         error('--verbose=1')
         error('--cleanup')
+        error('--debug-disposal-code-wrong-name', 'file3.pyx')
diff --git a/Cython/Compiler/Tests/TestGrammar.py b/Cython/Compiler/Tests/TestGrammar.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL1Rlc3RzL1Rlc3RHcmFtbWFyLnB5..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL1Rlc3RzL1Rlc3RHcmFtbWFyLnB5 100644
--- a/Cython/Compiler/Tests/TestGrammar.py
+++ b/Cython/Compiler/Tests/TestGrammar.py
@@ -27,4 +27,10 @@
     '1e1_0',
     '.1_4',
     '.1_4e1',
+    '0b_0',
+    '0x_f',
+    '0o_5',
+    '1_00_00j',
+    '1_00_00.5j',
+    '1_00_00e5_1j',
     '.1_4j',
@@ -30,4 +36,6 @@
     '.1_4j',
+    '(1_2.5+3_3j)',
+    '(.5_6j)',
 ]
 
 # Copied from CPython's test_grammar.py
@@ -36,6 +44,7 @@
     '0_',
     '42_',
     '1.4j_',
+    '0x_',
     '0b1_',
     '0xf_',
     '0o5_',
@@ -39,7 +48,8 @@
     '0b1_',
     '0xf_',
     '0o5_',
+    '0 if 1_Else 1',
     # Underscores in the base selector:
     '0_b0',
     '0_xf',
     '0_o5',
@@ -42,9 +52,5 @@
     # Underscores in the base selector:
     '0_b0',
     '0_xf',
     '0_o5',
-    # Underscore right after the base selector:
-    '0b_0',
-    '0x_f',
-    '0o_5',
     # Old-style octal, still disallowed:
@@ -50,8 +56,17 @@
     # Old-style octal, still disallowed:
-    #'0_7',
-    #'09_99',
-    # Special case with exponent:
-    '0 if 1_Else 1',
+    # FIXME: still need to support PY_VERSION_HEX < 3
+    '0_7',
+    '09_99',
+    # Multiple consecutive underscores:
+    '4_______2',
+    '0.1__4',
+    '0.1__4j',
+    '0b1001__0100',
+    '0xffff__ffff',
+    '0x___',
+    '0o5__77',
+    '1e1__0',
+    '1e1__0j',
     # Underscore right before a dot:
     '1_.4',
     '1_.4j',
@@ -59,5 +74,6 @@
     '1._4',
     '1._4j',
     '._5',
+    '._5j',
     # Underscore right after a sign:
     '1.0e+_1',
@@ -62,15 +78,9 @@
     # Underscore right after a sign:
     '1.0e+_1',
-    # Multiple consecutive underscores:
-    '4_______2',
-    '0.1__4',
-    '0b1001__0100',
-    '0xffff__ffff',
-    '0o5__77',
-    '1e1__0',
+    '1.0e+_1j',
     # Underscore right before j:
     '1.4_j',
     '1.4e5_j',
     # Underscore right before e:
     '1_e1',
     '1.4_e1',
@@ -71,9 +81,10 @@
     # Underscore right before j:
     '1.4_j',
     '1.4e5_j',
     # Underscore right before e:
     '1_e1',
     '1.4_e1',
+    '1.4_e1j',
     # Underscore right after e:
     '1e_1',
     '1.4e_1',
@@ -77,6 +88,10 @@
     # Underscore right after e:
     '1e_1',
     '1.4e_1',
+    '1.4e_1j',
+    # Complex cases with parens:
+    '(1+1.5_j_)',
+    '(1+1.5_j)',
     # Whitespace in literals
     '1_ 2',
     '1 _2',
@@ -117,5 +132,9 @@
                     # Add/MulNode() -> literal is first or second operand
                     literal_node = literal_node.operand2 if i % 2 else literal_node.operand1
                 if 'j' in literal or 'J' in literal:
-                    assert isinstance(literal_node, ExprNodes.ImagNode)
+                    if '+' in literal:
+                        # FIXME: tighten this test
+                        assert isinstance(literal_node, ExprNodes.AddNode), (literal, literal_node)
+                    else:
+                        assert isinstance(literal_node, ExprNodes.ImagNode), (literal, literal_node)
                 elif '.' in literal or 'e' in literal or 'E' in literal and not ('0x' in literal or '0X' in literal):
@@ -121,3 +140,3 @@
                 elif '.' in literal or 'e' in literal or 'E' in literal and not ('0x' in literal or '0X' in literal):
-                    assert isinstance(literal_node, ExprNodes.FloatNode)
+                    assert isinstance(literal_node, ExprNodes.FloatNode), (literal, literal_node)
                 else:
@@ -123,5 +142,5 @@
                 else:
-                    assert isinstance(literal_node, ExprNodes.IntNode)
+                    assert isinstance(literal_node, ExprNodes.IntNode), (literal, literal_node)
 
 
 if __name__ == "__main__":
diff --git a/Cython/Compiler/Tests/TestMemView.py b/Cython/Compiler/Tests/TestMemView.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL1Rlc3RzL1Rlc3RNZW1WaWV3LnB5..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL1Rlc3RzL1Rlc3RNZW1WaWV3LnB5 100644
--- a/Cython/Compiler/Tests/TestMemView.py
+++ b/Cython/Compiler/Tests/TestMemView.py
@@ -48,7 +48,7 @@
     def test_basic(self):
         t = self.parse(u"cdef int[:] x")
         memv_node = t.stats[0].base_type
-        self.assert_(isinstance(memv_node, MemoryViewSliceTypeNode))
+        self.assertTrue(isinstance(memv_node, MemoryViewSliceTypeNode))
 
     # we also test other similar declarations (buffers, anonymous C arrays)
     # since the parsing has to distinguish between them.
diff --git a/Cython/Compiler/Tests/TestParseTreeTransforms.py b/Cython/Compiler/Tests/TestParseTreeTransforms.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL1Rlc3RzL1Rlc3RQYXJzZVRyZWVUcmFuc2Zvcm1zLnB5..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL1Rlc3RzL1Rlc3RQYXJzZVRyZWVUcmFuc2Zvcm1zLnB5 100644
--- a/Cython/Compiler/Tests/TestParseTreeTransforms.py
+++ b/Cython/Compiler/Tests/TestParseTreeTransforms.py
@@ -3,7 +3,7 @@
 from Cython.TestUtils import TransformTest
 from Cython.Compiler.ParseTreeTransforms import *
 from Cython.Compiler.Nodes import *
-from Cython.Compiler import Main, Symtab
+from Cython.Compiler import Main, Symtab, Options
 
 
 class TestNormalizeTree(TransformTest):
@@ -87,7 +87,7 @@
 
     def test_pass_eliminated(self):
         t = self.run_pipeline([NormalizeTree(None)], u"pass")
-        self.assert_(len(t.stats) == 0)
+        self.assertTrue(len(t.stats) == 0)
 
 class TestWithTransform(object): # (TransformTest): # Disabled!
 
@@ -177,8 +177,8 @@
     def setUp(self):
         super(TestInterpretCompilerDirectives, self).setUp()
 
-        compilation_options = Main.CompilationOptions(Main.default_options)
-        ctx = compilation_options.create_context()
+        compilation_options = Options.CompilationOptions(Options.default_options)
+        ctx = Main.Context.from_options(compilation_options)
 
         transform = InterpretCompilerDirectives(ctx, ctx.compiler_directives)
         transform.module_scope = Symtab.ModuleScope('__main__', None, ctx)
diff --git a/Cython/Compiler/Tests/TestTreeFragment.py b/Cython/Compiler/Tests/TestTreeFragment.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL1Rlc3RzL1Rlc3RUcmVlRnJhZ21lbnQucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL1Rlc3RzL1Rlc3RUcmVlRnJhZ21lbnQucHk= 100644
--- a/Cython/Compiler/Tests/TestTreeFragment.py
+++ b/Cython/Compiler/Tests/TestTreeFragment.py
@@ -23,7 +23,7 @@
         T = self.fragment(u"y + y").substitute({"y": NameNode(pos=None, name="x")})
         self.assertEqual("x", T.stats[0].expr.operand1.name)
         self.assertEqual("x", T.stats[0].expr.operand2.name)
-        self.assert_(T.stats[0].expr.operand1 is not T.stats[0].expr.operand2)
+        self.assertTrue(T.stats[0].expr.operand1 is not T.stats[0].expr.operand2)
 
     def test_substitution(self):
         F = self.fragment(u"x = 4")
@@ -35,7 +35,7 @@
         F = self.fragment(u"PASS")
         pass_stat = PassStatNode(pos=None)
         T = F.substitute({"PASS" : pass_stat})
-        self.assert_(isinstance(T.stats[0], PassStatNode), T)
+        self.assertTrue(isinstance(T.stats[0], PassStatNode), T)
 
     def test_pos_is_transferred(self):
         F = self.fragment(u"""
@@ -55,9 +55,9 @@
         """)
         T = F.substitute(temps=[u"TMP"])
         s = T.body.stats
-        self.assert_(isinstance(s[0].expr, TempRefNode))
-        self.assert_(isinstance(s[1].rhs, TempRefNode))
-        self.assert_(s[0].expr.handle is s[1].rhs.handle)
+        self.assertTrue(isinstance(s[0].expr, TempRefNode))
+        self.assertTrue(isinstance(s[1].rhs, TempRefNode))
+        self.assertTrue(s[0].expr.handle is s[1].rhs.handle)
 
 if __name__ == "__main__":
     import unittest
diff --git a/Cython/Compiler/Tests/TestUtilityLoad.py b/Cython/Compiler/Tests/TestUtilityLoad.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL1Rlc3RzL1Rlc3RVdGlsaXR5TG9hZC5weQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL1Rlc3RzL1Rlc3RVdGlsaXR5TG9hZC5weQ== 100644
--- a/Cython/Compiler/Tests/TestUtilityLoad.py
+++ b/Cython/Compiler/Tests/TestUtilityLoad.py
@@ -22,10 +22,7 @@
     cls = Code.UtilityCode
 
     def test_load_as_string(self):
-        got = strip_2tup(self.cls.load_as_string(self.name))
-        self.assertEqual(got, self.expected)
-
         got = strip_2tup(self.cls.load_as_string(self.name, self.filename))
         self.assertEqual(got, self.expected)
 
     def test_load(self):
@@ -28,8 +25,8 @@
         got = strip_2tup(self.cls.load_as_string(self.name, self.filename))
         self.assertEqual(got, self.expected)
 
     def test_load(self):
-        utility = self.cls.load(self.name)
+        utility = self.cls.load(self.name, from_file=self.filename)
         got = strip_2tup((utility.proto, utility.impl))
         self.assertEqual(got, self.expected)
 
@@ -37,10 +34,6 @@
         got = strip_2tup((required.proto, required.impl))
         self.assertEqual(got, self.required)
 
-        utility = self.cls.load(self.name, from_file=self.filename)
-        got = strip_2tup((utility.proto, utility.impl))
-        self.assertEqual(got, self.expected)
-
         utility = self.cls.load_cached(self.name, from_file=self.filename)
         got = strip_2tup((utility.proto, utility.impl))
         self.assertEqual(got, self.expected)
@@ -59,7 +52,7 @@
     cls = Code.TempitaUtilityCode
 
     def test_load_as_string(self):
-        got = strip_2tup(self.cls.load_as_string(self.name, context=self.context))
+        got = strip_2tup(self.cls.load_as_string(self.name, self.filename, context=self.context))
         self.assertEqual(got, self.expected_tempita)
 
     def test_load(self):
@@ -63,7 +56,7 @@
         self.assertEqual(got, self.expected_tempita)
 
     def test_load(self):
-        utility = self.cls.load(self.name, context=self.context)
+        utility = self.cls.load(self.name, self.filename, context=self.context)
         got = strip_2tup((utility.proto, utility.impl))
         self.assertEqual(got, self.expected_tempita)
 
diff --git a/Cython/Compiler/Tests/Utils.py b/Cython/Compiler/Tests/Utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL1Rlc3RzL1V0aWxzLnB5
--- /dev/null
+++ b/Cython/Compiler/Tests/Utils.py
@@ -0,0 +1,36 @@
+import copy
+
+from .. import Options
+
+
+def backup_Options():
+    backup = {}
+    for name, value in vars(Options).items():
+        # we need a deep copy of _directive_defaults, because they can be changed
+        if name == '_directive_defaults':
+           value = copy.deepcopy(value)
+        backup[name] = value
+    return backup
+
+
+def restore_Options(backup):
+    no_value = object()
+    for name, orig_value in backup.items():
+        if getattr(Options, name, no_value) != orig_value:
+            setattr(Options, name, orig_value)
+    # strip Options from new keys that might have been added:
+    for name in vars(Options).keys():
+        if name not in backup:
+            delattr(Options, name)
+
+
+def check_global_options(expected_options, white_list=[]):
+    """
+    returns error message of "" if check Ok
+    """
+    no_value = object()
+    for name, orig_value in expected_options.items():
+        if name not in white_list:
+            if getattr(Options, name, no_value) != orig_value:
+                return "error in option " + name
+    return ""
diff --git a/Cython/Compiler/TreeFragment.py b/Cython/Compiler/TreeFragment.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL1RyZWVGcmFnbWVudC5weQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL1RyZWVGcmFnbWVudC5weQ== 100644
--- a/Cython/Compiler/TreeFragment.py
+++ b/Cython/Compiler/TreeFragment.py
@@ -29,8 +29,7 @@
             include_directories = []
         if compiler_directives is None:
             compiler_directives = {}
-        # TODO: see if "language_level=3" also works for our internal code here.
-        Main.Context.__init__(self, include_directories, compiler_directives, cpp=cpp, language_level=2)
+        Main.Context.__init__(self, include_directories, compiler_directives, cpp=cpp, language_level='3str')
         self.module_name = name
 
     def find_module(self, module_name, relative_to=None, pos=None, need_pxd=1, absolute_fallback=True):
diff --git a/Cython/Compiler/TypeInference.py b/Cython/Compiler/TypeInference.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL1R5cGVJbmZlcmVuY2UucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL1R5cGVJbmZlcmVuY2UucHk= 100644
--- a/Cython/Compiler/TypeInference.py
+++ b/Cython/Compiler/TypeInference.py
@@ -178,7 +178,7 @@
         return node
 
     def visit_FromCImportStatNode(self, node):
-        pass # Can't be assigned to...
+        return node # Can't be assigned to...
 
     def visit_FromImportStatNode(self, node):
         for name, target in node.items:
@@ -533,8 +533,8 @@
 def simply_type(result_type, pos):
     if result_type.is_reference:
         result_type = result_type.ref_base_type
-    if result_type.is_const:
-        result_type = result_type.const_base_type
+    if result_type.is_cv_qualified:
+        result_type = result_type.cv_base_type
     if result_type.is_cpp_class:
         result_type.check_nullary_constructor(pos)
     if result_type.is_array:
diff --git a/Cython/Compiler/TypeSlots.py b/Cython/Compiler/TypeSlots.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL1R5cGVTbG90cy5weQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL1R5cGVTbG90cy5weQ== 100644
--- a/Cython/Compiler/TypeSlots.py
+++ b/Cython/Compiler/TypeSlots.py
@@ -9,6 +9,8 @@
 from . import PyrexTypes
 from .Errors import error
 
+import copy
+
 invisible = ['__cinit__', '__dealloc__', '__richcmp__',
              '__nonzero__', '__bool__']
 
@@ -23,6 +25,7 @@
     #  fixed_arg_format   string
     #  ret_format         string
     #  error_value        string
+    #  use_fastcall       boolean
     #
     #  The formats are strings made up of the following
     #  characters:
@@ -86,7 +89,10 @@
         'z': "-1",
     }
 
-    def __init__(self, arg_format, ret_format):
-        self.has_dummy_arg = 0
-        self.has_generic_args = 0
+    # Use METH_FASTCALL instead of METH_VARARGS
+    use_fastcall = False
+
+    def __init__(self, arg_format, ret_format, nogil=False):
+        self.has_dummy_arg = False
+        self.has_generic_args = False
         if arg_format[:1] == '-':
@@ -92,4 +98,4 @@
         if arg_format[:1] == '-':
-            self.has_dummy_arg = 1
+            self.has_dummy_arg = True
             arg_format = arg_format[1:]
         if arg_format[-1:] == '*':
@@ -94,9 +100,9 @@
             arg_format = arg_format[1:]
         if arg_format[-1:] == '*':
-            self.has_generic_args = 1
+            self.has_generic_args = True
             arg_format = arg_format[:-1]
         self.fixed_arg_format = arg_format
         self.ret_format = ret_format
         self.error_value = self.error_value_map.get(ret_format, None)
         self.exception_check = ret_format != 'r' and self.error_value is not None
         self.is_staticmethod = False
@@ -97,9 +103,10 @@
             arg_format = arg_format[:-1]
         self.fixed_arg_format = arg_format
         self.ret_format = ret_format
         self.error_value = self.error_value_map.get(ret_format, None)
         self.exception_check = ret_format != 'r' and self.error_value is not None
         self.is_staticmethod = False
+        self.nogil = nogil
 
     def __repr__(self):
         return '<Signature[%s(%s%s)]>' % (
@@ -149,7 +156,8 @@
         exc_value = self.exception_value()
         return PyrexTypes.CFuncType(
             ret_type, args, exception_value=exc_value,
-            exception_check=self.exception_check)
+            exception_check=self.exception_check,
+            nogil=self.nogil)
 
     def method_flags(self):
         if self.ret_format == "O":
@@ -157,5 +165,9 @@
             if self.has_dummy_arg:
                 full_args = "O" + full_args
             if full_args in ["O", "T"]:
-                if self.has_generic_args:
+                if not self.has_generic_args:
+                    return [method_noargs]
+                elif self.use_fastcall:
+                    return [method_fastcall, method_keywords]
+                else:
                     return [method_varargs, method_keywords]
@@ -161,7 +173,5 @@
                     return [method_varargs, method_keywords]
-                else:
-                    return [method_noargs]
             elif full_args in ["OO", "TO"] and not self.has_generic_args:
                 return [method_onearg]
 
             if self.is_staticmethod:
@@ -164,7 +174,10 @@
             elif full_args in ["OO", "TO"] and not self.has_generic_args:
                 return [method_onearg]
 
             if self.is_staticmethod:
-                return [method_varargs, method_keywords]
+                if self.use_fastcall:
+                    return [method_fastcall, method_keywords]
+                else:
+                    return [method_varargs, method_keywords]
         return None
 
@@ -169,5 +182,33 @@
         return None
 
+    def method_function_type(self):
+        # Return the C function type
+        mflags = self.method_flags()
+        kw = "WithKeywords" if (method_keywords in mflags) else ""
+        for m in mflags:
+            if m == method_noargs or m == method_onearg:
+                return "PyCFunction"
+            if m == method_varargs:
+                return "PyCFunction" + kw
+            if m == method_fastcall:
+                return "__Pyx_PyCFunction_FastCall" + kw
+        return None
+
+    def with_fastcall(self):
+        # Return a copy of this Signature with use_fastcall=True
+        sig = copy.copy(self)
+        sig.use_fastcall = True
+        return sig
+
+    @property
+    def fastvar(self):
+        # Used to select variants of functions, one dealing with METH_VARARGS
+        # and one dealing with __Pyx_METH_FASTCALL
+        if self.use_fastcall:
+            return "FASTCALL"
+        else:
+            return "VARARGS"
+
 
 class SlotDescriptor(object):
     #  Abstract base class for type slot descriptors.
@@ -188,6 +229,12 @@
         self.py3 = py3
         self.py2 = py2
 
+    def slot_code(self, scope):
+        raise NotImplemented()
+
+    def spec_value(self, scope):
+        return self.slot_code(scope)
+
     def preprocessor_guard_code(self):
         ifdef = self.ifdef
         py2 = self.py2
@@ -201,6 +248,19 @@
             guard = ("#if PY_MAJOR_VERSION >= 3")
         return guard
 
+    def generate_spec(self, scope, code):
+        if self.is_initialised_dynamically:
+            return
+        value = self.spec_value(scope)
+        if value == "0":
+            return
+        preprocessor_guard = self.preprocessor_guard_code()
+        if preprocessor_guard:
+            code.putln(preprocessor_guard)
+        code.putln("{Py_%s, (void *)%s}," % (self.slot_name, value))
+        if preprocessor_guard:
+            code.putln("#endif")
+
     def generate(self, scope, code):
         preprocessor_guard = self.preprocessor_guard_code()
         if preprocessor_guard:
@@ -248,14 +308,17 @@
 
     def generate_dynamic_init_code(self, scope, code):
         if self.is_initialised_dynamically:
-            value = self.slot_code(scope)
-            if value != "0":
-                code.putln("%s.%s = %s;" % (
-                    scope.parent_type.typeobj_cname,
-                    self.slot_name,
-                    value
-                    )
-                )
+            self.generate_set_slot_code(
+                self.slot_code(scope), scope, code)
+
+    def generate_set_slot_code(self, value, scope, code):
+        if value == "0":
+            return
+        code.putln("%s.%s = %s;" % (
+            scope.parent_type.typeobj_cname,
+            self.slot_name,
+            value,
+        ))
 
 
 class FixedSlot(SlotDescriptor):
@@ -360,7 +423,7 @@
 class ConstructorSlot(InternalMethodSlot):
     #  Descriptor for tp_new and tp_dealloc.
 
-    def __init__(self, slot_name, method, **kargs):
+    def __init__(self, slot_name, method=None, **kargs):
         InternalMethodSlot.__init__(self, slot_name, **kargs)
         self.method = method
 
@@ -364,10 +427,8 @@
         InternalMethodSlot.__init__(self, slot_name, **kargs)
         self.method = method
 
-    def slot_code(self, scope):
-        entry = scope.lookup_here(self.method)
-        if (self.slot_name != 'tp_new'
-                and scope.parent_type.base_type
+    def _needs_own(self, scope):
+        if (scope.parent_type.base_type
                 and not scope.has_pyobject_attrs
                 and not scope.has_memoryview_attrs
                 and not scope.has_cpp_class_attrs
@@ -371,7 +432,23 @@
                 and not scope.has_pyobject_attrs
                 and not scope.has_memoryview_attrs
                 and not scope.has_cpp_class_attrs
-                and not (entry and entry.is_special)):
+                and not (self.slot_name == 'tp_new' and scope.parent_type.vtabslot_cname)):
+            entry = scope.lookup_here(self.method) if self.method else None
+            if not (entry and entry.is_special):
+                return False
+        # Unless we can safely delegate to the parent, all types need a tp_new().
+        return True
+
+    def _parent_slot_function(self, scope):
+        parent_type_scope = scope.parent_type.base_type.scope
+        if scope.parent_scope is parent_type_scope.parent_scope:
+            entry = scope.parent_scope.lookup_here(scope.parent_type.base_type.name)
+            if entry.visibility != 'extern':
+                return self.slot_code(parent_type_scope)
+        return None
+
+    def slot_code(self, scope):
+        if not self._needs_own(scope):
             # if the type does not have object attributes, it can
             # delegate GC methods to its parent - iff the parent
             # functions are defined in the same module
@@ -375,10 +452,10 @@
             # if the type does not have object attributes, it can
             # delegate GC methods to its parent - iff the parent
             # functions are defined in the same module
-            parent_type_scope = scope.parent_type.base_type.scope
-            if scope.parent_scope is parent_type_scope.parent_scope:
-                entry = scope.parent_scope.lookup_here(scope.parent_type.base_type.name)
-                if entry.visibility != 'extern':
-                    return self.slot_code(parent_type_scope)
-        if entry and not entry.is_special:
+            slot_code = self._parent_slot_function(scope)
+            return slot_code or '0'
+        return InternalMethodSlot.slot_code(self, scope)
+
+    def spec_value(self, scope):
+        if self.slot_name == "tp_dealloc" and not scope.lookup_here("__dealloc__"):
             return "0"
@@ -384,5 +461,20 @@
             return "0"
-        return InternalMethodSlot.slot_code(self, scope)
+        return self.slot_code(scope)
+
+    def generate_dynamic_init_code(self, scope, code):
+        if self.slot_code(scope) != '0':
+            return
+        # If we don't have our own slot function and don't know the
+        # parent function statically, copy it dynamically.
+        base_type = scope.parent_type.base_type
+        if base_type.is_extension_type and base_type.typeobj_cname:
+            src = '%s.%s' % (base_type.typeobj_cname, self.slot_name)
+        elif base_type.typeptr_cname:
+            src = '%s->%s' % (base_type.typeptr_cname, self.slot_name)
+        else:
+            return
+
+        self.generate_set_slot_code(src, scope, code)
 
 
 class SyntheticSlot(InternalMethodSlot):
@@ -404,6 +496,11 @@
         else:
             return self.default_value
 
+    def spec_value(self, scope):
+        if self.slot_name == "tp_getattro" and not scope.defines_any_special(self.user_methods):
+            return "PyObject_GenericGetAttr"
+        return self.slot_code(scope)
+
 
 class RichcmpSlot(MethodSlot):
     def slot_code(self, scope):
@@ -434,6 +531,10 @@
             value += "|Py_TPFLAGS_HAVE_GC"
         return value
 
+    def generate_spec(self, scope, code):
+        # Flags are stored in the PyType_Spec, not in a PyType_Slot.
+        return
+
 
 class DocStringSlot(SlotDescriptor):
     #  Descriptor for the docstring slot.
@@ -444,7 +545,7 @@
             return "0"
         if doc.is_unicode:
             doc = doc.as_utf8_string()
-        return doc.as_c_string_literal()
+        return "PyDoc_STR(%s)" % doc.as_c_string_literal()
 
 
 class SuiteSlot(SlotDescriptor):
@@ -487,6 +588,13 @@
             if self.ifdef:
                 code.putln("#endif")
 
+    def generate_spec(self, scope, code):
+        if self.slot_name == "tp_as_buffer":
+            # Cannot currently support the buffer protocol in the limited C-API.
+            return
+        for slot in self.sub_slots:
+            slot.generate_spec(scope, code)
+
 substructures = []   # List of all SuiteSlot instances
 
 class MethodTableSlot(SlotDescriptor):
@@ -520,7 +628,7 @@
     #  Slot descriptor for the base class slot.
 
     def __init__(self, name):
-        SlotDescriptor.__init__(self, name, dynamic = 1)
+        SlotDescriptor.__init__(self, name, dynamic=True)
 
     def generate_dynamic_init_code(self, scope, code):
         base_type = scope.parent_type.base_type
@@ -876,7 +984,7 @@
 
     MethodSlot(initproc, "tp_init", "__init__"),
     EmptySlot("tp_alloc"), #FixedSlot("tp_alloc", "PyType_GenericAlloc"),
-    InternalMethodSlot("tp_new"),
+    ConstructorSlot("tp_new", "__cinit__"),
     EmptySlot("tp_free"),
 
     EmptySlot("tp_is_gc"),
@@ -890,6 +998,8 @@
     EmptySlot("tp_finalize", ifdef="PY_VERSION_HEX >= 0x030400a1"),
     EmptySlot("tp_vectorcall", ifdef="PY_VERSION_HEX >= 0x030800b1"),
     EmptySlot("tp_print", ifdef="PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000"),
+    # PyPy specific extension - only here to avoid C compiler warnings.
+    EmptySlot("tp_pypy_flags", ifdef="CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM+0 >= 0x06000000"),
 )
 
 #------------------------------------------------------------------------------------------
@@ -920,5 +1030,6 @@
 method_noargs   = "METH_NOARGS"
 method_onearg   = "METH_O"
 method_varargs  = "METH_VARARGS"
+method_fastcall = "__Pyx_METH_FASTCALL"  # Actually VARARGS on versions < 3.7
 method_keywords = "METH_KEYWORDS"
 method_coexist  = "METH_COEXIST"
diff --git a/Cython/Compiler/UtilNodes.py b/Cython/Compiler/UtilNodes.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL1V0aWxOb2Rlcy5weQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL1V0aWxOb2Rlcy5weQ== 100644
--- a/Cython/Compiler/UtilNodes.py
+++ b/Cython/Compiler/UtilNodes.py
@@ -354,6 +354,9 @@
         self.body = self.body.analyse_expressions(env)
         return self
 
+    def may_be_none(self):
+        return self.result_ref.may_be_none()
+
     def generate_result_code(self, code):
         self.result_ref.result_code = self.result()
         self.body.generate_execution_code(code)
diff --git a/Cython/Compiler/UtilityCode.py b/Cython/Compiler/UtilityCode.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL1V0aWxpdHlDb2RlLnB5..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL1V0aWxpdHlDb2RlLnB5 100644
--- a/Cython/Compiler/UtilityCode.py
+++ b/Cython/Compiler/UtilityCode.py
@@ -131,7 +131,7 @@
             p = []
             for t in pipeline:
                 p.append(t)
-                if isinstance(p, ParseTreeTransforms.AnalyseDeclarationsTransform):
+                if isinstance(t, ParseTreeTransforms.AnalyseDeclarationsTransform):
                     break
 
             pipeline = p
diff --git a/Cython/Compiler/Visitor.py b/Cython/Compiler/Visitor.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0NvbXBpbGVyL1Zpc2l0b3IucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0NvbXBpbGVyL1Zpc2l0b3IucHk= 100644
--- a/Cython/Compiler/Visitor.py
+++ b/Cython/Compiler/Visitor.py
@@ -569,6 +569,17 @@
     ### dispatch to specific handlers
 
     def _find_handler(self, match_name, has_kwargs):
+        try:
+            match_name.encode('ascii')
+        except UnicodeEncodeError:
+            # specifically when running the Cython compiler under Python 2
+            #  getattr can't take a unicode string.
+            #  Classes with unicode names won't have specific handlers and thus it
+            #  should be OK to return None.
+            # Doing the test here ensures that the same code gets run on
+            # Python 2 and 3
+            return None
+
         call_type = has_kwargs and 'general' or 'simple'
         handler = getattr(self, '_handle_%s_%s' % (call_type, match_name), None)
         if handler is None:
@@ -821,6 +832,10 @@
                 result += "(type=%s, name=\"%s\")" % (repr(node.type), node.name)
             elif isinstance(node, Nodes.DefNode):
                 result += "(name=\"%s\")" % node.name
+            elif isinstance(node, ExprNodes.AttributeNode):
+                result += "(type=%s, attribute=\"%s\")" % (repr(node.type), node.attribute)
+            elif isinstance(node, ExprNodes.ConstNode):
+                result += "(type=%s, value=\"%s\")" % (repr(node.type), node.value)
             elif isinstance(node, ExprNodes.ExprNode):
                 t = node.type
                 result += "(type=%s)" % repr(t)
diff --git a/Cython/Debugger/Cygdb.py b/Cython/Debugger/Cygdb.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0RlYnVnZ2VyL0N5Z2RiLnB5..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0RlYnVnZ2VyL0N5Z2RiLnB5 100644
--- a/Cython/Debugger/Cygdb.py
+++ b/Cython/Debugger/Cygdb.py
@@ -45,17 +45,23 @@
             set print pretty on
 
             python
-            # Activate virtualenv, if we were launched from one
-            import os
-            virtualenv = os.getenv('VIRTUAL_ENV')
-            if virtualenv:
-                path_to_activate_this_py = os.path.join(virtualenv, 'bin', 'activate_this.py')
-                print("gdb command file: Activating virtualenv: %s; path_to_activate_this_py: %s" % (
-                    virtualenv, path_to_activate_this_py))
-                with open(path_to_activate_this_py) as f:
-                    exec(f.read(), dict(__file__=path_to_activate_this_py))
-
-            from Cython.Debugger import libcython, libpython
+            try:
+                # Activate virtualenv, if we were launched from one
+                import os
+                virtualenv = os.getenv('VIRTUAL_ENV')
+                if virtualenv:
+                    path_to_activate_this_py = os.path.join(virtualenv, 'bin', 'activate_this.py')
+                    print("gdb command file: Activating virtualenv: %s; path_to_activate_this_py: %s" % (
+                        virtualenv, path_to_activate_this_py))
+                    with open(path_to_activate_this_py) as f:
+                        exec(f.read(), dict(__file__=path_to_activate_this_py))
+                from Cython.Debugger import libcython, libpython
+            except Exception as ex:
+                from traceback import print_exc
+                print("There was an error in Python code originating from the file ''' + str(__file__) + '''")
+                print("It used the Python interpreter " + str(sys.executable))
+                print_exc()
+                exit(1)
             end
             '''))
 
@@ -79,8 +85,8 @@
                     gdb.lookup_type('PyModuleObject')
                 except RuntimeError:
                     sys.stderr.write(
-                        'Python was not compiled with debug symbols (or it was '
-                        'stripped). Some functionality may not work (properly).\\n')
+                        "''' + interpreter + ''' was not compiled with debug symbols (or it was "
+                        "stripped). Some functionality may not work (properly).\\n")
                 end
 
                 source .cygdbinit
diff --git a/Cython/Debugger/Tests/TestLibCython.py b/Cython/Debugger/Tests/TestLibCython.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0RlYnVnZ2VyL1Rlc3RzL1Rlc3RMaWJDeXRob24ucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0RlYnVnZ2VyL1Rlc3RzL1Rlc3RMaWJDeXRob24ucHk= 100644
--- a/Cython/Debugger/Tests/TestLibCython.py
+++ b/Cython/Debugger/Tests/TestLibCython.py
@@ -56,9 +56,9 @@
                 stdout, _ = p.communicate()
                 try:
                     internal_python_version = list(map(int, stdout.decode('ascii', 'ignore').split()))
-                    if internal_python_version < [2, 6]:
+                    if internal_python_version < [2, 7]:
                         have_gdb = False
                 except ValueError:
                     have_gdb = False
 
     if not have_gdb:
@@ -60,9 +60,9 @@
                         have_gdb = False
                 except ValueError:
                     have_gdb = False
 
     if not have_gdb:
-        warnings.warn('Skipping gdb tests, need gdb >= 7.2 with Python >= 2.6')
+        warnings.warn('Skipping gdb tests, need gdb >= 7.2 with Python >= 2.7')
 
     return have_gdb
 
diff --git a/Cython/Debugger/libcython.py b/Cython/Debugger/libcython.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0RlYnVnZ2VyL2xpYmN5dGhvbi5weQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0RlYnVnZ2VyL2xpYmN5dGhvbi5weQ== 100644
--- a/Cython/Debugger/libcython.py
+++ b/Cython/Debugger/libcython.py
@@ -392,7 +392,7 @@
 
         result = {}
         seen = set()
-        for k, v in pyobject_dict.items():
+        for k, v in pyobject_dict.iteritems():
             result[k.proxyval(seen)] = v
 
         return result
@@ -863,10 +863,10 @@
     def complete(self, text, word):
         # Filter init-module functions (breakpoints can be set using
         # modulename:linenumber).
-        names =  [n for n, L in self.cy.functions_by_name.items()
-                  if any(not f.is_initmodule_function for f in L)]
-        qnames = [n for n, f in self.cy.functions_by_qualified_name.items()
-                  if not f.is_initmodule_function]
+        names =  [n for n, L in self.cy.functions_by_name.iteritems()
+                        if any(not f.is_initmodule_function for f in L)]
+        qnames = [n for n, f in self.cy.functions_by_qualified_name.iteritems()
+                        if not f.is_initmodule_function]
 
         if parameters.complete_unqualified:
             all_names = itertools.chain(qnames, names)
@@ -1156,7 +1156,7 @@
 
         local_cython_vars = cython_function.locals
         max_name_length = len(max(local_cython_vars, key=len))
-        for name, cyvar in sorted(local_cython_vars.items(), key=sortkey):
+        for name, cyvar in sorted(local_cython_vars.iteritems(), key=sortkey):
             if self.is_initialized(self.get_cython_function(), cyvar.name):
                 value = gdb.parse_and_eval(cyvar.cname)
                 if not value.is_optimized_out:
@@ -1189,9 +1189,9 @@
 
         seen = set()
         print('Python globals:')
-        for k, v in sorted(global_python_dict.items(), key=sortkey):
+        for k, v in sorted(global_python_dict.iteritems(), key=sortkey):
             v = v.get_truncated_repr(libpython.MAX_OUTPUT_LEN)
             seen.add(k)
             print('    %-*s = %s' % (max_name_length, k, v))
 
         print('C globals:')
@@ -1193,9 +1193,9 @@
             v = v.get_truncated_repr(libpython.MAX_OUTPUT_LEN)
             seen.add(k)
             print('    %-*s = %s' % (max_name_length, k, v))
 
         print('C globals:')
-        for name, cyvar in sorted(module_globals.items(), key=sortkey):
+        for name, cyvar in sorted(module_globals.iteritems(), key=sortkey):
             if name not in seen:
                 try:
                     value = gdb.parse_and_eval(cyvar.cname)
@@ -1218,8 +1218,10 @@
         "Fill a remotely allocated dict with values from the Cython C stack"
         cython_func = self.get_cython_function()
 
-        for name, cyvar in cython_func.locals.items():
-            if cyvar.type == PythonObject and self.is_initialized(cython_func, name):
+        for name, cyvar in cython_func.locals.iteritems():
+            if (cyvar.type == PythonObject and
+                self.is_initialized(cython_func, name)):
+
                 try:
                     val = gdb.parse_and_eval(cyvar.cname)
                 except RuntimeError:
diff --git a/Cython/Debugger/libpython.py b/Cython/Debugger/libpython.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0RlYnVnZ2VyL2xpYnB5dGhvbi5weQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0RlYnVnZ2VyL2xpYnB5dGhvbi5weQ== 100644
--- a/Cython/Debugger/libpython.py
+++ b/Cython/Debugger/libpython.py
@@ -276,12 +276,13 @@
 
     def safe_tp_name(self):
         try:
-            return self.type().field('tp_name').string()
-        except NullPyObjectPtr:
-            # NULL tp_name?
-            return 'unknown'
-        except RuntimeError:
-            # Can't even read the object at all?
+            ob_type = self.type()
+            tp_name = ob_type.field('tp_name')
+            return tp_name.string()
+        # NullPyObjectPtr: NULL tp_name?
+        # RuntimeError: Can't even read the object at all?
+        # UnicodeDecodeError: Failed to decode tp_name bytestring
+        except (NullPyObjectPtr, RuntimeError, UnicodeDecodeError):
             return 'unknown'
 
     def proxyval(self, visited):
@@ -355,7 +356,9 @@
         try:
             tp_name = t.field('tp_name').string()
             tp_flags = int(t.field('tp_flags'))
-        except RuntimeError:
+        # RuntimeError: NULL pointers
+        # UnicodeDecodeError: string() fails to decode the bytestring
+        except (RuntimeError, UnicodeDecodeError):
             # Handle any kind of error e.g. NULL ptrs by simply using the base
             # class
             return cls
@@ -623,7 +626,10 @@
 
     def proxyval(self, visited):
         m_ml = self.field('m_ml') # m_ml is a (PyMethodDef*)
-        ml_name = m_ml['ml_name'].string()
+        try:
+            ml_name = m_ml['ml_name'].string()
+        except UnicodeDecodeError:
+            ml_name = '<ml_name:UnicodeDecodeError>'
 
         pyop_m_self = self.pyop_field('m_self')
         if pyop_m_self.is_null():
@@ -736,7 +742,7 @@
         else:
             offset = 8 * dk_size
 
-        ent_addr = keys['dk_indices']['as_1'].address
+        ent_addr = keys['dk_indices'].address
         ent_addr = ent_addr.cast(_type_unsigned_char_ptr()) + offset
         ent_ptr_t = gdb.lookup_type('PyDictKeyEntry').pointer()
         ent_addr = ent_addr.cast(ent_ptr_t)
@@ -934,6 +940,6 @@
         if long(f_trace) != 0:
             # we have a non-NULL f_trace:
             return self.f_lineno
-        else:
-            #try:
+
+        try:
             return self.co.addr2line(self.f_lasti)
@@ -939,9 +945,14 @@
             return self.co.addr2line(self.f_lasti)
-            #except ValueError:
-            #    return self.f_lineno
+        except Exception:
+            # bpo-34989: addr2line() is a complex function, it can fail in many
+            # ways. For example, it fails with a TypeError on "FakeRepr" if
+            # gdb fails to load debug symbols. Use a catch-all "except
+            # Exception" to make the whole function safe. The caller has to
+            # handle None anyway for optimized Python.
+            return None
 
     def current_line(self):
         '''Get the text of the current source line as a string, with a trailing
         newline character'''
         if self.is_optimized_out():
             return '(frame information optimized out)'
@@ -942,8 +953,13 @@
 
     def current_line(self):
         '''Get the text of the current source line as a string, with a trailing
         newline character'''
         if self.is_optimized_out():
             return '(frame information optimized out)'
+
+        lineno = self.current_line_num()
+        if lineno is None:
+            return '(failed to get frame line number)'
+
         filename = self.filename()
         try:
@@ -948,5 +964,6 @@
         filename = self.filename()
         try:
-            f = open(os_fsencode(filename), 'r')
+            with open(os_fsencode(filename), 'r') as fp:
+                lines = fp.readlines()
         except IOError:
             return None
@@ -951,11 +968,13 @@
         except IOError:
             return None
-        with f:
-            all_lines = f.readlines()
-            # Convert from 1-based current_line_num to 0-based list offset:
-            return all_lines[self.current_line_num()-1]
+
+        try:
+            # Convert from 1-based current_line_num to 0-based list offset
+            return lines[lineno - 1]
+        except IndexError:
+            return None
 
     def write_repr(self, out, visited):
         if self.is_optimized_out():
             out.write('(frame information optimized out)')
             return
@@ -957,8 +976,10 @@
 
     def write_repr(self, out, visited):
         if self.is_optimized_out():
             out.write('(frame information optimized out)')
             return
-        out.write('Frame 0x%x, for file %s, line %i, in %s ('
+        lineno = self.current_line_num()
+        lineno = str(lineno) if lineno is not None else "?"
+        out.write('Frame 0x%x, for file %s, line %s, in %s ('
                   % (self.as_address(),
                      self.co_filename.proxyval(visited),
@@ -963,6 +984,6 @@
                   % (self.as_address(),
                      self.co_filename.proxyval(visited),
-                     self.current_line_num(),
+                     lineno,
                      self.co_name.proxyval(visited)))
         first = True
         for pyop_name, pyop_value in self.iter_locals():
@@ -981,5 +1002,7 @@
             sys.stdout.write('  (frame information optimized out)\n')
             return
         visited = set()
-        sys.stdout.write('  File "%s", line %i, in %s\n'
+        lineno = self.current_line_num()
+        lineno = str(lineno) if lineno is not None else "?"
+        sys.stdout.write('  File "%s", line %s, in %s\n'
                   % (self.co_filename.proxyval(visited),
@@ -985,5 +1008,5 @@
                   % (self.co_filename.proxyval(visited),
-                     self.current_line_num(),
+                     lineno,
                      self.co_name.proxyval(visited)))
 
 class PySetObjectPtr(PyObjectPtr):
@@ -1092,6 +1115,7 @@
         out.write(quote)
 
 
+# Added in Cython for Py2 backwards compatibility.
 class PyStringObjectPtr(PyBytesObjectPtr):
     _typename = 'PyStringObject'
 
@@ -1166,7 +1190,7 @@
     def proxyval(self, visited):
         global _is_pep393
         if _is_pep393 is None:
-            fields = gdb.lookup_type('PyUnicodeObject').target().fields()
+            fields = gdb.lookup_type('PyUnicodeObject').fields()
             _is_pep393 = 'data' in [f.name for f in fields]
         if _is_pep393:
             # Python 3.3 and newer
@@ -1351,9 +1375,9 @@
         try:
             name = self.field('descr')['d_base']['name'].string()
             return repr(name)
-        except (NullPyObjectPtr, RuntimeError):
+        except (NullPyObjectPtr, RuntimeError, UnicodeDecodeError):
             return '<unknown name>'
 
     def safe_tp_name(self):
         try:
             return self.field('self')['ob_type']['tp_name'].string()
@@ -1355,9 +1379,9 @@
             return '<unknown name>'
 
     def safe_tp_name(self):
         try:
             return self.field('self')['ob_type']['tp_name'].string()
-        except (NullPyObjectPtr, RuntimeError):
+        except (NullPyObjectPtr, RuntimeError, UnicodeDecodeError):
             return '<unknown tp_name>'
 
     def safe_self_addresss(self):
@@ -1563,7 +1587,10 @@
                 # Use the prettyprinter for the func:
                 func = frame.read_var(arg_name)
                 return str(func)
+            except ValueError:
+                return ('PyCFunction invocation (unable to read %s: '
+                        'missing debuginfos?)' % arg_name)
             except RuntimeError:
                 return 'PyCFunction invocation (unable to read %s)' % arg_name
 
         if caller == 'wrapper_call':
@@ -1566,5 +1593,6 @@
             except RuntimeError:
                 return 'PyCFunction invocation (unable to read %s)' % arg_name
 
         if caller == 'wrapper_call':
+            arg_name = 'wp'
             try:
@@ -1570,3 +1598,3 @@
             try:
-                func = frame.read_var('wp')
+                func = frame.read_var(arg_name)
                 return str(func)
@@ -1572,2 +1600,5 @@
                 return str(func)
+            except ValueError:
+                return ('<wrapper_call invocation (unable to read %s: '
+                        'missing debuginfos?)>' % arg_name)
             except RuntimeError:
@@ -1573,5 +1604,5 @@
             except RuntimeError:
-                return '<wrapper_call invocation>'
+                return '<wrapper_call invocation (unable to read %s)>' % arg_name
 
         # This frame isn't worth reporting:
         return False
@@ -1730,6 +1761,9 @@
 
         filename = pyop.filename()
         lineno = pyop.current_line_num()
+        if lineno is None:
+            print('Unable to read python frame line number')
+            return
 
         if start is None:
             start = lineno - 5
@@ -2574,7 +2608,7 @@
         return pointer
 
     def free(self, pointer):
-        gdb.parse_and_eval("free((void *) %d)" % pointer)
+        gdb.parse_and_eval("(void) free((void *) %d)" % pointer)
 
     def incref(self, pointer):
         "Increment the reference count of a Python object in the inferior."
diff --git a/Cython/Distutils/old_build_ext.py b/Cython/Distutils/old_build_ext.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0Rpc3R1dGlscy9vbGRfYnVpbGRfZXh0LnB5..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0Rpc3R1dGlscy9vbGRfYnVpbGRfZXh0LnB5 100644
--- a/Cython/Distutils/old_build_ext.py
+++ b/Cython/Distutils/old_build_ext.py
@@ -84,9 +84,9 @@
     description = "build C/C++ and Cython extensions (compile/link to build directory)"
 
     sep_by = _build_ext.build_ext.sep_by
-    user_options = _build_ext.build_ext.user_options
-    boolean_options = _build_ext.build_ext.boolean_options
-    help_options = _build_ext.build_ext.help_options
+    user_options = _build_ext.build_ext.user_options[:]
+    boolean_options = _build_ext.build_ext.boolean_options[:]
+    help_options = _build_ext.build_ext.help_options[:]
 
     # Add the pyrex specific data.
     user_options.extend([
@@ -185,9 +185,8 @@
 
         _build_ext.build_ext.run(self)
 
-    def build_extensions(self):
-        # First, sanity-check the 'extensions' list
-        self.check_extensions_list(self.extensions)
-
+    def check_extensions_list(self, extensions):
+        # Note: might get called multiple times.
+        _build_ext.build_ext.check_extensions_list(self, extensions)
         for ext in self.extensions:
             ext.sources = self.cython_sources(ext.sources, ext)
@@ -192,7 +191,5 @@
         for ext in self.extensions:
             ext.sources = self.cython_sources(ext.sources, ext)
-        # Call original build_extensions
-        _build_ext.build_ext.build_extensions(self)
 
     def cython_sources(self, sources, extension):
         """
@@ -201,17 +198,6 @@
         found, and return a modified 'sources' list with Cython source
         files replaced by the generated C (or C++) files.
         """
-        try:
-            from Cython.Compiler.Main \
-                import CompilationOptions, \
-                       default_options as cython_default_options, \
-                       compile as cython_compile
-            from Cython.Compiler.Errors import PyrexError
-        except ImportError:
-            e = sys.exc_info()[1]
-            print("failed to import Cython: %s" % e)
-            raise DistutilsPlatformError("Cython does not appear to be installed")
-
         new_sources = []
         cython_sources = []
         cython_targets = {}
@@ -252,7 +238,7 @@
         #    2.    Add in any (unique) paths from the extension
         #        cython_include_dirs (if Cython.Distutils.extension is used).
         #    3.    Add in any (unique) paths from the extension include_dirs
-        includes = self.cython_include_dirs
+        includes = list(self.cython_include_dirs)
         try:
             for i in extension.cython_include_dirs:
                 if not i in includes:
@@ -271,7 +257,7 @@
         #    1. Start with the command line option.
         #    2. Add in any (unique) entries from the extension
         #         cython_directives (if Cython.Distutils.extension is used).
-        directives = self.cython_directives
+        directives = dict(self.cython_directives)
         if hasattr(extension, "cython_directives"):
             directives.update(extension.cython_directives)
 
@@ -275,8 +261,7 @@
         if hasattr(extension, "cython_directives"):
             directives.update(extension.cython_directives)
 
-        # Set the target_ext to '.c'.  Cython will change this to '.cpp' if
-        # needed.
+        # Set the target file extension for C/C++ mode.
         if cplus:
             target_ext = '.cpp'
         else:
@@ -314,6 +299,17 @@
         if not cython_sources:
             return new_sources
 
+        try:
+            from Cython.Compiler.Main \
+                import CompilationOptions, \
+                       default_options as cython_default_options, \
+                       compile as cython_compile
+            from Cython.Compiler.Errors import PyrexError
+        except ImportError:
+            e = sys.exc_info()[1]
+            print("failed to import Cython: %s" % e)
+            raise DistutilsPlatformError("Cython does not appear to be installed")
+
         module_name = extension.name
 
         for source in cython_sources:
diff --git a/Cython/Includes/Deprecated/python.pxd b/Cython/Includes/Deprecated/python.pxd
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL0RlcHJlY2F0ZWQvcHl0aG9uLnB4ZA==..0000000000000000000000000000000000000000
--- a/Cython/Includes/Deprecated/python.pxd
+++ /dev/null
@@ -1,2 +0,0 @@
-# Present for backwards compatibility
-from cpython cimport *
diff --git a/Cython/Includes/Deprecated/python_bool.pxd b/Cython/Includes/Deprecated/python_bool.pxd
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL0RlcHJlY2F0ZWQvcHl0aG9uX2Jvb2wucHhk..0000000000000000000000000000000000000000
--- a/Cython/Includes/Deprecated/python_bool.pxd
+++ /dev/null
@@ -1,2 +0,0 @@
-# Present for backwards compatibility
-from cpython.bool cimport *
diff --git a/Cython/Includes/Deprecated/python_buffer.pxd b/Cython/Includes/Deprecated/python_buffer.pxd
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL0RlcHJlY2F0ZWQvcHl0aG9uX2J1ZmZlci5weGQ=..0000000000000000000000000000000000000000
--- a/Cython/Includes/Deprecated/python_buffer.pxd
+++ /dev/null
@@ -1,2 +0,0 @@
-# Present for backwards compatibility
-from cpython.buffer cimport *
diff --git a/Cython/Includes/Deprecated/python_bytes.pxd b/Cython/Includes/Deprecated/python_bytes.pxd
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL0RlcHJlY2F0ZWQvcHl0aG9uX2J5dGVzLnB4ZA==..0000000000000000000000000000000000000000
--- a/Cython/Includes/Deprecated/python_bytes.pxd
+++ /dev/null
@@ -1,2 +0,0 @@
-# Present for backwards compatibility
-from cpython.bytes cimport *
diff --git a/Cython/Includes/Deprecated/python_cobject.pxd b/Cython/Includes/Deprecated/python_cobject.pxd
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL0RlcHJlY2F0ZWQvcHl0aG9uX2NvYmplY3QucHhk..0000000000000000000000000000000000000000
--- a/Cython/Includes/Deprecated/python_cobject.pxd
+++ /dev/null
@@ -1,2 +0,0 @@
-# Present for backwards compatibility
-from cpython.cobject cimport *
diff --git a/Cython/Includes/Deprecated/python_complex.pxd b/Cython/Includes/Deprecated/python_complex.pxd
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL0RlcHJlY2F0ZWQvcHl0aG9uX2NvbXBsZXgucHhk..0000000000000000000000000000000000000000
--- a/Cython/Includes/Deprecated/python_complex.pxd
+++ /dev/null
@@ -1,2 +0,0 @@
-# Present for backwards compatibility
-from cpython.complex cimport *
diff --git a/Cython/Includes/Deprecated/python_dict.pxd b/Cython/Includes/Deprecated/python_dict.pxd
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL0RlcHJlY2F0ZWQvcHl0aG9uX2RpY3QucHhk..0000000000000000000000000000000000000000
--- a/Cython/Includes/Deprecated/python_dict.pxd
+++ /dev/null
@@ -1,2 +0,0 @@
-# Present for backwards compatibility
-from cpython.dict cimport *
diff --git a/Cython/Includes/Deprecated/python_exc.pxd b/Cython/Includes/Deprecated/python_exc.pxd
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL0RlcHJlY2F0ZWQvcHl0aG9uX2V4Yy5weGQ=..0000000000000000000000000000000000000000
--- a/Cython/Includes/Deprecated/python_exc.pxd
+++ /dev/null
@@ -1,2 +0,0 @@
-# Present for backwards compatibility
-from cpython.exc cimport *
diff --git a/Cython/Includes/Deprecated/python_float.pxd b/Cython/Includes/Deprecated/python_float.pxd
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL0RlcHJlY2F0ZWQvcHl0aG9uX2Zsb2F0LnB4ZA==..0000000000000000000000000000000000000000
--- a/Cython/Includes/Deprecated/python_float.pxd
+++ /dev/null
@@ -1,2 +0,0 @@
-# Present for backwards compatibility
-from cpython.float cimport *
diff --git a/Cython/Includes/Deprecated/python_function.pxd b/Cython/Includes/Deprecated/python_function.pxd
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL0RlcHJlY2F0ZWQvcHl0aG9uX2Z1bmN0aW9uLnB4ZA==..0000000000000000000000000000000000000000
--- a/Cython/Includes/Deprecated/python_function.pxd
+++ /dev/null
@@ -1,2 +0,0 @@
-# Present for backwards compatibility
-from cpython.function cimport *
diff --git a/Cython/Includes/Deprecated/python_getargs.pxd b/Cython/Includes/Deprecated/python_getargs.pxd
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL0RlcHJlY2F0ZWQvcHl0aG9uX2dldGFyZ3MucHhk..0000000000000000000000000000000000000000
--- a/Cython/Includes/Deprecated/python_getargs.pxd
+++ /dev/null
@@ -1,2 +0,0 @@
-# Present for backwards compatibility
-from cpython.getargs cimport *
diff --git a/Cython/Includes/Deprecated/python_instance.pxd b/Cython/Includes/Deprecated/python_instance.pxd
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL0RlcHJlY2F0ZWQvcHl0aG9uX2luc3RhbmNlLnB4ZA==..0000000000000000000000000000000000000000
--- a/Cython/Includes/Deprecated/python_instance.pxd
+++ /dev/null
@@ -1,2 +0,0 @@
-# Present for backwards compatibility
-from cpython.instance cimport *
diff --git a/Cython/Includes/Deprecated/python_int.pxd b/Cython/Includes/Deprecated/python_int.pxd
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL0RlcHJlY2F0ZWQvcHl0aG9uX2ludC5weGQ=..0000000000000000000000000000000000000000
--- a/Cython/Includes/Deprecated/python_int.pxd
+++ /dev/null
@@ -1,2 +0,0 @@
-# Present for backwards compatibility
-from cpython.int cimport *
diff --git a/Cython/Includes/Deprecated/python_iterator.pxd b/Cython/Includes/Deprecated/python_iterator.pxd
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL0RlcHJlY2F0ZWQvcHl0aG9uX2l0ZXJhdG9yLnB4ZA==..0000000000000000000000000000000000000000
--- a/Cython/Includes/Deprecated/python_iterator.pxd
+++ /dev/null
@@ -1,2 +0,0 @@
-# Present for backwards compatibility
-from cpython.iterator cimport *
diff --git a/Cython/Includes/Deprecated/python_list.pxd b/Cython/Includes/Deprecated/python_list.pxd
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL0RlcHJlY2F0ZWQvcHl0aG9uX2xpc3QucHhk..0000000000000000000000000000000000000000
--- a/Cython/Includes/Deprecated/python_list.pxd
+++ /dev/null
@@ -1,2 +0,0 @@
-# Present for backwards compatibility
-from cpython.list cimport *
diff --git a/Cython/Includes/Deprecated/python_long.pxd b/Cython/Includes/Deprecated/python_long.pxd
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL0RlcHJlY2F0ZWQvcHl0aG9uX2xvbmcucHhk..0000000000000000000000000000000000000000
--- a/Cython/Includes/Deprecated/python_long.pxd
+++ /dev/null
@@ -1,2 +0,0 @@
-# Present for backwards compatibility
-from cpython.long cimport *
diff --git a/Cython/Includes/Deprecated/python_mapping.pxd b/Cython/Includes/Deprecated/python_mapping.pxd
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL0RlcHJlY2F0ZWQvcHl0aG9uX21hcHBpbmcucHhk..0000000000000000000000000000000000000000
--- a/Cython/Includes/Deprecated/python_mapping.pxd
+++ /dev/null
@@ -1,2 +0,0 @@
-# Present for backwards compatibility
-from cpython.mapping cimport *
diff --git a/Cython/Includes/Deprecated/python_mem.pxd b/Cython/Includes/Deprecated/python_mem.pxd
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL0RlcHJlY2F0ZWQvcHl0aG9uX21lbS5weGQ=..0000000000000000000000000000000000000000
--- a/Cython/Includes/Deprecated/python_mem.pxd
+++ /dev/null
@@ -1,2 +0,0 @@
-# Present for backwards compatibility
-from cpython.mem cimport *
diff --git a/Cython/Includes/Deprecated/python_method.pxd b/Cython/Includes/Deprecated/python_method.pxd
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL0RlcHJlY2F0ZWQvcHl0aG9uX21ldGhvZC5weGQ=..0000000000000000000000000000000000000000
--- a/Cython/Includes/Deprecated/python_method.pxd
+++ /dev/null
@@ -1,2 +0,0 @@
-# Present for backwards compatibility
-from cpython.method cimport *
diff --git a/Cython/Includes/Deprecated/python_module.pxd b/Cython/Includes/Deprecated/python_module.pxd
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL0RlcHJlY2F0ZWQvcHl0aG9uX21vZHVsZS5weGQ=..0000000000000000000000000000000000000000
--- a/Cython/Includes/Deprecated/python_module.pxd
+++ /dev/null
@@ -1,2 +0,0 @@
-# Present for backwards compatibility
-from cpython.module cimport *
diff --git a/Cython/Includes/Deprecated/python_number.pxd b/Cython/Includes/Deprecated/python_number.pxd
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL0RlcHJlY2F0ZWQvcHl0aG9uX251bWJlci5weGQ=..0000000000000000000000000000000000000000
--- a/Cython/Includes/Deprecated/python_number.pxd
+++ /dev/null
@@ -1,2 +0,0 @@
-# Present for backwards compatibility
-from cpython.number cimport *
diff --git a/Cython/Includes/Deprecated/python_object.pxd b/Cython/Includes/Deprecated/python_object.pxd
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL0RlcHJlY2F0ZWQvcHl0aG9uX29iamVjdC5weGQ=..0000000000000000000000000000000000000000
--- a/Cython/Includes/Deprecated/python_object.pxd
+++ /dev/null
@@ -1,2 +0,0 @@
-# Present for backwards compatibility
-from cpython.object cimport *
diff --git a/Cython/Includes/Deprecated/python_oldbuffer.pxd b/Cython/Includes/Deprecated/python_oldbuffer.pxd
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL0RlcHJlY2F0ZWQvcHl0aG9uX29sZGJ1ZmZlci5weGQ=..0000000000000000000000000000000000000000
--- a/Cython/Includes/Deprecated/python_oldbuffer.pxd
+++ /dev/null
@@ -1,2 +0,0 @@
-# Present for backwards compatibility
-from cpython.oldbuffer cimport *
diff --git a/Cython/Includes/Deprecated/python_pycapsule.pxd b/Cython/Includes/Deprecated/python_pycapsule.pxd
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL0RlcHJlY2F0ZWQvcHl0aG9uX3B5Y2Fwc3VsZS5weGQ=..0000000000000000000000000000000000000000
--- a/Cython/Includes/Deprecated/python_pycapsule.pxd
+++ /dev/null
@@ -1,2 +0,0 @@
-# Present for backwards compatibility
-from cpython.pycapsule cimport *
diff --git a/Cython/Includes/Deprecated/python_ref.pxd b/Cython/Includes/Deprecated/python_ref.pxd
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL0RlcHJlY2F0ZWQvcHl0aG9uX3JlZi5weGQ=..0000000000000000000000000000000000000000
--- a/Cython/Includes/Deprecated/python_ref.pxd
+++ /dev/null
@@ -1,2 +0,0 @@
-# Present for backwards compatibility
-from cpython.ref cimport *
diff --git a/Cython/Includes/Deprecated/python_sequence.pxd b/Cython/Includes/Deprecated/python_sequence.pxd
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL0RlcHJlY2F0ZWQvcHl0aG9uX3NlcXVlbmNlLnB4ZA==..0000000000000000000000000000000000000000
--- a/Cython/Includes/Deprecated/python_sequence.pxd
+++ /dev/null
@@ -1,2 +0,0 @@
-# Present for backwards compatibility
-from cpython.sequence cimport *
diff --git a/Cython/Includes/Deprecated/python_set.pxd b/Cython/Includes/Deprecated/python_set.pxd
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL0RlcHJlY2F0ZWQvcHl0aG9uX3NldC5weGQ=..0000000000000000000000000000000000000000
--- a/Cython/Includes/Deprecated/python_set.pxd
+++ /dev/null
@@ -1,2 +0,0 @@
-# Present for backwards compatibility
-from cpython.set cimport *
diff --git a/Cython/Includes/Deprecated/python_string.pxd b/Cython/Includes/Deprecated/python_string.pxd
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL0RlcHJlY2F0ZWQvcHl0aG9uX3N0cmluZy5weGQ=..0000000000000000000000000000000000000000
--- a/Cython/Includes/Deprecated/python_string.pxd
+++ /dev/null
@@ -1,2 +0,0 @@
-# Present for backwards compatibility
-from cpython.string cimport *
diff --git a/Cython/Includes/Deprecated/python_tuple.pxd b/Cython/Includes/Deprecated/python_tuple.pxd
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL0RlcHJlY2F0ZWQvcHl0aG9uX3R1cGxlLnB4ZA==..0000000000000000000000000000000000000000
--- a/Cython/Includes/Deprecated/python_tuple.pxd
+++ /dev/null
@@ -1,2 +0,0 @@
-# Present for backwards compatibility
-from cpython.tuple cimport *
diff --git a/Cython/Includes/Deprecated/python_type.pxd b/Cython/Includes/Deprecated/python_type.pxd
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL0RlcHJlY2F0ZWQvcHl0aG9uX3R5cGUucHhk..0000000000000000000000000000000000000000
--- a/Cython/Includes/Deprecated/python_type.pxd
+++ /dev/null
@@ -1,2 +0,0 @@
-# Present for backwards compatibility
-from cpython.type cimport *
diff --git a/Cython/Includes/Deprecated/python_unicode.pxd b/Cython/Includes/Deprecated/python_unicode.pxd
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL0RlcHJlY2F0ZWQvcHl0aG9uX3VuaWNvZGUucHhk..0000000000000000000000000000000000000000
--- a/Cython/Includes/Deprecated/python_unicode.pxd
+++ /dev/null
@@ -1,2 +0,0 @@
-# Present for backwards compatibility
-from cpython.unicode cimport *
diff --git a/Cython/Includes/Deprecated/python_version.pxd b/Cython/Includes/Deprecated/python_version.pxd
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL0RlcHJlY2F0ZWQvcHl0aG9uX3ZlcnNpb24ucHhk..0000000000000000000000000000000000000000
--- a/Cython/Includes/Deprecated/python_version.pxd
+++ /dev/null
@@ -1,2 +0,0 @@
-# Present for backwards compatibility
-from cpython.version cimport *
diff --git a/Cython/Includes/Deprecated/python_weakref.pxd b/Cython/Includes/Deprecated/python_weakref.pxd
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL0RlcHJlY2F0ZWQvcHl0aG9uX3dlYWtyZWYucHhk..0000000000000000000000000000000000000000
--- a/Cython/Includes/Deprecated/python_weakref.pxd
+++ /dev/null
@@ -1,2 +0,0 @@
-# Present for backwards compatibility
-from cpython.weakref cimport *
diff --git a/Cython/Includes/Deprecated/stdio.pxd b/Cython/Includes/Deprecated/stdio.pxd
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL0RlcHJlY2F0ZWQvc3RkaW8ucHhk..0000000000000000000000000000000000000000
--- a/Cython/Includes/Deprecated/stdio.pxd
+++ /dev/null
@@ -1,2 +0,0 @@
-# Present for backwards compatibility
-from libc.stdio cimport *
diff --git a/Cython/Includes/Deprecated/stdlib.pxd b/Cython/Includes/Deprecated/stdlib.pxd
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL0RlcHJlY2F0ZWQvc3RkbGliLnB4ZA==..0000000000000000000000000000000000000000
--- a/Cython/Includes/Deprecated/stdlib.pxd
+++ /dev/null
@@ -1,2 +0,0 @@
-# Present for backwards compatibility
-from libc.stdlib cimport *
diff --git a/Cython/Includes/Deprecated/stl.pxd b/Cython/Includes/Deprecated/stl.pxd
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL0RlcHJlY2F0ZWQvc3RsLnB4ZA==..0000000000000000000000000000000000000000
--- a/Cython/Includes/Deprecated/stl.pxd
+++ /dev/null
@@ -1,91 +0,0 @@
-cdef extern from "<vector>" namespace std:
-
-	cdef cppclass vector[TYPE]:
-		#constructors
-		__init__()
-		__init__(vector&)
-		__init__(int)
-		__init__(int, TYPE&)
-		__init__(iterator, iterator)
-		#operators
-		TYPE& __getitem__(int)
-		TYPE& __setitem__(int, TYPE&)
-		vector __new__(vector&)
-		bool __eq__(vector&, vector&)
-		bool __ne__(vector&, vector&)
-		bool __lt__(vector&, vector&)
-		bool __gt__(vector&, vector&)
-		bool __le__(vector&, vector&)
-		bool __ge__(vector&, vector&)
-		#others
-		void assign(int, TYPE)
-		#void assign(iterator, iterator)
-		TYPE& at(int)
-		TYPE& back()
-		iterator begin()
-		int capacity()
-		void clear()
-		bool empty()
-		iterator end()
-		iterator erase(iterator)
-		iterator erase(iterator, iterator)
-		TYPE& front()
-		iterator insert(iterator, TYPE&)
-		void insert(iterator, int, TYPE&)
-		void insert(iterator, iterator)
-		int max_size()
-		void pop_back()
-		void push_back(TYPE&)
-		iterator rbegin()
-		iterator rend()
-		void reserve(int)
-		void resize(int)
-		void resize(int, TYPE&) #void resize(size_type num, const TYPE& = TYPE())
-		int size()
-		void swap(container&)
-
-cdef extern from "<deque>" namespace std:
-
-	cdef cppclass deque[TYPE]:
-		#constructors
-		__init__()
-		__init__(deque&)
-		__init__(int)
-		__init__(int, TYPE&)
-		__init__(iterator, iterator)
-		#operators
-		TYPE& operator[]( size_type index );
-		const TYPE& operator[]( size_type index ) const;
-		deque __new__(deque&);
-		bool __eq__(deque&, deque&);
-		bool __ne__(deque&, deque&);
-		bool __lt__(deque&, deque&);
-		bool __gt__(deque&, deque&);
-		bool __le__(deque&, deque&);
-		bool __ge__(deque&, deque&);
-		#others
-		void assign(int, TYPE&)
-		void assign(iterator, iterator)
-		TYPE& at(int)
-		TYPE& back()
-		iterator begin()
-		void clear()
-		bool empty()
-		iterator end()
-		iterator erase(iterator)
-		iterator erase(iterator, iterator)
-		TYPE& front()
-		iterator insert(iterator, TYPE&)
-		void insert(iterator, int, TYPE&)
-		void insert(iterator, iterator, iterator)
-		int max_size()
-		void pop_back()
-		void pop_front()
-		void push_back(TYPE&)
-		void push_front(TYPE&)
-		iterator rbegin()
-		iterator rend()
-		void resize(int)
-		void resize(int, TYPE&)
-		int size()
-		void swap(container&)
diff --git a/Cython/Includes/cpython/bytes.pxd b/Cython/Includes/cpython/bytes.pxd
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL2NweXRob24vYnl0ZXMucHhk..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0luY2x1ZGVzL2NweXRob24vYnl0ZXMucHhk 100644
--- a/Cython/Includes/cpython/bytes.pxd
+++ b/Cython/Includes/cpython/bytes.pxd
@@ -68,6 +68,10 @@
     # Return value: New reference.
     # Identical to PyBytes_FromFormat() except that it takes exactly two arguments.
 
+    bytes PyBytes_FromObject(object o)
+    # Return value: New reference.
+    # Return the bytes representation of object o that implements the buffer protocol.
+
     Py_ssize_t PyBytes_Size(object string) except -1
     # Return the length of the string in string object string.
 
diff --git a/Cython/Includes/cpython/descr.pxd b/Cython/Includes/cpython/descr.pxd
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0luY2x1ZGVzL2NweXRob24vZGVzY3IucHhk
--- /dev/null
+++ b/Cython/Includes/cpython/descr.pxd
@@ -0,0 +1,26 @@
+from .object cimport PyObject, PyTypeObject
+
+cdef extern from "Python.h":
+    ctypedef object (*wrapperfunc)(self, args, void* wrapped)
+    ctypedef object (*wrapperfunc_kwds)(self, args, void* wrapped, kwds)
+
+    struct wrapperbase:
+        char* name
+        int offset
+        void* function
+        wrapperfunc wrapper
+        char* doc
+        int flags
+        PyObject* name_strobj
+
+    int PyWrapperFlag_KEYWORDS
+
+    ctypedef class __builtin__.wrapper_descriptor [object PyWrapperDescrObject]:
+        cdef type d_type
+        cdef d_name
+        cdef wrapperbase* d_base
+        cdef void* d_wrapped
+
+    object PyDescr_NewWrapper(PyTypeObject* cls, wrapperbase* wrapper, void* wrapped)
+
+    int PyDescr_IsData(descr)
diff --git a/Cython/Includes/cpython/dict.pxd b/Cython/Includes/cpython/dict.pxd
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL2NweXRob24vZGljdC5weGQ=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0luY2x1ZGVzL2NweXRob24vZGljdC5weGQ= 100644
--- a/Cython/Includes/cpython/dict.pxd
+++ b/Cython/Includes/cpython/dict.pxd
@@ -1,3 +1,4 @@
 from .object cimport PyObject
+from .pyport cimport uint64_t
 
 cdef extern from "Python.h":
@@ -2,5 +3,11 @@
 
 cdef extern from "Python.h":
+    # On Python 2, PyDict_GetItemWithError is called _PyDict_GetItemWithError
+    """
+    #if PY_MAJOR_VERSION <= 2
+    #define PyDict_GetItemWithError _PyDict_GetItemWithError
+    #endif
+    """
 
     ############################################################################
     # 7.4.1 Dictionary Objects
@@ -72,8 +79,14 @@
     # NULL if the key key is not present, but without setting an
     # exception.
 
+    PyObject* PyDict_GetItemWithError(object p, object key) except? NULL
+    # Return value: Borrowed reference.
+    # Variant of PyDict_GetItem() that does not suppress exceptions. Return
+    # NULL with an exception set if an exception occurred. Return NULL
+    # without an exception set if the key wasn’t present.
+
     PyObject* PyDict_GetItemString(object p, const char *key)
     # Return value: Borrowed reference.
     # This is the same as PyDict_GetItem(), but key is specified as a
     # char*, rather than a PyObject*.
 
@@ -75,8 +88,16 @@
     PyObject* PyDict_GetItemString(object p, const char *key)
     # Return value: Borrowed reference.
     # This is the same as PyDict_GetItem(), but key is specified as a
     # char*, rather than a PyObject*.
 
+    PyObject* PyDict_SetDefault(object p, object key, object default) except NULL
+    # Return value: Borrowed reference.
+    # This is the same as the Python-level dict.setdefault(). If present, it
+    # returns the value corresponding to key from the dictionary p. If the key
+    # is not in the dict, it is inserted with value defaultobj and defaultobj
+    # is returned. This function evaluates the hash function of key only once,
+    # instead of evaluating it independently for the lookup and the insertion.
+
     list PyDict_Items(object p)
     # Return value: New reference.
     # Return a PyListObject containing all the items from the
diff --git a/Cython/Includes/cpython/marshal.pxd b/Cython/Includes/cpython/marshal.pxd
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0luY2x1ZGVzL2NweXRob24vbWFyc2hhbC5weGQ=
--- /dev/null
+++ b/Cython/Includes/cpython/marshal.pxd
@@ -0,0 +1,66 @@
+from libc.stdio cimport FILE
+
+cdef extern from "Python.h":
+
+    ###########################################################################
+    # Data marshalling support
+    ###########################################################################
+
+    const int Py_MARSHAL_VERSION
+
+    void PyMarshal_WriteLongToFile(long value, FILE *file, int version)
+    # Marshal a long integer, value, to file. This will only write the
+    # least-significant 32 bits of value, regardless of the size of the native
+    # long type. version indicates the file format.
+
+    void PyMarshal_WriteObjectToFile(object value, FILE *file, int version)
+    # Marshal a Python object, value, to file. version indicates the file
+    # format.
+
+    bytes PyMarshal_WriteObjectToString(object value, int version)
+    # Return value: New reference.
+    # Return a bytes object containing the marshalled representation of value.
+    # version indicates the file format.
+
+    long PyMarshal_ReadLongFromFile(FILE *file) except? -1
+    # Return a C long from the data stream in a FILE* opened for reading. Only
+    # a 32-bit value can be read in using this function, regardless of the
+    # native size of long.
+
+    # On error, sets the appropriate exception (EOFError) and returns -1.
+
+    int PyMarshal_ReadShortFromFile(FILE *file) except? -1
+    # Return a C short from the data stream in a FILE* opened for reading. Only
+    # a 16-bit value can be read in using this function, regardless of the
+    # native size of short.
+
+    # On error, sets the appropriate exception (EOFError) and returns -1.
+
+    object PyMarshal_ReadObjectFromFile(FILE *file)
+    # Return value: New reference.
+    # Return a Python object from the data stream in a FILE* opened for
+    # reading.
+    
+    # On error, sets the appropriate exception (EOFError, ValueError or
+    # TypeError) and returns NULL.
+
+    object PyMarshal_ReadLastObjectFromFile(FILE *file)
+    # Return value: New reference.
+    # Return a Python object from the data stream in a FILE* opened for
+    # reading. Unlike PyMarshal_ReadObjectFromFile(), this function assumes
+    # that no further objects will be read from the file, allowing it to
+    # aggressively load file data into memory so that the de-serialization can
+    # operate from data in memory, rather than reading a byte at a time from the
+    # file. Only use these variant if you are certain that you won’t be reading
+    # anything else from the file.
+
+    # On error, sets the appropriate exception (EOFError, ValueError or
+    # TypeError) and returns NULL.
+
+    object PyMarshal_ReadObjectFromString(const char *data, Py_ssize_t len)
+    # Return value: New reference.
+    # Return a Python object from the data stream in a byte buffer containing
+    # len bytes pointed to by data.
+
+    # On error, sets the appropriate exception (EOFError, ValueError or
+    # TypeError) and returns NULL.
diff --git a/Cython/Includes/cpython/module.pxd b/Cython/Includes/cpython/module.pxd
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL2NweXRob24vbW9kdWxlLnB4ZA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0luY2x1ZGVzL2NweXRob24vbW9kdWxlLnB4ZA== 100644
--- a/Cython/Includes/cpython/module.pxd
+++ b/Cython/Includes/cpython/module.pxd
@@ -145,6 +145,12 @@
     bint PyModule_CheckExact(object p)
     # Return true if p is a module object, but not a subtype of PyModule_Type.
 
+    object PyModule_NewObject(object name)
+    # Return a new module object with the __name__ attribute set to name.
+    # The module’s __name__, __doc__, __package__, and __loader__
+    # attributes are filled in (all but __name__ are set to None); the caller
+    # is responsible for providing a __file__ attribute.
+
     object PyModule_New(const char *name)
     # Return value: New reference.
     # Return a new module object with the __name__ attribute set to
@@ -160,4 +166,8 @@
     # use other PyModule_*() and PyObject_*() functions rather than
     # directly manipulate a module's __dict__.
 
+    object PyModule_GetNameObject(object module)
+    # Return module’s __name__ value. If the module does not provide one, or if
+    # it is not a string, SystemError is raised and NULL is returned.
+
     char* PyModule_GetName(object module) except NULL
@@ -163,6 +173,16 @@
     char* PyModule_GetName(object module) except NULL
-    # Return module's __name__ value. If the module does not provide
-    # one, or if it is not a string, SystemError is raised and NULL is
-    # returned.
+    # Similar to PyModule_GetNameObject() but return the name encoded
+    # to 'utf-8'.
+
+    void* PyModule_GetState(object module)
+    # Return the “state” of the module, that is, a pointer to the block of
+    # memory allocated at module creation time, or NULL.
+    # See PyModuleDef.m_size.
+
+    object PyModule_GetFilenameObject(object module)
+    # Return the name of the file from which module was loaded using module’s
+    # __file__ attribute. If this is not defined, or if it is not a unicode
+    # string, raise SystemError and return NULL; otherwise return a reference
+    # to a Unicode object.
 
     char* PyModule_GetFilename(object module) except NULL
@@ -167,8 +187,7 @@
 
     char* PyModule_GetFilename(object module) except NULL
-    # Return the name of the file from which module was loaded using
-    # module's __file__ attribute. If this is not defined, or if it is
-    # not a string, raise SystemError and return NULL.
+    # Similar to PyModule_GetFilenameObject() but return the filename encoded
+    # to ‘utf-8’.
 
     int PyModule_AddObject(object module,  const char *name, object value) except -1
     # Add an object to module as name. This is a convenience function
diff --git a/Cython/Includes/cpython/object.pxd b/Cython/Includes/cpython/object.pxd
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL2NweXRob24vb2JqZWN0LnB4ZA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0luY2x1ZGVzL2NweXRob24vb2JqZWN0LnB4ZA== 100644
--- a/Cython/Includes/cpython/object.pxd
+++ b/Cython/Includes/cpython/object.pxd
@@ -45,6 +45,8 @@
 
         newfunc tp_new
         destructor tp_dealloc
+        destructor tp_del
+        destructor tp_finalize
         traverseproc tp_traverse
         inquiry tp_clear
         freefunc tp_free
@@ -63,6 +65,8 @@
         descrgetfunc tp_descr_get
         descrsetfunc tp_descr_set
 
+        unsigned int tp_version_tag
+
     ctypedef struct PyObject:
         Py_ssize_t ob_refcnt
         PyTypeObject *ob_type
@@ -128,6 +132,17 @@
     # failure. This is the equivalent of the Python statement "del
     # o.attr_name".
 
+    object PyObject_GenericGetDict(object o, void *context)
+    # Return value: New reference.
+    # A generic implementation for the getter of a __dict__ descriptor. It
+    # creates the dictionary if necessary.
+    # New in version 3.3.
+
+    int PyObject_GenericSetDict(object o, object value, void *context) except -1
+    # A generic implementation for the setter of a __dict__ descriptor. This
+    # implementation does not allow the dictionary to be deleted.
+    # New in version 3.3.
+
     int Py_LT, Py_LE, Py_EQ, Py_NE, Py_GT, Py_GE
 
     object PyObject_RichCompare(object o1, object o2, int opid)
@@ -177,6 +192,14 @@
     # equivalent of the Python expression "str(o)". Called by the
     # str() built-in function and by the print statement.
 
+    object PyObject_Bytes(object o)
+    # Return value: New reference.
+    # Compute a bytes representation of object o. Return NULL on
+    # failure and a bytes object on success. This is equivalent to
+    # the Python expression bytes(o), when o is not an integer.
+    # Unlike bytes(o), a TypeError is raised when o is an integer
+    # instead of a zero-initialized bytes object.
+
     object PyObject_Unicode(object o)
     # Return value: New reference.
     # Compute a Unicode string representation of object o. Returns the
@@ -320,6 +343,13 @@
     # returned. On error, -1 is returned. This is the equivalent to
     # the Python expression "len(o)".
 
+    Py_ssize_t PyObject_LengthHint(object o, Py_ssize_t default) except -1
+    # Return an estimated length for the object o. First try to return its
+    # actual length, then an estimate using __length_hint__(), and finally
+    # return the default value. On error, return -1. This is the equivalent to
+    # the Python expression "operator.length_hint(o, default)".
+    # New in version 3.4.
+
     object PyObject_GetItem(object o, object key)
     # Return value: New reference.
     # Return element of o corresponding to the object key or NULL on
@@ -397,3 +427,4 @@
     long Py_TPFLAGS_DEFAULT_EXTERNAL
     long Py_TPFLAGS_DEFAULT_CORE
     long Py_TPFLAGS_DEFAULT
+    long Py_TPFLAGS_HAVE_FINALIZE
diff --git a/Cython/Includes/cpython/pyport.pxd b/Cython/Includes/cpython/pyport.pxd
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0luY2x1ZGVzL2NweXRob24vcHlwb3J0LnB4ZA==
--- /dev/null
+++ b/Cython/Includes/cpython/pyport.pxd
@@ -0,0 +1,8 @@
+cdef extern from "Python.h":
+    ctypedef int int32_t
+    ctypedef int int64_t
+    ctypedef unsigned int uint32_t
+    ctypedef unsigned int uint64_t
+
+    const Py_ssize_t PY_SSIZE_T_MIN
+    const Py_ssize_t PY_SSIZE_T_MAX
diff --git a/Cython/Includes/cpython/pystate.pxd b/Cython/Includes/cpython/pystate.pxd
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL2NweXRob24vcHlzdGF0ZS5weGQ=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0luY2x1ZGVzL2NweXRob24vcHlzdGF0ZS5weGQ= 100644
--- a/Cython/Includes/cpython/pystate.pxd
+++ b/Cython/Includes/cpython/pystate.pxd
@@ -84,6 +84,9 @@
     # PyGILState_Release on the same thread.
     void PyGILState_Release(PyGILState_STATE)
 
+    # Return 1 if the current thread holds the GIL and 0 otherwise.
+    int PyGILState_Check()
+
     # Routines for advanced debuggers, requested by David Beazley.
     # Don't use unless you know what you are doing!
     PyInterpreterState * PyInterpreterState_Head()
diff --git a/Cython/Includes/cpython/type.pxd b/Cython/Includes/cpython/type.pxd
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL2NweXRob24vdHlwZS5weGQ=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0luY2x1ZGVzL2NweXRob24vdHlwZS5weGQ= 100644
--- a/Cython/Includes/cpython/type.pxd
+++ b/Cython/Includes/cpython/type.pxd
@@ -23,6 +23,11 @@
     # of the standard type object. Return false in all other
     # cases.
 
+    void PyType_Modified(type type)
+    # Invalidate the internal lookup cache for the type and all of its
+    # subtypes. This function must be called after any manual modification
+    # of the attributes or base classes of the type.
+
     bint PyType_HasFeature(object o, int feature)
     # Return true if the type object o sets the feature feature. Type
     # features are denoted by single bit flags.
diff --git a/Cython/Includes/cpython/unicode.pxd b/Cython/Includes/cpython/unicode.pxd
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL2NweXRob24vdW5pY29kZS5weGQ=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0luY2x1ZGVzL2NweXRob24vdW5pY29kZS5weGQ= 100644
--- a/Cython/Includes/cpython/unicode.pxd
+++ b/Cython/Includes/cpython/unicode.pxd
@@ -92,6 +92,14 @@
     # when u is NULL.
     unicode PyUnicode_FromUnicode(Py_UNICODE *u, Py_ssize_t size)
 
+    # Similar to PyUnicode_FromUnicode(), but u points to UTF-8 encoded
+    # bytes
+    unicode PyUnicode_FromStringAndSize(const char *u, Py_ssize_t size)
+
+    # Similar to PyUnicode_FromUnicode(), but u points to null-terminated
+    # UTF-8 encoded bytes.  The size is determined with strlen().
+    unicode PyUnicode_FromString(const char *u)
+
     # Create a Unicode Object from the given Unicode code point ordinal.
     #
     # The ordinal must be in range(0x10000) on narrow Python builds
diff --git a/Cython/Includes/libc/complex.pxd b/Cython/Includes/libc/complex.pxd
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0luY2x1ZGVzL2xpYmMvY29tcGxleC5weGQ=
--- /dev/null
+++ b/Cython/Includes/libc/complex.pxd
@@ -0,0 +1,35 @@
+cdef extern from "<complex.h>" nogil:
+    # Trigonometric functions.
+    double complex cacos(double complex z)
+    double complex casin(double complex z)
+    double complex catan(double complex z)
+    double complex ccos(double complex z)
+    double complex csin(double complex z)
+    double complex ctan(double complex z)
+
+    # Hyperbolic functions.
+    double complex cacosh(double complex z)
+    double complex casinh(double complex z)
+    double complex catanh(double complex z)
+    double complex ccosh(double complex z)
+    double complex csinh(double complex z)
+    double complex ctanh(double complex z)
+
+    # Exponential and logarithmic functions.
+    double complex cexp(double complex z)
+    double complex clog(double complex z)
+    double complex clog10(double complex z)
+
+    # Power functions.
+    double complex cpow(double complex x, double complex y)
+    double complex csqrt(double complex z)
+
+    # Absolute value, conjugates, and projection.
+    double cabs(double complex z)
+    double carg(double complex z)
+    double complex conj(double complex z)
+    double complex cproj(double complex z)
+
+    # Decomposing complex values.
+    double cimag(double complex z)
+    double creal(double complex z)
diff --git a/Cython/Includes/libc/time.pxd b/Cython/Includes/libc/time.pxd
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL2xpYmMvdGltZS5weGQ=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0luY2x1ZGVzL2xpYmMvdGltZS5weGQ= 100644
--- a/Cython/Includes/libc/time.pxd
+++ b/Cython/Includes/libc/time.pxd
@@ -1,4 +1,4 @@
-# http://en.wikipedia.org/wiki/C_date_and_time_functions
+# https://en.wikipedia.org/wiki/C_date_and_time_functions
 
 from libc.stddef cimport wchar_t
 
diff --git a/Cython/Includes/libcpp/algorithm.pxd b/Cython/Includes/libcpp/algorithm.pxd
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL2xpYmNwcC9hbGdvcml0aG0ucHhk..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0luY2x1ZGVzL2xpYmNwcC9hbGdvcml0aG0ucHhk 100644
--- a/Cython/Includes/libcpp/algorithm.pxd
+++ b/Cython/Includes/libcpp/algorithm.pxd
@@ -1,4 +1,6 @@
 from libcpp cimport bool
+from libcpp.utility cimport pair
+from libc.stddef import ptrdiff_t
 
 
 cdef extern from "<algorithm>" namespace "std" nogil:
@@ -2,8 +4,20 @@
 
 
 cdef extern from "<algorithm>" namespace "std" nogil:
-    # Sorting and searching
-    bool binary_search[Iter, T](Iter first, Iter last, const T& value)
-    bool binary_search[Iter, T, Compare](Iter first, Iter last, const T& value,
-                                         Compare comp)
+    # Non-modifying sequence operations
+    bool all_of[Iter, Pred](Iter first, Iter last, Pred pred) except +
+    bool any_of[Iter, Pred](Iter first, Iter last, Pred pred) except +
+    bool none_of[Iter, Pred](Iter first, Iter last, Pred pred) except +
+
+    void for_each[Iter, UnaryFunction](Iter first, Iter last, UnaryFunction f) except +  # actually returns f
+
+    ptrdiff_t count[Iter, T](Iter first, Iter last, const T& value) except +
+    ptrdiff_t count_if[Iter, Pred](Iter first, Iter last, Pred pred) except +
+
+    pair[Iter1, Iter2] mismatch[Iter1, Iter2](
+        Iter1 first1, Iter1 last1, Iter2 first2) except +  # other overloads are tricky
+
+    Iter find[Iter, T](Iter first, Iter last, const T& value) except +
+    Iter find_if[Iter, Pred](Iter first, Iter last, Pred pred) except +
+    Iter find_if_not[Iter, Pred](Iter first, Iter last, Pred pred) except +
 
@@ -9,5 +23,19 @@
 
-    Iter lower_bound[Iter, T](Iter first, Iter last, const T& value)
-    Iter lower_bound[Iter, T, Compare](Iter first, Iter last, const T& value,
-                                       Compare comp)
+    Iter1 find_end[Iter1, Iter2](Iter1 first1, Iter1 last1, Iter2 first2, Iter2 last2) except +
+    Iter1 find_end[Iter1, Iter2, BinaryPred](
+        Iter1 first1, Iter1 last1, Iter2 first2, Iter2 last2, BinaryPred pred) except +
+
+    Iter1 find_first_of[Iter1, Iter2](Iter1 first1, Iter1 last1, Iter2 first2, Iter2 last2) except +
+    Iter1 find_first_of[Iter1, Iter2, BinaryPred](
+        Iter1 first1, Iter1 last1, Iter2 first2, Iter2 last2, BinaryPred pred) except +
+
+    Iter adjacent_find[Iter](Iter first, Iter last) except +
+    Iter adjacent_find[Iter, BinaryPred](Iter first, Iter last, BinaryPred pred) except +
+
+    Iter1 search[Iter1, Iter2](Iter1 first1, Iter1 last1, Iter2 first2, Iter2 last2) except +
+    Iter1 search[Iter1, Iter2, BinaryPred](
+        Iter1 first1, Iter1 last1, Iter2 first2, Iter2 last2, BinaryPred pred) except +
+    Iter search_n[Iter, Size, T](Iter first1, Iter last1, Size count, const T& value) except +
+    Iter search_n[Iter, Size, T, BinaryPred](
+        Iter first1, Iter last1, Size count, const T& value, BinaryPred pred) except +
 
@@ -13,5 +41,21 @@
 
-    Iter upper_bound[Iter, T](Iter first, Iter last, const T& value)
-    Iter upper_bound[Iter, T, Compare](Iter first, Iter last, const T& value,
-                                       Compare comp)
+    # Modifying sequence operations
+    OutputIt copy[InputIt, OutputIt](InputIt first, InputIt last, OutputIt d_first) except +
+    OutputIt copy_if[InputIt, OutputIt, Pred](InputIt first, InputIt last, OutputIt d_first, Pred pred) except +
+    OutputIt copy_n[InputIt, Size, OutputIt](InputIt first, Size count, OutputIt result) except +
+    Iter2 copy_backward[Iter1, Iter2](Iter1 first, Iter1 last, Iter2 d_last) except +
+
+    OutputIt move[InputIt, OutputIt](InputIt first, InputIt last, OutputIt d_first) except +
+    Iter2 move_backward[Iter1, Iter2](Iter1 first, Iter1 last, Iter2 d_last) except +
+
+    void fill[Iter, T](Iter first, Iter last, const T& value) except +
+    Iter fill_n[Iter, Size, T](Iter first, Size count, const T& value) except +
+
+    OutputIt transform[InputIt, OutputIt, UnaryOp](
+        InputIt first1, InputIt last1, OutputIt d_first, UnaryOp unary_op) except +
+    OutputIt transform[InputIt1, InputIt2, OutputIt, BinaryOp](
+        InputIt1 first1, InputIt1 last1, InputIt2 first2, OutputIt d_first, BinaryOp binary_op) except +
+
+    void generate[Iter, Generator](Iter first, Iter last, Generator g) except +
+    void generate_n[Iter, Size, Generator](Iter first, Size count, Generator g) except +
 
@@ -17,5 +61,7 @@
 
-    void partial_sort[Iter](Iter first, Iter middle, Iter last)
-    void partial_sort[Iter, Compare](Iter first, Iter middle, Iter last,
-                                     Compare comp)
+    Iter remove[Iter, T](Iter first, Iter last, const T& value) except +
+    Iter remove_if[Iter, UnaryPred](Iter first, Iter last, UnaryPred pred) except +
+    OutputIt remove_copy[InputIt, OutputIt, T](InputIt first, InputIt last, OutputIt d_first, const T& value) except +
+    OutputIt remove_copy_if[InputIt, OutputIt, UnaryPred](
+        InputIt first, InputIt last, OutputIt d_first, UnaryPred pred) except +
 
@@ -21,4 +67,15 @@
 
-    void sort[Iter](Iter first, Iter last)
-    void sort[Iter, Compare](Iter first, Iter last, Compare comp)
+    void replace[Iter, T](Iter first, Iter last, const T& old_value, const T& new_value) except +
+    void replace_if[Iter, UnaryPred, T](Iter first, Iter last, UnaryPred pred, const T& new_value) except +
+    OutputIt replace_copy[InputIt, OutputIt, T](
+        InputIt first, InputIt last, OutputIt d_first, const T& old_value, const T& new_value) except +
+    OutputIt replace_copy_if[InputIt, OutputIt, UnaryPred, T](
+        InputIt first, InputIt last, OutputIt d_first, UnaryPred pred, const T& new_value) except +
+
+    void swap[T](T& a, T& b) except +  # array overload also works
+    Iter2 swap_ranges[Iter1, Iter2](Iter1 first1, Iter1 last1, Iter2 first2) except +
+    void iter_swap[Iter](Iter a, Iter b) except +
+
+    void reverse[Iter](Iter first, Iter last) except +
+    OutputIt reverse_copy[InputIt, OutputIt](InputIt first, InputIt last, OutputIt d_first) except +
 
@@ -24,5 +81,18 @@
 
-    # Removing duplicates
-    Iter unique[Iter](Iter first, Iter last)
-    Iter unique[Iter, BinaryPredicate](Iter first, Iter last, BinaryPredicate p)
+    Iter rotate[Iter](Iter first, Iter n_first, Iter last) except +
+    OutputIt rotate_copy[InputIt, OutputIt](InputIt first, InputIt n_first, InputIt last, OutputIt d_first) except +
+
+    Iter unique[Iter](Iter first, Iter last) except +
+    Iter unique[Iter, BinaryPred](Iter first, Iter last, BinaryPred p) except +
+    OutputIt unique_copy[InputIt, OutputIt](InputIt first, InputIt last, OutputIt d_first) except +
+    OutputIt unique_copy[InputIt, OutputIt, BinaryPred](
+        InputIt first, InputIt last, OutputIt d_first, BinaryPred pred) except +
+
+    # Partitioning operations
+    bool is_partitioned[Iter, Pred](Iter first, Iter last, Pred p) except +
+    Iter partition[Iter, Pred](Iter first, Iter last, Pred p) except +
+    pair[OutputIt1, OutputIt2] partition_copy[InputIt, OutputIt1, OutputIt2, Pred](
+        InputIt first, InputIt last, OutputIt1 d_first_true, OutputIt2 d_first_false, Pred p) except +
+    Iter stable_partition[Iter, Pred](Iter first, Iter last, Pred p) except +
+    Iter partition_point[Iter, Pred](Iter first, Iter last, Pred p) except +
 
@@ -28,5 +98,19 @@
 
-    # Binary heaps (priority queues)
-    void make_heap[Iter](Iter first, Iter last)
-    void make_heap[Iter, Compare](Iter first, Iter last, Compare comp)
+    # Sorting operations
+    bool is_sorted[Iter](Iter first, Iter last) except +
+    bool is_sorted[Iter, Compare](Iter first, Iter last, Compare comp) except +
+
+    Iter is_sorted_until[Iter](Iter first, Iter last) except +
+    Iter is_sorted_until[Iter, Compare](Iter first, Iter last, Compare comp) except +
+
+    void sort[Iter](Iter first, Iter last) except +
+    void sort[Iter, Compare](Iter first, Iter last, Compare comp) except +
+
+    void partial_sort[Iter](Iter first, Iter middle, Iter last) except +
+    void partial_sort[Iter, Compare](Iter first, Iter middle, Iter last, Compare comp) except +
+
+    OutputIt partial_sort_copy[InputIt, OutputIt](
+        InputIt first, InputIt last, OutputIt d_first, OutputIt d_last) except +
+    OutputIt partial_sort_copy[InputIt, OutputIt, Compare](
+        InputIt first, InputIt last, OutputIt d_first, OutputIt d_last, Compare comp) except +
 
@@ -32,4 +116,11 @@
 
-    void pop_heap[Iter](Iter first, Iter last)
-    void pop_heap[Iter, Compare](Iter first, Iter last, Compare comp)
+    void stable_sort[Iter](Iter first, Iter last) except +
+    void stable_sort[Iter, Compare](Iter first, Iter last, Compare comp) except +
+
+    void nth_element[Iter](Iter first, Iter nth, Iter last) except +
+    void nth_element[Iter, Compare](Iter first, Iter nth, Iter last, Compare comp) except +
+
+    # Binary search operations (on sorted ranges)
+    Iter lower_bound[Iter, T](Iter first, Iter last, const T& value) except +
+    Iter lower_bound[Iter, T, Compare](Iter first, Iter last, const T& value, Compare comp) except +
 
@@ -35,4 +126,11 @@
 
-    void push_heap[Iter](Iter first, Iter last)
-    void push_heap[Iter, Compare](Iter first, Iter last, Compare comp)
+    Iter upper_bound[Iter, T](Iter first, Iter last, const T& value) except +
+    Iter upper_bound[Iter, T, Compare](Iter first, Iter last, const T& value, Compare comp) except +
+
+    bool binary_search[Iter, T](Iter first, Iter last, const T& value) except +
+    bool binary_search[Iter, T, Compare](Iter first, Iter last, const T& value, Compare comp) except +
+
+    # Other operations on sorted ranges
+
+    # Set operations (on sorted ranges)
 
@@ -38,4 +136,11 @@
 
-    void sort_heap[Iter](Iter first, Iter last)
-    void sort_heap[Iter, Compare](Iter first, Iter last, Compare comp)
+    # Heap operations
+    void make_heap[Iter](Iter first, Iter last) except +
+    void make_heap[Iter, Compare](Iter first, Iter last, Compare comp) except +
+
+    void push_heap[Iter](Iter first, Iter last) except +
+    void push_heap[Iter, Compare](Iter first, Iter last, Compare comp) except +
+
+    void pop_heap[Iter](Iter first, Iter last) except +
+    void pop_heap[Iter, Compare](Iter first, Iter last, Compare comp) except +
 
@@ -41,3 +146,10 @@
 
-    # Copy
-    OutputIter copy[InputIter,OutputIter](InputIter,InputIter,OutputIter)
+    void sort_heap[Iter](Iter first, Iter last) except +
+    void sort_heap[Iter, Compare](Iter first, Iter last, Compare comp) except +
+
+    # Minimum/maximum operations
+    Iter min_element[Iter](Iter first, Iter last) except +
+
+    # Comparison operations
+
+    # Permutation operations
diff --git a/Cython/Includes/libcpp/atomic.pxd b/Cython/Includes/libcpp/atomic.pxd
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0luY2x1ZGVzL2xpYmNwcC9hdG9taWMucHhk
--- /dev/null
+++ b/Cython/Includes/libcpp/atomic.pxd
@@ -0,0 +1,60 @@
+
+cdef extern from "<atomic>" namespace "std" nogil:
+    
+    cdef enum memory_order:
+        memory_order_relaxed
+        memory_order_consume
+        memory_order_acquire
+        memory_order_release
+        memory_order_acq_rel
+        memory_order_seq_cst
+    
+    cdef cppclass atomic[T]:
+        atomic()
+        atomic(T)
+        
+        bint is_lock_free()
+        void store(T)
+        void store(T, memory_order)
+        T load()
+        T load(memory_order)
+        T exchange(T)
+        T exchange(T, memory_order)
+        
+        bint compare_exchange_weak(T&, T, memory_order, memory_order)
+        bint compare_exchange_weak(T&, T, memory_order)
+        bint compare_exchange_weak(T&, T)
+        bint compare_exchange_strong(T&, T, memory_order, memory_order)
+        bint compare_exchange_strong(T&, T, memory_order)
+        bint compare_exchange_strong(T&, T)
+        
+        T fetch_add(T, memory_order)
+        T fetch_add(T)
+        T fetch_sub(T, memory_order)
+        T fetch_sub(T)
+        T fetch_and(T, memory_order)
+        T fetch_and(T)
+        T fetch_or(T, memory_order)
+        T fetch_or(T)
+        T fetch_xor(T, memory_order)
+        T fetch_xor(T)
+        
+        T operator++()
+        T operator++(int)
+        T operator--()
+        T operator--(int)
+        
+        # modify-in-place operators not yet supported by Cython:
+        # T operator+=(T)
+        # T operator-=(T)
+        # T operator&=(T)
+        # T operator|=(T)
+        # T operator^=(T)
+        
+        bint operator==(atomic[T]&, atomic[T]&)
+        bint operator==(atomic[T]&, T&)
+        bint operator==(T&, atomic[T]&)
+        bint operator!=(atomic[T]&, atomic[T]&)
+        bint operator!=(atomic[T]&, T&)
+        bint operator!=(T&, atomic[T]&)
+
diff --git a/Cython/Includes/libcpp/functional.pxd b/Cython/Includes/libcpp/functional.pxd
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL2xpYmNwcC9mdW5jdGlvbmFsLnB4ZA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0luY2x1ZGVzL2xpYmNwcC9mdW5jdGlvbmFsLnB4ZA== 100644
--- a/Cython/Includes/libcpp/functional.pxd
+++ b/Cython/Includes/libcpp/functional.pxd
@@ -1,3 +1,5 @@
+from libcpp cimport bool
+
 cdef extern from "<functional>" namespace "std" nogil:
     cdef cppclass function[T]:
         function() except +
@@ -10,4 +12,10 @@
         function operator=(void*)
         function operator=[U](U)
 
-        bint operator bool()
+        bool operator bool()
+
+    # Comparisons
+    cdef cppclass greater[T=*]:
+        # https://github.com/cython/cython/issues/3193
+        greater() except +
+        bool operator()(const T& lhs, const T& rhs) except +
diff --git a/Cython/Includes/libcpp/iterator.pxd b/Cython/Includes/libcpp/iterator.pxd
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL2xpYmNwcC9pdGVyYXRvci5weGQ=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0luY2x1ZGVzL2xpYmNwcC9pdGVyYXRvci5weGQ= 100644
--- a/Cython/Includes/libcpp/iterator.pxd
+++ b/Cython/Includes/libcpp/iterator.pxd
@@ -1,6 +1,8 @@
 #Basic reference: http://www.cplusplus.com/reference/iterator/
 #Most of these classes are in fact empty structs
 
+from libc.stddef import ptrdiff_t
+
 cdef extern from "<iterator>" namespace "std" nogil:
     cdef cppclass iterator[Category,T,Distance,Pointer,Reference]:
         pass
@@ -29,4 +31,4 @@
     ##insert_iterator<Container> inserter (Container& x, typename Container::iterator it)
     insert_iterator[CONTAINER] inserter[CONTAINER,ITERATOR](CONTAINER &, ITERATOR)
 
-
+    ptrdiff_t distance[It](It first, It last)
diff --git a/Cython/Includes/libcpp/numeric.pxd b/Cython/Includes/libcpp/numeric.pxd
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0luY2x1ZGVzL2xpYmNwcC9udW1lcmljLnB4ZA==
--- /dev/null
+++ b/Cython/Includes/libcpp/numeric.pxd
@@ -0,0 +1,23 @@
+cdef extern from "<numeric>" namespace "std" nogil:
+    T inner_product[InputIt1, InputIt2, T](InputIt1 first1, InputIt1 last1, InputIt2 first2, T init)
+
+    T inner_product[InputIt1, InputIt2, T, BinaryOperation1, BinaryOperation2](InputIt1 first1, InputIt1 last1,
+                                                                               InputIt2 first2, T init,
+                                                                               BinaryOperation1 op1,
+                                                                               BinaryOperation2 op2)
+
+    void iota[ForwardIt, T](ForwardIt first, ForwardIt last, T value)
+
+    T accumulate[InputIt, T](InputIt first, InputIt last, T init)
+
+    T accumulate[InputIt, T, BinaryOperation](InputIt first, InputIt last, T init, BinaryOperation op)
+
+    void adjacent_difference[InputIt, OutputIt](InputIt in_first, InputIt in_last, OutputIt out_first)
+
+    void adjacent_difference[InputIt, OutputIt, BinaryOperation](InputIt in_first, InputIt in_last, OutputIt out_first,
+                                                                 BinaryOperation op)
+
+    void partial_sum[InputIt, OutputIt](InputIt in_first, OutputIt in_last, OutputIt out_first)
+
+    void partial_sum[InputIt, OutputIt, BinaryOperation](InputIt in_first, InputIt in_last, OutputIt out_first,
+                                                         BinaryOperation op)
diff --git a/Cython/Includes/libcpp/string.pxd b/Cython/Includes/libcpp/string.pxd
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL2xpYmNwcC9zdHJpbmcucHhk..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0luY2x1ZGVzL2xpYmNwcC9zdHJpbmcucHhk 100644
--- a/Cython/Includes/libcpp/string.pxd
+++ b/Cython/Includes/libcpp/string.pxd
@@ -8,13 +8,6 @@
     size_t npos = -1
 
     cdef cppclass string:
-        string() except +
-        string(const char *) except +
-        string(const char *, size_t) except +
-        string(const string&) except +
-        # as a string formed by a repetition of character c, n times.
-        string(size_t, char) except +
-
         cppclass iterator:
             iterator()
             char& operator*()
@@ -40,6 +33,15 @@
         cppclass const_reverse_iterator(reverse_iterator):
             pass
 
+        string() except +
+        string(const char *) except +
+        string(const char *, size_t) except +
+        string(const string&) except +
+        # as a string formed by a repetition of character c, n times.
+        string(size_t, char) except +
+        # from a pair of iterators
+        string(iterator first, iterator last) except +
+
         iterator begin()
         const_iterator const_begin "begin"()
         iterator end()
@@ -60,6 +62,10 @@
         void reserve(size_t)
         void clear()
         bint empty()
+        iterator erase(iterator position)
+        iterator erase(const_iterator position)
+        iterator erase(iterator first, iterator last)
+        iterator erase(const_iterator first, const_iterator last)
 
         char& at(size_t)
         char& operator[](size_t)
diff --git a/Cython/Includes/libcpp/utility.pxd b/Cython/Includes/libcpp/utility.pxd
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL2xpYmNwcC91dGlsaXR5LnB4ZA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0luY2x1ZGVzL2xpYmNwcC91dGlsaXR5LnB4ZA== 100644
--- a/Cython/Includes/libcpp/utility.pxd
+++ b/Cython/Includes/libcpp/utility.pxd
@@ -13,3 +13,17 @@
         bint operator>(pair&, pair&)
         bint operator<=(pair&, pair&)
         bint operator>=(pair&, pair&)
+
+cdef extern from * namespace "cython_std" nogil:
+    """
+    #if __cplusplus > 199711L
+    #include <type_traits>
+
+    namespace cython_std {
+    template <typename T> typename std::remove_reference<T>::type&& move(T& t) noexcept { return std::move(t); }
+    template <typename T> typename std::remove_reference<T>::type&& move(T&& t) noexcept { return std::move(t); }
+    }
+
+    #endif
+    """
+    cdef T move[T](T)
diff --git a/Cython/Includes/numpy/__init__.pxd b/Cython/Includes/numpy/__init__.pxd
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL251bXB5L19faW5pdF9fLnB4ZA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0luY2x1ZGVzL251bXB5L19faW5pdF9fLnB4ZA== 100644
--- a/Cython/Includes/numpy/__init__.pxd
+++ b/Cython/Includes/numpy/__init__.pxd
@@ -244,5 +244,4 @@
 
         cdef:
             # Only taking a few of the most commonly used and stable fields.
-            # One should use PyArray_* macros instead to access the C fields.
             char *data
@@ -248,7 +247,4 @@
             char *data
-            int ndim "nd"
-            npy_intp *shape "dimensions"
-            npy_intp *strides
             dtype descr  # deprecated since NumPy 1.7 !
             PyObject* base
 
@@ -252,6 +248,23 @@
             dtype descr  # deprecated since NumPy 1.7 !
             PyObject* base
 
+            @property
+            cdef int ndim(self):
+                return PyArray_NDIM(self)
+
+            @property
+            cdef npy_intp *shape(self):
+                return PyArray_DIMS(self)
+
+            @property
+            cdef npy_intp *strides(self):
+                return PyArray_STRIDES(self)
+
+            @property
+            cdef npy_intp size(self):
+                return PyArray_SIZE(ndarray)
+
+
         # Note: This syntax (function definition in pxd files) is an
         # experimental exception made for __getbuffer__ and __releasebuffer__
         # -- the details of this may change.
@@ -417,6 +430,9 @@
         int len
 
     int _import_array() except -1
+    # A second definition so _import_array isn't marked as used when we use it here.
+    # Do not use - subject to change any time.
+    int __pyx_import_array "_import_array"() except -1
 
     #
     # Macros from ndarrayobject.h
@@ -1033,7 +1049,7 @@
 # Cython code.
 cdef inline int import_array() except -1:
     try:
-        _import_array()
+        __pyx_import_array()
     except Exception:
         raise ImportError("numpy.core.multiarray failed to import")
 
diff --git a/Cython/Includes/posix/dlfcn.pxd b/Cython/Includes/posix/dlfcn.pxd
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL3Bvc2l4L2RsZmNuLnB4ZA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0luY2x1ZGVzL3Bvc2l4L2RsZmNuLnB4ZA== 100644
--- a/Cython/Includes/posix/dlfcn.pxd
+++ b/Cython/Includes/posix/dlfcn.pxd
@@ -1,5 +1,5 @@
 # POSIX dynamic linking/loading interface.
-# http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/dlfcn.h.html
+# https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/dlfcn.h.html
 
 cdef extern from "<dlfcn.h>" nogil:
     void *dlopen(const char *, int)
diff --git a/Cython/Includes/posix/mman.pxd b/Cython/Includes/posix/mman.pxd
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL3Bvc2l4L21tYW4ucHhk..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0luY2x1ZGVzL3Bvc2l4L21tYW4ucHhk 100644
--- a/Cython/Includes/posix/mman.pxd
+++ b/Cython/Includes/posix/mman.pxd
@@ -1,4 +1,4 @@
-# http://pubs.opengroup.org/onlinepubs/009695399/basedefs/sys/mman.h.html
+# https://pubs.opengroup.org/onlinepubs/009695399/basedefs/sys/mman.h.html
 
 from posix.types cimport off_t, mode_t
 
diff --git a/Cython/Includes/posix/resource.pxd b/Cython/Includes/posix/resource.pxd
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL3Bvc2l4L3Jlc291cmNlLnB4ZA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0luY2x1ZGVzL3Bvc2l4L3Jlc291cmNlLnB4ZA== 100644
--- a/Cython/Includes/posix/resource.pxd
+++ b/Cython/Includes/posix/resource.pxd
@@ -1,4 +1,4 @@
-# http://pubs.opengroup.org/onlinepubs/009695399/basedefs/sys/resource.h.html
+# https://pubs.opengroup.org/onlinepubs/009695399/basedefs/sys/resource.h.html
 
 from posix.time  cimport timeval
 from posix.types cimport id_t
diff --git a/Cython/Includes/posix/stdio.pxd b/Cython/Includes/posix/stdio.pxd
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL3Bvc2l4L3N0ZGlvLnB4ZA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0luY2x1ZGVzL3Bvc2l4L3N0ZGlvLnB4ZA== 100644
--- a/Cython/Includes/posix/stdio.pxd
+++ b/Cython/Includes/posix/stdio.pxd
@@ -1,5 +1,5 @@
 # POSIX additions to <stdio.h>.
-# http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/stdio.h.html
+# https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/stdio.h.html
 
 from libc.stdio cimport FILE
 from libc.stddef cimport wchar_t
diff --git a/Cython/Includes/posix/stdlib.pxd b/Cython/Includes/posix/stdlib.pxd
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL3Bvc2l4L3N0ZGxpYi5weGQ=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0luY2x1ZGVzL3Bvc2l4L3N0ZGxpYi5weGQ= 100644
--- a/Cython/Includes/posix/stdlib.pxd
+++ b/Cython/Includes/posix/stdlib.pxd
@@ -1,5 +1,5 @@
 # POSIX additions to <stdlib.h>
-# http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/stdlib.h.html
+# https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/stdlib.h.html
 
 cdef extern from "<stdlib.h>" nogil:
     void   _Exit(int)
diff --git a/Cython/Includes/posix/time.pxd b/Cython/Includes/posix/time.pxd
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL3Bvc2l4L3RpbWUucHhk..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0luY2x1ZGVzL3Bvc2l4L3RpbWUucHhk 100644
--- a/Cython/Includes/posix/time.pxd
+++ b/Cython/Includes/posix/time.pxd
@@ -1,4 +1,4 @@
-# http://pubs.opengroup.org/onlinepubs/009695399/basedefs/sys/time.h.html
+# https://pubs.opengroup.org/onlinepubs/009695399/basedefs/sys/time.h.html
 
 from posix.types cimport suseconds_t, time_t, clockid_t, timer_t
 from posix.signal cimport sigevent
diff --git a/Cython/Includes/posix/wait.pxd b/Cython/Includes/posix/wait.pxd
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL0luY2x1ZGVzL3Bvc2l4L3dhaXQucHhk..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL0luY2x1ZGVzL3Bvc2l4L3dhaXQucHhk 100644
--- a/Cython/Includes/posix/wait.pxd
+++ b/Cython/Includes/posix/wait.pxd
@@ -1,4 +1,4 @@
-# http://pubs.opengroup.org/onlinepubs/009695399/basedefs/sys/wait.h.html
+# https://pubs.opengroup.org/onlinepubs/009695399/basedefs/sys/wait.h.html
 
 from posix.types cimport pid_t, id_t
 from posix.signal cimport siginfo_t
diff --git a/Cython/Plex/Actions.pxd b/Cython/Plex/Actions.pxd
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1BsZXgvQWN0aW9ucy5weGQ=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1BsZXgvQWN0aW9ucy5weGQ= 100644
--- a/Cython/Plex/Actions.pxd
+++ b/Cython/Plex/Actions.pxd
@@ -1,2 +1,3 @@
+# cython: language_level=3
 
 cdef class Action:
@@ -1,6 +2,6 @@
 
 cdef class Action:
-  cdef perform(self, token_stream, text)
-  cpdef same_as(self, other)
+    cdef perform(self, token_stream, text)
+    cpdef same_as(self, other)
 
 cdef class Return(Action):
@@ -5,7 +6,7 @@
 
 cdef class Return(Action):
-  cdef object value
-  cdef perform(self, token_stream, text)
-  cpdef same_as(self, other)
+    cdef object value
+    cdef perform(self, token_stream, text)
+    cpdef same_as(self, other)
 
 cdef class Call(Action):
@@ -10,7 +11,11 @@
 
 cdef class Call(Action):
-  cdef object function
-  cdef perform(self, token_stream, text)
-  cpdef same_as(self, other)
+    cdef object function
+    cdef perform(self, token_stream, text)
+    cpdef same_as(self, other)
+
+cdef class Method(Action):
+    cdef str name
+    cdef dict kwargs
 
 cdef class Begin(Action):
@@ -15,7 +20,7 @@
 
 cdef class Begin(Action):
-  cdef object state_name
-  cdef perform(self, token_stream, text)
-  cpdef same_as(self, other)
+    cdef object state_name
+    cdef perform(self, token_stream, text)
+    cpdef same_as(self, other)
 
 cdef class Ignore(Action):
@@ -20,5 +25,5 @@
 
 cdef class Ignore(Action):
-  cdef perform(self, token_stream, text)
+    cdef perform(self, token_stream, text)
 
 cdef class Text(Action):
@@ -23,3 +28,3 @@
 
 cdef class Text(Action):
-  cdef perform(self, token_stream, text)
+    cdef perform(self, token_stream, text)
diff --git a/Cython/Plex/Actions.py b/Cython/Plex/Actions.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1BsZXgvQWN0aW9ucy5weQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1BsZXgvQWN0aW9ucy5weQ== 100644
--- a/Cython/Plex/Actions.py
+++ b/Cython/Plex/Actions.py
@@ -1,1 +1,2 @@
+# cython: language_level=3str
 # cython: auto_pickle=False
@@ -1,11 +2,10 @@
 # cython: auto_pickle=False
-#=======================================================================
-#
-#   Python Lexical Analyser
-#
-#   Actions for use in token specifications
-#
-#=======================================================================
+"""
+Python Lexical Analyser
+
+Actions for use in token specifications
+"""
+
 
 class Action(object):
     def perform(self, token_stream, text):
@@ -14,6 +14,12 @@
     def same_as(self, other):
         return self is other
 
+    def __copy__(self):
+        return self  # immutable, no need to copy
+
+    def __deepcopy__(self, memo):
+        return self  # immutable, no need to copy
+
 
 class Return(Action):
     """
@@ -31,7 +37,7 @@
         return isinstance(other, Return) and self.value == other.value
 
     def __repr__(self):
-        return "Return(%s)" % repr(self.value)
+        return "Return(%r)" % self.value
 
 
 class Call(Action):
@@ -52,6 +58,31 @@
         return isinstance(other, Call) and self.function is other.function
 
 
+class Method(Action):
+    """
+    Plex action that calls a specific method on the token stream,
+    passing the matched text and any provided constant keyword arguments.
+    """
+
+    def __init__(self, name, **kwargs):
+        self.name = name
+        self.kwargs = kwargs or None
+
+    def perform(self, token_stream, text):
+        method = getattr(token_stream, self.name)
+        # self.kwargs is almost always unused => avoid call overhead
+        return method(text, **self.kwargs) if self.kwargs is not None else method(text)
+
+    def __repr__(self):
+        kwargs = (
+            ', '.join(sorted(['%s=%r' % item for item in self.kwargs.items()]))
+            if self.kwargs is not None else '')
+        return "Method(%s%s%s)" % (self.name, ', ' if kwargs else '', kwargs)
+
+    def same_as(self, other):
+        return isinstance(other, Method) and self.name == other.name and self.kwargs == other.kwargs
+
+
 class Begin(Action):
     """
     Begin(state_name) is a Plex action which causes the Scanner to
@@ -87,7 +118,6 @@
 
 
 IGNORE = Ignore()
-#IGNORE.__doc__ = Ignore.__doc__
 
 
 class Text(Action):
@@ -105,6 +135,3 @@
 
 
 TEXT = Text()
-#TEXT.__doc__ = Text.__doc__
-
-
diff --git a/Cython/Plex/DFA.py b/Cython/Plex/DFA.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1BsZXgvREZBLnB5..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1BsZXgvREZBLnB5 100644
--- a/Cython/Plex/DFA.py
+++ b/Cython/Plex/DFA.py
@@ -1,8 +1,3 @@
-#=======================================================================
-#
-#   Python Lexical Analyser
-#
-#   Converting NFA to DFA
-#
-#=======================================================================
+"""
+Python Lexical Analyser
 
@@ -8,4 +3,6 @@
 
+Converting NFA to DFA
+"""
 from __future__ import absolute_import
 
 from . import Machines
@@ -29,9 +26,10 @@
     # is reached.
     new_machine = Machines.FastMachine()
     state_map = StateMap(new_machine)
+
     # Seed the process using the initial states of the old machine.
     # Make the corresponding new states into initial states of the new
     # machine with the same names.
     for (key, old_state) in old_machine.initial_states.items():
         new_state = state_map.old_to_new(epsilon_closure(old_state))
         new_machine.make_initial_state(key, new_state)
@@ -32,9 +30,10 @@
     # Seed the process using the initial states of the old machine.
     # Make the corresponding new states into initial states of the new
     # machine with the same names.
     for (key, old_state) in old_machine.initial_states.items():
         new_state = state_map.old_to_new(epsilon_closure(old_state))
         new_machine.make_initial_state(key, new_state)
+
     # Tricky bit here: we add things to the end of this list while we're
     # iterating over it. The iteration stops when closure is achieved.
     for new_state in new_machine.states:
@@ -45,6 +44,7 @@
                     transitions.add_set(event, set_epsilon_closure(old_target_states))
         for event, old_states in transitions.items():
             new_machine.add_transitions(new_state, event, state_map.old_to_new(old_states))
+
     if debug:
         debug.write("\n===== State Mapping =====\n")
         state_map.dump(debug)
@@ -119,8 +119,6 @@
             new_state = self.new_machine.new_state(action)
             self.old_to_new_dict[key] = new_state
             self.new_to_old_dict[id(new_state)] = old_state_set
-            #for old_state in old_state_set.keys():
-            #new_state.merge_actions(old_state)
         return new_state
 
     def highest_priority_action(self, state_set):
@@ -133,13 +131,6 @@
                 best_priority = priority
         return best_action
 
-    #    def old_to_new_set(self, old_state_set):
-    #        """
-    #        Return the new state corresponding to a set of old states as
-    #        a singleton set.
-    #        """
-    #        return {self.old_to_new(old_state_set):1}
-
     def new_to_old(self, new_state):
         """Given a new state, return a set of corresponding old states."""
         return self.new_to_old_dict[id(new_state)]
@@ -160,5 +151,3 @@
             old_state_set = self.new_to_old_dict[id(new_state)]
             file.write("   State %s <-- %s\n" % (
                 new_state['number'], state_set_str(old_state_set)))
-
-
diff --git a/Cython/Plex/Errors.py b/Cython/Plex/Errors.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1BsZXgvRXJyb3JzLnB5..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1BsZXgvRXJyb3JzLnB5 100644
--- a/Cython/Plex/Errors.py
+++ b/Cython/Plex/Errors.py
@@ -1,10 +1,8 @@
-#=======================================================================
-#
-#   Python Lexical Analyser
-#
-#   Exception classes
-#
-#=======================================================================
+"""
+Python Lexical Analyser
+
+Exception classes
+"""
 
 
 class PlexError(Exception):
@@ -19,10 +17,6 @@
     pass
 
 
-class InvalidRegex(PlexError):
-    pass
-
-
 class InvalidToken(PlexError):
     def __init__(self, token_number, message):
         PlexError.__init__(self, "Token number %d: %s" % (token_number, message))
diff --git a/Cython/Plex/Lexicons.py b/Cython/Plex/Lexicons.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1BsZXgvTGV4aWNvbnMucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1BsZXgvTGV4aWNvbnMucHk= 100644
--- a/Cython/Plex/Lexicons.py
+++ b/Cython/Plex/Lexicons.py
@@ -1,8 +1,3 @@
-#=======================================================================
-#
-#   Python Lexical Analyser
-#
-#   Lexical Analyser Specification
-#
-#=======================================================================
+"""
+Python Lexical Analyser
 
@@ -8,3 +3,5 @@
 
+Lexical Analyser Specification
+"""
 from __future__ import absolute_import
 
@@ -9,7 +6,5 @@
 from __future__ import absolute_import
 
-import types
-
 from . import Actions
 from . import DFA
 from . import Errors
@@ -114,6 +109,6 @@
     machine = None  # Machine
     tables = None   # StateTableMachine
 
-    def __init__(self, specifications, debug=None, debug_flags=7, timings=None):
+    def __init__(self, specifications, debug=None, debug_flags=7):
         if not isinstance(specifications, list):
             raise Errors.InvalidScanner("Scanner definition is not a list")
@@ -118,5 +113,3 @@
         if not isinstance(specifications, list):
             raise Errors.InvalidScanner("Scanner definition is not a list")
-        if timings:
-            from .Timing import time
 
@@ -122,6 +115,4 @@
 
-            total_time = 0.0
-            time1 = time()
         nfa = Machines.Machine()
         default_initial_state = nfa.new_initial_state('')
         token_number = 1
@@ -125,6 +116,7 @@
         nfa = Machines.Machine()
         default_initial_state = nfa.new_initial_state('')
         token_number = 1
+
         for spec in specifications:
             if isinstance(spec, State):
                 user_initial_state = nfa.new_initial_state(spec.name)
@@ -140,10 +132,7 @@
                 raise Errors.InvalidToken(
                     token_number,
                     "Expected a token definition (tuple) or State instance")
-        if timings:
-            time2 = time()
-            total_time = total_time + (time2 - time1)
-            time3 = time()
+
         if debug and (debug_flags & 1):
             debug.write("\n============= NFA ===========\n")
             nfa.dump(debug)
@@ -147,4 +136,5 @@
         if debug and (debug_flags & 1):
             debug.write("\n============= NFA ===========\n")
             nfa.dump(debug)
+
         dfa = DFA.nfa_to_dfa(nfa, debug=(debug_flags & 3) == 3 and debug)
@@ -150,7 +140,5 @@
         dfa = DFA.nfa_to_dfa(nfa, debug=(debug_flags & 3) == 3 and debug)
-        if timings:
-            time4 = time()
-            total_time = total_time + (time4 - time3)
+
         if debug and (debug_flags & 2):
             debug.write("\n============= DFA ===========\n")
             dfa.dump(debug)
@@ -154,12 +142,9 @@
         if debug and (debug_flags & 2):
             debug.write("\n============= DFA ===========\n")
             dfa.dump(debug)
-        if timings:
-            timings.write("Constructing NFA : %5.2f\n" % (time2 - time1))
-            timings.write("Converting to DFA: %5.2f\n" % (time4 - time3))
-            timings.write("TOTAL            : %5.2f\n" % total_time)
+
         self.machine = dfa
 
     def add_token_to_machine(self, machine, initial_state, token_spec, token_number):
         try:
             (re, action_spec) = self.parse_token_definition(token_spec)
@@ -161,12 +146,8 @@
         self.machine = dfa
 
     def add_token_to_machine(self, machine, initial_state, token_spec, token_number):
         try:
             (re, action_spec) = self.parse_token_definition(token_spec)
-            # Disabled this -- matching empty strings can be useful
-            #if re.nullable:
-            #  raise Errors.InvalidToken(
-            #    token_number, "Pattern can match 0 input symbols")
             if isinstance(action_spec, Actions.Action):
                 action = action_spec
             else:
@@ -188,6 +169,7 @@
             raise Errors.InvalidToken("Token definition is not a tuple")
         if len(token_spec) != 2:
             raise Errors.InvalidToken("Wrong number of items in token definition")
+
         pattern, action = token_spec
         if not isinstance(pattern, Regexps.RE):
             raise Errors.InvalidToken("Pattern is not an RE instance")
@@ -195,6 +177,3 @@
 
     def get_initial_state(self, name):
         return self.machine.get_initial_state(name)
-
-
-
diff --git a/Cython/Plex/Machines.py b/Cython/Plex/Machines.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1BsZXgvTWFjaGluZXMucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1BsZXgvTWFjaGluZXMucHk= 100644
--- a/Cython/Plex/Machines.py
+++ b/Cython/Plex/Machines.py
@@ -1,8 +1,3 @@
-#=======================================================================
-#
-#   Python Lexical Analyser
-#
-#   Classes for building NFAs and DFAs
-#
-#=======================================================================
+"""
+Python Lexical Analyser
 
@@ -8,3 +3,5 @@
 
+Classes for building NFAs and DFAs
+"""
 from __future__ import absolute_import
 
@@ -9,7 +6,5 @@
 from __future__ import absolute_import
 
-import sys
-
 from .Transitions import TransitionMap
 
 try:
@@ -36,7 +31,6 @@
         self.initial_states = {}
 
     def __del__(self):
-        #print "Destroying", self ###
         for state in self.states:
             state.destroy()
 
@@ -81,8 +75,7 @@
     def __init__(self):
         # Preinitialise the list of empty transitions, because
         # the nfa-to-dfa algorithm needs it
-        #self.transitions = {'':[]}
         self.transitions = TransitionMap()
         self.action_priority = LOWEST_PRIORITY
 
     def destroy(self):
@@ -85,8 +78,7 @@
         self.transitions = TransitionMap()
         self.action_priority = LOWEST_PRIORITY
 
     def destroy(self):
-        #print "Destroying", self ###
         self.transitions = None
         self.action = None
         self.epsilon_closure = None
diff --git a/Cython/Plex/Regexps.py b/Cython/Plex/Regexps.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1BsZXgvUmVnZXhwcy5weQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1BsZXgvUmVnZXhwcy5weQ== 100644
--- a/Cython/Plex/Regexps.py
+++ b/Cython/Plex/Regexps.py
@@ -1,8 +1,3 @@
-#=======================================================================
-#
-#     Python Lexical Analyser
-#
-#     Regular Expressions
-#
-#=======================================================================
+"""
+Python Lexical Analyser
 
@@ -8,4 +3,6 @@
 
+Regular Expressions
+"""
 from __future__ import absolute_import
 
 import types
@@ -186,37 +183,6 @@
 #     These are the basic REs from which all others are built.
 #
 
-## class Char(RE):
-##     """
-##     Char(c) is an RE which matches the character |c|.
-##     """
-
-##     nullable = 0
-
-##     def __init__(self, char):
-##         self.char = char
-##         self.match_nl = char == '\n'
-
-##     def build_machine(self, m, initial_state, final_state, match_bol, nocase):
-##         c = self.char
-##         if match_bol and c != BOL:
-##             s1 = self.build_opt(m, initial_state, BOL)
-##         else:
-##             s1 = initial_state
-##         if c == '\n' or c == EOF:
-##             s1 = self.build_opt(m, s1, EOL)
-##         if len(c) == 1:
-##             code = ord(self.char)
-##             s1.add_transition((code, code+1), final_state)
-##             if nocase and is_letter_code(code):
-##                 code2 = other_case_code(code)
-##                 s1.add_transition((code2, code2+1), final_state)
-##         else:
-##             s1.add_transition(c, final_state)
-
-##     def calc_str(self):
-##         return "Char(%s)" % repr(self.char)
-
 
 def Char(c):
     """
@@ -428,6 +394,7 @@
             name = "Case"
         return "%s(%s)" % (name, self.re)
 
+
 #
 #     Composite RE constructors
 #     -------------------------
@@ -469,7 +436,6 @@
     """
     Any(s) is an RE which matches any character in the string |s|.
     """
-    #result = apply(Alt, tuple(map(Char, s)))
     result = CodeRanges(chars_to_ranges(s))
     result.str = "Any(%s)" % repr(s)
     return result
@@ -549,6 +515,7 @@
     """
     return SwitchCase(re, nocase=0)
 
+
 #
 #     RE Constants
 #
@@ -573,4 +540,3 @@
     Eof is an RE which matches the end of the file.
     """
 Eof.str = "Eof"
-
diff --git a/Cython/Plex/Scanners.pxd b/Cython/Plex/Scanners.pxd
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1BsZXgvU2Nhbm5lcnMucHhk..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1BsZXgvU2Nhbm5lcnMucHhk 100644
--- a/Cython/Plex/Scanners.pxd
+++ b/Cython/Plex/Scanners.pxd
@@ -28,5 +28,4 @@
 
     cdef public level
 
-    @cython.final
     @cython.locals(input_state=long)
@@ -32,4 +31,4 @@
     @cython.locals(input_state=long)
-    cdef next_char(self)
+    cdef inline next_char(self)
     @cython.locals(action=Action)
     cpdef tuple read(self)
@@ -34,7 +33,6 @@
     @cython.locals(action=Action)
     cpdef tuple read(self)
-    @cython.final
-    cdef tuple scan_a_token(self)
+    cdef inline tuple scan_a_token(self)
     ##cdef tuple position(self)  # used frequently by Parsing.py
 
     @cython.final
@@ -44,7 +42,5 @@
                    trace=bint, discard=Py_ssize_t, data=unicode, buffer=unicode)
     cdef run_machine_inlined(self)
 
-    @cython.final
-    cdef begin(self, state)
-    @cython.final
-    cdef produce(self, value, text = *)
+    cdef inline begin(self, state)
+    cdef inline produce(self, value, text = *)
diff --git a/Cython/Plex/Scanners.py b/Cython/Plex/Scanners.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1BsZXgvU2Nhbm5lcnMucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1BsZXgvU2Nhbm5lcnMucHk= 100644
--- a/Cython/Plex/Scanners.py
+++ b/Cython/Plex/Scanners.py
@@ -1,1 +1,2 @@
+# cython: language_level=3str
 # cython: auto_pickle=False
@@ -1,10 +2,4 @@
 # cython: auto_pickle=False
-#=======================================================================
-#
-#   Python Lexical Analyser
-#
-#
-#   Scanning an input stream
-#
-#=======================================================================
+"""
+Python Lexical Analyser
 
@@ -10,5 +5,7 @@
 
+Scanning an input stream
+"""
 from __future__ import absolute_import
 
 import cython
 
@@ -11,8 +8,8 @@
 from __future__ import absolute_import
 
 import cython
 
-cython.declare(BOL=object, EOL=object, EOF=object, NOT_FOUND=object)
+cython.declare(BOL=object, EOL=object, EOF=object, NOT_FOUND=object)  # noqa:E402
 
 from . import Errors
 from .Regexps import BOL, EOL, EOF
@@ -173,5 +170,6 @@
         buf_len = len(buffer)
         b_action, b_cur_pos, b_cur_line, b_cur_line_start, b_cur_char, b_input_state, b_next_pos = \
             None, 0, 0, 0, u'', 0, 0
+
         trace = self.trace
         while 1:
@@ -176,6 +174,7 @@
         trace = self.trace
         while 1:
-            if trace:  #TRACE#
-                print("State %d, %d/%d:%s -->" % (  #TRACE#
-                    state['number'], input_state, cur_pos, repr(cur_char)))  #TRACE#
+            if trace:
+                print("State %d, %d/%d:%s -->" % (
+                    state['number'], input_state, cur_pos, repr(cur_char)))
+
             # Begin inlined self.save_for_backup()
@@ -181,7 +180,6 @@
             # Begin inlined self.save_for_backup()
-            #action = state.action #@slow
-            action = state['action']  #@fast
+            action = state['action']
             if action is not None:
                 b_action, b_cur_pos, b_cur_line, b_cur_line_start, b_cur_char, b_input_state, b_next_pos = \
                     action, cur_pos, cur_line, cur_line_start, cur_char, input_state, next_pos
             # End inlined self.save_for_backup()
@@ -184,5 +182,6 @@
             if action is not None:
                 b_action, b_cur_pos, b_cur_line, b_cur_line_start, b_cur_char, b_input_state, b_next_pos = \
                     action, cur_pos, cur_line, cur_line_start, cur_char, input_state, next_pos
             # End inlined self.save_for_backup()
+
             c = cur_char
@@ -188,6 +187,6 @@
             c = cur_char
-            #new_state = state.new_state(c) #@slow
-            new_state = state.get(c, NOT_FOUND)  #@fast
-            if new_state is NOT_FOUND:  #@fast
-                new_state = c and state.get('else')  #@fast
+            new_state = state.get(c, NOT_FOUND)
+            if new_state is NOT_FOUND:
+                new_state = c and state.get('else')
+
             if new_state:
@@ -193,6 +192,6 @@
             if new_state:
-                if trace:  #TRACE#
-                    print("State %d" % new_state['number'])  #TRACE#
+                if trace:
+                    print("State %d" % new_state['number'])
                 state = new_state
                 # Begin inlined: self.next_char()
                 if input_state == 1:
@@ -240,8 +239,8 @@
                     cur_char = u''
                     # End inlined self.next_char()
             else:  # not new_state
-                if trace:  #TRACE#
-                    print("blocked")  #TRACE#
+                if trace:
+                    print("blocked")
                 # Begin inlined: action = self.back_up()
                 if b_action is not None:
                     (action, cur_pos, cur_line, cur_line_start,
@@ -252,9 +251,10 @@
                     action = None
                 break  # while 1
                 # End inlined: action = self.back_up()
+
         self.cur_pos = cur_pos
         self.cur_line = cur_line
         self.cur_line_start = cur_line_start
         self.cur_char = cur_char
         self.input_state = input_state
         self.next_pos = next_pos
@@ -255,12 +255,12 @@
         self.cur_pos = cur_pos
         self.cur_line = cur_line
         self.cur_line_start = cur_line_start
         self.cur_char = cur_char
         self.input_state = input_state
         self.next_pos = next_pos
-        if trace:  #TRACE#
-            if action is not None:  #TRACE#
-                print("Doing %s" % action)  #TRACE#
+        if trace:
+            if action is not None:
+                print("Doing %s" % action)
         return action
 
     def next_char(self):
@@ -306,7 +306,8 @@
         return (self.name, self.start_line, self.start_col)
 
     def get_position(self):
-        """Python accessible wrapper around position(), only for error reporting.
+        """
+        Python accessible wrapper around position(), only for error reporting.
         """
         return self.position()
 
@@ -336,3 +337,4 @@
         Override this method if you want something to be done at
         end of file.
         """
+        pass
diff --git a/Cython/Plex/Timing.py b/Cython/Plex/Timing.py
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1BsZXgvVGltaW5nLnB5..0000000000000000000000000000000000000000
--- a/Cython/Plex/Timing.py
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-#   Get time in platform-dependent way
-#
-
-from __future__ import absolute_import
-
-import os
-from sys import platform, exit, stderr
-
-if platform == 'mac':
-    import MacOS
-    def time():
-        return MacOS.GetTicks() / 60.0
-    timekind = "real"
-elif hasattr(os, 'times'):
-    def time():
-        t = os.times()
-        return t[0] + t[1]
-    timekind = "cpu"
-else:
-    stderr.write(
-        "Don't know how to get time on platform %s\n" % repr(platform))
-    exit(1)
diff --git a/Cython/Plex/Traditional.py b/Cython/Plex/Traditional.py
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1BsZXgvVHJhZGl0aW9uYWwucHk=..0000000000000000000000000000000000000000
--- a/Cython/Plex/Traditional.py
+++ /dev/null
@@ -1,158 +0,0 @@
-#=======================================================================
-#
-#   Python Lexical Analyser
-#
-#   Traditional Regular Expression Syntax
-#
-#=======================================================================
-
-from __future__ import absolute_import
-
-from .Regexps import Alt, Seq, Rep, Rep1, Opt, Any, AnyBut, Bol, Eol, Char
-from .Errors import PlexError
-
-
-class RegexpSyntaxError(PlexError):
-    pass
-
-
-def re(s):
-    """
-    Convert traditional string representation of regular expression |s|
-    into Plex representation.
-    """
-    return REParser(s).parse_re()
-
-
-class REParser(object):
-    def __init__(self, s):
-        self.s = s
-        self.i = -1
-        self.end = 0
-        self.next()
-
-    def parse_re(self):
-        re = self.parse_alt()
-        if not self.end:
-            self.error("Unexpected %s" % repr(self.c))
-        return re
-
-    def parse_alt(self):
-        """Parse a set of alternative regexps."""
-        re = self.parse_seq()
-        if self.c == '|':
-            re_list = [re]
-            while self.c == '|':
-                self.next()
-                re_list.append(self.parse_seq())
-            re = Alt(*re_list)
-        return re
-
-    def parse_seq(self):
-        """Parse a sequence of regexps."""
-        re_list = []
-        while not self.end and not self.c in "|)":
-            re_list.append(self.parse_mod())
-        return Seq(*re_list)
-
-    def parse_mod(self):
-        """Parse a primitive regexp followed by *, +, ? modifiers."""
-        re = self.parse_prim()
-        while not self.end and self.c in "*+?":
-            if self.c == '*':
-                re = Rep(re)
-            elif self.c == '+':
-                re = Rep1(re)
-            else:  # self.c == '?'
-                re = Opt(re)
-            self.next()
-        return re
-
-    def parse_prim(self):
-        """Parse a primitive regexp."""
-        c = self.get()
-        if c == '.':
-            re = AnyBut("\n")
-        elif c == '^':
-            re = Bol
-        elif c == '$':
-            re = Eol
-        elif c == '(':
-            re = self.parse_alt()
-            self.expect(')')
-        elif c == '[':
-            re = self.parse_charset()
-            self.expect(']')
-        else:
-            if c == '\\':
-                c = self.get()
-            re = Char(c)
-        return re
-
-    def parse_charset(self):
-        """Parse a charset. Does not include the surrounding []."""
-        char_list = []
-        invert = 0
-        if self.c == '^':
-            invert = 1
-            self.next()
-        if self.c == ']':
-            char_list.append(']')
-            self.next()
-        while not self.end and self.c != ']':
-            c1 = self.get()
-            if self.c == '-' and self.lookahead(1) != ']':
-                self.next()
-                c2 = self.get()
-                for a in range(ord(c1), ord(c2) + 1):
-                    char_list.append(chr(a))
-            else:
-                char_list.append(c1)
-        chars = ''.join(char_list)
-        if invert:
-            return AnyBut(chars)
-        else:
-            return Any(chars)
-
-    def next(self):
-        """Advance to the next char."""
-        s = self.s
-        i = self.i = self.i + 1
-        if i < len(s):
-            self.c = s[i]
-        else:
-            self.c = ''
-            self.end = 1
-
-    def get(self):
-        if self.end:
-            self.error("Premature end of string")
-        c = self.c
-        self.next()
-        return c
-
-    def lookahead(self, n):
-        """Look ahead n chars."""
-        j = self.i + n
-        if j < len(self.s):
-            return self.s[j]
-        else:
-            return ''
-
-    def expect(self, c):
-        """
-        Expect to find character |c| at current position.
-        Raises an exception otherwise.
-        """
-        if self.c == c:
-            self.next()
-        else:
-            self.error("Missing %s" % repr(c))
-
-    def error(self, mess):
-        """Raise exception to signal syntax error in regexp."""
-        raise RegexpSyntaxError("Syntax error in regexp %s at position %d: %s" % (
-            repr(self.s), self.i, mess))
-
-
-
diff --git a/Cython/Plex/Transitions.py b/Cython/Plex/Transitions.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1BsZXgvVHJhbnNpdGlvbnMucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1BsZXgvVHJhbnNpdGlvbnMucHk= 100644
--- a/Cython/Plex/Transitions.py
+++ b/Cython/Plex/Transitions.py
@@ -1,6 +1,3 @@
-#
-# Plex - Transition Maps
-#
-# This version represents state sets directly as dicts for speed.
-#
+"""
+Plex - Transition Maps
 
@@ -6,4 +3,6 @@
 
+This version represents state sets directly as dicts for speed.
+"""
 from __future__ import absolute_import
 
 try:
@@ -50,7 +49,6 @@
             special = {}
         self.map = map
         self.special = special
-        #self.check() ###
 
     def add(self, event, new_state,
             TupleType=tuple):
@@ -84,8 +82,7 @@
         else:
             self.get_special(event).update(new_set)
 
-    def get_epsilon(self,
-                    none=None):
+    def get_epsilon(self):
         """
         Return the mapping for epsilon, or None.
         """
@@ -89,7 +86,7 @@
         """
         Return the mapping for epsilon, or None.
         """
-        return self.special.get('', none)
+        return self.special.get('')
 
     def iteritems(self,
                   len=len):
@@ -132,6 +129,7 @@
         # Special case: code == map[-1]
         if code == maxint:
             return hi
+
         # General case
         lo = 0
         # loop invariant: map[lo] <= code < map[hi] and hi - lo >= 2
@@ -147,7 +145,6 @@
             return lo
         else:
             map[hi:hi] = [code, map[hi - 1].copy()]
-            #self.check() ###
             return hi
 
     def get_special(self, event):
@@ -243,9 +240,5 @@
 #   State set manipulation functions
 #
 
-#def merge_state_sets(set1, set2):
-#        for state in set2.keys():
-#            set1[state] = 1
-
 def state_set_str(set):
     return "[%s]" % ','.join(["S%d" % state.number for state in set])
diff --git a/Cython/Plex/__init__.py b/Cython/Plex/__init__.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1BsZXgvX19pbml0X18ucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1BsZXgvX19pbml0X18ucHk= 100644
--- a/Cython/Plex/__init__.py
+++ b/Cython/Plex/__init__.py
@@ -1,6 +1,3 @@
-#=======================================================================
-#
-#   Python Lexical Analyser
-#
-#=======================================================================
+"""
+Python Lexical Analyser
 
@@ -6,5 +3,4 @@
 
-"""
 The Plex module provides lexical analysers with similar capabilities
 to GNU Flex. The following classes and functions are exported;
 see the attached docstrings for more information.
@@ -29,6 +25,6 @@
                     Actions for associating with patterns when
         creating a Lexicon.
 """
-
+# flake8: noqa:F401
 from __future__ import absolute_import
 
@@ -33,6 +29,6 @@
 from __future__ import absolute_import
 
-from .Actions import TEXT, IGNORE, Begin
+from .Actions import TEXT, IGNORE, Begin, Method
 from .Lexicons import Lexicon, State
 from .Regexps import RE, Seq, Alt, Rep1, Empty, Str, Any, AnyBut, AnyChar, Range
 from .Regexps import Opt, Rep, Bol, Eol, Eof, Case, NoCase
diff --git a/Cython/Shadow.py b/Cython/Shadow.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1NoYWRvdy5weQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1NoYWRvdy5weQ== 100644
--- a/Cython/Shadow.py
+++ b/Cython/Shadow.py
@@ -1,7 +1,7 @@
 # cython.* namespace for pure mode.
 from __future__ import absolute_import
 
-__version__ = "0.29.16"
+__version__ = "3.0a3"
 
 try:
     from __builtin__ import basestring
@@ -71,7 +71,7 @@
     else:
         # int[8] etc.
         assert int(item) == item  # array size must be a plain integer
-        array(base_type, item)
+        return array(base_type, item)
 
 # END shameless copy
 
@@ -123,6 +123,8 @@
 
 final = internal = type_version_tag = no_gc_clear = no_gc = _empty_decorator
 
+binding = lambda _: _empty_decorator
+
 
 _cython_inline = None
 def inline(f, *args, **kwds):
@@ -144,10 +146,12 @@
 # Special functions
 
 def cdiv(a, b):
-    q = a / b
-    if q < 0:
-        q += 1
-    return q
+    if a < 0:
+        a = -a
+        b = -b
+    if b < 0:
+        return (a + b + 1) // b
+    return a // b
 
 def cmod(a, b):
     r = a % b
@@ -151,10 +155,10 @@
 
 def cmod(a, b):
     r = a % b
-    if (a*b) < 0:
+    if (a * b) < 0 and r:
         r -= b
     return r
 
 
 # Emulated language constructs
 
@@ -155,9 +159,9 @@
         r -= b
     return r
 
 
 # Emulated language constructs
 
-def cast(type, *args, **kwargs):
+def cast(t, *args, **kwargs):
     kwargs.pop('typecheck', None)
     assert not kwargs
@@ -162,9 +166,13 @@
     kwargs.pop('typecheck', None)
     assert not kwargs
-    if hasattr(type, '__call__'):
-        return type(*args)
-    else:
-        return args[0]
+   
+    if isinstance(t, typedef):
+        return t(*args)
+    elif isinstance(t, type): #Doesn't work with old-style classes of Python 2.x
+        if len(args) != 1 or not (args[0] is None or isinstance(args[0], t)):
+            return t(*args)
+            
+    return args[0]
 
 def sizeof(arg):
     return 1
@@ -176,10 +184,15 @@
 def address(arg):
     return pointer(type(arg))([arg])
 
-def declare(type=None, value=_Unspecified, **kwds):
-    if type not in (None, object) and hasattr(type, '__call__'):
-        if value is not _Unspecified:
-            return type(value)
-        else:
-            return type()
+def _is_value_type(t):
+    if isinstance(t, typedef):
+        return _is_value_type(t._basetype)
+        
+    return isinstance(t, type) and issubclass(t, (StructType, UnionType, ArrayType))
+
+def declare(t=None, value=_Unspecified, **kwds):
+    if value is not _Unspecified:
+        return cast(t, value)
+    elif _is_value_type(t):
+        return t()
     else:
@@ -185,5 +198,5 @@
     else:
-        return value
+        return None
 
 class _nogil(object):
     """Support for 'with nogil' statement and @nogil decorator.
@@ -256,8 +269,11 @@
 
 class ArrayType(PointerType):
 
-    def __init__(self):
-        self._items = [None] * self._n
+    def __init__(self, value=None):
+        if value is None:
+            self._items = [None] * self._n
+        else:
+            super(ArrayType, self).__init__(value)
 
 
 class StructType(CythonType):
diff --git a/Cython/StringIOTree.py b/Cython/StringIOTree.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1N0cmluZ0lPVHJlZS5weQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1N0cmluZ0lPVHJlZS5weQ== 100644
--- a/Cython/StringIOTree.py
+++ b/Cython/StringIOTree.py
@@ -39,6 +39,7 @@
     from cStringIO import StringIO
 except ImportError:
     from io import StringIO
+import sys
 
 
 class StringIOTree(object):
diff --git a/Cython/Tempita/_tempita.py b/Cython/Tempita/_tempita.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1RlbXBpdGEvX3RlbXBpdGEucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1RlbXBpdGEvX3RlbXBpdGEucHk= 100644
--- a/Cython/Tempita/_tempita.py
+++ b/Cython/Tempita/_tempita.py
@@ -1,3 +1,5 @@
+# cython: language_level=3str
+
 """
 A small templating language
 
@@ -144,9 +146,8 @@
 
     def from_filename(cls, filename, namespace=None, encoding=None,
                       default_inherit=None, get_template=get_file_template):
-        f = open(filename, 'rb')
-        c = f.read()
-        f.close()
+        with open(filename, 'rb') as f:
+            c = f.read()
         if encoding:
             c = c.decode(encoding)
         return cls(content=c, name=filename, namespace=namespace,
@@ -1162,9 +1163,8 @@
         template_content = sys.stdin.read()
         template_name = '<stdin>'
     else:
-        f = open(template_name, 'rb')
-        template_content = f.read()
-        f.close()
+        with open(template_name, 'rb') as f:
+            template_content = f.read()
     if options.use_html:
         TemplateClass = HTMLTemplate
     else:
@@ -1172,9 +1172,8 @@
     template = TemplateClass(template_content, name=template_name)
     result = template.substitute(vars)
     if options.output:
-        f = open(options.output, 'wb')
-        f.write(result)
-        f.close()
+        with open(options.output, 'wb') as f:
+            f.write(result)
     else:
         sys.stdout.write(result)
 
diff --git a/Cython/TestUtils.py b/Cython/TestUtils.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1Rlc3RVdGlscy5weQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1Rlc3RVdGlscy5weQ== 100644
--- a/Cython/TestUtils.py
+++ b/Cython/TestUtils.py
@@ -2,4 +2,6 @@
 
 import os
 import unittest
+import shlex
+import sys
 import tempfile
@@ -5,4 +7,5 @@
 import tempfile
+from io import open
 
 from .Compiler import Errors
 from .CodeWriter import CodeWriter
@@ -184,34 +187,41 @@
     visit_Node = VisitorTransform.recurse_to_children
 
 
-def unpack_source_tree(tree_file, dir=None):
-    if dir is None:
-        dir = tempfile.mkdtemp()
-    header = []
-    cur_file = None
-    f = open(tree_file)
-    try:
-        lines = f.readlines()
-    finally:
-        f.close()
-    del f
-    try:
-        for line in lines:
-            if line[:5] == '#####':
-                filename = line.strip().strip('#').strip().replace('/', os.path.sep)
-                path = os.path.join(dir, filename)
-                if not os.path.exists(os.path.dirname(path)):
-                    os.makedirs(os.path.dirname(path))
-                if cur_file is not None:
-                    f, cur_file = cur_file, None
-                    f.close()
-                cur_file = open(path, 'w')
-            elif cur_file is not None:
-                cur_file.write(line)
-            elif line.strip() and not line.lstrip().startswith('#'):
-                if line.strip() not in ('"""', "'''"):
-                    header.append(line)
-    finally:
-        if cur_file is not None:
-            cur_file.close()
-    return dir, ''.join(header)
+def unpack_source_tree(tree_file, workdir, cython_root):
+    programs = {
+        'PYTHON': [sys.executable],
+        'CYTHON': [sys.executable, os.path.join(cython_root, 'cython.py')],
+        'CYTHONIZE': [sys.executable, os.path.join(cython_root, 'cythonize.py')]
+    }
+
+    if workdir is None:
+        workdir = tempfile.mkdtemp()
+    header, cur_file = [], None
+    with open(tree_file, 'rb') as f:
+        try:
+            for line in f:
+                if line[:5] == b'#####':
+                    filename = line.strip().strip(b'#').strip().decode('utf8').replace('/', os.path.sep)
+                    path = os.path.join(workdir, filename)
+                    if not os.path.exists(os.path.dirname(path)):
+                        os.makedirs(os.path.dirname(path))
+                    if cur_file is not None:
+                        to_close, cur_file = cur_file, None
+                        to_close.close()
+                    cur_file = open(path, 'wb')
+                elif cur_file is not None:
+                    cur_file.write(line)
+                elif line.strip() and not line.lstrip().startswith(b'#'):
+                    if line.strip() not in (b'"""', b"'''"):
+                        command = shlex.split(line.decode('utf8'))
+                        if not command: continue
+                        # In Python 3: prog, *args = command
+                        prog, args = command[0], command[1:]
+                        try:
+                            header.append(programs[prog]+args)
+                        except KeyError:
+                            header.append(command)
+        finally:
+            if cur_file is not None:
+                cur_file.close()
+    return workdir, header
diff --git a/Cython/Tests/TestCodeWriter.py b/Cython/Tests/TestCodeWriter.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1Rlc3RzL1Rlc3RDb2RlV3JpdGVyLnB5..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1Rlc3RzL1Rlc3RDb2RlV3JpdGVyLnB5 100644
--- a/Cython/Tests/TestCodeWriter.py
+++ b/Cython/Tests/TestCodeWriter.py
@@ -19,9 +19,8 @@
 
     def test_print(self):
         self.t(u"""
-                    print x, y
-                    print x + y ** 2
-                    print x, y, z,
+                    print(x + y ** 2)
+                    print(x, y, z)
                """)
 
     def test_if(self):
@@ -65,5 +64,5 @@
     def test_for_loop(self):
         self.t(u"""
                     for x, y, z in f(g(h(34) * 2) + 23):
-                        print x, y, z
+                        print(x, y, z)
                     else:
@@ -69,7 +68,13 @@
                     else:
-                        print 43
+                        print(43)
+                """)
+        self.t(u"""
+                    for abc in (1, 2, 3):
+                        print(x, y, z)
+                    else:
+                        print(43)
                 """)
 
     def test_inplace_assignment(self):
         self.t(u"x += 43")
 
@@ -71,8 +76,11 @@
                 """)
 
     def test_inplace_assignment(self):
         self.t(u"x += 43")
 
+    def test_cascaded_assignment(self):
+        self.t(u"x = y = z = abc = 43")
+
     def test_attribute(self):
         self.t(u"a.x")
 
diff --git a/Cython/Tests/TestJediTyper.py b/Cython/Tests/TestJediTyper.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1Rlc3RzL1Rlc3RKZWRpVHlwZXIucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1Rlc3RzL1Rlc3RKZWRpVHlwZXIucHk= 100644
--- a/Cython/Tests/TestJediTyper.py
+++ b/Cython/Tests/TestJediTyper.py
@@ -11,7 +11,7 @@
 from tempfile import NamedTemporaryFile
 
 from Cython.Compiler.ParseTreeTransforms import NormalizeTree, InterpretCompilerDirectives
-from Cython.Compiler import Main, Symtab, Visitor
+from Cython.Compiler import Main, Symtab, Visitor, Options
 from Cython.TestUtils import TransformTest
 
 TOOLS_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', 'Tools'))
@@ -210,8 +210,8 @@
     """
     def setUp(self):
         super(TestTypeInjection, self).setUp()
-        compilation_options = Main.CompilationOptions(Main.default_options)
-        ctx = compilation_options.create_context()
+        compilation_options = Options.CompilationOptions(Options.default_options)
+        ctx = Main.Context.from_options(compilation_options)
         transform = InterpretCompilerDirectives(ctx, ctx.compiler_directives)
         transform.module_scope = Symtab.ModuleScope('__main__', None, ctx)
         self.declarations_finder = DeclarationsFinder()
diff --git a/Cython/Tests/xmlrunner.py b/Cython/Tests/xmlrunner.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1Rlc3RzL3htbHJ1bm5lci5weQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1Rlc3RzL3htbHJ1bm5lci5weQ== 100644
--- a/Cython/Tests/xmlrunner.py
+++ b/Cython/Tests/xmlrunner.py
@@ -27,8 +27,8 @@
 
     def test_choice(self):
         element = random.choice(self.seq)
-        self.assert_(element in self.seq)
+        self.assertTrue(element in self.seq)
 
     def test_sample(self):
         self.assertRaises(ValueError, random.sample, self.seq, 20)
         for element in random.sample(self.seq, 5):
@@ -31,8 +31,8 @@
 
     def test_sample(self):
         self.assertRaises(ValueError, random.sample, self.seq, 20)
         for element in random.sample(self.seq, 5):
-            self.assert_(element in self.seq)
+            self.assertTrue(element in self.seq)
 
 if __name__ == '__main__':
     unittest.main(testRunner=xmlrunner.XMLTestRunner(output='test-reports'))
diff --git a/Cython/Utility/AsyncGen.c b/Cython/Utility/AsyncGen.c
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1V0aWxpdHkvQXN5bmNHZW4uYw==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1V0aWxpdHkvQXN5bmNHZW4uYw== 100644
--- a/Cython/Utility/AsyncGen.c
+++ b/Cython/Utility/AsyncGen.c
@@ -11,6 +11,7 @@
     PyObject *ag_finalizer;
     int ag_hooks_inited;
     int ag_closed;
+    int ag_running_async;
 } __pyx_PyAsyncGenObject;
 
 static PyTypeObject *__pyx__PyAsyncGenWrappedValueType = 0;
@@ -18,5 +19,5 @@
 static PyTypeObject *__pyx__PyAsyncGenAThrowType = 0;
 static PyTypeObject *__pyx_AsyncGenType = 0;
 
-#define __Pyx_AsyncGen_CheckExact(obj) (Py_TYPE(obj) == __pyx_AsyncGenType)
+#define __Pyx_AsyncGen_CheckExact(obj) __Pyx_IS_TYPE(obj, __pyx_AsyncGenType)
 #define __pyx_PyAsyncGenASend_CheckExact(o) \
@@ -22,3 +23,3 @@
 #define __pyx_PyAsyncGenASend_CheckExact(o) \
-                    (Py_TYPE(o) == __pyx__PyAsyncGenASendType)
+                    __Pyx_IS_TYPE(o, __pyx__PyAsyncGenASendType)
 #define __pyx_PyAsyncGenAThrow_CheckExact(o) \
@@ -24,5 +25,5 @@
 #define __pyx_PyAsyncGenAThrow_CheckExact(o) \
-                    (Py_TYPE(o) == __pyx__PyAsyncGenAThrowType)
+                    __Pyx_IS_TYPE(o, __pyx__PyAsyncGenAThrowType)
 
 static PyObject *__Pyx_async_gen_anext(PyObject *o);
 static CYTHON_INLINE PyObject *__Pyx_async_gen_asend_iternext(PyObject *o);
@@ -42,6 +43,7 @@
     gen->ag_finalizer = NULL;
     gen->ag_closed = 0;
     gen->ag_hooks_inited = 0;
+    gen->ag_running_async = 0;
     return __Pyx__Coroutine_NewInit((__pyx_CoroutineObject*)gen, body, code, closure, name, qualname, module_name);
 }
 
@@ -127,6 +129,8 @@
 
 static const char *__Pyx_NON_INIT_CORO_MSG = "can't send non-None value to a just-started coroutine";
 static const char *__Pyx_ASYNC_GEN_IGNORED_EXIT_MSG = "async generator ignored GeneratorExit";
+static const char *__Pyx_ASYNC_GEN_CANNOT_REUSE_SEND_MSG = "cannot reuse already awaited __anext__()/asend()";
+static const char *__Pyx_ASYNC_GEN_CANNOT_REUSE_CLOSE_MSG = "cannot reuse already awaited aclose()/athrow()";
 
 typedef enum {
     __PYX_AWAITABLE_STATE_INIT,   /* new awaitable, has not yet been iterated */
@@ -178,7 +182,7 @@
 static int __Pyx_ag_asend_freelist_free = 0;
 
 #define __pyx__PyAsyncGenWrappedValue_CheckExact(o) \
-                    (Py_TYPE(o) == __pyx__PyAsyncGenWrappedValueType)
+                    __Pyx_IS_TYPE(o, __pyx__PyAsyncGenWrappedValueType)
 
 
 static int
@@ -253,7 +257,7 @@
 __Pyx_async_gen_anext(PyObject *g)
 {
     __pyx_PyAsyncGenObject *o = (__pyx_PyAsyncGenObject*) g;
-    if (__Pyx_async_gen_init_hooks(o)) {
+    if (unlikely(__Pyx_async_gen_init_hooks(o))) {
         return NULL;
     }
     return __Pyx_async_gen_asend_new(o, NULL);
@@ -268,7 +272,7 @@
 static PyObject *
 __Pyx_async_gen_asend(__pyx_PyAsyncGenObject *o, PyObject *arg)
 {
-    if (__Pyx_async_gen_init_hooks(o)) {
+    if (unlikely(__Pyx_async_gen_init_hooks(o))) {
         return NULL;
     }
     return __Pyx_async_gen_asend_new(o, arg);
@@ -278,7 +282,7 @@
 static PyObject *
 __Pyx_async_gen_aclose(__pyx_PyAsyncGenObject *o, CYTHON_UNUSED PyObject *arg)
 {
-    if (__Pyx_async_gen_init_hooks(o)) {
+    if (unlikely(__Pyx_async_gen_init_hooks(o))) {
         return NULL;
     }
     return __Pyx_async_gen_athrow_new(o, NULL);
@@ -288,7 +292,7 @@
 static PyObject *
 __Pyx_async_gen_athrow(__pyx_PyAsyncGenObject *o, PyObject *args)
 {
-    if (__Pyx_async_gen_init_hooks(o)) {
+    if (unlikely(__Pyx_async_gen_init_hooks(o))) {
         return NULL;
     }
     return __Pyx_async_gen_athrow_new(o, args);
@@ -313,7 +317,7 @@
 
 static PyMemberDef __Pyx_async_gen_memberlist[] = {
     //REMOVED: {(char*) "ag_frame",   T_OBJECT, offsetof(__pyx_PyAsyncGenObject, ag_frame),   READONLY},
-    {(char*) "ag_running", T_BOOL,   offsetof(__pyx_CoroutineObject, is_running), READONLY, NULL},
+    {(char*) "ag_running", T_BOOL,   offsetof(__pyx_PyAsyncGenObject, ag_running_async), READONLY, NULL},
     //REMOVED: {(char*) "ag_code",    T_OBJECT, offsetof(__pyx_PyAsyncGenObject, ag_code),    READONLY},
     //ADDED: "ag_await"
     {(char*) "ag_await", T_OBJECT, offsetof(__pyx_CoroutineObject, yieldfrom), READONLY,
@@ -360,7 +364,7 @@
     sizeof(__pyx_PyAsyncGenObject),             /* tp_basicsize */
     0,                                          /* tp_itemsize */
     (destructor)__Pyx_Coroutine_dealloc,        /* tp_dealloc */
-    0,                                          /* tp_print */
+    0,                                          /* tp_vectorcall_offset */
     0,                                          /* tp_getattr */
     0,                                          /* tp_setattr */
 #if CYTHON_USE_ASYNC_SLOTS
@@ -427,6 +431,9 @@
 #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
     0,                                          /*tp_print*/
 #endif
+#if CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM+0 >= 0x06000000
+    0,                                          /*tp_pypy_flags*/
+#endif
 };
 
 
@@ -445,7 +452,7 @@
     while (__Pyx_ag_asend_freelist_free) {
         __pyx_PyAsyncGenASend *o;
         o = __Pyx_ag_asend_freelist[--__Pyx_ag_asend_freelist_free];
-        assert(Py_TYPE(o) == __pyx__PyAsyncGenASendType);
+        assert(__Pyx_IS_TYPE(o, __pyx__PyAsyncGenASendType));
         PyObject_GC_Del(o);
     }
 
@@ -471,6 +478,7 @@
             gen->ag_closed = 1;
         }
 
+        gen->ag_running_async = 0;
         return NULL;
     }
 
@@ -478,6 +486,7 @@
         /* async yield */
         __Pyx_ReturnWithStopIteration(((__pyx__PyAsyncGenWrappedValue*)result)->agw_val);
         Py_DECREF(result);
+        gen->ag_running_async = 0;
         return NULL;
     }
 
@@ -494,7 +503,7 @@
     PyObject_GC_UnTrack((PyObject *)o);
     Py_CLEAR(o->ags_gen);
     Py_CLEAR(o->ags_sendval);
-    if (__Pyx_ag_asend_freelist_free < _PyAsyncGen_MAXFREELIST) {
+    if (likely(__Pyx_ag_asend_freelist_free < _PyAsyncGen_MAXFREELIST)) {
         assert(__pyx_PyAsyncGenASend_CheckExact(o));
         __Pyx_ag_asend_freelist[__Pyx_ag_asend_freelist_free++] = o;
     } else {
@@ -518,8 +527,8 @@
     PyObject *result;
 
     if (unlikely(o->ags_state == __PYX_AWAITABLE_STATE_CLOSED)) {
-        PyErr_SetNone(PyExc_StopIteration);
+        PyErr_SetString(PyExc_RuntimeError, __Pyx_ASYNC_GEN_CANNOT_REUSE_SEND_MSG);
         return NULL;
     }
 
     if (o->ags_state == __PYX_AWAITABLE_STATE_INIT) {
@@ -522,10 +531,17 @@
         return NULL;
     }
 
     if (o->ags_state == __PYX_AWAITABLE_STATE_INIT) {
+        if (unlikely(o->ags_gen->ag_running_async)) {
+            PyErr_SetString(
+                PyExc_RuntimeError,
+                "anext(): asynchronous generator is already running");
+            return NULL;
+        }
+
         if (arg == NULL || arg == Py_None) {
             arg = o->ags_sendval ? o->ags_sendval : Py_None;
         }
         o->ags_state = __PYX_AWAITABLE_STATE_ITER;
     }
 
@@ -526,9 +542,10 @@
         if (arg == NULL || arg == Py_None) {
             arg = o->ags_sendval ? o->ags_sendval : Py_None;
         }
         o->ags_state = __PYX_AWAITABLE_STATE_ITER;
     }
 
+    o->ags_gen->ag_running_async = 1;
     result = __Pyx_Coroutine_Send((PyObject*)o->ags_gen, arg);
     result = __Pyx_async_gen_unwrap_value(o->ags_gen, result);
 
@@ -553,7 +570,7 @@
     PyObject *result;
 
     if (unlikely(o->ags_state == __PYX_AWAITABLE_STATE_CLOSED)) {
-        PyErr_SetNone(PyExc_StopIteration);
+        PyErr_SetString(PyExc_RuntimeError, __Pyx_ASYNC_GEN_CANNOT_REUSE_SEND_MSG);
         return NULL;
     }
 
@@ -602,7 +619,7 @@
     0,                                          /* tp_itemsize */
     /* methods */
     (destructor)__Pyx_async_gen_asend_dealloc,        /* tp_dealloc */
-    0,                                          /* tp_print */
+    0,                                          /* tp_vectorcall_offset */
     0,                                          /* tp_getattr */
     0,                                          /* tp_setattr */
 #if CYTHON_USE_ASYNC_SLOTS
@@ -662,6 +679,9 @@
 #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
     0,                                          /*tp_print*/
 #endif
+#if CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM+0 >= 0x06000000
+    0,                                          /*tp_pypy_flags*/
+#endif
 };
 
 
@@ -669,9 +689,9 @@
 __Pyx_async_gen_asend_new(__pyx_PyAsyncGenObject *gen, PyObject *sendval)
 {
     __pyx_PyAsyncGenASend *o;
-    if (__Pyx_ag_asend_freelist_free) {
+    if (likely(__Pyx_ag_asend_freelist_free)) {
         __Pyx_ag_asend_freelist_free--;
         o = __Pyx_ag_asend_freelist[__Pyx_ag_asend_freelist_free];
         _Py_NewReference((PyObject *)o);
     } else {
         o = PyObject_GC_New(__pyx_PyAsyncGenASend, __pyx__PyAsyncGenASendType);
@@ -673,9 +693,9 @@
         __Pyx_ag_asend_freelist_free--;
         o = __Pyx_ag_asend_freelist[__Pyx_ag_asend_freelist_free];
         _Py_NewReference((PyObject *)o);
     } else {
         o = PyObject_GC_New(__pyx_PyAsyncGenASend, __pyx__PyAsyncGenASendType);
-        if (o == NULL) {
+        if (unlikely(o == NULL)) {
             return NULL;
         }
     }
@@ -701,7 +721,7 @@
 {
     PyObject_GC_UnTrack((PyObject *)o);
     Py_CLEAR(o->agw_val);
-    if (__Pyx_ag_value_freelist_free < _PyAsyncGen_MAXFREELIST) {
+    if (likely(__Pyx_ag_value_freelist_free < _PyAsyncGen_MAXFREELIST)) {
         assert(__pyx__PyAsyncGenWrappedValue_CheckExact(o));
         __Pyx_ag_value_freelist[__Pyx_ag_value_freelist_free++] = o;
     } else {
@@ -726,7 +746,7 @@
     0,                                          /* tp_itemsize */
     /* methods */
     (destructor)__Pyx_async_gen_wrapped_val_dealloc,  /* tp_dealloc */
-    0,                                          /* tp_print */
+    0,                                          /* tp_vectorcall_offset */
     0,                                          /* tp_getattr */
     0,                                          /* tp_setattr */
     0,                                          /* tp_as_async */
@@ -777,6 +797,9 @@
 #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
     0,                                          /*tp_print*/
 #endif
+#if CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM+0 >= 0x06000000
+    0,                                          /*tp_pypy_flags*/
+#endif
 };
 
 
@@ -787,7 +810,7 @@
     __pyx__PyAsyncGenWrappedValue *o;
     assert(val);
 
-    if (__Pyx_ag_value_freelist_free) {
+    if (likely(__Pyx_ag_value_freelist_free)) {
         __Pyx_ag_value_freelist_free--;
         o = __Pyx_ag_value_freelist[__Pyx_ag_value_freelist_free];
         assert(__pyx__PyAsyncGenWrappedValue_CheckExact(o));
@@ -832,5 +855,5 @@
 __Pyx_async_gen_athrow_send(__pyx_PyAsyncGenAThrow *o, PyObject *arg)
 {
     __pyx_CoroutineObject *gen = (__pyx_CoroutineObject*)o->agt_gen;
-    PyObject *retval;
+    PyObject *retval, *exc_type;
 
@@ -836,7 +859,14 @@
 
-    if (o->agt_state == __PYX_AWAITABLE_STATE_CLOSED) {
+    if (unlikely(o->agt_state == __PYX_AWAITABLE_STATE_CLOSED)) {
+        PyErr_SetString(PyExc_RuntimeError, __Pyx_ASYNC_GEN_CANNOT_REUSE_CLOSE_MSG);
+        return NULL;
+    }
+
+    if (unlikely(gen->resume_label == -1)) {
+        // already run past the end
+        o->agt_state = __PYX_AWAITABLE_STATE_CLOSED;
         PyErr_SetNone(PyExc_StopIteration);
         return NULL;
     }
 
     if (o->agt_state == __PYX_AWAITABLE_STATE_INIT) {
@@ -838,10 +868,19 @@
         PyErr_SetNone(PyExc_StopIteration);
         return NULL;
     }
 
     if (o->agt_state == __PYX_AWAITABLE_STATE_INIT) {
-        if (o->agt_gen->ag_closed) {
-            PyErr_SetNone(PyExc_StopIteration);
+        if (unlikely(o->agt_gen->ag_running_async)) {
+            o->agt_state = __PYX_AWAITABLE_STATE_CLOSED;
+            if (o->agt_args == NULL) {
+                PyErr_SetString(
+                    PyExc_RuntimeError,
+                    "aclose(): asynchronous generator is already running");
+            } else {
+                PyErr_SetString(
+                    PyExc_RuntimeError,
+                    "athrow(): asynchronous generator is already running");
+            }
             return NULL;
         }
 
@@ -845,9 +884,15 @@
             return NULL;
         }
 
-        if (arg != Py_None) {
+        if (unlikely(o->agt_gen->ag_closed)) {
+            o->agt_state = __PYX_AWAITABLE_STATE_CLOSED;
+            PyErr_SetNone(__Pyx_PyExc_StopAsyncIteration);
+            return NULL;
+        }
+
+        if (unlikely(arg != Py_None)) {
             PyErr_SetString(PyExc_RuntimeError, __Pyx_NON_INIT_CORO_MSG);
             return NULL;
         }
 
         o->agt_state = __PYX_AWAITABLE_STATE_ITER;
@@ -849,11 +894,12 @@
             PyErr_SetString(PyExc_RuntimeError, __Pyx_NON_INIT_CORO_MSG);
             return NULL;
         }
 
         o->agt_state = __PYX_AWAITABLE_STATE_ITER;
+        o->agt_gen->ag_running_async = 1;
 
         if (o->agt_args == NULL) {
             /* aclose() mode */
             o->agt_gen->ag_closed = 1;
 
             retval = __Pyx__Coroutine_Throw((PyObject*)gen,
@@ -854,12 +900,11 @@
 
         if (o->agt_args == NULL) {
             /* aclose() mode */
             o->agt_gen->ag_closed = 1;
 
             retval = __Pyx__Coroutine_Throw((PyObject*)gen,
-                                /* Do not close generator when
-                                   PyExc_GeneratorExit is passed */
-                                PyExc_GeneratorExit, NULL, NULL, NULL, 0);
+                /* Do not close generator when PyExc_GeneratorExit is passed */
+                PyExc_GeneratorExit, NULL, NULL, NULL, 0);
 
             if (retval && __pyx__PyAsyncGenWrappedValue_CheckExact(retval)) {
                 Py_DECREF(retval);
@@ -870,9 +915,8 @@
             PyObject *tb = NULL;
             PyObject *val = NULL;
 
-            if (!PyArg_UnpackTuple(o->agt_args, "athrow", 1, 3,
-                                   &typ, &val, &tb)) {
+            if (unlikely(!PyArg_UnpackTuple(o->agt_args, "athrow", 1, 3, &typ, &val, &tb))) {
                 return NULL;
             }
 
             retval = __Pyx__Coroutine_Throw((PyObject*)gen,
@@ -875,9 +919,9 @@
                 return NULL;
             }
 
             retval = __Pyx__Coroutine_Throw((PyObject*)gen,
-                                /* Do not close generator when PyExc_GeneratorExit is passed */
-                                typ, val, tb, o->agt_args, 0);
+                /* Do not close generator when PyExc_GeneratorExit is passed */
+                typ, val, tb, o->agt_args, 0);
             retval = __Pyx_async_gen_unwrap_value(o->agt_gen, retval);
         }
         if (retval == NULL) {
@@ -894,7 +938,7 @@
     } else {
         /* aclose() mode */
         if (retval) {
-            if (__pyx__PyAsyncGenWrappedValue_CheckExact(retval)) {
+            if (unlikely(__pyx__PyAsyncGenWrappedValue_CheckExact(retval))) {
                 Py_DECREF(retval);
                 goto yield_close;
             }
@@ -908,8 +952,10 @@
     }
 
 yield_close:
+    o->agt_gen->ag_running_async = 0;
+    o->agt_state = __PYX_AWAITABLE_STATE_CLOSED;
     PyErr_SetString(
         PyExc_RuntimeError, __Pyx_ASYNC_GEN_IGNORED_EXIT_MSG);
     return NULL;
 
 check_error:
@@ -911,9 +957,11 @@
     PyErr_SetString(
         PyExc_RuntimeError, __Pyx_ASYNC_GEN_IGNORED_EXIT_MSG);
     return NULL;
 
 check_error:
-    if (PyErr_ExceptionMatches(__Pyx_PyExc_StopAsyncIteration)) {
-        o->agt_state = __PYX_AWAITABLE_STATE_CLOSED;
+    o->agt_gen->ag_running_async = 0;
+    o->agt_state = __PYX_AWAITABLE_STATE_CLOSED;
+    exc_type = PyErr_Occurred();
+    if (__Pyx_PyErr_GivenExceptionMatches2(exc_type, __Pyx_PyExc_StopAsyncIteration, PyExc_GeneratorExit)) {
         if (o->agt_args == NULL) {
             // when aclose() is called we don't want to propagate
@@ -918,8 +966,9 @@
         if (o->agt_args == NULL) {
             // when aclose() is called we don't want to propagate
-            // StopAsyncIteration; just raise StopIteration, signalling
-            // that 'aclose()' is done.
+            // StopAsyncIteration or GeneratorExit; just raise
+            // StopIteration, signalling that this 'aclose()' await
+            // is done.
             PyErr_Clear();
             PyErr_SetNone(PyExc_StopIteration);
         }
     }
@@ -922,12 +971,7 @@
             PyErr_Clear();
             PyErr_SetNone(PyExc_StopIteration);
         }
     }
-    else if (PyErr_ExceptionMatches(PyExc_GeneratorExit)) {
-        o->agt_state = __PYX_AWAITABLE_STATE_CLOSED;
-        PyErr_Clear();          /* ignore these errors */
-        PyErr_SetNone(PyExc_StopIteration);
-    }
     return NULL;
 }
 
@@ -937,13 +981,8 @@
 {
     PyObject *retval;
 
-    if (o->agt_state == __PYX_AWAITABLE_STATE_INIT) {
-        PyErr_SetString(PyExc_RuntimeError, __Pyx_NON_INIT_CORO_MSG);
-        return NULL;
-    }
-
-    if (o->agt_state == __PYX_AWAITABLE_STATE_CLOSED) {
-        PyErr_SetNone(PyExc_StopIteration);
+    if (unlikely(o->agt_state == __PYX_AWAITABLE_STATE_CLOSED)) {
+        PyErr_SetString(PyExc_RuntimeError, __Pyx_ASYNC_GEN_CANNOT_REUSE_CLOSE_MSG);
         return NULL;
     }
 
@@ -951,9 +990,12 @@
     if (o->agt_args) {
         return __Pyx_async_gen_unwrap_value(o->agt_gen, retval);
     } else {
-        /* aclose() mode */
-        if (retval && __pyx__PyAsyncGenWrappedValue_CheckExact(retval)) {
+        // aclose() mode
+        PyObject *exc_type;
+        if (unlikely(retval && __pyx__PyAsyncGenWrappedValue_CheckExact(retval))) {
+            o->agt_gen->ag_running_async = 0;
+            o->agt_state = __PYX_AWAITABLE_STATE_CLOSED;
             Py_DECREF(retval);
             PyErr_SetString(PyExc_RuntimeError, __Pyx_ASYNC_GEN_IGNORED_EXIT_MSG);
             return NULL;
         }
@@ -956,7 +998,16 @@
             Py_DECREF(retval);
             PyErr_SetString(PyExc_RuntimeError, __Pyx_ASYNC_GEN_IGNORED_EXIT_MSG);
             return NULL;
         }
+        exc_type = PyErr_Occurred();
+        if (__Pyx_PyErr_GivenExceptionMatches2(exc_type, __Pyx_PyExc_StopAsyncIteration, PyExc_GeneratorExit)) {
+            // when aclose() is called we don't want to propagate
+            // StopAsyncIteration or GeneratorExit; just raise
+            // StopIteration, signalling that this 'aclose()' await
+            // is done.
+            PyErr_Clear();
+            PyErr_SetNone(PyExc_StopIteration);
+        }
         return retval;
     }
 }
@@ -1002,7 +1053,7 @@
     sizeof(__pyx_PyAsyncGenAThrow),                   /* tp_basicsize */
     0,                                          /* tp_itemsize */
     (destructor)__Pyx_async_gen_athrow_dealloc,       /* tp_dealloc */
-    0,                                          /* tp_print */
+    0,                                          /* tp_vectorcall_offset */
     0,                                          /* tp_getattr */
     0,                                          /* tp_setattr */
 #if CYTHON_USE_ASYNC_SLOTS
@@ -1062,6 +1113,9 @@
 #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
     0,                                          /*tp_print*/
 #endif
+#if CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM+0 >= 0x06000000
+    0,                                          /*tp_pypy_flags*/
+#endif
 };
 
 
@@ -1070,7 +1124,7 @@
 {
     __pyx_PyAsyncGenAThrow *o;
     o = PyObject_GC_New(__pyx_PyAsyncGenAThrow, __pyx__PyAsyncGenAThrowType);
-    if (o == NULL) {
+    if (unlikely(o == NULL)) {
         return NULL;
     }
     o->agt_gen = gen;
diff --git a/Cython/Utility/Buffer.c b/Cython/Utility/Buffer.c
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1V0aWxpdHkvQnVmZmVyLmM=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1V0aWxpdHkvQnVmZmVyLmM= 100644
--- a/Cython/Utility/Buffer.c
+++ b/Cython/Utility/Buffer.c
@@ -224,8 +224,8 @@
 //  the format string; the access mode/flags is checked by the
 //  exporter. See:
 //
-//  http://docs.python.org/3/library/struct.html
-//  http://legacy.python.org/dev/peps/pep-3118/#additions-to-the-struct-string-syntax
+//  https://docs.python.org/3/library/struct.html
+//  https://www.python.org/dev/peps/pep-3118/#additions-to-the-struct-string-syntax
 //
 //  The alignment code is copied from _struct.c in Python.
 
@@ -602,9 +602,8 @@
 __pyx_buffmt_parse_array(__Pyx_BufFmt_Context* ctx, const char** tsp)
 {
     const char *ts = *tsp;
-    int i = 0, number;
-    int ndim = ctx->head->field->type->ndim;
-;
+    int i = 0, number, ndim;
+
     ++ts;
     if (ctx->new_count != 1) {
         PyErr_SetString(PyExc_ValueError,
@@ -615,6 +614,9 @@
     /* Process the previous element */
     if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
 
+    // store ndim now, as field advanced by __Pyx_BufFmt_ProcessTypeChunk call
+    ndim = ctx->head->field->type->ndim;
+
     /* Parse all numbers in the format string */
     while (*ts && *ts != ')') {
         // ignore space characters (not using isspace() due to C/C++ problem on MacOS-X)
@@ -757,8 +759,8 @@
       case 'l': case 'L': case 'q': case 'Q':
       case 'f': case 'd': case 'g':
       case 'O': case 'p':
-        if (ctx->enc_type == *ts && got_Z == ctx->is_complex &&
-            ctx->enc_packmode == ctx->new_packmode) {
+        if ((ctx->enc_type == *ts) && (got_Z == ctx->is_complex) &&
+            (ctx->enc_packmode == ctx->new_packmode) && (!ctx->is_valid_array)) {
           /* Continue pooling same type */
           ctx->enc_count += ctx->new_count;
           ctx->new_count = 1;
diff --git a/Cython/Utility/Builtins.c b/Cython/Utility/Builtins.c
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1V0aWxpdHkvQnVpbHRpbnMuYw==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1V0aWxpdHkvQnVpbHRpbnMuYw== 100644
--- a/Cython/Utility/Builtins.c
+++ b/Cython/Utility/Builtins.c
@@ -20,16 +20,8 @@
 // access requires a rewrite as a dedicated class.
 
 static PyObject* __Pyx_Globals(void) {
-    Py_ssize_t i;
-    PyObject *names;
-    PyObject *globals = $moddict_cname;
-    Py_INCREF(globals);
-    names = PyObject_Dir($module_cname);
-    if (!names)
-        goto bad;
-    for (i = PyList_GET_SIZE(names)-1; i >= 0; i--) {
-#if CYTHON_COMPILING_IN_PYPY
-        PyObject* name = PySequence_ITEM(names, i);
-        if (!name)
-            goto bad;
+    PyObject *globals;
+#if CYTHON_COMPILING_IN_LIMITED_API
+    globals = PyModule_GetDict($module_cname);
+    if (unlikely(!globals)) return NULL;
 #else
@@ -35,9 +27,3 @@
 #else
-        PyObject* name = PyList_GET_ITEM(names, i);
-#endif
-        if (!PyDict_Contains(globals, name)) {
-            PyObject* value = __Pyx_GetAttr($module_cname, name);
-            if (!value) {
-#if CYTHON_COMPILING_IN_PYPY
-                Py_DECREF(name);
+    globals = $moddict_cname;
 #endif
@@ -43,17 +29,3 @@
 #endif
-                goto bad;
-            }
-            if (PyDict_SetItem(globals, name, value) < 0) {
-#if CYTHON_COMPILING_IN_PYPY
-                Py_DECREF(name);
-#endif
-                Py_DECREF(value);
-                goto bad;
-            }
-        }
-#if CYTHON_COMPILING_IN_PYPY
-        Py_DECREF(name);
-#endif
-    }
-    Py_DECREF(names);
+    Py_INCREF(globals);
     return globals;
@@ -59,8 +31,4 @@
     return globals;
-bad:
-    Py_XDECREF(names);
-    Py_XDECREF(globals);
-    return NULL;
 }
 
 //////////////////// PyExecGlobals.proto ////////////////////
@@ -100,7 +68,7 @@
 
     if (!globals || globals == Py_None) {
         globals = $moddict_cname;
-    } else if (!PyDict_Check(globals)) {
+    } else if (unlikely(!PyDict_Check(globals))) {
         PyErr_Format(PyExc_TypeError, "exec() arg 2 must be a dict, not %.200s",
                      Py_TYPE(globals)->tp_name);
         goto bad;
@@ -110,8 +78,8 @@
     }
 
     if (__Pyx_PyDict_GetItemStr(globals, PYIDENT("__builtins__")) == NULL) {
-        if (PyDict_SetItem(globals, PYIDENT("__builtins__"), PyEval_GetBuiltins()) < 0)
+        if (unlikely(PyDict_SetItem(globals, PYIDENT("__builtins__"), PyEval_GetBuiltins()) < 0))
             goto bad;
     }
 
     if (PyCode_Check(o)) {
@@ -114,8 +82,8 @@
             goto bad;
     }
 
     if (PyCode_Check(o)) {
-        if (__Pyx_PyCode_HasFreeVars((PyCodeObject *)o)) {
+        if (unlikely(__Pyx_PyCode_HasFreeVars((PyCodeObject *)o))) {
             PyErr_SetString(PyExc_TypeError,
                 "code object passed to exec() may not contain free variables");
             goto bad;
@@ -131,6 +99,6 @@
         if (PyUnicode_Check(o)) {
             cf.cf_flags = PyCF_SOURCE_IS_UTF8;
             s = PyUnicode_AsUTF8String(o);
-            if (!s) goto bad;
+            if (unlikely(!s)) goto bad;
             o = s;
         #if PY_MAJOR_VERSION >= 3
@@ -135,4 +103,4 @@
             o = s;
         #if PY_MAJOR_VERSION >= 3
-        } else if (!PyBytes_Check(o)) {
+        } else if (unlikely(!PyBytes_Check(o))) {
         #else
@@ -138,5 +106,5 @@
         #else
-        } else if (!PyString_Check(o)) {
+        } else if (unlikely(!PyString_Check(o))) {
         #endif
             PyErr_Format(PyExc_TypeError,
                 "exec: arg 1 must be string, bytes or code object, got %.200s",
@@ -167,7 +135,7 @@
 static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *, PyObject *, PyObject *); /*proto*/
 
 //////////////////// GetAttr3 ////////////////////
-//@requires: ObjectHandling.c::GetAttr
+//@requires: ObjectHandling.c::PyObjectGetAttrStr
 //@requires: Exceptions.c::PyThreadStateGet
 //@requires: Exceptions.c::PyErrFetchRestore
 //@requires: Exceptions.c::PyErrExceptionMatches
@@ -183,7 +151,17 @@
 }
 
 static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *o, PyObject *n, PyObject *d) {
-    PyObject *r = __Pyx_GetAttr(o, n);
+    PyObject *r;
+#if CYTHON_USE_TYPE_SLOTS
+    if (likely(PyString_Check(n))) {
+        r = __Pyx_PyObject_GetAttrStrNoError(o, n);
+        if (unlikely(!r) && likely(!PyErr_Occurred())) {
+            r = __Pyx_NewRef(d);
+        }
+        return r;
+    }
+#endif
+    r = PyObject_GetAttr(o, n);
     return (likely(r)) ? r : __Pyx_GetAttr3Default(d);
 }
 
@@ -202,7 +180,7 @@
         return -1;
     }
     r = __Pyx_GetAttr(o, n);
-    if (unlikely(!r)) {
+    if (!r) {
         PyErr_Clear();
         return 0;
     } else {
@@ -218,7 +196,7 @@
 //////////////////// Intern ////////////////////
 
 static PyObject* __Pyx_Intern(PyObject* s) {
-    if (!(likely(PyString_CheckExact(s)))) {
+    if (unlikely(!PyString_CheckExact(s))) {
         PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "str", Py_TYPE(s)->tp_name);
         return 0;
     }
@@ -418,9 +396,6 @@
 
 //////////////////// py_dict_viewkeys.proto ////////////////////
 
-#if PY_VERSION_HEX < 0x02070000
-#error This module uses dict views, which require Python 2.7 or later
-#endif
 static CYTHON_INLINE PyObject* __Pyx_PyDict_ViewKeys(PyObject* d); /*proto*/
 
 //////////////////// py_dict_viewkeys ////////////////////
@@ -434,9 +409,6 @@
 
 //////////////////// py_dict_viewvalues.proto ////////////////////
 
-#if PY_VERSION_HEX < 0x02070000
-#error This module uses dict views, which require Python 2.7 or later
-#endif
 static CYTHON_INLINE PyObject* __Pyx_PyDict_ViewValues(PyObject* d); /*proto*/
 
 //////////////////// py_dict_viewvalues ////////////////////
@@ -450,9 +422,6 @@
 
 //////////////////// py_dict_viewitems.proto ////////////////////
 
-#if PY_VERSION_HEX < 0x02070000
-#error This module uses dict views, which require Python 2.7 or later
-#endif
 static CYTHON_INLINE PyObject* __Pyx_PyDict_ViewItems(PyObject* d); /*proto*/
 
 //////////////////// py_dict_viewitems ////////////////////
diff --git a/Cython/Utility/CConvert.pyx b/Cython/Utility/CConvert.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1V0aWxpdHkvQ0NvbnZlcnQucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1V0aWxpdHkvQ0NvbnZlcnQucHl4 100644
--- a/Cython/Utility/CConvert.pyx
+++ b/Cython/Utility/CConvert.pyx
@@ -18,7 +18,7 @@
         value = obj['{{member.name}}']
     except KeyError:
         raise ValueError("No value specified for struct attribute '{{member.name}}'")
-    result.{{member.cname}} = value
+    result.{{member.name}} = value
     {{endfor}}
     return result
 
diff --git a/Cython/Utility/Capsule.c b/Cython/Utility/Capsule.c
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1V0aWxpdHkvQ2Fwc3VsZS5j..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1V0aWxpdHkvQ2Fwc3VsZS5j 100644
--- a/Cython/Utility/Capsule.c
+++ b/Cython/Utility/Capsule.c
@@ -6,5 +6,5 @@
 //////////////// Capsule ////////////////
 
 static CYTHON_INLINE PyObject *
-__pyx_capsule_create(void *p, CYTHON_UNUSED const char *sig)
+__pyx_capsule_create(void *p, const char *sig)
 {
@@ -10,11 +10,3 @@
 {
-    PyObject *cobj;
-
-#if PY_VERSION_HEX >= 0x02070000
-    cobj = PyCapsule_New(p, sig, NULL);
-#else
-    cobj = PyCObject_FromVoidPtr(p, NULL);
-#endif
-
-    return cobj;
+    return PyCapsule_New(p, sig, NULL);
 }
diff --git a/Cython/Utility/CommonStructures.c b/Cython/Utility/CommonStructures.c
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1V0aWxpdHkvQ29tbW9uU3RydWN0dXJlcy5j..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1V0aWxpdHkvQ29tbW9uU3RydWN0dXJlcy5j 100644
--- a/Cython/Utility/CommonStructures.c
+++ b/Cython/Utility/CommonStructures.c
@@ -1,6 +1,9 @@
 /////////////// FetchCommonType.proto ///////////////
 
 static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type);
+#if CYTHON_COMPILING_IN_LIMITED_API
+static PyTypeObject* __Pyx_FetchCommonTypeFromSpec(PyType_Spec *spec, PyObject *bases);
+#endif
 
 /////////////// FetchCommonType ///////////////
 
@@ -4,7 +7,10 @@
 
 /////////////// FetchCommonType ///////////////
 
-static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type) {
-    PyObject* fake_module;
-    PyTypeObject* cached_type = NULL;
+static PyObject *__Pyx_FetchSharedCythonABIModule(void) {
+    PyObject *abi_module = PyImport_AddModule((char*) "_cython_" CYTHON_ABI);
+    if (!abi_module) return NULL;
+    Py_INCREF(abi_module);
+    return abi_module;
+}
 
@@ -10,5 +16,19 @@
 
-    fake_module = PyImport_AddModule((char*) "_cython_" CYTHON_ABI);
-    if (!fake_module) return NULL;
-    Py_INCREF(fake_module);
+static int __Pyx_VerifyCachedType(PyObject *cached_type,
+                               const char *name,
+                               Py_ssize_t basicsize,
+                               Py_ssize_t expected_basicsize) {
+    if (!PyType_Check(cached_type)) {
+        PyErr_Format(PyExc_TypeError,
+            "Shared Cython type %.200s is not a type object", name);
+        return -1;
+    }
+    if (basicsize != expected_basicsize) {
+        PyErr_Format(PyExc_TypeError,
+            "Shared Cython type %.200s has the wrong size, try recompiling",
+            name);
+        return -1;
+    }
+    return 0;
+}
 
@@ -14,3 +34,9 @@
 
-    cached_type = (PyTypeObject*) PyObject_GetAttrString(fake_module, type->tp_name);
+static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type) {
+    PyObject* abi_module;
+    PyTypeObject *cached_type = NULL;
+
+    abi_module = __Pyx_FetchSharedCythonABIModule();
+    if (!abi_module) return NULL;
+    cached_type = (PyTypeObject*) PyObject_GetAttrString(abi_module, type->tp_name);
     if (cached_type) {
@@ -16,7 +42,8 @@
     if (cached_type) {
-        if (!PyType_Check((PyObject*)cached_type)) {
-            PyErr_Format(PyExc_TypeError,
-                "Shared Cython type %.200s is not a type object",
-                type->tp_name);
+        if (__Pyx_VerifyCachedType(
+              (PyObject *)cached_type,
+              type->tp_name,
+              cached_type->tp_basicsize,
+              type->tp_basicsize) < 0) {
             goto bad;
         }
@@ -21,18 +48,5 @@
             goto bad;
         }
-        if (cached_type->tp_basicsize != type->tp_basicsize) {
-            PyErr_Format(PyExc_TypeError,
-                "Shared Cython type %.200s has the wrong size, try recompiling",
-                type->tp_name);
-            goto bad;
-        }
-    } else {
-        if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad;
-        PyErr_Clear();
-        if (PyType_Ready(type) < 0) goto bad;
-        if (PyObject_SetAttrString(fake_module, type->tp_name, (PyObject*) type) < 0)
-            goto bad;
-        Py_INCREF(type);
-        cached_type = type;
+        goto done;
     }
 
@@ -37,3 +51,11 @@
     }
 
+    if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad;
+    PyErr_Clear();
+    if (PyType_Ready(type) < 0) goto bad;
+    if (PyObject_SetAttrString(abi_module, type->tp_name, (PyObject *)type) < 0)
+        goto bad;
+    Py_INCREF(type);
+    cached_type = type;
+
 done:
@@ -39,5 +61,5 @@
 done:
-    Py_DECREF(fake_module);
+    Py_DECREF(abi_module);
     // NOTE: always returns owned reference, or NULL on error
     return cached_type;
 
@@ -47,6 +69,50 @@
     goto done;
 }
 
+#if CYTHON_COMPILING_IN_LIMITED_API
+static PyTypeObject *__Pyx_FetchCommonTypeFromSpec(PyType_Spec *spec, PyObject *bases) {
+    PyObject *abi_module, *py_basicsize, *cached_type = NULL;
+    Py_ssize_t basicsize;
+
+    abi_module = __Pyx_FetchSharedCythonABIModule();
+    if (!abi_module) return NULL;
+    cached_type = PyObject_GetAttrString(abi_module, spec->name);
+    if (cached_type) {
+        py_basicsize = PyObject_GetAttrString(cached_type, "__basicsize__");
+        if (!py_basicsize) goto bad;
+        basicsize = PyLong_AsSsize_t(py_basicsize);
+        Py_DECREF(py_basicsize);
+        py_basicsize = 0;
+        if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred()) goto bad;
+        if (__Pyx_VerifyCachedType(
+              cached_type,
+              spec->name,
+              basicsize,
+              spec->basicsize) < 0) {
+            goto bad;
+        }
+        goto done;
+    }
+
+    if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad;
+    PyErr_Clear();
+    cached_type = PyType_FromSpecWithBases(spec, bases);
+    if (unlikely(!cached_type)) goto bad;
+    if (PyObject_SetAttrString(abi_module, spec->name, cached_type) < 0) goto bad;
+
+done:
+    Py_DECREF(abi_module);
+    // NOTE: always returns owned reference, or NULL on error
+    assert(cached_type == NULL || PyType_Check(cached_type));
+    return (PyTypeObject *) cached_type;
+
+bad:
+    Py_XDECREF(cached_type);
+    cached_type = NULL;
+    goto done;
+}
+#endif
+
 
 /////////////// FetchCommonPointer.proto ///////////////
 
@@ -56,8 +122,7 @@
 
 
 static void* __Pyx_FetchCommonPointer(void* pointer, const char* name) {
-#if PY_VERSION_HEX >= 0x02070000
-    PyObject* fake_module = NULL;
+    PyObject* abi_module = NULL;
     PyObject* capsule = NULL;
     void* value = NULL;
 
@@ -61,7 +126,7 @@
     PyObject* capsule = NULL;
     void* value = NULL;
 
-    fake_module = PyImport_AddModule((char*) "_cython_" CYTHON_ABI);
-    if (!fake_module) return NULL;
-    Py_INCREF(fake_module);
+    abi_module = PyImport_AddModule((char*) "_cython_" CYTHON_ABI);
+    if (!abi_module) return NULL;
+    Py_INCREF(abi_module);
 
@@ -67,7 +132,7 @@
 
-    capsule = PyObject_GetAttrString(fake_module, name);
+    capsule = PyObject_GetAttrString(abi_module, name);
     if (!capsule) {
         if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad;
         PyErr_Clear();
         capsule = PyCapsule_New(pointer, name, NULL);
         if (!capsule) goto bad;
@@ -69,12 +134,12 @@
     if (!capsule) {
         if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad;
         PyErr_Clear();
         capsule = PyCapsule_New(pointer, name, NULL);
         if (!capsule) goto bad;
-        if (PyObject_SetAttrString(fake_module, name, capsule) < 0)
+        if (PyObject_SetAttrString(abi_module, name, capsule) < 0)
             goto bad;
     }
     value = PyCapsule_GetPointer(capsule, name);
 
 bad:
     Py_XDECREF(capsule);
@@ -75,8 +140,8 @@
             goto bad;
     }
     value = PyCapsule_GetPointer(capsule, name);
 
 bad:
     Py_XDECREF(capsule);
-    Py_DECREF(fake_module);
+    Py_DECREF(abi_module);
     return value;
@@ -82,5 +147,2 @@
     return value;
-#else
-    return pointer;
-#endif
 }
diff --git a/Cython/Utility/Coroutine.c b/Cython/Utility/Coroutine.c
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1V0aWxpdHkvQ29yb3V0aW5lLmM=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1V0aWxpdHkvQ29yb3V0aW5lLmM= 100644
--- a/Cython/Utility/Coroutine.c
+++ b/Cython/Utility/Coroutine.c
@@ -5,9 +5,10 @@
 //////////////////// GeneratorYieldFrom ////////////////////
 //@requires: Generator
 
+#if CYTHON_USE_TYPE_SLOTS
 static void __PyxPyIter_CheckErrorAndDecref(PyObject *source) {
     PyErr_Format(PyExc_TypeError,
                  "iter() returned non-iterator of type '%.100s'",
                  Py_TYPE(source)->tp_name);
     Py_DECREF(source);
 }
@@ -8,9 +9,10 @@
 static void __PyxPyIter_CheckErrorAndDecref(PyObject *source) {
     PyErr_Format(PyExc_TypeError,
                  "iter() returned non-iterator of type '%.100s'",
                  Py_TYPE(source)->tp_name);
     Py_DECREF(source);
 }
+#endif
 
 static CYTHON_INLINE PyObject* __Pyx_Generator_Yield_From(__pyx_CoroutineObject *gen, PyObject *source) {
     PyObject *source_gen, *retval;
@@ -362,7 +364,8 @@
 //////////////////// CoroutineBase.proto ////////////////////
 //@substitute: naming
 
-typedef PyObject *(*__pyx_coroutine_body_t)(PyObject *, PyThreadState *, PyObject *);
+struct __pyx_CoroutineObject;
+typedef PyObject *(*__pyx_coroutine_body_t)(struct __pyx_CoroutineObject *, PyThreadState *, PyObject *);
 
 #if CYTHON_USE_EXC_INFO_STACK
 // See  https://bugs.python.org/issue25612
@@ -376,7 +379,7 @@
 } __Pyx_ExcInfoStruct;
 #endif
 
-typedef struct {
+typedef struct __pyx_CoroutineObject {
     PyObject_HEAD
     __pyx_coroutine_body_t body;
     PyObject *closure;
@@ -388,6 +391,7 @@
     PyObject *gi_qualname;
     PyObject *gi_modulename;
     PyObject *gi_code;
+    PyObject *gi_frame;
     int resume_label;
     // using T_BOOL for property below requires char value
     char is_running;
@@ -438,6 +442,6 @@
 #define __Pyx_Coroutine_USED
 static PyTypeObject *__pyx_CoroutineType = 0;
 static PyTypeObject *__pyx_CoroutineAwaitType = 0;
-#define __Pyx_Coroutine_CheckExact(obj) (Py_TYPE(obj) == __pyx_CoroutineType)
+#define __Pyx_Coroutine_CheckExact(obj) __Pyx_IS_TYPE(obj, __pyx_CoroutineType)
 // __Pyx_Coroutine_Check(obj): see override for IterableCoroutine below
 #define __Pyx_Coroutine_Check(obj) __Pyx_Coroutine_CheckExact(obj)
@@ -442,6 +446,6 @@
 // __Pyx_Coroutine_Check(obj): see override for IterableCoroutine below
 #define __Pyx_Coroutine_Check(obj) __Pyx_Coroutine_CheckExact(obj)
-#define __Pyx_CoroutineAwait_CheckExact(obj) (Py_TYPE(obj) == __pyx_CoroutineAwaitType)
+#define __Pyx_CoroutineAwait_CheckExact(obj) __Pyx_IS_TYPE(obj, __pyx_CoroutineAwaitType)
 
 #define __Pyx_Coroutine_New(body, code, closure, name, qualname, module_name)  \
     __Pyx__Coroutine_New(__pyx_CoroutineType, body, code, closure, name, qualname, module_name)
@@ -462,7 +466,7 @@
 
 #define __Pyx_Generator_USED
 static PyTypeObject *__pyx_GeneratorType = 0;
-#define __Pyx_Generator_CheckExact(obj) (Py_TYPE(obj) == __pyx_GeneratorType)
+#define __Pyx_Generator_CheckExact(obj) __Pyx_IS_TYPE(obj, __pyx_GeneratorType)
 
 #define __Pyx_Generator_New(body, code, closure, name, qualname, module_name)  \
     __Pyx__Coroutine_New(__pyx_GeneratorType, body, code, closure, name, qualname, module_name)
@@ -484,4 +488,6 @@
 //@requires: Exceptions.c::RaiseException
 //@requires: Exceptions.c::SaveResetException
 //@requires: ObjectHandling.c::PyObjectCallMethod1
+//@requires: ObjectHandling.c::PyObjectCallNoArg
+//@requires: ObjectHandling.c::PyObjectFastCall
 //@requires: ObjectHandling.c::PyObjectGetAttrStr
@@ -487,4 +493,5 @@
 //@requires: ObjectHandling.c::PyObjectGetAttrStr
+//@requires: ObjectHandling.c::PyObjectGetAttrStrNoError
 //@requires: CommonStructures.c::FetchCommonType
 
 #include <structmember.h>
@@ -519,7 +526,7 @@
             value = Py_None;
         }
 #if PY_VERSION_HEX >= 0x030300A0
-        else if (Py_TYPE(ev) == (PyTypeObject*)PyExc_StopIteration) {
+        else if (likely(__Pyx_IS_TYPE(ev, (PyTypeObject*)PyExc_StopIteration))) {
             value = ((PyStopIterationObject *)ev)->value;
             Py_INCREF(value);
             Py_DECREF(ev);
@@ -738,7 +745,7 @@
 #endif
 
     self->is_running = 1;
-    retval = self->body((PyObject *) self, tstate, value);
+    retval = self->body(self, tstate, value);
     self->is_running = 0;
 
 #if CYTHON_USE_EXC_INFO_STACK
@@ -894,5 +901,5 @@
     {
         PyObject *meth;
         gen->is_running = 1;
-        meth = __Pyx_PyObject_GetAttrStr(yf, PYIDENT("close"));
+        meth = __Pyx_PyObject_GetAttrStrNoError(yf, PYIDENT("close"));
         if (unlikely(!meth)) {
@@ -898,4 +905,4 @@
         if (unlikely(!meth)) {
-            if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
+            if (unlikely(PyErr_Occurred())) {
                 PyErr_WriteUnraisable(yf);
             }
@@ -900,4 +907,3 @@
                 PyErr_WriteUnraisable(yf);
             }
-            PyErr_Clear();
         } else {
@@ -903,3 +909,3 @@
         } else {
-            retval = PyObject_CallFunction(meth, NULL);
+            retval = __Pyx_PyObject_CallNoArg(meth);
             Py_DECREF(meth);
@@ -905,5 +911,5 @@
             Py_DECREF(meth);
-            if (!retval)
+            if (unlikely(!retval))
                 err = -1;
         }
         gen->is_running = 0;
@@ -1041,6 +1047,6 @@
             ret = __Pyx__Coroutine_Throw(((__pyx_CoroutineAwaitObject*)yf)->coroutine, typ, val, tb, args, close_on_genexit);
         #endif
         } else {
-            PyObject *meth = __Pyx_PyObject_GetAttrStr(yf, PYIDENT("throw"));
+            PyObject *meth = __Pyx_PyObject_GetAttrStrNoError(yf, PYIDENT("throw"));
             if (unlikely(!meth)) {
                 Py_DECREF(yf);
@@ -1045,6 +1051,6 @@
             if (unlikely(!meth)) {
                 Py_DECREF(yf);
-                if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
+                if (unlikely(PyErr_Occurred())) {
                     gen->is_running = 0;
                     return NULL;
                 }
@@ -1048,9 +1054,8 @@
                     gen->is_running = 0;
                     return NULL;
                 }
-                PyErr_Clear();
                 __Pyx_Coroutine_Undelegate(gen);
                 gen->is_running = 0;
                 goto throw_here;
             }
             if (likely(args)) {
@@ -1052,8 +1057,8 @@
                 __Pyx_Coroutine_Undelegate(gen);
                 gen->is_running = 0;
                 goto throw_here;
             }
             if (likely(args)) {
-                ret = PyObject_CallObject(meth, args);
+                ret = __Pyx_PyObject_Call(meth, args, NULL);
             } else {
                 // "tb" or even "val" might be NULL, but that also correctly terminates the argument list
@@ -1058,6 +1063,7 @@
             } else {
                 // "tb" or even "val" might be NULL, but that also correctly terminates the argument list
-                ret = PyObject_CallFunctionObjArgs(meth, typ, val, tb, NULL);
+                PyObject *cargs[4] = {NULL, typ, val, tb};
+                ret = __Pyx_PyObject_FastCall(meth, cargs+1, 3 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET);
             }
             Py_DECREF(meth);
         }
@@ -1078,7 +1084,7 @@
     PyObject *val = NULL;
     PyObject *tb = NULL;
 
-    if (!PyArg_UnpackTuple(args, (char *)"throw", 1, 3, &typ, &val, &tb))
+    if (unlikely(!PyArg_UnpackTuple(args, (char *)"throw", 1, 3, &typ, &val, &tb)))
         return NULL;
 
     return __Pyx__Coroutine_Throw(self, typ, val, tb, args, 1);
@@ -1111,6 +1117,7 @@
     }
 #endif
     Py_CLEAR(gen->gi_code);
+    Py_CLEAR(gen->gi_frame);
     Py_CLEAR(gen->gi_name);
     Py_CLEAR(gen->gi_qualname);
     Py_CLEAR(gen->gi_modulename);
@@ -1128,6 +1135,6 @@
         // Generator is paused or unstarted, so we need to close
         PyObject_GC_Track(self);
 #if PY_VERSION_HEX >= 0x030400a1 && CYTHON_USE_TP_FINALIZE
-        if (PyObject_CallFinalizerFromDealloc(self))
+        if (unlikely(PyObject_CallFinalizerFromDealloc(self)))
 #else
         Py_TYPE(gen)->tp_del(self);
@@ -1132,6 +1139,6 @@
 #else
         Py_TYPE(gen)->tp_del(self);
-        if (self->ob_refcnt > 0)
+        if (unlikely(self->ob_refcnt > 0))
 #endif
         {
             // resurrected.  :(
@@ -1247,7 +1254,7 @@
     // Undo the temporary resurrection; can't use DECREF here, it would
     // cause a recursive call.
     assert(self->ob_refcnt > 0);
-    if (--self->ob_refcnt == 0) {
+    if (likely(--self->ob_refcnt == 0)) {
         // this is the normal path out
         return;
     }
@@ -1292,8 +1299,6 @@
 static int
 __Pyx_Coroutine_set_name(__pyx_CoroutineObject *self, PyObject *value, CYTHON_UNUSED void *context)
 {
-    PyObject *tmp;
-
 #if PY_MAJOR_VERSION >= 3
     if (unlikely(value == NULL || !PyUnicode_Check(value)))
 #else
@@ -1304,5 +1309,4 @@
                         "__name__ must be set to a string object");
         return -1;
     }
-    tmp = self->gi_name;
     Py_INCREF(value);
@@ -1308,6 +1312,5 @@
     Py_INCREF(value);
-    self->gi_name = value;
-    Py_XDECREF(tmp);
+    __Pyx_Py_XDECREF_SET(self->gi_name, value);
     return 0;
 }
 
@@ -1324,8 +1327,6 @@
 static int
 __Pyx_Coroutine_set_qualname(__pyx_CoroutineObject *self, PyObject *value, CYTHON_UNUSED void *context)
 {
-    PyObject *tmp;
-
 #if PY_MAJOR_VERSION >= 3
     if (unlikely(value == NULL || !PyUnicode_Check(value)))
 #else
@@ -1336,5 +1337,4 @@
                         "__qualname__ must be set to a string object");
         return -1;
     }
-    tmp = self->gi_qualname;
     Py_INCREF(value);
@@ -1340,6 +1340,5 @@
     Py_INCREF(value);
-    self->gi_qualname = value;
-    Py_XDECREF(tmp);
+    __Pyx_Py_XDECREF_SET(self->gi_qualname, value);
     return 0;
 }
 
@@ -1343,6 +1342,30 @@
     return 0;
 }
 
+static PyObject *
+__Pyx_Coroutine_get_frame(__pyx_CoroutineObject *self, CYTHON_UNUSED void *context)
+{
+    PyObject *frame = self->gi_frame;
+    if (!frame) {
+        if (unlikely(!self->gi_code)) {
+            // Avoid doing something stupid, e.g. during garbage collection.
+            Py_RETURN_NONE;
+        }
+        frame = (PyObject *) PyFrame_New(
+            PyThreadState_Get(),            /*PyThreadState *tstate,*/
+            (PyCodeObject*) self->gi_code,  /*PyCodeObject *code,*/
+            $moddict_cname,                 /*PyObject *globals,*/
+            0                               /*PyObject *locals*/
+        );
+        if (unlikely(!frame))
+            return NULL;
+        // keep the frame cached once it's created
+        self->gi_frame = frame;
+    }
+    Py_INCREF(frame);
+    return frame;
+}
+
 static __pyx_CoroutineObject *__Pyx__Coroutine_New(
             PyTypeObject* type, __pyx_coroutine_body_t body, PyObject *code, PyObject *closure,
             PyObject *name, PyObject *qualname, PyObject *module_name) {
@@ -1377,6 +1400,7 @@
     gen->gi_modulename = module_name;
     Py_XINCREF(code);
     gen->gi_code = code;
+    gen->gi_frame = NULL;
 
     PyObject_GC_Track(gen);
     return gen;
@@ -1503,6 +1527,9 @@
 #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
     0,                                  /*tp_print*/
 #endif
+#if CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM+0 >= 0x06000000
+    0,                                          /*tp_pypy_flags*/
+#endif
 };
 
 #if PY_VERSION_HEX < 0x030500B1 || defined(__Pyx_IterableCoroutine_USED) || CYTHON_USE_ASYNC_SLOTS
@@ -1532,13 +1559,6 @@
 }
 #endif
 
-static PyObject *
-__Pyx_Coroutine_get_frame(CYTHON_UNUSED __pyx_CoroutineObject *self, CYTHON_UNUSED void *context)
-{
-    // Fake implementation that always returns None, but at least does not raise an AttributeError.
-    Py_RETURN_NONE;
-}
-
 #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 && PY_VERSION_HEX < 0x030500B1
 static PyObject *__Pyx_Coroutine_compare(PyObject *obj, PyObject *other, int op) {
     PyObject* result;
@@ -1667,6 +1687,9 @@
 #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
     0,                                  /*tp_print*/
 #endif
+#if CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM+0 >= 0x06000000
+    0,                                          /*tp_pypy_flags*/
+#endif
 };
 
 static int __pyx_Coroutine_init(void) {
@@ -1695,7 +1718,7 @@
 static PyTypeObject *__pyx_IterableCoroutineType = 0;
 
 #undef __Pyx_Coroutine_Check
-#define __Pyx_Coroutine_Check(obj) (__Pyx_Coroutine_CheckExact(obj) || (Py_TYPE(obj) == __pyx_IterableCoroutineType))
+#define __Pyx_Coroutine_Check(obj) (__Pyx_Coroutine_CheckExact(obj) || __Pyx_IS_TYPE(obj, __pyx_IterableCoroutineType))
 
 #define __Pyx_IterableCoroutine_New(body, code, closure, name, qualname, module_name)  \
     __Pyx__Coroutine_New(__pyx_IterableCoroutineType, body, code, closure, name, qualname, module_name)
@@ -1778,6 +1801,9 @@
 #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
     0,                                  /*tp_print*/
 #endif
+#if CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM+0 >= 0x06000000
+    0,                                          /*tp_pypy_flags*/
+#endif
 };
 
 
@@ -1818,6 +1844,8 @@
      (char*) PyDoc_STR("name of the generator"), 0},
     {(char *) "__qualname__", (getter)__Pyx_Coroutine_get_qualname, (setter)__Pyx_Coroutine_set_qualname,
      (char*) PyDoc_STR("qualified name of the generator"), 0},
+    {(char *) "gi_frame", (getter)__Pyx_Coroutine_get_frame, NULL,
+     (char*) PyDoc_STR("Frame of the coroutine"), 0},
     {0, 0, 0, 0, 0}
 };
 
@@ -1884,6 +1912,9 @@
 #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
     0,                                  /*tp_print*/
 #endif
+#if CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM+0 >= 0x06000000
+    0,                                          /*tp_pypy_flags*/
+#endif
 };
 
 static int __pyx_Generator_init(void) {
@@ -2047,7 +2078,7 @@
     if (CYTHON_REGISTER_ABCS && !abc_patched) {
         PyObject *module;
         module = PyImport_ImportModule((PY_MAJOR_VERSION >= 3) ? "collections.abc" : "collections");
-        if (!module) {
+        if (unlikely(!module)) {
             PyErr_WriteUnraisable(NULL);
             if (unlikely(PyErr_WarnEx(PyExc_RuntimeWarning,
                     ((PY_MAJOR_VERSION >= 3) ?
@@ -2280,6 +2311,9 @@
 #if PY_VERSION_HEX >= 0x030400a1
     0,                                  /*tp_finalize*/
 #endif
+#if CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM+0 >= 0x06000000
+    0,                                          /*tp_pypy_flags*/
+#endif
 };
 #endif
 
@@ -2305,7 +2339,7 @@
     __Pyx_PyExc_StopAsyncIteration = (PyObject*) __Pyx_FetchCommonType(&__Pyx__PyExc_StopAsyncIteration_type);
     if (unlikely(!__Pyx_PyExc_StopAsyncIteration))
         return -1;
-    if (builtins && unlikely(PyMapping_SetItemString(builtins, (char*) "StopAsyncIteration", __Pyx_PyExc_StopAsyncIteration) < 0))
+    if (likely(builtins) && unlikely(PyMapping_SetItemString(builtins, (char*) "StopAsyncIteration", __Pyx_PyExc_StopAsyncIteration) < 0))
         return -1;
 #endif
     return 0;
diff --git a/Cython/Utility/CpdefEnums.pyx b/Cython/Utility/CpdefEnums.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1V0aWxpdHkvQ3BkZWZFbnVtcy5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1V0aWxpdHkvQ3BkZWZFbnVtcy5weXg= 100644
--- a/Cython/Utility/CpdefEnums.pyx
+++ b/Cython/Utility/CpdefEnums.pyx
@@ -6,10 +6,7 @@
     int PY_VERSION_HEX
 
 cdef object __Pyx_OrderedDict
-if PY_VERSION_HEX >= 0x02070000:
-    from collections import OrderedDict as __Pyx_OrderedDict
-else:
-    __Pyx_OrderedDict = dict
+from collections import OrderedDict as __Pyx_OrderedDict
 
 @cython.internal
 cdef class __Pyx_EnumMeta(type):
@@ -23,8 +20,7 @@
 
 # @cython.internal
 cdef object __Pyx_EnumBase
-class __Pyx_EnumBase(int):
-    __metaclass__ = __Pyx_EnumMeta
+class __Pyx_EnumBase(int, metaclass=__Pyx_EnumMeta):
     def __new__(cls, value, name=None):
         for v in cls:
             if v == value:
diff --git a/Cython/Utility/CppSupport.cpp b/Cython/Utility/CppSupport.cpp
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1V0aWxpdHkvQ3BwU3VwcG9ydC5jcHA=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1V0aWxpdHkvQ3BwU3VwcG9ydC5jcHA= 100644
--- a/Cython/Utility/CppSupport.cpp
+++ b/Cython/Utility/CppSupport.cpp
@@ -56,3 +56,14 @@
   using returnable_type = typename pythonic::returnable<typename std::remove_cv<typename std::remove_reference<T>::type>::type>::type;
   return to_python(returnable_type{std::forward<T>(value)});
 }
+
+#define __Pyx_PythranShapeAccessor(x) (x.shape().array())
+
+////////////// MoveIfSupported.proto //////////////////
+
+#if __cplusplus >= 201103L
+  #include <utility>
+  #define __PYX_STD_MOVE_IF_SUPPORTED(x) std::move(x)
+#else
+  #define __PYX_STD_MOVE_IF_SUPPORTED(x) x
+#endif
diff --git a/Cython/Utility/CythonFunction.c b/Cython/Utility/CythonFunction.c
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1V0aWxpdHkvQ3l0aG9uRnVuY3Rpb24uYw==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1V0aWxpdHkvQ3l0aG9uRnVuY3Rpb24uYw== 100644
--- a/Cython/Utility/CythonFunction.c
+++ b/Cython/Utility/CythonFunction.c
@@ -1,2 +1,1 @@
-
 
@@ -2,5 +1,6 @@
 
-//////////////////// CythonFunction.proto ////////////////////
+//////////////////// CythonFunctionShared.proto ////////////////////
+
 #define __Pyx_CyFunction_USED 1
 
 #define __Pyx_CYFUNCTION_STATICMETHOD  0x01
@@ -20,6 +20,9 @@
 
 typedef struct {
     PyCFunctionObject func;
+#if CYTHON_BACKPORT_VECTORCALL
+    __pyx_vectorcallfunc func_vectorcall;
+#endif
 #if PY_VERSION_HEX < 0x030500A0
     PyObject *func_weakreflist;
 #endif
@@ -46,4 +49,5 @@
     PyObject *func_annotations; /* function annotations dict */
 } __pyx_CyFunctionObject;
 
+#if !CYTHON_COMPILING_IN_LIMITED_API
 static PyTypeObject *__pyx_CyFunctionType = 0;
@@ -49,4 +53,5 @@
 static PyTypeObject *__pyx_CyFunctionType = 0;
+#endif
 
 #define __Pyx_CyFunction_Check(obj)  (__Pyx_TypeCheck(obj, __pyx_CyFunctionType))
 
@@ -50,8 +55,5 @@
 
 #define __Pyx_CyFunction_Check(obj)  (__Pyx_TypeCheck(obj, __pyx_CyFunctionType))
 
-#define __Pyx_CyFunction_NewEx(ml, flags, qualname, self, module, globals, code) \
-    __Pyx_CyFunction_New(__pyx_CyFunctionType, ml, flags, qualname, self, module, globals, code)
-
-static PyObject *__Pyx_CyFunction_New(PyTypeObject *, PyMethodDef *ml,
+static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject* op, PyMethodDef *ml,
                                       int flags, PyObject* qualname,
@@ -57,5 +59,5 @@
                                       int flags, PyObject* qualname,
-                                      PyObject *self,
+                                      PyObject *closure,
                                       PyObject *module, PyObject *globals,
                                       PyObject* code);
 
@@ -72,6 +74,17 @@
 
 static int __pyx_CyFunction_init(void);
 
-//////////////////// CythonFunction ////////////////////
+#if CYTHON_METH_FASTCALL
+static PyObject * __Pyx_CyFunction_Vectorcall_NOARGS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames);
+static PyObject * __Pyx_CyFunction_Vectorcall_O(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames);
+static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames);
+#if CYTHON_BACKPORT_VECTORCALL
+#define __Pyx_CyFunction_func_vectorcall(f) (((__pyx_CyFunctionObject*)f)->func_vectorcall)
+#else
+#define __Pyx_CyFunction_func_vectorcall(f) (((__pyx_CyFunctionObject*)f)->func.vectorcall)
+#endif
+#endif
+
+//////////////////// CythonFunctionShared ////////////////////
 //@substitute: naming
 //@requires: CommonStructures.c::FetchCommonType
@@ -76,6 +89,7 @@
 //@substitute: naming
 //@requires: CommonStructures.c::FetchCommonType
-////@requires: ObjectHandling.c::PyObjectGetAttrStr
+//@requires: ObjectHandling.c::PyMethodNew
+//@requires: ObjectHandling.c::PyVectorcallFastCallDict
 
 #include <structmember.h>
 
@@ -103,9 +117,8 @@
 static int
 __Pyx_CyFunction_set_doc(__pyx_CyFunctionObject *op, PyObject *value, CYTHON_UNUSED void *context)
 {
-    PyObject *tmp = op->func_doc;
     if (value == NULL) {
         // Mark as deleted
         value = Py_None;
     }
     Py_INCREF(value);
@@ -107,10 +120,9 @@
     if (value == NULL) {
         // Mark as deleted
         value = Py_None;
     }
     Py_INCREF(value);
-    op->func_doc = value;
-    Py_XDECREF(tmp);
+    __Pyx_Py_XDECREF_SET(op->func_doc, value);
     return 0;
 }
 
@@ -133,8 +145,6 @@
 static int
 __Pyx_CyFunction_set_name(__pyx_CyFunctionObject *op, PyObject *value, CYTHON_UNUSED void *context)
 {
-    PyObject *tmp;
-
 #if PY_MAJOR_VERSION >= 3
     if (unlikely(value == NULL || !PyUnicode_Check(value)))
 #else
@@ -145,5 +155,4 @@
                         "__name__ must be set to a string object");
         return -1;
     }
-    tmp = op->func_name;
     Py_INCREF(value);
@@ -149,6 +158,5 @@
     Py_INCREF(value);
-    op->func_name = value;
-    Py_XDECREF(tmp);
+    __Pyx_Py_XDECREF_SET(op->func_name, value);
     return 0;
 }
 
@@ -162,8 +170,6 @@
 static int
 __Pyx_CyFunction_set_qualname(__pyx_CyFunctionObject *op, PyObject *value, CYTHON_UNUSED void *context)
 {
-    PyObject *tmp;
-
 #if PY_MAJOR_VERSION >= 3
     if (unlikely(value == NULL || !PyUnicode_Check(value)))
 #else
@@ -174,5 +180,4 @@
                         "__qualname__ must be set to a string object");
         return -1;
     }
-    tmp = op->func_qualname;
     Py_INCREF(value);
@@ -178,6 +183,5 @@
     Py_INCREF(value);
-    op->func_qualname = value;
-    Py_XDECREF(tmp);
+    __Pyx_Py_XDECREF_SET(op->func_qualname, value);
     return 0;
 }
 
@@ -208,8 +212,6 @@
 static int
 __Pyx_CyFunction_set_dict(__pyx_CyFunctionObject *op, PyObject *value, CYTHON_UNUSED void *context)
 {
-    PyObject *tmp;
-
     if (unlikely(value == NULL)) {
         PyErr_SetString(PyExc_TypeError,
                "function's dictionary may not be deleted");
@@ -220,5 +222,4 @@
                "setting function's dictionary to a non-dict");
         return -1;
     }
-    tmp = op->func_dict;
     Py_INCREF(value);
@@ -224,6 +225,5 @@
     Py_INCREF(value);
-    op->func_dict = value;
-    Py_XDECREF(tmp);
+    __Pyx_Py_XDECREF_SET(op->func_dict, value);
     return 0;
 }
 
@@ -276,7 +276,6 @@
 
 static int
 __Pyx_CyFunction_set_defaults(__pyx_CyFunctionObject *op, PyObject* value, CYTHON_UNUSED void *context) {
-    PyObject* tmp;
     if (!value) {
         // del => explicit None to prevent rebuilding
         value = Py_None;
@@ -280,9 +279,9 @@
     if (!value) {
         // del => explicit None to prevent rebuilding
         value = Py_None;
-    } else if (value != Py_None && !PyTuple_Check(value)) {
+    } else if (unlikely(value != Py_None && !PyTuple_Check(value))) {
         PyErr_SetString(PyExc_TypeError,
                         "__defaults__ must be set to a tuple object");
         return -1;
     }
     Py_INCREF(value);
@@ -284,11 +283,9 @@
         PyErr_SetString(PyExc_TypeError,
                         "__defaults__ must be set to a tuple object");
         return -1;
     }
     Py_INCREF(value);
-    tmp = op->defaults_tuple;
-    op->defaults_tuple = value;
-    Py_XDECREF(tmp);
+    __Pyx_Py_XDECREF_SET(op->defaults_tuple, value);
     return 0;
 }
 
@@ -297,7 +294,7 @@
     PyObject* result = op->defaults_tuple;
     if (unlikely(!result)) {
         if (op->defaults_getter) {
-            if (__Pyx_CyFunction_init_defaults(op) < 0) return NULL;
+            if (unlikely(__Pyx_CyFunction_init_defaults(op) < 0)) return NULL;
             result = op->defaults_tuple;
         } else {
             result = Py_None;
@@ -309,7 +306,6 @@
 
 static int
 __Pyx_CyFunction_set_kwdefaults(__pyx_CyFunctionObject *op, PyObject* value, CYTHON_UNUSED void *context) {
-    PyObject* tmp;
     if (!value) {
         // del => explicit None to prevent rebuilding
         value = Py_None;
@@ -313,9 +309,9 @@
     if (!value) {
         // del => explicit None to prevent rebuilding
         value = Py_None;
-    } else if (value != Py_None && !PyDict_Check(value)) {
+    } else if (unlikely(value != Py_None && !PyDict_Check(value))) {
         PyErr_SetString(PyExc_TypeError,
                         "__kwdefaults__ must be set to a dict object");
         return -1;
     }
     Py_INCREF(value);
@@ -317,11 +313,9 @@
         PyErr_SetString(PyExc_TypeError,
                         "__kwdefaults__ must be set to a dict object");
         return -1;
     }
     Py_INCREF(value);
-    tmp = op->defaults_kwdict;
-    op->defaults_kwdict = value;
-    Py_XDECREF(tmp);
+    __Pyx_Py_XDECREF_SET(op->defaults_kwdict, value);
     return 0;
 }
 
@@ -330,7 +324,7 @@
     PyObject* result = op->defaults_kwdict;
     if (unlikely(!result)) {
         if (op->defaults_getter) {
-            if (__Pyx_CyFunction_init_defaults(op) < 0) return NULL;
+            if (unlikely(__Pyx_CyFunction_init_defaults(op) < 0)) return NULL;
             result = op->defaults_kwdict;
         } else {
             result = Py_None;
@@ -342,6 +336,5 @@
 
 static int
 __Pyx_CyFunction_set_annotations(__pyx_CyFunctionObject *op, PyObject* value, CYTHON_UNUSED void *context) {
-    PyObject* tmp;
     if (!value || value == Py_None) {
         value = NULL;
@@ -346,8 +339,8 @@
     if (!value || value == Py_None) {
         value = NULL;
-    } else if (!PyDict_Check(value)) {
+    } else if (unlikely(!PyDict_Check(value))) {
         PyErr_SetString(PyExc_TypeError,
                         "__annotations__ must be set to a dict object");
         return -1;
     }
     Py_XINCREF(value);
@@ -349,11 +342,9 @@
         PyErr_SetString(PyExc_TypeError,
                         "__annotations__ must be set to a dict object");
         return -1;
     }
     Py_XINCREF(value);
-    tmp = op->func_annotations;
-    op->func_annotations = value;
-    Py_XDECREF(tmp);
+    __Pyx_Py_XDECREF_SET(op->func_annotations, value);
     return 0;
 }
 
@@ -421,6 +412,14 @@
 
 static PyMemberDef __pyx_CyFunction_members[] = {
     {(char *) "__module__", T_OBJECT, offsetof(PyCFunctionObject, m_module), PY_WRITE_RESTRICTED, 0},
+#if CYTHON_COMPILING_IN_LIMITED_API
+    {(char *) "__dictoffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_dict), READONLY, 0},
+#if PY_VERSION_HEX < 0x030500A0
+    {(char *) "__weaklistoffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_weakreflist), READONLY, 0},
+#else
+    {(char *) "__weaklistoffset__", T_PYSSIZET, offsetof(PyCFunctionObject, m_weakreflist), READONLY, 0},
+#endif
+#endif
     {0, 0, 0,  0, 0}
 };
 
@@ -428,7 +427,8 @@
 __Pyx_CyFunction_reduce(__pyx_CyFunctionObject *m, CYTHON_UNUSED PyObject *args)
 {
 #if PY_MAJOR_VERSION >= 3
-    return PyUnicode_FromString(m->func.m_ml->ml_name);
+    Py_INCREF(m->func_qualname);
+    return m->func_qualname;
 #else
     return PyString_FromString(m->func.m_ml->ml_name);
 #endif
@@ -446,11 +446,9 @@
 #define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func.m_weakreflist)
 #endif
 
-
-static PyObject *__Pyx_CyFunction_New(PyTypeObject *type, PyMethodDef *ml, int flags, PyObject* qualname,
-                                      PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) {
-    __pyx_CyFunctionObject *op = PyObject_GC_New(__pyx_CyFunctionObject, type);
-    if (op == NULL)
+static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject *op, PyMethodDef *ml, int flags, PyObject* qualname,
+                                       PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) {
+    if (unlikely(op == NULL))
         return NULL;
     op->flags = flags;
     __Pyx_CyFunction_weakreflist(op) = NULL;
@@ -478,7 +476,27 @@
     op->defaults_kwdict = NULL;
     op->defaults_getter = NULL;
     op->func_annotations = NULL;
-    PyObject_GC_Track(op);
+#if CYTHON_METH_FASTCALL
+    switch (ml->ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | METH_KEYWORDS)) {
+    case METH_NOARGS:
+        __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_NOARGS;
+        break;
+    case METH_O:
+        __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_O;
+        break;
+    // case METH_FASTCALL is not used
+    case METH_FASTCALL | METH_KEYWORDS:
+        __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS;
+        break;
+    // case METH_VARARGS is not used
+    case METH_VARARGS | METH_KEYWORDS:
+        __Pyx_CyFunction_func_vectorcall(op) = NULL;
+        break;
+    default:
+        PyErr_SetString(PyExc_SystemError, "Bad call flags for CyFunction");
+        return NULL;
+    }
+#endif
     return (PyObject *) op;
 }
 
@@ -551,26 +569,6 @@
     return 0;
 }
 
-static PyObject *__Pyx_CyFunction_descr_get(PyObject *func, PyObject *obj, PyObject *type)
-{
-    __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func;
-
-    if (m->flags & __Pyx_CYFUNCTION_STATICMETHOD) {
-        Py_INCREF(func);
-        return func;
-    }
-
-    if (m->flags & __Pyx_CYFUNCTION_CLASSMETHOD) {
-        if (type == NULL)
-            type = (PyObject *)(Py_TYPE(obj));
-        return __Pyx_PyMethod_New(func, type, (PyObject *)(Py_TYPE(type)));
-    }
-
-    if (obj == Py_None)
-        obj = NULL;
-    return __Pyx_PyMethod_New(func, obj, type);
-}
-
 static PyObject*
 __Pyx_CyFunction_repr(__pyx_CyFunctionObject *op)
 {
@@ -630,10 +628,7 @@
         }
         break;
     default:
-        PyErr_SetString(PyExc_SystemError, "Bad call flags in "
-                        "__Pyx_CyFunction_Call. METH_OLDARGS is no "
-                        "longer supported!");
-
+        PyErr_SetString(PyExc_SystemError, "Bad call flags for CyFunction");
         return NULL;
     }
     PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments",
@@ -648,6 +643,16 @@
 static PyObject *__Pyx_CyFunction_CallAsMethod(PyObject *func, PyObject *args, PyObject *kw) {
     PyObject *result;
     __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *) func;
+
+#if CYTHON_METH_FASTCALL
+    // Prefer vectorcall if available. This is not the typical case, as
+    // CPython would normally use vectorcall directly instead of tp_call.
+     __pyx_vectorcallfunc vc = __Pyx_CyFunction_func_vectorcall(cyfunc);
+    if (vc) {
+        return __Pyx_PyVectorcall_FastCallDict(func, vc, &PyTuple_GET_ITEM(args, 0), PyTuple_GET_SIZE(args), kw);
+    }
+#endif
+
     if ((cyfunc->flags & __Pyx_CYFUNCTION_CCLASS) && !(cyfunc->flags & __Pyx_CYFUNCTION_STATICMETHOD)) {
         Py_ssize_t argc;
         PyObject *new_args;
@@ -673,9 +678,149 @@
     return result;
 }
 
+#if CYTHON_METH_FASTCALL
+// Check that kwnames is empty (if you want to allow keyword arguments,
+// simply pass kwnames=NULL) and figure out what to do with "self".
+// Return value:
+//  1: self = args[0]
+//  0: self = cyfunc->func.m_self
+// -1: error
+static CYTHON_INLINE int __Pyx_CyFunction_Vectorcall_CheckArgs(__pyx_CyFunctionObject *cyfunc, Py_ssize_t nargs, PyObject *kwnames)
+{
+    int ret = 0;
+    if ((cyfunc->flags & __Pyx_CYFUNCTION_CCLASS) && !(cyfunc->flags & __Pyx_CYFUNCTION_STATICMETHOD)) {
+        if (unlikely(nargs < 1)) {
+            PyErr_Format(PyExc_TypeError, "%.200s() needs an argument",
+                         cyfunc->func.m_ml->ml_name);
+            return -1;
+        }
+        ret = 1;
+    }
+    if (unlikely(kwnames) && unlikely(PyTuple_GET_SIZE(kwnames))) {
+        PyErr_Format(PyExc_TypeError,
+                     "%.200s() takes no keyword arguments", cyfunc->func.m_ml->ml_name);
+        return -1;
+    }
+    return ret;
+}
+
+static PyObject * __Pyx_CyFunction_Vectorcall_NOARGS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
+{
+    __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func;
+    PyMethodDef* def = cyfunc->func.m_ml;
+#if CYTHON_BACKPORT_VECTORCALL
+    Py_ssize_t nargs = (Py_ssize_t)nargsf;
+#else
+    Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
+#endif
+    PyObject *self;
+    switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, kwnames)) {
+    case 1:
+        self = args[0];
+        args += 1;
+        nargs -= 1;
+        break;
+    case 0:
+        self = cyfunc->func.m_self;
+        break;
+    default:
+        return NULL;
+    }
+
+    if (unlikely(nargs != 0)) {
+        PyErr_Format(PyExc_TypeError,
+            "%.200s() takes no arguments (%" CYTHON_FORMAT_SSIZE_T "d given)",
+            def->ml_name, nargs);
+        return NULL;
+    }
+    return def->ml_meth(self, NULL);
+}
+
+static PyObject * __Pyx_CyFunction_Vectorcall_O(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
+{
+    __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func;
+    PyMethodDef* def = cyfunc->func.m_ml;
+#if CYTHON_BACKPORT_VECTORCALL
+    Py_ssize_t nargs = (Py_ssize_t)nargsf;
+#else
+    Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
+#endif
+    PyObject *self;
+    switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, kwnames)) {
+    case 1:
+        self = args[0];
+        args += 1;
+        nargs -= 1;
+        break;
+    case 0:
+        self = cyfunc->func.m_self;
+        break;
+    default:
+        return NULL;
+    }
+
+    if (unlikely(nargs != 1)) {
+        PyErr_Format(PyExc_TypeError,
+            "%.200s() takes exactly one argument (%" CYTHON_FORMAT_SSIZE_T "d given)",
+            def->ml_name, nargs);
+        return NULL;
+    }
+    return def->ml_meth(self, args[0]);
+}
+
+static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
+{
+    __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func;
+    PyMethodDef* def = cyfunc->func.m_ml;
+#if CYTHON_BACKPORT_VECTORCALL
+    Py_ssize_t nargs = (Py_ssize_t)nargsf;
+#else
+    Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
+#endif
+    PyObject *self;
+    switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, NULL)) {
+    case 1:
+        self = args[0];
+        args += 1;
+        nargs -= 1;
+        break;
+    case 0:
+        self = cyfunc->func.m_self;
+        break;
+    default:
+        return NULL;
+    }
+
+    return ((_PyCFunctionFastWithKeywords)(void(*)(void))def->ml_meth)(self, args, nargs, kwnames);
+}
+#endif
+
+#if CYTHON_COMPILING_IN_LIMITED_API
+static PyType_Slot __pyx_CyFunctionType_slots[] = {
+    {Py_tp_dealloc, (void *)__Pyx_CyFunction_dealloc},
+    {Py_tp_repr, (void *)__Pyx_CyFunction_repr},
+    {Py_tp_call, (void *)__Pyx_CyFunction_CallAsMethod},
+    {Py_tp_traverse, (void *)__Pyx_CyFunction_traverse},
+    {Py_tp_clear, (void *)__Pyx_CyFunction_clear},
+    {Py_tp_methods, (void *)__pyx_CyFunction_methods},
+    {Py_tp_members, (void *)__pyx_CyFunction_members},
+    {Py_tp_getset, (void *)__pyx_CyFunction_getsets},
+    {Py_tp_descr_get, (void *)__Pyx_PyMethod_New},
+    {0, 0},
+};
+
+static PyType_Spec __pyx_CyFunctionType_spec = {
+    "cython_function_or_method",
+    sizeof(__pyx_CyFunctionObject),
+    0,
+    // TODO: Support _Py_TPFLAGS_HAVE_VECTORCALL and _Py_TPFLAGS_HAVE_VECTORCALL
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+    __pyx_CyFunctionType_slots
+};
+#else
 static PyTypeObject __pyx_CyFunctionType_type = {
     PyVarObject_HEAD_INIT(0, 0)
     "cython_function_or_method",      /*tp_name*/
     sizeof(__pyx_CyFunctionObject),   /*tp_basicsize*/
     0,                                  /*tp_itemsize*/
     (destructor) __Pyx_CyFunction_dealloc, /*tp_dealloc*/
@@ -676,7 +821,8 @@
 static PyTypeObject __pyx_CyFunctionType_type = {
     PyVarObject_HEAD_INIT(0, 0)
     "cython_function_or_method",      /*tp_name*/
     sizeof(__pyx_CyFunctionObject),   /*tp_basicsize*/
     0,                                  /*tp_itemsize*/
     (destructor) __Pyx_CyFunction_dealloc, /*tp_dealloc*/
+#if !CYTHON_METH_FASTCALL
     0,                                  /*tp_print*/
@@ -682,6 +828,11 @@
     0,                                  /*tp_print*/
+#elif CYTHON_BACKPORT_VECTORCALL
+    (printfunc)offsetof(__pyx_CyFunctionObject, func_vectorcall), /*tp_vectorcall_offset backported into tp_print*/
+#else
+    offsetof(__pyx_CyFunctionObject, func.vectorcall), /*tp_vectorcall_offset*/
+#endif
     0,                                  /*tp_getattr*/
     0,                                  /*tp_setattr*/
 #if PY_MAJOR_VERSION < 3
     0,                                  /*tp_compare*/
 #else
@@ -683,9 +834,9 @@
     0,                                  /*tp_getattr*/
     0,                                  /*tp_setattr*/
 #if PY_MAJOR_VERSION < 3
     0,                                  /*tp_compare*/
 #else
-    0,                                  /*reserved*/
+    0,                                  /*tp_as_async*/
 #endif
     (reprfunc) __Pyx_CyFunction_repr,   /*tp_repr*/
     0,                                  /*tp_as_number*/
@@ -697,6 +848,12 @@
     0,                                  /*tp_getattro*/
     0,                                  /*tp_setattro*/
     0,                                  /*tp_as_buffer*/
+#ifdef Py_TPFLAGS_METHOD_DESCRIPTOR
+    Py_TPFLAGS_METHOD_DESCRIPTOR |
+#endif
+#ifdef _Py_TPFLAGS_HAVE_VECTORCALL
+    _Py_TPFLAGS_HAVE_VECTORCALL |
+#endif
     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
     0,                                  /*tp_doc*/
     (traverseproc) __Pyx_CyFunction_traverse,   /*tp_traverse*/
@@ -714,7 +871,7 @@
     __pyx_CyFunction_getsets,           /*tp_getset*/
     0,                                  /*tp_base*/
     0,                                  /*tp_dict*/
-    __Pyx_CyFunction_descr_get,         /*tp_descr_get*/
+    __Pyx_PyMethod_New,                 /*tp_descr_get*/
     0,                                  /*tp_descr_set*/
     offsetof(__pyx_CyFunctionObject, func_dict),/*tp_dictoffset*/
     0,                                  /*tp_init*/
@@ -738,4 +895,7 @@
 #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
     0,                                  /*tp_print*/
 #endif
+#if CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM+0 >= 0x06000000
+    0,                                          /*tp_pypy_flags*/
+#endif
 };
@@ -741,4 +901,5 @@
 };
+#endif  /* CYTHON_COMPILING_IN_LIMITED_API */
 
 
 static int __pyx_CyFunction_init(void) {
@@ -742,4 +903,7 @@
 
 
 static int __pyx_CyFunction_init(void) {
+#if CYTHON_COMPILING_IN_LIMITED_API
+    __pyx_CyFunctionType = __Pyx_FetchCommonTypeFromSpec(&__pyx_CyFunctionType_spec, NULL);
+#else
     __pyx_CyFunctionType = __Pyx_FetchCommonType(&__pyx_CyFunctionType_type);
@@ -745,4 +909,5 @@
     __pyx_CyFunctionType = __Pyx_FetchCommonType(&__pyx_CyFunctionType_type);
+#endif
     if (unlikely(__pyx_CyFunctionType == NULL)) {
         return -1;
     }
@@ -779,7 +944,32 @@
     Py_INCREF(dict);
 }
 
+
+//////////////////// CythonFunction.proto ////////////////////
+
+static PyObject *__Pyx_CyFunction_New(PyMethodDef *ml,
+                                      int flags, PyObject* qualname,
+                                      PyObject *closure,
+                                      PyObject *module, PyObject *globals,
+                                      PyObject* code);
+
+//////////////////// CythonFunction ////////////////////
+//@requires: CythonFunctionShared
+
+static PyObject *__Pyx_CyFunction_New(PyMethodDef *ml, int flags, PyObject* qualname,
+                                      PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) {
+    PyObject *op = __Pyx_CyFunction_Init(
+        PyObject_GC_New(__pyx_CyFunctionObject, __pyx_CyFunctionType),
+        ml, flags, qualname, closure, module, globals, code
+    );
+    if (likely(op)) {
+        PyObject_GC_Track(op);
+    }
+    return op;
+}
+
+
 //////////////////// CyFunctionClassCell.proto ////////////////////
 static int __Pyx_CyFunction_InitClassCell(PyObject *cyfunctions, PyObject *classobj);/*proto*/
 
 //////////////////// CyFunctionClassCell ////////////////////
@@ -782,8 +972,8 @@
 //////////////////// CyFunctionClassCell.proto ////////////////////
 static int __Pyx_CyFunction_InitClassCell(PyObject *cyfunctions, PyObject *classobj);/*proto*/
 
 //////////////////// CyFunctionClassCell ////////////////////
-//@requires: CythonFunction
+//@requires: CythonFunctionShared
 
 static int __Pyx_CyFunction_InitClassCell(PyObject *cyfunctions, PyObject *classobj) {
     Py_ssize_t i, count = PyList_GET_SIZE(cyfunctions);
@@ -806,4 +996,5 @@
     return 0;
 }
 
+
 //////////////////// FusedFunction.proto ////////////////////
@@ -809,4 +1000,5 @@
 //////////////////// FusedFunction.proto ////////////////////
+
 typedef struct {
     __pyx_CyFunctionObject func;
     PyObject *__signatures__;
@@ -810,7 +1002,6 @@
 typedef struct {
     __pyx_CyFunctionObject func;
     PyObject *__signatures__;
-    PyObject *type;
     PyObject *self;
 } __pyx_FusedFunctionObject;
 
@@ -814,12 +1005,9 @@
     PyObject *self;
 } __pyx_FusedFunctionObject;
 
-#define __pyx_FusedFunction_NewEx(ml, flags, qualname, self, module, globals, code)         \
-        __pyx_FusedFunction_New(__pyx_FusedFunctionType, ml, flags, qualname, self, module, globals, code)
-static PyObject *__pyx_FusedFunction_New(PyTypeObject *type,
-                                         PyMethodDef *ml, int flags,
-                                         PyObject *qualname, PyObject *self,
+static PyObject *__pyx_FusedFunction_New(PyMethodDef *ml, int flags,
+                                         PyObject *qualname, PyObject *closure,
                                          PyObject *module, PyObject *globals,
                                          PyObject *code);
 
 static int __pyx_FusedFunction_clear(__pyx_FusedFunctionObject *self);
@@ -822,5 +1010,6 @@
                                          PyObject *module, PyObject *globals,
                                          PyObject *code);
 
 static int __pyx_FusedFunction_clear(__pyx_FusedFunctionObject *self);
+#if !CYTHON_COMPILING_IN_LIMITED_API
 static PyTypeObject *__pyx_FusedFunctionType = NULL;
@@ -826,6 +1015,7 @@
 static PyTypeObject *__pyx_FusedFunctionType = NULL;
+#endif
 static int __pyx_FusedFunction_init(void);
 
 #define __Pyx_FusedFunction_USED
 
 //////////////////// FusedFunction ////////////////////
@@ -827,8 +1017,8 @@
 static int __pyx_FusedFunction_init(void);
 
 #define __Pyx_FusedFunction_USED
 
 //////////////////// FusedFunction ////////////////////
-//@requires: CythonFunction
+//@requires: CythonFunctionShared
 
 static PyObject *
@@ -833,7 +1023,7 @@
 
 static PyObject *
-__pyx_FusedFunction_New(PyTypeObject *type, PyMethodDef *ml, int flags,
-                        PyObject *qualname, PyObject *self,
+__pyx_FusedFunction_New(PyMethodDef *ml, int flags,
+                        PyObject *qualname, PyObject *closure,
                         PyObject *module, PyObject *globals,
                         PyObject *code)
 {
@@ -837,16 +1027,18 @@
                         PyObject *module, PyObject *globals,
                         PyObject *code)
 {
-    __pyx_FusedFunctionObject *fusedfunc =
-        (__pyx_FusedFunctionObject *) __Pyx_CyFunction_New(type, ml, flags, qualname,
-                                                           self, module, globals, code);
-    if (!fusedfunc)
-        return NULL;
-
-    fusedfunc->__signatures__ = NULL;
-    fusedfunc->type = NULL;
-    fusedfunc->self = NULL;
-    return (PyObject *) fusedfunc;
+    PyObject *op = __Pyx_CyFunction_Init(
+        // __pyx_CyFunctionObject is correct below since that's the cast that we want.
+        PyObject_GC_New(__pyx_CyFunctionObject, __pyx_FusedFunctionType),
+        ml, flags, qualname, closure, module, globals, code
+    );
+    if (likely(op)) {
+        __pyx_FusedFunctionObject *fusedfunc = (__pyx_FusedFunctionObject *) op;
+        fusedfunc->__signatures__ = NULL;
+        fusedfunc->self = NULL;
+        PyObject_GC_Track(op);
+    }
+    return op;
 }
 
 static void
@@ -854,7 +1046,6 @@
 {
     PyObject_GC_UnTrack(self);
     Py_CLEAR(self->self);
-    Py_CLEAR(self->type);
     Py_CLEAR(self->__signatures__);
     __Pyx__CyFunction_dealloc((__pyx_CyFunctionObject *) self);
 }
@@ -865,7 +1056,6 @@
                              void *arg)
 {
     Py_VISIT(self->self);
-    Py_VISIT(self->type);
     Py_VISIT(self->__signatures__);
     return __Pyx_CyFunction_traverse((__pyx_CyFunctionObject *) self, visit, arg);
 }
@@ -874,7 +1064,6 @@
 __pyx_FusedFunction_clear(__pyx_FusedFunctionObject *self)
 {
     Py_CLEAR(self->self);
-    Py_CLEAR(self->type);
     Py_CLEAR(self->__signatures__);
     return __Pyx_CyFunction_clear((__pyx_CyFunctionObject *) self);
 }
@@ -896,7 +1085,7 @@
     if (obj == Py_None)
         obj = NULL;
 
-    meth = (__pyx_FusedFunctionObject *) __pyx_FusedFunction_NewEx(
+    meth = (__pyx_FusedFunctionObject *) __pyx_FusedFunction_New(
                     ((PyCFunctionObject *) func)->m_ml,
                     ((__pyx_CyFunctionObject *) func)->flags,
                     ((__pyx_CyFunctionObject *) func)->func_qualname,
@@ -904,7 +1093,7 @@
                     ((PyCFunctionObject *) func)->m_module,
                     ((__pyx_CyFunctionObject *) func)->func_globals,
                     ((__pyx_CyFunctionObject *) func)->func_code);
-    if (!meth)
+    if (unlikely(!meth))
         return NULL;
 
     // defaults needs copying fully rather than just copying the pointer
@@ -914,9 +1103,10 @@
         PyObject **pydefaults;
         int i;
 
-        if (!__Pyx_CyFunction_InitDefaults((PyObject*)meth,
-                                      func->func.defaults_size,
-                                      func->func.defaults_pyobjects)) {
+        if (unlikely(!__Pyx_CyFunction_InitDefaults(
+                (PyObject*)meth,
+                func->func.defaults_size,
+                func->func.defaults_pyobjects))) {
             Py_XDECREF((PyObject*)meth);
             return NULL;
         }
@@ -933,9 +1123,6 @@
     Py_XINCREF(func->__signatures__);
     meth->__signatures__ = func->__signatures__;
 
-    Py_XINCREF(type);
-    meth->type = type;
-
     Py_XINCREF(func->func.defaults_tuple);
     meth->func.defaults_tuple = func->func.defaults_tuple;
 
@@ -949,5 +1136,5 @@
 }
 
 static PyObject *
-_obj_to_str(PyObject *obj)
+_obj_to_string(PyObject *obj)
 {
@@ -953,4 +1140,10 @@
 {
-    if (PyType_Check(obj))
+    if (PyUnicode_CheckExact(obj))
+        return __Pyx_NewRef(obj);
+#if PY_MAJOR_VERSION == 2
+    else if (PyString_Check(obj))
+        return PyUnicode_FromEncodedObject(obj, NULL, "strict");
+#endif
+    else if (PyType_Check(obj))
         return PyObject_GetAttr(obj, PYIDENT("__name__"));
     else
@@ -955,6 +1148,6 @@
         return PyObject_GetAttr(obj, PYIDENT("__name__"));
     else
-        return PyObject_Str(obj);
+        return PyObject_Unicode(obj);
 }
 
 static PyObject *
@@ -964,9 +1157,9 @@
     PyObject *unbound_result_func;
     PyObject *result_func = NULL;
 
-    if (self->__signatures__ == NULL) {
+    if (unlikely(self->__signatures__ == NULL)) {
         PyErr_SetString(PyExc_TypeError, "Function is not fused");
         return NULL;
     }
 
     if (PyTuple_Check(idx)) {
@@ -968,7 +1161,6 @@
         PyErr_SetString(PyExc_TypeError, "Function is not fused");
         return NULL;
     }
 
     if (PyTuple_Check(idx)) {
-        PyObject *list = PyList_New(0);
         Py_ssize_t n = PyTuple_GET_SIZE(idx);
@@ -974,5 +1166,4 @@
         Py_ssize_t n = PyTuple_GET_SIZE(idx);
-        PyObject *string = NULL;
-        PyObject *sep = NULL;
+        PyObject *list = PyList_New(n);
         int i;
 
@@ -977,6 +1168,6 @@
         int i;
 
-        if (!list)
+        if (unlikely(!list))
             return NULL;
 
         for (i = 0; i < n; i++) {
@@ -980,6 +1171,7 @@
             return NULL;
 
         for (i = 0; i < n; i++) {
+            PyObject *string;
 #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
             PyObject *item = PyTuple_GET_ITEM(idx, i);
 #else
@@ -983,5 +1175,5 @@
 #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
             PyObject *item = PyTuple_GET_ITEM(idx, i);
 #else
-            PyObject *item = PySequence_ITEM(idx, i);
+            PyObject *item = PySequence_ITEM(idx, i);  if (unlikely(!item)) goto __pyx_err;
 #endif
@@ -987,5 +1179,5 @@
 #endif
-            string = _obj_to_str(item);
+            string = _obj_to_string(item);
 #if !(CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS)
             Py_DECREF(item);
 #endif
@@ -989,9 +1181,7 @@
 #if !(CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS)
             Py_DECREF(item);
 #endif
-            if (!string || PyList_Append(list, string) < 0)
-                goto __pyx_err;
-
-            Py_DECREF(string);
+            if (unlikely(!string)) goto __pyx_err;
+            PyList_SET_ITEM(list, i, string);
         }
 
@@ -996,8 +1186,5 @@
         }
 
-        sep = PyUnicode_FromString("|");
-        if (sep)
-            signature = PyUnicode_Join(sep, list);
-__pyx_err:
-;
+        signature = PyUnicode_Join(PYUNICODE("|"), list);
+__pyx_err:;
         Py_DECREF(list);
@@ -1003,3 +1190,2 @@
         Py_DECREF(list);
-        Py_XDECREF(sep);
     } else {
@@ -1005,4 +1191,4 @@
     } else {
-        signature = _obj_to_str(idx);
+        signature = _obj_to_string(idx);
     }
 
@@ -1007,7 +1193,7 @@
     }
 
-    if (!signature)
+    if (unlikely(!signature))
         return NULL;
 
     unbound_result_func = PyObject_GetItem(self->__signatures__, signature);
 
@@ -1010,9 +1196,9 @@
         return NULL;
 
     unbound_result_func = PyObject_GetItem(self->__signatures__, signature);
 
-    if (unbound_result_func) {
-        if (self->self || self->type) {
+    if (likely(unbound_result_func)) {
+        if (self->self) {
             __pyx_FusedFunctionObject *unbound = (__pyx_FusedFunctionObject *) unbound_result_func;
 
             // TODO: move this to InitClassCell
@@ -1016,5 +1202,4 @@
             __pyx_FusedFunctionObject *unbound = (__pyx_FusedFunctionObject *) unbound_result_func;
 
             // TODO: move this to InitClassCell
-            Py_CLEAR(unbound->func.func_classobj);
             Py_XINCREF(self->func.func_classobj);
@@ -1020,4 +1205,4 @@
             Py_XINCREF(self->func.func_classobj);
-            unbound->func.func_classobj = self->func.func_classobj;
+            __Pyx_Py_XDECREF_SET(unbound->func.func_classobj, self->func.func_classobj);
 
             result_func = __pyx_FusedFunction_descr_get(unbound_result_func,
@@ -1022,6 +1207,6 @@
 
             result_func = __pyx_FusedFunction_descr_get(unbound_result_func,
-                                                        self->self, self->type);
+                                                        self->self, self->self);
         } else {
             result_func = unbound_result_func;
             Py_INCREF(result_func);
@@ -1062,5 +1247,4 @@
     PyObject *new_args = NULL;
     __pyx_FusedFunctionObject *new_func = NULL;
     PyObject *result = NULL;
-    PyObject *self = NULL;
     int is_staticmethod = binding_func->func.flags & __Pyx_CYFUNCTION_STATICMETHOD;
@@ -1066,5 +1250,4 @@
     int is_staticmethod = binding_func->func.flags & __Pyx_CYFUNCTION_STATICMETHOD;
-    int is_classmethod = binding_func->func.flags & __Pyx_CYFUNCTION_CLASSMETHOD;
 
     if (binding_func->self) {
         // Bound method call, put 'self' in the args tuple
@@ -1068,5 +1251,6 @@
 
     if (binding_func->self) {
         // Bound method call, put 'self' in the args tuple
+        PyObject *self;
         Py_ssize_t i;
         new_args = PyTuple_New(argc + 1);
@@ -1071,6 +1255,6 @@
         Py_ssize_t i;
         new_args = PyTuple_New(argc + 1);
-        if (!new_args)
+        if (unlikely(!new_args))
             return NULL;
 
         self = binding_func->self;
@@ -1074,8 +1258,6 @@
             return NULL;
 
         self = binding_func->self;
-#if !(CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS)
-        Py_INCREF(self);
-#endif
+
         Py_INCREF(self);
         PyTuple_SET_ITEM(new_args, 0, self);
@@ -1080,5 +1262,6 @@
         Py_INCREF(self);
         PyTuple_SET_ITEM(new_args, 0, self);
+        self = NULL;
 
         for (i = 0; i < argc; i++) {
 #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
@@ -1091,16 +1274,5 @@
         }
 
         args = new_args;
-    } else if (binding_func->type) {
-        // Unbound method call
-        if (argc < 1) {
-            PyErr_SetString(PyExc_TypeError, "Need at least one argument, 0 given.");
-            return NULL;
-        }
-#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
-        self = PyTuple_GET_ITEM(args, 0);
-#else
-        self = PySequence_ITEM(args, 0);  if (unlikely(!self)) return NULL;
-#endif
     }
 
@@ -1105,22 +1277,5 @@
     }
 
-    if (self && !is_classmethod && !is_staticmethod) {
-        int is_instance = PyObject_IsInstance(self, binding_func->type);
-        if (unlikely(!is_instance)) {
-            PyErr_Format(PyExc_TypeError,
-                         "First argument should be of type %.200s, got %.200s.",
-                         ((PyTypeObject *) binding_func->type)->tp_name,
-                         self->ob_type->tp_name);
-            goto bad;
-        } else if (unlikely(is_instance == -1)) {
-            goto bad;
-        }
-    }
-#if !(CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS)
-    Py_XDECREF(self);
-    self = NULL;
-#endif
-
     if (binding_func->__signatures__) {
         PyObject *tup;
         if (is_staticmethod && binding_func->func.flags & __Pyx_CYFUNCTION_CCLASS) {
@@ -1144,11 +1299,10 @@
             goto bad;
 
         Py_XINCREF(binding_func->func.func_classobj);
-        Py_CLEAR(new_func->func.func_classobj);
-        new_func->func.func_classobj = binding_func->func.func_classobj;
+        __Pyx_Py_XDECREF_SET(new_func->func.func_classobj, binding_func->func.func_classobj);
 
         func = (PyObject *) new_func;
     }
 
     result = __pyx_FusedFunction_callfunction(func, args, kw);
 bad:
@@ -1149,12 +1303,9 @@
 
         func = (PyObject *) new_func;
     }
 
     result = __pyx_FusedFunction_callfunction(func, args, kw);
 bad:
-#if !(CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS)
-    Py_XDECREF(self);
-#endif
     Py_XDECREF(new_args);
     Py_XDECREF((PyObject *) new_func);
     return result;
@@ -1169,6 +1320,29 @@
     {0, 0, 0, 0, 0},
 };
 
+#if CYTHON_COMPILING_IN_LIMITED_API
+static PyType_Slot __pyx_FusedFunctionType_slots[] = {
+    {Py_tp_dealloc, (void *)__pyx_FusedFunction_dealloc},
+    {Py_tp_call, (void *)__pyx_FusedFunction_call},
+    {Py_tp_traverse, (void *)__pyx_FusedFunction_traverse},
+    {Py_tp_clear, (void *)__pyx_FusedFunction_clear},
+    {Py_tp_members, (void *)__pyx_FusedFunction_members},
+    {Py_tp_getset, (void *)__pyx_CyFunction_getsets},
+    {Py_tp_descr_get, (void *)__pyx_FusedFunction_descr_get},
+    {Py_mp_subscript, (void *)__pyx_FusedFunction_getitem},
+    {0, 0},
+};
+
+static PyType_Spec __pyx_FusedFunctionType_spec = {
+    "fused_cython_function",
+    sizeof(__pyx_FusedFunctionObject),
+    0,
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    __pyx_FusedFunctionType_slots
+};
+
+#else  /* !CYTHON_COMPILING_IN_LIMITED_API */
+
 static PyMappingMethods __pyx_FusedFunction_mapping_methods = {
     0,
     (binaryfunc) __pyx_FusedFunction_getitem,
@@ -1187,7 +1361,7 @@
 #if PY_MAJOR_VERSION < 3
     0,                                  /*tp_compare*/
 #else
-    0,                                  /*reserved*/
+    0,                                  /*tp_as_async*/
 #endif
     0,                                  /*tp_repr*/
     0,                                  /*tp_as_number*/
@@ -1239,4 +1413,7 @@
 #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
     0,                                  /*tp_print*/
 #endif
+#if CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM+0 >= 0x06000000
+    0,                                          /*tp_pypy_flags*/
+#endif
 };
@@ -1242,3 +1419,4 @@
 };
+#endif
 
 static int __pyx_FusedFunction_init(void) {
@@ -1243,5 +1421,13 @@
 
 static int __pyx_FusedFunction_init(void) {
+#if CYTHON_COMPILING_IN_LIMITED_API
+    PyObject *bases = PyTuple_Pack(1, __pyx_CyFunctionType);
+    if (unlikely(!bases)) {
+        return -1;
+    }
+    __pyx_FusedFunctionType = __Pyx_FetchCommonTypeFromSpec(&__pyx_FusedFunctionType_spec, bases);
+    Py_DECREF(bases);
+#else
     // Set base from __Pyx_FetchCommonTypeFromSpec, in case it's different from the local static value.
     __pyx_FusedFunctionType_type.tp_base = __pyx_CyFunctionType;
     __pyx_FusedFunctionType = __Pyx_FetchCommonType(&__pyx_FusedFunctionType_type);
@@ -1245,7 +1431,8 @@
     // Set base from __Pyx_FetchCommonTypeFromSpec, in case it's different from the local static value.
     __pyx_FusedFunctionType_type.tp_base = __pyx_CyFunctionType;
     __pyx_FusedFunctionType = __Pyx_FetchCommonType(&__pyx_FusedFunctionType_type);
-    if (__pyx_FusedFunctionType == NULL) {
+#endif
+    if (unlikely(__pyx_FusedFunctionType == NULL)) {
         return -1;
     }
     return 0;
@@ -1271,5 +1458,5 @@
 #else
     // It appears that PyMethodDescr_Type is not exposed anywhere in the CPython C-API
     static PyTypeObject *methoddescr_type = NULL;
-    if (methoddescr_type == NULL) {
+    if (unlikely(methoddescr_type == NULL)) {
        PyObject *meth = PyObject_GetAttrString((PyObject*)&PyList_Type, "append");
@@ -1275,5 +1462,5 @@
        PyObject *meth = PyObject_GetAttrString((PyObject*)&PyList_Type, "append");
-       if (!meth) return NULL;
+       if (unlikely(!meth)) return NULL;
        methoddescr_type = Py_TYPE(meth);
        Py_DECREF(meth);
     }
diff --git a/Cython/Utility/Embed.c b/Cython/Utility/Embed.c
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1V0aWxpdHkvRW1iZWQuYw==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1V0aWxpdHkvRW1iZWQuYw== 100644
--- a/Cython/Utility/Embed.c
+++ b/Cython/Utility/Embed.c
@@ -11,6 +11,8 @@
 #else
 static int __Pyx_main(int argc, wchar_t **argv) {
 #endif
+    wchar_t *program = NULL;
+
     /* 754 requires that FP exceptions run in "no stop" mode by default,
      * and until C vendors implement C99's ways to control FP exceptions,
      * Python requires non-stop mode.  Alas, some platforms enable FP
@@ -66,6 +68,8 @@
 #if PY_MAJOR_VERSION >= 3 && !defined(WIN32) && !defined(MS_WINDOWS)
 #include <locale.h>
 
+#if PY_VERSION_HEX < 0x03050000
+
 static wchar_t*
 __Pyx_char2wchar(char* arg)
 {
@@ -170,6 +174,8 @@
     return NULL;
 }
 
+#endif
+
 int
 %(main_method)s(int argc, char **argv)
 {
@@ -192,7 +198,12 @@
         res = 0;
         setlocale(LC_ALL, "");
         for (i = 0; i < argc; i++) {
-            argv_copy2[i] = argv_copy[i] = __Pyx_char2wchar(argv[i]);
+            argv_copy2[i] = argv_copy[i] =
+#if PY_VERSION_HEX < 0x03050000
+                __Pyx_char2wchar(argv[i]);
+#else
+                Py_DecodeLocale(argv[i], NULL);
+#endif
             if (!argv_copy[i]) res = 1;  /* failure, but continue to simplify cleanup */
         }
         setlocale(LC_ALL, oldloc);
diff --git a/Cython/Utility/Exceptions.c b/Cython/Utility/Exceptions.c
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1V0aWxpdHkvRXhjZXB0aW9ucy5j..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1V0aWxpdHkvRXhjZXB0aW9ucy5j 100644
--- a/Cython/Utility/Exceptions.c
+++ b/Cython/Utility/Exceptions.c
@@ -284,7 +284,7 @@
     PyErr_SetObject(type, value);
 
     if (tb) {
-#if CYTHON_COMPILING_IN_PYPY
+#if CYTHON_COMPILING_IN_PYPY ||  CYTHON_COMPILING_IN_LIMITED_API
         PyObject *tmp_type, *tmp_value, *tmp_tb;
         PyErr_Fetch(&tmp_type, &tmp_value, &tmp_tb);
         Py_INCREF(tb);
@@ -641,7 +641,7 @@
 #endif
 
 /////////////// CLineInTraceback ///////////////
-//@requires: ObjectHandling.c::PyObjectGetAttrStr
+//@requires: ObjectHandling.c::PyObjectGetAttrStrNoError
 //@requires: ObjectHandling.c::PyDictVersioning
 //@requires: PyErrFetchRestore
 //@substitute: naming
@@ -670,7 +670,7 @@
     } else
 #endif
     {
-      PyObject *use_cline_obj = __Pyx_PyObject_GetAttrStr(${cython_runtime_cname}, PYIDENT("cline_in_traceback"));
+      PyObject *use_cline_obj = __Pyx_PyObject_GetAttrStrNoError(${cython_runtime_cname}, PYIDENT("cline_in_traceback"));
       if (use_cline_obj) {
         use_cline = PyObject_Not(use_cline_obj) ? Py_False : Py_True;
         Py_DECREF(use_cline_obj);
@@ -705,6 +705,17 @@
 #include "frameobject.h"
 #include "traceback.h"
 
+#if CYTHON_COMPILING_IN_LIMITED_API
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename) {
+    if (c_line) {
+        // Avoid "unused" warning as long as we don't use this.
+        (void) $cfilenm_cname;
+        c_line = __Pyx_CLineForTraceback(__Pyx_PyThreadState_Current, c_line);
+    }
+    _PyTraceback_Add(funcname, filename, c_line ? -c_line : py_line);
+}
+#else
 static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
             const char *funcname, int c_line,
             int py_line, const char *filename) {
@@ -735,6 +746,7 @@
     if (!py_funcname) goto bad;
     py_code = __Pyx_PyCode_New(
         0,            /*int argcount,*/
+        0,            /*int posonlyargcount,*/
         0,            /*int kwonlyargcount,*/
         0,            /*int nlocals,*/
         0,            /*int stacksize,*/
@@ -790,3 +802,4 @@
     Py_XDECREF(py_code);
     Py_XDECREF(py_frame);
 }
+#endif
diff --git a/Cython/Utility/ExtensionTypes.c b/Cython/Utility/ExtensionTypes.c
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1V0aWxpdHkvRXh0ZW5zaW9uVHlwZXMuYw==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1V0aWxpdHkvRXh0ZW5zaW9uVHlwZXMuYw== 100644
--- a/Cython/Utility/ExtensionTypes.c
+++ b/Cython/Utility/ExtensionTypes.c
@@ -74,6 +74,49 @@
     return r;
 }
 
+/////////////// PyTrashcan.proto ///////////////
+
+// These macros are taken from https://github.com/python/cpython/pull/11841
+// Unlike the Py_TRASHCAN_SAFE_BEGIN/Py_TRASHCAN_SAFE_END macros, they
+// allow dealing correctly with subclasses.
+
+// This requires CPython version >= 2.7.4
+// (or >= 3.2.4 but we don't support such old Python 3 versions anyway)
+#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x02070400
+#define __Pyx_TRASHCAN_BEGIN_CONDITION(op, cond) \
+    do { \
+        PyThreadState *_tstate = NULL; \
+        // If "cond" is false, then _tstate remains NULL and the deallocator
+        // is run normally without involving the trashcan
+        if (cond) { \
+            _tstate = PyThreadState_GET(); \
+            if (_tstate->trash_delete_nesting >= PyTrash_UNWIND_LEVEL) { \
+                // Store the object (to be deallocated later) and jump past
+                // Py_TRASHCAN_END, skipping the body of the deallocator
+                _PyTrash_thread_deposit_object((PyObject*)(op)); \
+                break; \
+            } \
+            ++_tstate->trash_delete_nesting; \
+        }
+        // The body of the deallocator is here.
+#define __Pyx_TRASHCAN_END \
+        if (_tstate) { \
+            --_tstate->trash_delete_nesting; \
+            if (_tstate->trash_delete_later && _tstate->trash_delete_nesting <= 0) \
+                _PyTrash_thread_destroy_chain(); \
+        } \
+    } while (0);
+
+#define __Pyx_TRASHCAN_BEGIN(op, dealloc) __Pyx_TRASHCAN_BEGIN_CONDITION(op, \
+        Py_TYPE(op)->tp_dealloc == (destructor)(dealloc))
+
+#else
+// The trashcan is a no-op on other Python implementations
+// or old CPython versions
+#define __Pyx_TRASHCAN_BEGIN(op, dealloc)
+#define __Pyx_TRASHCAN_END
+#endif
+
 /////////////// CallNextTpDealloc.proto ///////////////
 
 static void __Pyx_call_next_tp_dealloc(PyObject* obj, destructor current_tp_dealloc);
@@ -129,4 +172,5 @@
 
 /////////////// SetupReduce.proto ///////////////
 
+#if !CYTHON_COMPILING_IN_LIMITED_API
 static int __Pyx_setup_reduce(PyObject* type_obj);
@@ -132,3 +176,4 @@
 static int __Pyx_setup_reduce(PyObject* type_obj);
+#endif
 
 /////////////// SetupReduce ///////////////
@@ -133,5 +178,6 @@
 
 /////////////// SetupReduce ///////////////
+//@requires: ObjectHandling.c::PyObjectGetAttrStrNoError
 //@requires: ObjectHandling.c::PyObjectGetAttrStr
 //@substitute: naming
 
@@ -135,7 +181,8 @@
 //@requires: ObjectHandling.c::PyObjectGetAttrStr
 //@substitute: naming
 
+#if !CYTHON_COMPILING_IN_LIMITED_API
 static int __Pyx_setup_reduce_is_named(PyObject* meth, PyObject* name) {
   int ret;
   PyObject *name_attr;
 
@@ -138,8 +185,8 @@
 static int __Pyx_setup_reduce_is_named(PyObject* meth, PyObject* name) {
   int ret;
   PyObject *name_attr;
 
-  name_attr = __Pyx_PyObject_GetAttrStr(meth, PYIDENT("__name__"));
+  name_attr = __Pyx_PyObject_GetAttrStrNoError(meth, PYIDENT("__name__"));
   if (likely(name_attr)) {
       ret = PyObject_RichCompareBool(name_attr, name, Py_EQ);
   } else {
@@ -188,7 +235,13 @@
         reduce = __Pyx_PyObject_GetAttrStr(type_obj, PYIDENT("__reduce__")); if (unlikely(!reduce)) goto __PYX_BAD;
 
         if (reduce == object_reduce || __Pyx_setup_reduce_is_named(reduce, PYIDENT("__reduce_cython__"))) {
-            reduce_cython = __Pyx_PyObject_GetAttrStr(type_obj, PYIDENT("__reduce_cython__")); if (unlikely(!reduce_cython)) goto __PYX_BAD;
-            ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, PYIDENT("__reduce__"), reduce_cython); if (unlikely(ret < 0)) goto __PYX_BAD;
-            ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, PYIDENT("__reduce_cython__")); if (unlikely(ret < 0)) goto __PYX_BAD;
+            reduce_cython = __Pyx_PyObject_GetAttrStrNoError(type_obj, PYIDENT("__reduce_cython__"));
+            if (likely(reduce_cython)) {
+                ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, PYIDENT("__reduce__"), reduce_cython); if (unlikely(ret < 0)) goto __PYX_BAD;
+                ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, PYIDENT("__reduce_cython__")); if (unlikely(ret < 0)) goto __PYX_BAD;
+            } else if (reduce == object_reduce || PyErr_Occurred()) {
+                // Ignore if we're done, i.e. if 'reduce' already has the right name and the original is gone.
+                // Otherwise: error.
+                goto __PYX_BAD;
+            }
 
@@ -194,4 +247,4 @@
 
-            setstate = __Pyx_PyObject_GetAttrStr(type_obj, PYIDENT("__setstate__"));
+            setstate = __Pyx_PyObject_GetAttrStrNoError(type_obj, PYIDENT("__setstate__"));
             if (!setstate) PyErr_Clear();
             if (!setstate || __Pyx_setup_reduce_is_named(setstate, PYIDENT("__setstate_cython__"))) {
@@ -196,8 +249,14 @@
             if (!setstate) PyErr_Clear();
             if (!setstate || __Pyx_setup_reduce_is_named(setstate, PYIDENT("__setstate_cython__"))) {
-                setstate_cython = __Pyx_PyObject_GetAttrStr(type_obj, PYIDENT("__setstate_cython__")); if (unlikely(!setstate_cython)) goto __PYX_BAD;
-                ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, PYIDENT("__setstate__"), setstate_cython); if (unlikely(ret < 0)) goto __PYX_BAD;
-                ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, PYIDENT("__setstate_cython__")); if (unlikely(ret < 0)) goto __PYX_BAD;
+                setstate_cython = __Pyx_PyObject_GetAttrStrNoError(type_obj, PYIDENT("__setstate_cython__"));
+                if (likely(setstate_cython)) {
+                    ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, PYIDENT("__setstate__"), setstate_cython); if (unlikely(ret < 0)) goto __PYX_BAD;
+                    ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, PYIDENT("__setstate_cython__")); if (unlikely(ret < 0)) goto __PYX_BAD;
+                } else if (!setstate || PyErr_Occurred()) {
+                    // Ignore if we're done, i.e. if 'setstate' already has the right name and the original is gone.
+                    // Otherwise: error.
+                    goto __PYX_BAD;
+                }
             }
             PyType_Modified((PyTypeObject*)type_obj);
         }
@@ -206,7 +265,7 @@
 
 __PYX_BAD:
     if (!PyErr_Occurred())
-        PyErr_Format(PyExc_RuntimeError, "Unable to initialize pickling for %s", ((PyTypeObject*)type_obj)->tp_name);
+        PyErr_Format(PyExc_RuntimeError, "Unable to initialize pickling for %s", __Pyx_PyType_Name(type_obj));
     ret = -1;
 __PYX_GOOD:
 #if !CYTHON_USE_PYTYPE_LOOKUP
@@ -220,3 +279,4 @@
     Py_XDECREF(setstate_cython);
     return ret;
 }
+#endif
diff --git a/Cython/Utility/FunctionArguments.c b/Cython/Utility/FunctionArguments.c
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1V0aWxpdHkvRnVuY3Rpb25Bcmd1bWVudHMuYw==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1V0aWxpdHkvRnVuY3Rpb25Bcmd1bWVudHMuYw== 100644
--- a/Cython/Utility/FunctionArguments.c
+++ b/Cython/Utility/FunctionArguments.c
@@ -2,7 +2,7 @@
 
 
 #define __Pyx_ArgTypeTest(obj, type, none_allowed, name, exact) \
-    ((likely((Py_TYPE(obj) == type) | (none_allowed && (obj == Py_None)))) ? 1 : \
+    ((likely(__Pyx_IS_TYPE(obj, type) | (none_allowed && (obj == Py_None)))) ? 1 : \
         __Pyx__ArgTypeTest(obj, type, name, exact))
 
 static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *name, int exact); /*proto*/
@@ -117,7 +117,7 @@
 
 //////////////////// KeywordStringCheck.proto ////////////////////
 
-static int __Pyx_CheckKeywordStrings(PyObject *kwdict, const char* function_name, int kw_allowed); /*proto*/
+static int __Pyx_CheckKeywordStrings(PyObject *kw, const char* function_name, int kw_allowed); /*proto*/
 
 //////////////////// KeywordStringCheck ////////////////////
 
@@ -121,8 +121,11 @@
 
 //////////////////// KeywordStringCheck ////////////////////
 
-//  __Pyx_CheckKeywordStrings raises an error if non-string keywords
-//  were passed to a function, or if any keywords were passed to a
-//  function that does not accept them.
+// __Pyx_CheckKeywordStrings raises an error if non-string keywords
+// were passed to a function, or if any keywords were passed to a
+// function that does not accept them.
+//
+// The "kw" argument is either a dict (for METH_VARARGS) or a tuple
+// (for METH_FASTCALL).
 
 static int __Pyx_CheckKeywordStrings(
@@ -127,6 +130,6 @@
 
 static int __Pyx_CheckKeywordStrings(
-    PyObject *kwdict,
+    PyObject *kw,
     const char* function_name,
     int kw_allowed)
 {
@@ -134,7 +137,7 @@
     Py_ssize_t pos = 0;
 #if CYTHON_COMPILING_IN_PYPY
     /* PyPy appears to check keywords at call time, not at unpacking time => not much to do here */
-    if (!kw_allowed && PyDict_Next(kwdict, &pos, &key, 0))
+    if (!kw_allowed && PyDict_Next(kw, &pos, &key, 0))
         goto invalid_keyword;
     return 1;
 #else
@@ -138,10 +141,27 @@
         goto invalid_keyword;
     return 1;
 #else
-    while (PyDict_Next(kwdict, &pos, &key, 0)) {
+    if (CYTHON_METH_FASTCALL && likely(PyTuple_Check(kw))) {
+        if (unlikely(PyTuple_GET_SIZE(kw) == 0))
+            return 1;
+        if (!kw_allowed)
+            goto invalid_keyword;
+#if PY_VERSION_HEX < 0x03090000
+        // On CPython >= 3.9, the FASTCALL protocol guarantees that keyword
+        // names are strings (see https://bugs.python.org/issue37540)
+        for (pos = 0; pos < PyTuple_GET_SIZE(kw); pos++) {
+            key = PyTuple_GET_ITEM(kw, pos);
+            if (unlikely(!PyUnicode_Check(key)))
+                goto invalid_keyword_type;
+        }
+#endif
+        return 1;
+    }
+
+    while (PyDict_Next(kw, &pos, &key, 0)) {
         #if PY_MAJOR_VERSION < 3
         if (unlikely(!PyString_Check(key)))
         #endif
             if (unlikely(!PyUnicode_Check(key)))
                 goto invalid_keyword_type;
     }
@@ -142,10 +162,10 @@
         #if PY_MAJOR_VERSION < 3
         if (unlikely(!PyString_Check(key)))
         #endif
             if (unlikely(!PyUnicode_Check(key)))
                 goto invalid_keyword_type;
     }
-    if ((!kw_allowed) && unlikely(key))
+    if (!kw_allowed && unlikely(key))
         goto invalid_keyword;
     return 1;
 invalid_keyword_type:
@@ -154,4 +174,5 @@
     return 0;
 #endif
 invalid_keyword:
+    #if PY_MAJOR_VERSION < 3
     PyErr_Format(PyExc_TypeError,
@@ -157,5 +178,4 @@
     PyErr_Format(PyExc_TypeError,
-    #if PY_MAJOR_VERSION < 3
         "%.200s() got an unexpected keyword argument '%.200s'",
         function_name, PyString_AsString(key));
     #else
@@ -159,6 +179,7 @@
         "%.200s() got an unexpected keyword argument '%.200s'",
         function_name, PyString_AsString(key));
     #else
+    PyErr_Format(PyExc_TypeError,
         "%s() got an unexpected keyword argument '%U'",
         function_name, key);
     #endif
@@ -168,11 +189,12 @@
 
 //////////////////// ParseKeywords.proto ////////////////////
 
-static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
-    PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
+static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject *const *kwvalues,
+    PyObject **argnames[],
+    PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args,
     const char* function_name); /*proto*/
 
 //////////////////// ParseKeywords ////////////////////
 //@requires: RaiseDoubleKeywords
 
 //  __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
@@ -173,9 +195,9 @@
     const char* function_name); /*proto*/
 
 //////////////////// ParseKeywords ////////////////////
 //@requires: RaiseDoubleKeywords
 
 //  __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
-//  arguments from the kwds dict into kwds2.  If kwds2 is NULL, unknown
+//  arguments from kwds into the dict kwds2.  If kwds2 is NULL, unknown
 //  keywords will raise an invalid keyword error.
 //
@@ -180,5 +202,9 @@
 //  keywords will raise an invalid keyword error.
 //
+//  When not using METH_FASTCALL, kwds is a dict and kwvalues is NULL.
+//  Otherwise, kwds is a tuple with keyword names and kwvalues is a C
+//  array with the corresponding values.
+//
 //  Three kinds of errors are checked: 1) non-string keywords, 2)
 //  unexpected keywords and 3) overlap with positional arguments.
 //
@@ -190,6 +216,7 @@
 
 static int __Pyx_ParseOptionalKeywords(
     PyObject *kwds,
+    PyObject *const *kwvalues,
     PyObject **argnames[],
     PyObject *kwds2,
     PyObject *values[],
@@ -200,4 +227,5 @@
     Py_ssize_t pos = 0;
     PyObject*** name;
     PyObject*** first_kw_arg = argnames + num_pos_args;
+    int kwds_is_tuple = CYTHON_METH_FASTCALL && likely(PyTuple_Check(kwds));
 
@@ -203,5 +231,16 @@
 
-    while (PyDict_Next(kwds, &pos, &key, &value)) {
+    while (1) {
+        if (kwds_is_tuple) {
+            if (pos >= PyTuple_GET_SIZE(kwds)) break;
+            key = PyTuple_GET_ITEM(kwds, pos);
+            value = kwvalues[pos];
+            pos++;
+        }
+        else
+        {
+            if (!PyDict_Next(kwds, &pos, &key, &value)) break;
+        }
+
         name = first_kw_arg;
         while (*name && (**name != key)) name++;
         if (*name) {
@@ -211,7 +250,7 @@
 
         name = first_kw_arg;
         #if PY_MAJOR_VERSION < 3
-        if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {
+        if (likely(PyString_Check(key))) {
             while (*name) {
                 if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))
                         && _PyString_Eq(**name, key)) {
@@ -237,5 +276,5 @@
         #endif
         if (likely(PyUnicode_Check(key))) {
             while (*name) {
-                int cmp = (**name == key) ? 0 :
+                int cmp = (
                 #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
@@ -241,3 +280,3 @@
                 #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
-                    (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
+                    (__Pyx_PyUnicode_GET_LENGTH(**name) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 :
                 #endif
@@ -243,6 +282,7 @@
                 #endif
-                    // need to convert argument name from bytes to unicode for comparison
-                    PyUnicode_Compare(**name, key);
+                    // In Py2, we may need to convert the argument name from str to unicode for comparison.
+                    PyUnicode_Compare(**name, key)
+                );
                 if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
                 if (cmp == 0) {
                     values[name-argnames] = value;
@@ -257,7 +297,7 @@
                 while (argname != first_kw_arg) {
                     int cmp = (**argname == key) ? 0 :
                     #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
-                        (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
+                        (__Pyx_PyUnicode_GET_LENGTH(**argname) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 :
                     #endif
                         // need to convert argument name from bytes to unicode for comparison
                         PyUnicode_Compare(**argname, key);
@@ -284,4 +324,5 @@
         "%.200s() keywords must be strings", function_name);
     goto bad;
 invalid_keyword:
+    #if PY_MAJOR_VERSION < 3
     PyErr_Format(PyExc_TypeError,
@@ -287,5 +328,4 @@
     PyErr_Format(PyExc_TypeError,
-    #if PY_MAJOR_VERSION < 3
         "%.200s() got an unexpected keyword argument '%.200s'",
         function_name, PyString_AsString(key));
     #else
@@ -289,6 +329,7 @@
         "%.200s() got an unexpected keyword argument '%.200s'",
         function_name, PyString_AsString(key));
     #else
+    PyErr_Format(PyExc_TypeError,
         "%s() got an unexpected keyword argument '%U'",
         function_name, key);
     #endif
@@ -314,7 +355,7 @@
     if (unlikely(!iter)) {
         // slow fallback: try converting to dict, then iterate
         PyObject *args;
-        if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad;
+        if (unlikely(!PyErr_ExceptionMatches(PyExc_AttributeError))) goto bad;
         PyErr_Clear();
         args = PyTuple_Pack(1, source_mapping);
         if (likely(args)) {
@@ -350,3 +391,74 @@
     Py_XDECREF(iter);
     return -1;
 }
+
+
+/////////////// fastcall.proto ///////////////
+
+// We define various functions and macros with two variants:
+//..._FASTCALL and ..._VARARGS
+
+// The first is used when METH_FASTCALL is enabled and the second is used
+// otherwise. If the Python implementation does not support METH_FASTCALL
+// (because it's an old version of CPython or it's not CPython at all),
+// then the ..._FASTCALL macros simply alias ..._VARARGS
+
+#define __Pyx_Arg_VARARGS(args, i) PyTuple_GET_ITEM(args, i)
+#define __Pyx_NumKwargs_VARARGS(kwds) PyDict_Size(kwds)
+#define __Pyx_KwValues_VARARGS(args, nargs) NULL
+#define __Pyx_GetKwValue_VARARGS(kw, kwvalues, s) __Pyx_PyDict_GetItemStrWithError(kw, s)
+#define __Pyx_KwargsAsDict_VARARGS(kw, kwvalues) PyDict_Copy(kw)
+#if CYTHON_METH_FASTCALL
+    #define __Pyx_Arg_FASTCALL(args, i) args[i]
+    #define __Pyx_NumKwargs_FASTCALL(kwds) PyTuple_GET_SIZE(kwds)
+    #define __Pyx_KwValues_FASTCALL(args, nargs) (&args[nargs])
+    static CYTHON_INLINE PyObject * __Pyx_GetKwValue_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues, PyObject *s);
+    #define __Pyx_KwargsAsDict_FASTCALL(kw, kwvalues) _PyStack_AsDict(kwvalues, kw)
+#else
+    #define __Pyx_Arg_FASTCALL __Pyx_Arg_VARARGS
+    #define __Pyx_NumKwargs_FASTCALL __Pyx_NumKwargs_VARARGS
+    #define __Pyx_KwValues_FASTCALL __Pyx_KwValues_VARARGS
+    #define __Pyx_GetKwValue_FASTCALL __Pyx_GetKwValue_VARARGS
+    #define __Pyx_KwargsAsDict_FASTCALL __Pyx_KwargsAsDict_VARARGS
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __Pyx_ArgsSlice_VARARGS(args, start, stop) __Pyx_PyTuple_FromArray(&__Pyx_Arg_VARARGS(args, start), stop - start)
+#define __Pyx_ArgsSlice_FASTCALL(args, start, stop) __Pyx_PyTuple_FromArray(&__Pyx_Arg_FASTCALL(args, start), stop - start)
+#else
+/* Not CPython, so certainly no METH_FASTCALL support */
+#define __Pyx_ArgsSlice_VARARGS(args, start, stop) PyTuple_GetSlice(args, start, stop)
+#define __Pyx_ArgsSlice_FASTCALL(args, start, stop) PyTuple_GetSlice(args, start, stop)
+#endif
+
+
+/////////////// fastcall ///////////////
+//@requires: ObjectHandling.c::TupleAndListFromArray
+//@requires: StringTools.c::UnicodeEquals
+
+#if CYTHON_METH_FASTCALL
+// kwnames: tuple with names of keyword arguments
+// kwvalues: C array with values of keyword arguments
+// s: str with the keyword name to look for
+static CYTHON_INLINE PyObject * __Pyx_GetKwValue_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues, PyObject *s)
+{
+    // Search the kwnames array for s and return the corresponding value.
+    // We do two loops: a first one to compare pointers (which will find a
+    // match if the name in kwnames is interned, given that s is interned
+    // by Cython). A second loop compares the actual strings.
+    Py_ssize_t i, n = PyTuple_GET_SIZE(kwnames);
+    for (i = 0; i < n; i++)
+    {
+        if (s == PyTuple_GET_ITEM(kwnames, i)) return kwvalues[i];
+    }
+    for (i = 0; i < n; i++)
+    {
+        int eq = __Pyx_PyUnicode_Equals(s, PyTuple_GET_ITEM(kwnames, i), Py_EQ);
+        if (unlikely(eq != 0)) {
+            if (unlikely(eq < 0)) return NULL;  // error
+            return kwvalues[i];
+        }
+    }
+    return NULL;  // not found (no exception set)
+}
+#endif
diff --git a/Cython/Utility/ImportExport.c b/Cython/Utility/ImportExport.c
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1V0aWxpdHkvSW1wb3J0RXhwb3J0LmM=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1V0aWxpdHkvSW1wb3J0RXhwb3J0LmM= 100644
--- a/Cython/Utility/ImportExport.c
+++ b/Cython/Utility/ImportExport.c
@@ -9,6 +9,147 @@
 #endif
 
 
+/////////////// ImportDottedModule.proto ///////////////
+
+static PyObject *__Pyx_ImportDottedModule(PyObject *name, PyObject *parts_tuple); /*proto*/
+
+/////////////// ImportDottedModule ///////////////
+//@requires: Import
+
+#if PY_MAJOR_VERSION >= 3
+static PyObject *__Pyx__ImportDottedModule_Error(PyObject *name, PyObject *parts_tuple, Py_ssize_t count) {
+    PyObject *partial_name = NULL, *slice = NULL, *sep = NULL;
+    if (unlikely(PyErr_Occurred())) {
+        PyErr_Clear();
+    }
+    if (likely(PyTuple_GET_SIZE(parts_tuple) == count)) {
+        partial_name = name;
+    } else {
+        PyObject *sep;
+        PyObject *slice = PySequence_GetSlice(parts_tuple, 0, count);
+        if (unlikely(!slice))
+            goto bad;
+        sep = PyUnicode_FromStringAndSize(".", 1);
+        if (unlikely(!sep))
+            goto bad;
+        partial_name = PyUnicode_Join(sep, slice);
+    }
+
+    PyErr_Format(
+#if PY_MAJOR_VERSION < 3
+        PyExc_ImportError,
+        "No module named '%s'", PyString_AS_STRING(partial_name));
+#else
+#if PY_VERSION_HEX >= 0x030600B1
+        PyExc_ModuleNotFoundError,
+#else
+        PyExc_ImportError,
+#endif
+        "No module named '%U'", partial_name);
+#endif
+
+bad:
+    Py_XDECREF(sep);
+    Py_XDECREF(slice);
+    Py_XDECREF(partial_name);
+    return NULL;
+}
+#endif
+
+#if PY_MAJOR_VERSION >= 3
+static PyObject *__Pyx__ImportDottedModule_Lookup(PyObject *name) {
+    PyObject *imported_module;
+#if PY_VERSION_HEX < 0x030700A1
+    PyObject *modules = PyImport_GetModuleDict();
+    if (unlikely(!modules))
+        return NULL;
+    imported_module = __Pyx_PyDict_GetItemStr(modules, name);
+    Py_XINCREF(imported_module);
+#else
+    imported_module = PyImport_GetModule(name);
+#endif
+    return imported_module;
+}
+#endif
+
+static PyObject *__Pyx__ImportDottedModule(PyObject *name, CYTHON_UNUSED PyObject *parts_tuple) {
+#if PY_MAJOR_VERSION < 3
+    PyObject *module, *from_list, *star = PYIDENT("*");
+    from_list = PyList_New(1);
+    if (unlikely(!from_list))
+        return NULL;
+    Py_INCREF(star);
+    PyList_SET_ITEM(from_list, 0, star);
+    module = __Pyx_Import(name, from_list, 0);
+    Py_DECREF(from_list);
+    return module;
+#else
+    Py_ssize_t i, nparts;
+    PyObject *imported_module;
+    PyObject *module = __Pyx_Import(name, NULL, 0);
+    if (!parts_tuple || unlikely(!module))
+        return module;
+
+    // Look up module in sys.modules, which is safer than the attribute lookups below.
+    imported_module = __Pyx__ImportDottedModule_Lookup(name);
+    if (likely(imported_module)) {
+        Py_DECREF(module);
+        return imported_module;
+    }
+    PyErr_Clear();
+
+    nparts = PyTuple_GET_SIZE(parts_tuple);
+    for (i=1; i < nparts && module; i++) {
+        PyObject *part, *submodule;
+#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
+        part = PyTuple_GET_ITEM(parts_tuple, i);
+#else
+        part = PySequence_ITEM(parts_tuple, i);
+#endif
+        submodule = __Pyx_PyObject_GetAttrStrNoError(module, part);
+#if !(CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS)
+        Py_DECREF(part);
+#endif
+        Py_DECREF(module);
+        module = submodule;
+    }
+    if (likely(module))
+        return module;
+    return __Pyx__ImportDottedModule_Error(name, parts_tuple, i);
+#endif
+}
+
+static PyObject *__Pyx_ImportDottedModule(PyObject *name, PyObject *parts_tuple) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030400B1
+    PyObject *module = __Pyx__ImportDottedModule_Lookup(name);
+    if (likely(module)) {
+        // CPython guards against thread-concurrent initialisation in importlib.
+        // In this case, we let PyImport_ImportModuleLevelObject() handle the locking.
+        PyObject *spec = __Pyx_PyObject_GetAttrStrNoError(module, PYIDENT("__spec__"));
+        if (likely(spec)) {
+            PyObject *unsafe = __Pyx_PyObject_GetAttrStrNoError(spec, PYIDENT("_initializing"));
+            if (likely(!unsafe || !__Pyx_PyObject_IsTrue(unsafe))) {
+                Py_DECREF(spec);
+                spec = NULL;
+            }
+            Py_XDECREF(unsafe);
+        }
+        if (likely(!spec)) {
+            // Not in initialisation phase => use modules as is.
+            PyErr_Clear();
+            return module;
+        }
+        Py_DECREF(spec);
+        Py_DECREF(module);
+    } else if (PyErr_Occurred()) {
+        PyErr_Clear();
+    }
+#endif
+
+    return __Pyx__ImportDottedModule(name, parts_tuple);
+}
+
+
 /////////////// Import.proto ///////////////
 
 static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); /*proto*/
@@ -18,4 +159,6 @@
 //@substitute: naming
 
 static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) {
+    PyObject *module = 0;
+    PyObject *empty_dict = 0;
     PyObject *empty_list = 0;
@@ -21,8 +164,4 @@
     PyObject *empty_list = 0;
-    PyObject *module = 0;
-    PyObject *global_dict = 0;
-    PyObject *empty_dict = 0;
-    PyObject *list;
     #if PY_MAJOR_VERSION < 3
     PyObject *py_import;
     py_import = __Pyx_PyObject_GetAttrStr($builtins_cname, PYIDENT("__import__"));
@@ -26,5 +165,5 @@
     #if PY_MAJOR_VERSION < 3
     PyObject *py_import;
     py_import = __Pyx_PyObject_GetAttrStr($builtins_cname, PYIDENT("__import__"));
-    if (!py_import)
+    if (unlikely(!py_import))
         goto bad;
@@ -30,6 +169,3 @@
         goto bad;
-    #endif
-    if (from_list)
-        list = from_list;
-    else {
+    if (!from_list) {
         empty_list = PyList_New(0);
@@ -35,3 +171,3 @@
         empty_list = PyList_New(0);
-        if (!empty_list)
+        if (unlikely(!empty_list))
             goto bad;
@@ -37,3 +173,3 @@
             goto bad;
-        list = empty_list;
+        from_list = empty_list;
     }
@@ -39,5 +175,3 @@
     }
-    global_dict = PyModule_GetDict($module_cname);
-    if (!global_dict)
-        goto bad;
+    #endif
     empty_dict = PyDict_New();
@@ -43,6 +177,6 @@
     empty_dict = PyDict_New();
-    if (!empty_dict)
+    if (unlikely(!empty_dict))
         goto bad;
     {
         #if PY_MAJOR_VERSION >= 3
         if (level == -1) {
@@ -45,6 +179,7 @@
         goto bad;
     {
         #if PY_MAJOR_VERSION >= 3
         if (level == -1) {
-            if (strchr(__Pyx_MODULE_NAME, '.')) {
+            // Avoid C compiler warning if strchr() evaluates to false at compile time.
+            if ((1) && (strchr(__Pyx_MODULE_NAME, '.'))) {
                 /* try package relative import first */
@@ -50,2 +185,3 @@
                 /* try package relative import first */
+                #if CYTHON_COMPILING_IN_LIMITED_API
                 module = PyImport_ImportModuleLevelObject(
@@ -51,7 +187,11 @@
                 module = PyImport_ImportModuleLevelObject(
-                    name, global_dict, empty_dict, list, 1);
-                if (!module) {
-                    if (!PyErr_ExceptionMatches(PyExc_ImportError))
+                    name, empty_dict, empty_dict, from_list, 1);
+                #else
+                module = PyImport_ImportModuleLevelObject(
+                    name, $moddict_cname, empty_dict, from_list, 1);
+                #endif
+                if (unlikely(!module)) {
+                    if (unlikely(!PyErr_ExceptionMatches(PyExc_ImportError)))
                         goto bad;
                     PyErr_Clear();
                 }
@@ -62,6 +202,6 @@
         if (!module) {
             #if PY_MAJOR_VERSION < 3
             PyObject *py_level = PyInt_FromLong(level);
-            if (!py_level)
+            if (unlikely(!py_level))
                 goto bad;
             module = PyObject_CallFunctionObjArgs(py_import,
@@ -66,5 +206,5 @@
                 goto bad;
             module = PyObject_CallFunctionObjArgs(py_import,
-                name, global_dict, empty_dict, list, py_level, (PyObject *)NULL);
+                name, $moddict_cname, empty_dict, from_list, py_level, (PyObject *)NULL);
             Py_DECREF(py_level);
             #else
@@ -69,3 +209,4 @@
             Py_DECREF(py_level);
             #else
+            #if CYTHON_COMPILING_IN_LIMITED_API
             module = PyImport_ImportModuleLevelObject(
@@ -71,6 +212,10 @@
             module = PyImport_ImportModuleLevelObject(
-                name, global_dict, empty_dict, list, level);
+                name, empty_dict, empty_dict, from_list, level);
+            #else
+            module = PyImport_ImportModuleLevelObject(
+                name, $moddict_cname, empty_dict, from_list, level);
+            #endif
             #endif
         }
     }
 bad:
@@ -73,7 +218,9 @@
             #endif
         }
     }
 bad:
+    Py_XDECREF(empty_dict);
+    Py_XDECREF(empty_list);
     #if PY_MAJOR_VERSION < 3
     Py_XDECREF(py_import);
     #endif
@@ -77,8 +224,6 @@
     #if PY_MAJOR_VERSION < 3
     Py_XDECREF(py_import);
     #endif
-    Py_XDECREF(empty_list);
-    Py_XDECREF(empty_dict);
     return module;
 }
 
@@ -331,7 +476,7 @@
     PyObject *result = 0;
     char warning[200];
     Py_ssize_t basicsize;
-#ifdef Py_LIMITED_API
+#if CYTHON_COMPILING_IN_LIMITED_API
     PyObject *py_basicsize;
 #endif
 
@@ -344,7 +489,7 @@
             module_name, class_name);
         goto bad;
     }
-#ifndef Py_LIMITED_API
+#if !CYTHON_COMPILING_IN_LIMITED_API
     basicsize = ((PyTypeObject *)result)->tp_basicsize;
 #else
     py_basicsize = PyObject_GetAttrString(result, "__basicsize__");
@@ -412,7 +557,6 @@
                 PyModule_GetName(module), funcname);
         goto bad;
     }
-#if PY_VERSION_HEX >= 0x02070000
     if (!PyCapsule_IsValid(cobj, sig)) {
         PyErr_Format(PyExc_TypeError,
             "C function %.200s.%.200s has wrong signature (expected %.500s, got %.500s)",
@@ -420,21 +564,6 @@
         goto bad;
     }
     tmp.p = PyCapsule_GetPointer(cobj, sig);
-#else
-    {const char *desc, *s1, *s2;
-    desc = (const char *)PyCObject_GetDesc(cobj);
-    if (!desc)
-        goto bad;
-    s1 = desc; s2 = sig;
-    while (*s1 != '\0' && *s1 == *s2) { s1++; s2++; }
-    if (*s1 != *s2) {
-        PyErr_Format(PyExc_TypeError,
-            "C function %.200s.%.200s has wrong signature (expected %.500s, got %.500s)",
-             PyModule_GetName(module), funcname, sig, desc);
-        goto bad;
-    }
-    tmp.p = PyCObject_AsVoidPtr(cobj);}
-#endif
     *f = tmp.fp;
     if (!(*f))
         goto bad;
@@ -472,5 +601,4 @@
             goto bad;
     }
     tmp.fp = f;
-#if PY_VERSION_HEX >= 0x02070000
     cobj = PyCapsule_New(tmp.p, sig, 0);
@@ -476,7 +604,4 @@
     cobj = PyCapsule_New(tmp.p, sig, 0);
-#else
-    cobj = PyCObject_FromVoidPtrAndDesc(tmp.p, (void *)sig, 0);
-#endif
     if (!cobj)
         goto bad;
     if (PyDict_SetItemString(d, name, cobj) < 0)
@@ -513,7 +638,6 @@
                 PyModule_GetName(module), name);
         goto bad;
     }
-#if PY_VERSION_HEX >= 0x02070000
     if (!PyCapsule_IsValid(cobj, sig)) {
         PyErr_Format(PyExc_TypeError,
             "C variable %.200s.%.200s has wrong signature (expected %.500s, got %.500s)",
@@ -521,21 +645,6 @@
         goto bad;
     }
     *p = PyCapsule_GetPointer(cobj, sig);
-#else
-    {const char *desc, *s1, *s2;
-    desc = (const char *)PyCObject_GetDesc(cobj);
-    if (!desc)
-        goto bad;
-    s1 = desc; s2 = sig;
-    while (*s1 != '\0' && *s1 == *s2) { s1++; s2++; }
-    if (*s1 != *s2) {
-        PyErr_Format(PyExc_TypeError,
-            "C variable %.200s.%.200s has wrong signature (expected %.500s, got %.500s)",
-             PyModule_GetName(module), name, sig, desc);
-        goto bad;
-    }
-    *p = PyCObject_AsVoidPtr(cobj);}
-#endif
     if (!(*p))
         goto bad;
     Py_DECREF(d);
@@ -567,5 +676,4 @@
         if (__Pyx_PyObject_SetAttrStr($module_cname, PYIDENT("$api_name"), d) < 0)
             goto bad;
     }
-#if PY_VERSION_HEX >= 0x02070000
     cobj = PyCapsule_New(p, sig, 0);
@@ -571,7 +679,4 @@
     cobj = PyCapsule_New(p, sig, 0);
-#else
-    cobj = PyCObject_FromVoidPtrAndDesc(p, (void *)sig, 0);
-#endif
     if (!cobj)
         goto bad;
     if (PyDict_SetItem(d, name, cobj) < 0)
@@ -592,4 +697,7 @@
 
 /////////////// SetVTable ///////////////
 
+#if CYTHON_COMPILING_IN_LIMITED_API
+static int __Pyx_SetVtable(PyObject *type, void *vtable) {
+#else
 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
@@ -595,3 +703,3 @@
 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
-#if PY_VERSION_HEX >= 0x02070000
+#endif
     PyObject *ob = PyCapsule_New(vtable, 0, 0);
@@ -597,6 +705,3 @@
     PyObject *ob = PyCapsule_New(vtable, 0, 0);
-#else
-    PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
-#endif
     if (!ob)
         goto bad;
@@ -601,3 +706,6 @@
     if (!ob)
         goto bad;
+#if CYTHON_COMPILING_IN_LIMITED_API
+    if (PyObject_SetAttr(type, PYIDENT("__pyx_vtable__"), ob) < 0)
+#else
     if (PyDict_SetItem(dict, PYIDENT("__pyx_vtable__"), ob) < 0)
@@ -603,4 +711,5 @@
     if (PyDict_SetItem(dict, PYIDENT("__pyx_vtable__"), ob) < 0)
+#endif
         goto bad;
     Py_DECREF(ob);
     return 0;
@@ -612,7 +721,7 @@
 
 /////////////// GetVTable.proto ///////////////
 
-static void* __Pyx_GetVtable(PyObject *dict); /*proto*/
+static void* __Pyx_GetVtable(PyTypeObject *type); /*proto*/
 
 /////////////// GetVTable ///////////////
 
@@ -616,5 +725,5 @@
 
 /////////////// GetVTable ///////////////
 
-static void* __Pyx_GetVtable(PyObject *dict) {
+static void* __Pyx_GetVtable(PyTypeObject *type) {
     void* ptr;
@@ -620,4 +729,8 @@
     void* ptr;
-    PyObject *ob = PyObject_GetItem(dict, PYIDENT("__pyx_vtable__"));
+#if CYTHON_COMPILING_IN_LIMITED_API
+    PyObject *ob = PyObject_GetAttr((PyObject *)type, PYIDENT("__pyx_vtable__"));
+#else
+    PyObject *ob = PyObject_GetItem(type->tp_dict, PYIDENT("__pyx_vtable__"));
+#endif
     if (!ob)
         goto bad;
@@ -622,4 +735,3 @@
     if (!ob)
         goto bad;
-#if PY_VERSION_HEX >= 0x02070000
     ptr = PyCapsule_GetPointer(ob, 0);
@@ -625,7 +737,4 @@
     ptr = PyCapsule_GetPointer(ob, 0);
-#else
-    ptr = PyCObject_AsVoidPtr(ob);
-#endif
     if (!ptr && !PyErr_Occurred())
         PyErr_SetString(PyExc_RuntimeError, "invalid vtable found for imported type");
     Py_DECREF(ob);
@@ -665,9 +774,9 @@
     // instance struct is so extended.  (It would be good to also do this
     // check when a multiple-base class is created in pure Python as well.)
     for (i = 1; i < PyTuple_GET_SIZE(bases); i++) {
-        void* base_vtable = __Pyx_GetVtable(((PyTypeObject*)PyTuple_GET_ITEM(bases, i))->tp_dict);
+        void* base_vtable = __Pyx_GetVtable(((PyTypeObject*)PyTuple_GET_ITEM(bases, i)));
         if (base_vtable != NULL) {
             int j;
             PyTypeObject* base = type->tp_base;
             for (j = 0; j < base_depth; j++) {
                 if (base_vtables[j] == unknown) {
@@ -669,9 +778,9 @@
         if (base_vtable != NULL) {
             int j;
             PyTypeObject* base = type->tp_base;
             for (j = 0; j < base_depth; j++) {
                 if (base_vtables[j] == unknown) {
-                    base_vtables[j] = __Pyx_GetVtable(base->tp_dict);
+                    base_vtables[j] = __Pyx_GetVtable(base);
                     base_vtables[j + 1] = unknown;
                 }
                 if (base_vtables[j] == base_vtable) {
diff --git a/Cython/Utility/MemoryView.pyx b/Cython/Utility/MemoryView.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1V0aWxpdHkvTWVtb3J5Vmlldy5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1V0aWxpdHkvTWVtb3J5Vmlldy5weXg= 100644
--- a/Cython/Utility/MemoryView.pyx
+++ b/Cython/Utility/MemoryView.pyx
@@ -8,5 +8,6 @@
 
 # from cpython cimport ...
 cdef extern from "Python.h":
+    ctypedef struct PyObject
     int PyIndex_Check(object)
     object PyLong_FromVoidPtr(void *)
@@ -11,5 +12,8 @@
     int PyIndex_Check(object)
     object PyLong_FromVoidPtr(void *)
+    PyObject *PyExc_IndexError
+    PyObject *PyExc_ValueError
+    PyObject *PyExc_MemoryError
 
 cdef extern from "pythread.h":
     ctypedef void *PyThread_type_lock
@@ -94,9 +98,6 @@
     void free(void *) nogil
     void *memcpy(void *dest, void *src, size_t n) nogil
 
-
-
-
 #
 ### cython.array class
 #
@@ -123,8 +124,7 @@
                   mode="c", bint allocate_buffer=True):
 
         cdef int idx
-        cdef Py_ssize_t i, dim
-        cdef PyObject **p
+        cdef Py_ssize_t dim
 
         self.ndim = <int> len(shape)
         self.itemsize = itemsize
@@ -150,7 +150,7 @@
         # cdef Py_ssize_t dim, stride
         for idx, dim in enumerate(shape):
             if dim <= 0:
-                raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
+                raise ValueError(f"Invalid shape in axis {idx}: {dim}.")
             self._shape[idx] = dim
 
         cdef char order
@@ -154,9 +154,6 @@
             self._shape[idx] = dim
 
         cdef char order
-        if mode == 'fortran':
-            order = b'F'
-            self.mode = u'fortran'
-        elif mode == 'c':
+        if mode == 'c':
             order = b'C'
             self.mode = u'c'
@@ -161,3 +158,6 @@
             order = b'C'
             self.mode = u'c'
+        elif mode == 'fortran':
+            order = b'F'
+            self.mode = u'fortran'
         else:
@@ -163,3 +163,3 @@
         else:
-            raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode)
+            raise ValueError(f"Invalid mode, expected 'c' or 'fortran', got {mode}")
 
@@ -165,6 +165,5 @@
 
-        self.len = fill_contig_strides_array(self._shape, self._strides,
-                                             itemsize, self.ndim, order)
+        self.len = fill_contig_strides_array(self._shape, self._strides, itemsize, self.ndim, order)
 
         self.free_data = allocate_buffer
         self.dtype_is_object = format == b'O'
@@ -168,4 +167,5 @@
 
         self.free_data = allocate_buffer
         self.dtype_is_object = format == b'O'
+
         if allocate_buffer:
@@ -171,15 +171,5 @@
         if allocate_buffer:
-            # use malloc() for backwards compatibility
-            # in case external code wants to change the data pointer
-            self.data = <char *>malloc(self.len)
-            if not self.data:
-                raise MemoryError("unable to allocate array data.")
-
-            if self.dtype_is_object:
-                p = <PyObject **> self.data
-                for i in range(self.len / itemsize):
-                    p[i] = Py_None
-                    Py_INCREF(Py_None)
+            _allocate_buffer(self)
 
     @cname('getbuffer')
     def __getbuffer__(self, Py_buffer *info, int flags):
@@ -211,5 +201,5 @@
     def __dealloc__(array self):
         if self.callback_free_data != NULL:
             self.callback_free_data(self.data)
-        elif self.free_data:
+        elif self.free_data and self.data is not NULL:
             if self.dtype_is_object:
@@ -215,6 +205,5 @@
             if self.dtype_is_object:
-                refcount_objects_in_slice(self.data, self._shape,
-                                          self._strides, self.ndim, False)
+                refcount_objects_in_slice(self.data, self._shape, self._strides, self.ndim, inc=False)
             free(self.data)
         PyObject_Free(self._shape)
 
@@ -240,8 +229,15 @@
         self.memview[item] = value
 
 
-@cname("__pyx_array_new")
-cdef array array_cwrapper(tuple shape, Py_ssize_t itemsize, char *format,
-                          char *mode, char *buf):
-    cdef array result
+@cname("__pyx_array_allocate_buffer")
+cdef int _allocate_buffer(array self) except -1:
+    # use malloc() for backwards compatibility
+    # in case external code wants to change the data pointer
+    cdef Py_ssize_t i
+    cdef PyObject **p
+
+    self.free_data = True
+    self.data = <char *>malloc(self.len)
+    if not self.data:
+        raise MemoryError("unable to allocate array data.")
 
@@ -247,4 +243,17 @@
 
-    if buf == NULL:
-        result = array(shape, itemsize, format, mode.decode('ASCII'))
+    if self.dtype_is_object:
+        p = <PyObject **> self.data
+        for i in range(self.len // self.itemsize):
+            p[i] = Py_None
+            Py_INCREF(Py_None)
+    return 0
+
+
+@cname("__pyx_array_new")
+cdef array array_cwrapper(tuple shape, Py_ssize_t itemsize, char *format, char *c_mode, char *buf):
+    cdef array result
+    cdef str mode = "fortran" if c_mode[0] == b'f' else "c"  # this often comes from a constant C string.
+
+    if buf is NULL:
+        result = array.__new__(array, shape, itemsize, format, mode)
     else:
@@ -250,6 +259,5 @@
     else:
-        result = array(shape, itemsize, format, mode.decode('ASCII'),
-                       allocate_buffer=False)
+        result = array.__new__(array, shape, itemsize, format, mode, allocate_buffer=False)
         result.data = buf
 
     return result
@@ -327,7 +335,7 @@
 
 
 @cname('__pyx_memoryview')
-cdef class memoryview(object):
+cdef class memoryview:
 
     cdef object obj
     cdef object _size
@@ -441,4 +449,6 @@
     cdef setitem_slice_assignment(self, dst, src):
         cdef {{memviewslice_name}} dst_slice
         cdef {{memviewslice_name}} src_slice
+        cdef {{memviewslice_name}} msrc = get_slice_from_memview(src, &src_slice)[0]
+        cdef {{memviewslice_name}} mdst = get_slice_from_memview(dst, &dst_slice)[0]
 
@@ -444,7 +454,5 @@
 
-        memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0],
-                                 get_slice_from_memview(dst, &dst_slice)[0],
-                                 src.ndim, dst.ndim, self.dtype_is_object)
+        memoryview_copy_contents(msrc, mdst, src.ndim, dst.ndim, self.dtype_is_object)
 
     cdef setitem_slice_assign_scalar(self, memoryview dst, value):
         cdef int array[128]
@@ -557,6 +565,9 @@
 
     @property
     def base(self):
+        return self._get_base()
+
+    cdef _get_base(self):
         return self.obj
 
     @property
@@ -668,8 +679,6 @@
     Replace all ellipses with full slices and fill incomplete indices with
     full slices.
     """
-    if not isinstance(index, tuple):
-        tup = (index,)
-    else:
-        tup = index
+    cdef Py_ssize_t idx
+    tup = <tuple>index if isinstance(index, tuple) else (index,)
 
@@ -675,4 +684,4 @@
 
-    result = []
+    result = [slice(None)] * ndim
     have_slices = False
     seen_ellipsis = False
@@ -677,5 +686,6 @@
     have_slices = False
     seen_ellipsis = False
-    for idx, item in enumerate(tup):
+    idx = 0
+    for item in tup:
         if item is Ellipsis:
             if not seen_ellipsis:
@@ -680,4 +690,4 @@
         if item is Ellipsis:
             if not seen_ellipsis:
-                result.extend([slice(None)] * (ndim - len(tup) + 1))
+                idx += ndim - len(tup)
                 seen_ellipsis = True
@@ -683,5 +693,3 @@
                 seen_ellipsis = True
-            else:
-                result.append(slice(None))
             have_slices = True
         else:
@@ -686,5 +694,9 @@
             have_slices = True
         else:
-            if not isinstance(item, slice) and not PyIndex_Check(item):
-                raise TypeError("Cannot index with type '%s'" % type(item))
+            if isinstance(item, slice):
+                have_slices = True
+            elif not PyIndex_Check(item):
+                raise TypeError(f"Cannot index with type '{type(item)}'")
+            result[idx] = item
+        idx += 1
 
@@ -690,11 +702,5 @@
 
-            have_slices = have_slices or isinstance(item, slice)
-            result.append(item)
-
-    nslices = ndim - len(result)
-    if nslices:
-        result.extend([slice(None)] * nslices)
-
+    nslices = ndim - idx
     return have_slices or nslices, tuple(result)
 
 cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim):
@@ -740,8 +746,8 @@
     #  may not be as expected"
     cdef {{memviewslice_name}} *p_dst = &dst
     cdef int *p_suboffset_dim = &suboffset_dim
-    cdef Py_ssize_t start, stop, step
+    cdef Py_ssize_t start, stop, step, cindex
     cdef bint have_start, have_stop, have_step
 
     for dim, index in enumerate(indices):
         if PyIndex_Check(index):
@@ -744,7 +750,8 @@
     cdef bint have_start, have_stop, have_step
 
     for dim, index in enumerate(indices):
         if PyIndex_Check(index):
+            cindex = index
             slice_memviewslice(
                 p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
                 dim, new_ndim, p_suboffset_dim,
@@ -748,7 +755,7 @@
             slice_memviewslice(
                 p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
                 dim, new_ndim, p_suboffset_dim,
-                index, 0, 0, # start, stop, step
+                cindex, 0, 0, # start, stop, step
                 0, 0, 0, # have_{start,stop,step}
                 False)
         elif index is None:
@@ -829,6 +836,6 @@
         if start < 0:
             start += shape
         if not 0 <= start < shape:
-            _err_dim(IndexError, "Index out of bounds (axis %d)", dim)
+            _err_dim(PyExc_IndexError, "Index out of bounds (axis %d)", dim)
     else:
         # index is a slice
@@ -833,9 +840,12 @@
     else:
         # index is a slice
-        negative_step = have_step != 0 and step < 0
-
-        if have_step and step == 0:
-            _err_dim(ValueError, "Step may not be zero (axis %d)", dim)
+        if have_step:
+            negative_step = step < 0
+            if step == 0:
+                _err_dim(PyExc_ValueError, "Step may not be zero (axis %d)", dim)
+        else:
+            negative_step = False
+            step = 1
 
         # check our bounds and set defaults
         if have_start:
@@ -867,9 +877,6 @@
             else:
                 stop = shape
 
-        if not have_step:
-            step = 1
-
         # len = ceil( (stop - start) / step )
         with cython.cdivision(True):
             new_shape = (stop - start) // step
@@ -885,7 +892,7 @@
         dst.shape[new_ndim] = new_shape
         dst.suboffsets[new_ndim] = suboffset
 
-    # Add the slicing or idexing offsets to the right suboffset or base data *
+    # Add the slicing or indexing offsets to the right suboffset or base data *
     if suboffset_dim[0] < 0:
         dst.data += start * stride
     else:
@@ -896,7 +903,7 @@
             if new_ndim == 0:
                 dst.data = (<char **> dst.data)[0] + suboffset
             else:
-                _err_dim(IndexError, "All dimensions preceding dimension %d "
+                _err_dim(PyExc_IndexError, "All dimensions preceding dimension %d "
                                      "must be indexed and not sliced", dim)
         else:
             suboffset_dim[0] = new_ndim
@@ -914,7 +921,7 @@
     cdef char *resultp
 
     if view.ndim == 0:
-        shape = view.len / itemsize
+        shape = view.len // itemsize
         stride = itemsize
     else:
         shape = view.shape[dim]
@@ -925,6 +932,6 @@
     if index < 0:
         index += view.shape[dim]
         if index < 0:
-            raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+            raise IndexError(f"Out of bounds on buffer access (axis {dim})")
 
     if index >= shape:
@@ -929,6 +936,6 @@
 
     if index >= shape:
-        raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+        raise IndexError(f"Out of bounds on buffer access (axis {dim})")
 
     resultp = bufp + index * stride
     if suboffset >= 0:
@@ -940,7 +947,7 @@
 ### Transposing a memoryviewslice
 #
 @cname('__pyx_memslice_transpose')
-cdef int transpose_memslice({{memviewslice_name}} *memslice) nogil except 0:
+cdef int transpose_memslice({{memviewslice_name}} *memslice) nogil except -1:
     cdef int ndim = memslice.memview.view.ndim
 
     cdef Py_ssize_t *shape = memslice.shape
@@ -948,9 +955,9 @@
 
     # reverse strides and shape
     cdef int i, j
-    for i in range(ndim / 2):
+    for i in range(ndim // 2):
         j = ndim - 1 - i
         strides[i], strides[j] = strides[j], strides[i]
         shape[i], shape[j] = shape[j], shape[i]
 
         if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0:
@@ -952,7 +959,7 @@
         j = ndim - 1 - i
         strides[i], strides[j] = strides[j], strides[i]
         shape[i], shape[j] = shape[j], shape[i]
 
         if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0:
-            _err(ValueError, "Cannot transpose memoryview with indirect dimensions")
+            _err(PyExc_ValueError, "Cannot transpose memoryview with indirect dimensions")
 
@@ -958,5 +965,5 @@
 
-    return 1
+    return 0
 
 #
 ### Creating new memoryview objects from slices and memoryviews
@@ -988,8 +995,7 @@
         else:
             memoryview.assign_item_from_object(self, itemp, value)
 
-    @property
-    def base(self):
+    cdef _get_base(self):
         return self.from_object
 
     __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)")
@@ -1010,8 +1016,8 @@
     # assert 0 < ndim <= memviewslice.memview.view.ndim, (
     #                 ndim, memviewslice.memview.view.ndim)
 
-    result = _memoryviewslice(None, 0, dtype_is_object)
+    result = _memoryviewslice.__new__(_memoryviewslice, None, 0, dtype_is_object)
 
     result.from_slice = memviewslice
     __PYX_INC_MEMVIEW(&memviewslice, 1)
 
@@ -1014,8 +1020,8 @@
 
     result.from_slice = memviewslice
     __PYX_INC_MEMVIEW(&memviewslice, 1)
 
-    result.from_object = (<memoryview> memviewslice.memview).base
+    result.from_object = (<memoryview> memviewslice.memview)._get_base()
     result.typeinfo = memviewslice.memview.typeinfo
 
     result.view = memviewslice.memview.view
@@ -1107,10 +1113,7 @@
 ### Copy the contents of a memoryview slices
 #
 cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil:
-    if arg < 0:
-        return -arg
-    else:
-        return arg
+    return -arg if arg < 0 else arg
 
 @cname('__pyx_get_best_slice_order')
 cdef char get_best_order({{memviewslice_name}} *mslice, int ndim) nogil:
@@ -1221,7 +1224,7 @@
 
     result = malloc(size)
     if not result:
-        _err(MemoryError, NULL)
+        _err_no_memory()
 
     # tmpslice[0] = src
     tmpslice.data = <char *> result
@@ -1230,8 +1233,7 @@
         tmpslice.shape[i] = src.shape[i]
         tmpslice.suboffsets[i] = -1
 
-    fill_contig_strides_array(&tmpslice.shape[0], &tmpslice.strides[0], itemsize,
-                              ndim, order)
+    fill_contig_strides_array(&tmpslice.shape[0], &tmpslice.strides[0], itemsize, ndim, order)
 
     # We need to broadcast strides again
     for i in range(ndim):
@@ -1250,7 +1252,6 @@
 @cname('__pyx_memoryview_err_extents')
 cdef int _err_extents(int i, Py_ssize_t extent1,
                              Py_ssize_t extent2) except -1 with gil:
-    raise ValueError("got differing extents in dimension %d (got %d and %d)" %
-                                                        (i, extent1, extent2))
+    raise ValueError(f"got differing extents in dimension {i} (got {extent1} and {extent2})")
 
 @cname('__pyx_memoryview_err_dim')
@@ -1255,6 +1256,6 @@
 
 @cname('__pyx_memoryview_err_dim')
-cdef int _err_dim(object error, char *msg, int dim) except -1 with gil:
-    raise error(msg.decode('ascii') % dim)
+cdef int _err_dim(PyObject *error, str msg, int dim) except -1 with gil:
+    raise (<object>error)(msg % dim)
 
 @cname('__pyx_memoryview_err')
@@ -1259,10 +1260,12 @@
 
 @cname('__pyx_memoryview_err')
-cdef int _err(object error, char *msg) except -1 with gil:
-    if msg != NULL:
-        raise error(msg.decode('ascii'))
-    else:
-        raise error
+cdef int _err(PyObject *error, str msg) except -1 with gil:
+    raise (<object>error)(msg)
+
+@cname('__pyx_memoryview_err_no_memory')
+cdef int _err_no_memory() except -1 with gil:
+    raise MemoryError
+
 
 @cname('__pyx_memoryview_copy_contents')
 cdef int memoryview_copy_contents({{memviewslice_name}} src,
@@ -1297,7 +1300,7 @@
                 _err_extents(i, dst.shape[i], src.shape[i])
 
         if src.suboffsets[i] >= 0:
-            _err_dim(ValueError, "Dimension %d is not direct", i)
+            _err_dim(PyExc_ValueError, "Dimension %d is not direct", i)
 
     if slices_overlap(&src, &dst, ndim, itemsize):
         # slices overlap, copy to temp, copy temp to dst
@@ -1317,5 +1320,5 @@
 
         if direct_copy:
             # Contiguous slices with same order
-            refcount_copying(&dst, dtype_is_object, ndim, False)
+            refcount_copying(&dst, dtype_is_object, ndim, inc=False)
             memcpy(dst.data, src.data, slice_get_size(&src, ndim))
@@ -1321,5 +1324,5 @@
             memcpy(dst.data, src.data, slice_get_size(&src, ndim))
-            refcount_copying(&dst, dtype_is_object, ndim, True)
+            refcount_copying(&dst, dtype_is_object, ndim, inc=True)
             free(tmpdata)
             return 0
 
@@ -1329,5 +1332,5 @@
         transpose_memslice(&src)
         transpose_memslice(&dst)
 
-    refcount_copying(&dst, dtype_is_object, ndim, False)
+    refcount_copying(&dst, dtype_is_object, ndim, inc=False)
     copy_strided_to_strided(&src, &dst, ndim, itemsize)
@@ -1333,5 +1336,5 @@
     copy_strided_to_strided(&src, &dst, ndim, itemsize)
-    refcount_copying(&dst, dtype_is_object, ndim, True)
+    refcount_copying(&dst, dtype_is_object, ndim, inc=True)
 
     free(tmpdata)
     return 0
@@ -1359,8 +1362,6 @@
 #
 
 @cname('__pyx_memoryview_refcount_copying')
-cdef void refcount_copying({{memviewslice_name}} *dst, bint dtype_is_object,
-                           int ndim, bint inc) nogil:
-    # incref or decref the objects in the destination slice if the dtype is
-    # object
+cdef void refcount_copying({{memviewslice_name}} *dst, bint dtype_is_object, int ndim, bint inc) nogil:
+    # incref or decref the objects in the destination slice if the dtype is object
     if dtype_is_object:
@@ -1366,6 +1367,5 @@
     if dtype_is_object:
-        refcount_objects_in_slice_with_gil(dst.data, dst.shape,
-                                           dst.strides, ndim, inc)
+        refcount_objects_in_slice_with_gil(dst.data, dst.shape, dst.strides, ndim, inc)
 
 @cname('__pyx_memoryview_refcount_objects_in_slice_with_gil')
 cdef void refcount_objects_in_slice_with_gil(char *data, Py_ssize_t *shape,
@@ -1377,6 +1377,7 @@
 cdef void refcount_objects_in_slice(char *data, Py_ssize_t *shape,
                                     Py_ssize_t *strides, int ndim, bint inc):
     cdef Py_ssize_t i
+    cdef Py_ssize_t stride = strides[0]
 
     for i in range(shape[0]):
         if ndim == 1:
@@ -1385,6 +1386,5 @@
             else:
                 Py_DECREF((<PyObject **> data)[0])
         else:
-            refcount_objects_in_slice(data, shape + 1, strides + 1,
-                                      ndim - 1, inc)
+            refcount_objects_in_slice(data, shape + 1, strides + 1, ndim - 1, inc)
 
@@ -1390,5 +1390,5 @@
 
-        data += strides[0]
+        data += stride
 
 #
 ### Scalar to slice assignment
@@ -1397,10 +1397,9 @@
 cdef void slice_assign_scalar({{memviewslice_name}} *dst, int ndim,
                               size_t itemsize, void *item,
                               bint dtype_is_object) nogil:
-    refcount_copying(dst, dtype_is_object, ndim, False)
-    _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim,
-                         itemsize, item)
-    refcount_copying(dst, dtype_is_object, ndim, True)
+    refcount_copying(dst, dtype_is_object, ndim, inc=False)
+    _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim, itemsize, item)
+    refcount_copying(dst, dtype_is_object, ndim, inc=True)
 
 
 @cname('__pyx_memoryview__slice_assign_scalar')
@@ -1417,8 +1416,7 @@
             data += stride
     else:
         for i in range(extent):
-            _slice_assign_scalar(data, shape + 1, strides + 1,
-                                ndim - 1, itemsize, item)
+            _slice_assign_scalar(data, shape + 1, strides + 1, ndim - 1, itemsize, item)
             data += stride
 
 
@@ -1464,6 +1462,7 @@
     cdef __Pyx_StructField *field
     cdef __pyx_typeinfo_string fmt
     cdef bytes part, result
+    cdef Py_ssize_t i
 
     if type.typegroup == 'S':
         assert type.fields != NULL and type.fields.type != NULL
@@ -1484,4 +1483,5 @@
         result = alignment.join(parts) + b'}'
     else:
         fmt = __Pyx_TypeInfoToFormat(type)
+        result = fmt.string
         if type.arraysize[0]:
@@ -1487,7 +1487,5 @@
         if type.arraysize[0]:
-            extents = [unicode(type.arraysize[i]) for i in range(type.ndim)]
-            result = (u"(%s)" % u','.join(extents)).encode('ascii') + fmt.string
-        else:
-            result = fmt.string
+            extents = [f"{type.arraysize[i]}" for i in range(type.ndim)]
+            result = f"({u','.join(extents)})".encode('ascii') + result
 
     return result
diff --git a/Cython/Utility/MemoryView_C.c b/Cython/Utility/MemoryView_C.c
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1V0aWxpdHkvTWVtb3J5Vmlld19DLmM=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1V0aWxpdHkvTWVtb3J5Vmlld19DLmM= 100644
--- a/Cython/Utility/MemoryView_C.c
+++ b/Cython/Utility/MemoryView_C.c
@@ -927,7 +927,7 @@
 ////////// FillStrided1DScalar //////////
 
 /* Fill a slice with a scalar value. The dimension is direct and strided or contiguous */
-/* This can be used as a callback for the memoryview object to efficienty assign a scalar */
+/* This can be used as a callback for the memoryview object to efficiently assign a scalar */
 /* Currently unused */
 static void
 __pyx_fill_slice_{{dtype_name}}({{type_decl}} *p, Py_ssize_t extent, Py_ssize_t stride,
diff --git a/Cython/Utility/ModuleSetupCode.c b/Cython/Utility/ModuleSetupCode.c
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1V0aWxpdHkvTW9kdWxlU2V0dXBDb2RlLmM=..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1V0aWxpdHkvTW9kdWxlU2V0dXBDb2RlLmM= 100644
--- a/Cython/Utility/ModuleSetupCode.c
+++ b/Cython/Utility/ModuleSetupCode.c
@@ -1,3 +1,16 @@
+/////////////// InitLimitedAPI ///////////////
+
+#if defined(CYTHON_LIMITED_API) && 0  /* disabled: enabling Py_LIMITED_API needs more work */
+  #ifndef Py_LIMITED_API
+    #if CYTHON_LIMITED_API+0 > 0x03030000
+      #define Py_LIMITED_API CYTHON_LIMITED_API
+    #else
+      #define Py_LIMITED_API 0x03030000
+    #endif
+  #endif
+#endif
+
+
 /////////////// CModulePreamble ///////////////
 
 #include <stddef.h> /* For offsetof */
@@ -29,9 +42,7 @@
 
 #ifndef HAVE_LONG_LONG
   // CPython has required PY_LONG_LONG support for years, even if HAVE_LONG_LONG is not defined for us
-  #if PY_VERSION_HEX >= 0x02070000
-    #define HAVE_LONG_LONG
-  #endif
+  #define HAVE_LONG_LONG
 #endif
 
 #ifndef PY_LONG_LONG
@@ -46,6 +57,7 @@
   #define CYTHON_COMPILING_IN_PYPY 1
   #define CYTHON_COMPILING_IN_PYSTON 0
   #define CYTHON_COMPILING_IN_CPYTHON 0
+  #define CYTHON_COMPILING_IN_LIMITED_API 0
 
   #undef CYTHON_USE_TYPE_SLOTS
   #define CYTHON_USE_TYPE_SLOTS 0
@@ -73,5 +85,9 @@
   #define CYTHON_UNPACK_METHODS 0
   #undef CYTHON_FAST_THREAD_STATE
   #define CYTHON_FAST_THREAD_STATE 0
+  #undef CYTHON_FAST_GIL
+  #define CYTHON_FAST_GIL 0
+  #undef CYTHON_METH_FASTCALL
+  #define CYTHON_METH_FASTCALL 0
   #undef CYTHON_FAST_PYCALL
   #define CYTHON_FAST_PYCALL 0
@@ -76,5 +92,8 @@
   #undef CYTHON_FAST_PYCALL
   #define CYTHON_FAST_PYCALL 0
+  #ifndef CYTHON_PEP487_INIT_SUBCLASS
+    #define CYTHON_PEP487_INIT_SUBCLASS (PY_MAJOR_VERSION >= 3)
+  #endif
   #undef CYTHON_PEP489_MULTI_PHASE_INIT
   #define CYTHON_PEP489_MULTI_PHASE_INIT 0
   #undef CYTHON_USE_TP_FINALIZE
@@ -88,6 +107,7 @@
   #define CYTHON_COMPILING_IN_PYPY 0
   #define CYTHON_COMPILING_IN_PYSTON 1
   #define CYTHON_COMPILING_IN_CPYTHON 0
+  #define CYTHON_COMPILING_IN_LIMITED_API 0
 
   #ifndef CYTHON_USE_TYPE_SLOTS
     #define CYTHON_USE_TYPE_SLOTS 1
@@ -116,5 +136,9 @@
   #endif
   #undef CYTHON_FAST_THREAD_STATE
   #define CYTHON_FAST_THREAD_STATE 0
+  #undef CYTHON_FAST_GIL
+  #define CYTHON_FAST_GIL 0
+  #undef CYTHON_METH_FASTCALL
+  #define CYTHON_METH_FASTCALL 0
   #undef CYTHON_FAST_PYCALL
   #define CYTHON_FAST_PYCALL 0
@@ -119,5 +143,7 @@
   #undef CYTHON_FAST_PYCALL
   #define CYTHON_FAST_PYCALL 0
+  #undef CYTHON_PEP487_INIT_SUBCLASS
+  #define CYTHON_PEP487_INIT_SUBCLASS 0
   #undef CYTHON_PEP489_MULTI_PHASE_INIT
   #define CYTHON_PEP489_MULTI_PHASE_INIT 0
   #undef CYTHON_USE_TP_FINALIZE
@@ -127,7 +153,55 @@
   #undef CYTHON_USE_EXC_INFO_STACK
   #define CYTHON_USE_EXC_INFO_STACK 0
 
+#elif defined(CYTHON_LIMITED_API)
+  #define CYTHON_COMPILING_IN_PYPY 0
+  #define CYTHON_COMPILING_IN_PYSTON 0
+  #define CYTHON_COMPILING_IN_CPYTHON 0
+  #define CYTHON_COMPILING_IN_LIMITED_API 1
+
+  #undef CYTHON_USE_TYPE_SLOTS
+  #define CYTHON_USE_TYPE_SLOTS 0
+  #undef CYTHON_USE_PYTYPE_LOOKUP
+  #define CYTHON_USE_PYTYPE_LOOKUP 0
+  #undef CYTHON_USE_PYLIST_INTERNALS
+  #define CYTHON_USE_ASYNC_SLOTS 0
+  #define CYTHON_USE_PYLIST_INTERNALS 0
+  #undef CYTHON_USE_UNICODE_INTERNALS
+  #define CYTHON_USE_UNICODE_INTERNALS 0
+  #ifndef CYTHON_USE_UNICODE_WRITER
+    #define CYTHON_USE_UNICODE_WRITER 1
+  #endif
+  #undef CYTHON_USE_PYLONG_INTERNALS
+  #define CYTHON_USE_PYLONG_INTERNALS 0
+  #ifndef CYTHON_AVOID_BORROWED_REFS
+    #define CYTHON_AVOID_BORROWED_REFS 0
+  #endif
+  #undef CYTHON_ASSUME_SAFE_MACROS
+  #define CYTHON_ASSUME_SAFE_MACROS 0
+  #undef CYTHON_UNPACK_METHODS
+  #define CYTHON_UNPACK_METHODS 0
+  #undef CYTHON_FAST_THREAD_STATE
+  #define CYTHON_FAST_THREAD_STATE 0
+  #undef CYTHON_FAST_GIL
+  #define CYTHON_FAST_GIL 0
+  #undef CYTHON_METH_FASTCALL
+  #define CYTHON_METH_FASTCALL 0
+  #undef CYTHON_FAST_PYCALL
+  #define CYTHON_FAST_PYCALL 0
+  #ifndef CYTHON_PEP487_INIT_SUBCLASS
+    #define CYTHON_PEP487_INIT_SUBCLASS 1
+  #endif
+  #undef CYTHON_PEP489_MULTI_PHASE_INIT
+  #define CYTHON_PEP489_MULTI_PHASE_INIT 0
+  #ifndef CYTHON_USE_TP_FINALIZE
+    #define CYTHON_USE_TP_FINALIZE 1
+  #endif
+  #undef CYTHON_USE_DICT_VERSIONS
+  #define CYTHON_USE_DICT_VERSIONS 0
+  #undef CYTHON_USE_EXC_INFO_STACK
+  #define CYTHON_USE_EXC_INFO_STACK 0
+
 #else
   #define CYTHON_COMPILING_IN_PYPY 0
   #define CYTHON_COMPILING_IN_PYSTON 0
   #define CYTHON_COMPILING_IN_CPYTHON 1
@@ -130,8 +204,9 @@
 #else
   #define CYTHON_COMPILING_IN_PYPY 0
   #define CYTHON_COMPILING_IN_PYSTON 0
   #define CYTHON_COMPILING_IN_CPYTHON 1
+  #define CYTHON_COMPILING_IN_LIMITED_API 0
 
   #ifndef CYTHON_USE_TYPE_SLOTS
     #define CYTHON_USE_TYPE_SLOTS 1
   #endif
@@ -134,12 +209,8 @@
 
   #ifndef CYTHON_USE_TYPE_SLOTS
     #define CYTHON_USE_TYPE_SLOTS 1
   #endif
-  #if PY_VERSION_HEX < 0x02070000
-    // looks like calling _PyType_Lookup() isn't safe in Py<=2.6/3.1
-    #undef CYTHON_USE_PYTYPE_LOOKUP
-    #define CYTHON_USE_PYTYPE_LOOKUP 0
-  #elif !defined(CYTHON_USE_PYTYPE_LOOKUP)
+  #ifndef CYTHON_USE_PYTYPE_LOOKUP
     #define CYTHON_USE_PYTYPE_LOOKUP 1
   #endif
   #if PY_MAJOR_VERSION < 3
@@ -148,10 +219,7 @@
   #elif !defined(CYTHON_USE_ASYNC_SLOTS)
     #define CYTHON_USE_ASYNC_SLOTS 1
   #endif
-  #if PY_VERSION_HEX < 0x02070000
-    #undef CYTHON_USE_PYLONG_INTERNALS
-    #define CYTHON_USE_PYLONG_INTERNALS 0
-  #elif !defined(CYTHON_USE_PYLONG_INTERNALS)
+  #ifndef CYTHON_USE_PYLONG_INTERNALS
     #define CYTHON_USE_PYLONG_INTERNALS 1
   #endif
   #ifndef CYTHON_USE_PYLIST_INTERNALS
@@ -178,6 +246,15 @@
   #ifndef CYTHON_FAST_THREAD_STATE
     #define CYTHON_FAST_THREAD_STATE 1
   #endif
+  #ifndef CYTHON_FAST_GIL
+    // Py3<3.5.2 does not support _PyThreadState_UncheckedGet().
+    #define CYTHON_FAST_GIL (PY_MAJOR_VERSION < 3 || PY_VERSION_HEX >= 0x03060000)
+  #endif
+  #ifndef CYTHON_METH_FASTCALL
+    // CPython 3.6 introduced METH_FASTCALL but with slightly different
+    // semantics. It became stable starting from CPython 3.7.
+    #define CYTHON_METH_FASTCALL (PY_VERSION_HEX >= 0x030700A1)
+  #endif
   #ifndef CYTHON_FAST_PYCALL
     #define CYTHON_FAST_PYCALL 1
   #endif
@@ -181,6 +258,9 @@
   #ifndef CYTHON_FAST_PYCALL
     #define CYTHON_FAST_PYCALL 1
   #endif
+  #ifndef CYTHON_PEP487_INIT_SUBCLASS
+    #define CYTHON_PEP487_INIT_SUBCLASS 1
+  #endif
   #ifndef CYTHON_PEP489_MULTI_PHASE_INIT
     #define CYTHON_PEP489_MULTI_PHASE_INIT (PY_VERSION_HEX >= 0x03050000)
   #endif
@@ -199,6 +279,13 @@
 #define CYTHON_FAST_PYCCALL  (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1)
 #endif
 
+#if !defined(CYTHON_VECTORCALL)
+#define CYTHON_VECTORCALL  (CYTHON_FAST_PYCCALL && PY_VERSION_HEX >= 0x030800B1)
+#endif
+
+/* Whether to use METH_FASTCALL with a fake backported implementation of vectorcall */
+#define CYTHON_BACKPORT_VECTORCALL (CYTHON_METH_FASTCALL && PY_VERSION_HEX < 0x030800B1)
+
 #if CYTHON_USE_PYLONG_INTERNALS
   #include "longintrepr.h"
   /* These short defines can easily conflict with other code */
@@ -268,6 +355,7 @@
 #ifdef _MSC_VER
     #ifndef _MSC_STDINT_H_
         #if _MSC_VER < 1300
-           typedef unsigned char     uint8_t;
-           typedef unsigned int      uint32_t;
+            typedef unsigned char     uint8_t;
+            typedef unsigned short    uint16_t;
+            typedef unsigned int      uint32_t;
         #else
@@ -273,9 +361,23 @@
         #else
-           typedef unsigned __int8   uint8_t;
-           typedef unsigned __int32  uint32_t;
+            typedef unsigned __int8   uint8_t;
+            typedef unsigned __int16  uint16_t;
+            typedef unsigned __int32  uint32_t;
+        #endif
+    #endif
+    #if _MSC_VER < 1300
+        #ifdef _WIN64
+            typedef unsigned long long  __pyx_uintptr_t;
+        #else
+            typedef unsigned int        __pyx_uintptr_t;
+        #endif
+    #else
+        #ifdef _WIN64
+            typedef unsigned __int64    __pyx_uintptr_t;
+        #else
+            typedef unsigned __int32    __pyx_uintptr_t;
         #endif
     #endif
 #else
    #ifndef __VMS
       #include <stdint.h>
    #endif
@@ -276,9 +378,10 @@
         #endif
     #endif
 #else
    #ifndef __VMS
       #include <stdint.h>
    #endif
+    typedef uintptr_t  __pyx_uintptr_t;
 #endif
 
 
@@ -342,7 +445,7 @@
   #endif
 #endif
 
-// Work around clang bug http://stackoverflow.com/questions/21847816/c-invoke-nested-template-class-destructor
+// Work around clang bug https://stackoverflow.com/questions/21847816/c-invoke-nested-template-class-destructor
 template<typename T>
 void __Pyx_call_destructor(T& x) {
     x.~T();
@@ -378,5 +481,6 @@
 
 #if PY_MAJOR_VERSION < 3
   #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
-  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+  #define __Pyx_DefaultClassType PyClass_Type
+  #define __Pyx_PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
           PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
@@ -382,4 +486,3 @@
           PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
-  #define __Pyx_DefaultClassType PyClass_Type
 #else
   #define __Pyx_BUILTIN_MODULE_NAME "builtins"
@@ -384,6 +487,11 @@
 #else
   #define __Pyx_BUILTIN_MODULE_NAME "builtins"
-#if PY_VERSION_HEX >= 0x030800A4 && PY_VERSION_HEX < 0x030800B2
-  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
-          PyCode_New(a, 0, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+  #define __Pyx_DefaultClassType PyType_Type
+#if PY_VERSION_HEX >= 0x030800B2
+  #define __Pyx_PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_NewWithPosOnlyArgs(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+#elif PY_VERSION_HEX >= 0x030800A4
+  // TODO: remove this special case once Py3.8 is released.
+  #define __Pyx_PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
 #else
@@ -389,4 +497,4 @@
 #else
-  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+  #define __Pyx_PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
           PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
 #endif
@@ -391,6 +499,11 @@
           PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
 #endif
-  #define __Pyx_DefaultClassType PyType_Type
+#endif
+
+#if PY_VERSION_HEX >= 0x030900A4 || defined(Py_IS_TYPE)
+  #define __Pyx_IS_TYPE(ob, type) Py_IS_TYPE(ob, type)
+#else
+  #define __Pyx_IS_TYPE(ob, type) (((const PyObject*)ob)->ob_type == (type))
 #endif
 
 #ifndef Py_TPFLAGS_CHECKTYPES
@@ -428,7 +541,9 @@
   #define __Pyx_PyCFunctionFast _PyCFunctionFast
   #define __Pyx_PyCFunctionFastWithKeywords _PyCFunctionFastWithKeywords
 #endif
-#if CYTHON_FAST_PYCCALL
-#define __Pyx_PyFastCFunction_Check(func) \
-    ((PyCFunction_Check(func) && (METH_FASTCALL == (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS)))))
+
+#if CYTHON_METH_FASTCALL
+  #define __Pyx_METH_FASTCALL METH_FASTCALL
+  #define __Pyx_PyCFunction_FastCall __Pyx_PyCFunctionFast
+  #define __Pyx_PyCFunction_FastCallWithKeywords __Pyx_PyCFunctionFastWithKeywords
 #else
@@ -434,5 +549,21 @@
 #else
-#define __Pyx_PyFastCFunction_Check(func) 0
+  #define __Pyx_METH_FASTCALL METH_VARARGS
+  #define __Pyx_PyCFunction_FastCall PyCFunction
+  #define __Pyx_PyCFunction_FastCallWithKeywords PyCFunctionWithKeywords
+#endif
+
+#if CYTHON_VECTORCALL
+  #define __pyx_vectorcallfunc vectorcallfunc
+  #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET  PY_VECTORCALL_ARGUMENTS_OFFSET
+  #define __Pyx_PyVectorcall_NARGS(n)  PyVectorcall_NARGS(n)
+#elif CYTHON_BACKPORT_VECTORCALL
+  typedef PyObject *(*__pyx_vectorcallfunc)(PyObject *callable, PyObject *const *args,
+                                            size_t nargsf, PyObject *kwnames);
+  #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET  ((size_t)1 << (8 * sizeof(size_t) - 1))
+  #define __Pyx_PyVectorcall_NARGS(n)  ((n) & ~__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)
+#else
+  #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET  0
+  #define __Pyx_PyVectorcall_NARGS(n)  (n)
 #endif
 
 #if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc)
@@ -451,8 +582,11 @@
   // special C-API functions only in Pyston
   #define __Pyx_PyCode_HasFreeVars(co)  PyCode_HasFreeVars(co)
   #define __Pyx_PyFrame_SetLineNumber(frame, lineno) PyFrame_SetLineNumber(frame, lineno)
+#elif CYTHON_COMPILING_IN_LIMITED_API
+  #define __Pyx_PyCode_HasFreeVars(co)  (PyCode_GetNumFree(co) > 0)
+  #define __Pyx_PyFrame_SetLineNumber(frame, lineno)
 #else
   #define __Pyx_PyCode_HasFreeVars(co)  (PyCode_GetNumFree(co) > 0)
   #define __Pyx_PyFrame_SetLineNumber(frame, lineno)  (frame)->f_lineno = (lineno)
 #endif
 
@@ -454,9 +588,11 @@
 #else
   #define __Pyx_PyCode_HasFreeVars(co)  (PyCode_GetNumFree(co) > 0)
   #define __Pyx_PyFrame_SetLineNumber(frame, lineno)  (frame)->f_lineno = (lineno)
 #endif
 
-#if !CYTHON_FAST_THREAD_STATE || PY_VERSION_HEX < 0x02070000
+#if CYTHON_COMPILING_IN_LIMITED_API
+  #define __Pyx_PyThreadState_Current PyThreadState_Get()
+#elif !CYTHON_FAST_THREAD_STATE
   #define __Pyx_PyThreadState_Current PyThreadState_GET()
 #elif PY_VERSION_HEX >= 0x03060000
   //#elif PY_VERSION_HEX >= 0x03050200
@@ -468,6 +604,18 @@
   #define __Pyx_PyThreadState_Current _PyThreadState_Current
 #endif
 
+#if CYTHON_COMPILING_IN_LIMITED_API
+static inline void *__Pyx_PyModule_GetState(PyObject *op)
+{
+    void *result;
+
+    result = PyModule_GetState(op);
+    if (!result)
+        Py_FatalError("Couldn't find the module state");
+    return result;
+}
+#endif
+
 // TSS (Thread Specific Storage) API
 #if PY_VERSION_HEX < 0x030700A2 && !defined(PyThread_tss_create) && !defined(Py_tss_NEEDS_INIT)
 #include "pythread.h"
@@ -516,6 +664,16 @@
   #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceDivide(x,y)
 #endif
 
-#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 && CYTHON_USE_UNICODE_INTERNALS
-#define __Pyx_PyDict_GetItemStr(dict, name)  _PyDict_GetItem_KnownHash(dict, name, ((PyASCIIObject *) name)->hash)
+#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX > 0x030600B4 && CYTHON_USE_UNICODE_INTERNALS
+// _PyDict_GetItem_KnownHash() exists since CPython 3.5, but it was
+// dropping exceptions. Since 3.6, exceptions are kept.
+#define __Pyx_PyDict_GetItemStrWithError(dict, name)  _PyDict_GetItem_KnownHash(dict, name, ((PyASCIIObject *) name)->hash)
+static CYTHON_INLINE PyObject * __Pyx_PyDict_GetItemStr(PyObject *dict, PyObject *name) {
+    PyObject *res = __Pyx_PyDict_GetItemStrWithError(dict, name);
+    if (res == NULL) PyErr_Clear();
+    return res;
+}
+#elif PY_MAJOR_VERSION >= 3 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07020000)
+#define __Pyx_PyDict_GetItemStrWithError  PyDict_GetItemWithError
+#define __Pyx_PyDict_GetItemStr           PyDict_GetItem
 #else
@@ -521,4 +679,10 @@
 #else
-#define __Pyx_PyDict_GetItemStr(dict, name)  PyDict_GetItem(dict, name)
+static CYTHON_INLINE PyObject * __Pyx_PyDict_GetItemStrWithError(PyObject *dict, PyObject *name) {
+    PyObject *res = PyObject_GetItem(dict, name);
+    if (res == NULL && PyErr_ExceptionMatches(PyExc_KeyError))
+        PyErr_Clear();
+    return res;
+}
+#define __Pyx_PyDict_GetItemStr           PyDict_GetItem
 #endif
 
@@ -523,7 +687,32 @@
 #endif
 
-/* new Py3.3 unicode type (PEP 393) */
-#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
+/* Type slots */
+#if CYTHON_COMPILING_IN_LIMITED_API
+  #if defined(_PyType_Name)
+    #define __Pyx_PyType_Name(tp)     (_PyType_Name((PyTypeObject *)tp))
+  #else
+    #define __Pyx_PyType_Name(tp)     (((PyTypeObject *)tp)->tp_name)
+  #endif
+  #define __Pyx_PyType_GetFlags(tp)   (PyType_GetFlags((PyTypeObject *)tp))
+#else
+  #define __Pyx_PyType_Name(tp)       (((PyTypeObject *)tp)->tp_name)
+  #define __Pyx_PyType_GetFlags(tp)   (((PyTypeObject *)tp)->tp_flags)
+#endif
+
+#if CYTHON_COMPILING_IN_LIMITED_API
+  #define CYTHON_PEP393_ENABLED 1
+  #define __Pyx_PyUnicode_READY(op)       (0)
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GetLength(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_ReadChar(u, i)
+  #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u)   ((void)u, 1114111)
+  #define __Pyx_PyUnicode_KIND(u)         ((void)u, (0))
+  // __Pyx_PyUnicode_DATA() and __Pyx_PyUnicode_READ() must go together, e.g. for iteration.
+  #define __Pyx_PyUnicode_DATA(u)         ((void*)u)
+  #define __Pyx_PyUnicode_READ(k, d, i)   ((void)k, PyUnicode_ReadChar((PyObject*)(d), i))
+  //#define __Pyx_PyUnicode_WRITE(k, d, i, ch)  /* not available */
+  #define __Pyx_PyUnicode_IS_TRUE(u)      (0 != PyUnicode_GetLength(u))
+#elif PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
+  /* new Py3.3 unicode type (PEP 393) */
   #define CYTHON_PEP393_ENABLED 1
   #define __Pyx_PyUnicode_READY(op)       (likely(PyUnicode_IS_READY(op)) ? \
                                               0 : _PyUnicode_Ready((PyObject *)(op)))
@@ -546,7 +735,7 @@
   #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u)   ((sizeof(Py_UNICODE) == 2) ? 65535 : 1114111)
   #define __Pyx_PyUnicode_KIND(u)         (sizeof(Py_UNICODE))
   #define __Pyx_PyUnicode_DATA(u)         ((void*)PyUnicode_AS_UNICODE(u))
-  /* (void)(k) => avoid unused variable warning due to macro: */
+  // (void)(k) => avoid unused variable warning due to macro:
   #define __Pyx_PyUnicode_READ(k, d, i)   ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i]))
   #define __Pyx_PyUnicode_WRITE(k, d, i, ch)  (((void)(k)), ((Py_UNICODE*)d)[i] = ch)
   #define __Pyx_PyUnicode_IS_TRUE(u)      (0 != PyUnicode_GET_SIZE(u))
@@ -607,4 +796,11 @@
   #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj))
 #endif
 
+#if CYTHON_COMPILING_IN_CPYTHON
+  #define __Pyx_PySequence_ListKeepNew(obj) \
+    (likely(PyList_CheckExact(obj) && Py_REFCNT(obj) == 1) ? __Pyx_NewRef(obj) : PySequence_List(obj))
+#else
+  #define __Pyx_PySequence_ListKeepNew(obj)  PySequence_List(obj)
+#endif
+
 #ifndef PySet_CheckExact
@@ -610,5 +806,5 @@
 #ifndef PySet_CheckExact
-  #define PySet_CheckExact(obj)        (Py_TYPE(obj) == &PySet_Type)
+  #define PySet_CheckExact(obj)        __Pyx_IS_TYPE(obj, &PySet_Type)
 #endif
 
 #if CYTHON_ASSUME_SAFE_MACROS
@@ -649,6 +845,6 @@
 #if PY_VERSION_HEX < 0x030200A4
   typedef long Py_hash_t;
   #define __Pyx_PyInt_FromHash_t PyInt_FromLong
-  #define __Pyx_PyInt_AsHash_t   PyInt_AsLong
+  #define __Pyx_PyInt_AsHash_t   __Pyx_PyIndex_AsHash_t
 #else
   #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
@@ -653,12 +849,6 @@
 #else
   #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
-  #define __Pyx_PyInt_AsHash_t   PyInt_AsSsize_t
-#endif
-
-#if PY_MAJOR_VERSION >= 3
-  #define __Pyx_PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : (Py_INCREF(func), func))
-#else
-  #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass)
+  #define __Pyx_PyInt_AsHash_t   __Pyx_PyIndex_AsSsize_t
 #endif
 
 // backport of PyAsyncMethods from Py3.5 to older Py3.x versions
@@ -933,4 +1123,7 @@
     return 0;
 }
 
+#if CYTHON_COMPILING_IN_LIMITED_API
+static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *module, const char* from_name, const char* to_name, int allow_none) {
+#else
 static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name, int allow_none) {
@@ -936,5 +1129,6 @@
 static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name, int allow_none) {
+#endif
     PyObject *value = PyObject_GetAttrString(spec, from_name);
     int result = 0;
     if (likely(value)) {
         if (allow_none || value != Py_None) {
@@ -937,5 +1131,8 @@
     PyObject *value = PyObject_GetAttrString(spec, from_name);
     int result = 0;
     if (likely(value)) {
         if (allow_none || value != Py_None) {
+#if CYTHON_COMPILING_IN_LIMITED_API
+            result = PyModule_AddObject(module, to_name, value);
+#else
             result = PyDict_SetItemString(moddict, to_name, value);
@@ -941,4 +1138,5 @@
             result = PyDict_SetItemString(moddict, to_name, value);
+#endif
         }
         Py_DECREF(value);
     } else if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
@@ -965,6 +1163,9 @@
     Py_DECREF(modname);
     if (unlikely(!module)) goto bad;
 
+#if CYTHON_COMPILING_IN_LIMITED_API
+    moddict = module;
+#else
     moddict = PyModule_GetDict(module);
     if (unlikely(!moddict)) goto bad;
     // moddict is a borrowed reference
@@ -968,6 +1169,7 @@
     moddict = PyModule_GetDict(module);
     if (unlikely(!moddict)) goto bad;
     // moddict is a borrowed reference
+#endif
 
     if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__", 1) < 0)) goto bad;
     if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__", 1) < 0)) goto bad;
@@ -984,6 +1186,7 @@
 
 /////////////// CodeObjectCache.proto ///////////////
 
+#if !CYTHON_COMPILING_IN_LIMITED_API
 typedef struct {
     PyCodeObject* code_object;
     int code_line;
@@ -1000,8 +1203,9 @@
 static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);
 static PyCodeObject *__pyx_find_code_object(int code_line);
 static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);
+#endif
 
 /////////////// CodeObjectCache ///////////////
 // Note that errors are simply ignored in the code below.
 // This is just a cache, if a lookup or insertion fails - so what?
 
@@ -1003,8 +1207,9 @@
 
 /////////////// CodeObjectCache ///////////////
 // Note that errors are simply ignored in the code below.
 // This is just a cache, if a lookup or insertion fails - so what?
 
+#if !CYTHON_COMPILING_IN_LIMITED_API
 static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {
     int start = 0, mid = 0, end = count - 1;
     if (end >= 0 && code_line > entries[end].code_line) {
@@ -1085,6 +1290,7 @@
     __pyx_code_cache.count++;
     Py_INCREF(code_object);
 }
+#endif
 
 /////////////// CodeObjectCache.cleanup ///////////////
 
@@ -1088,6 +1294,7 @@
 
 /////////////// CodeObjectCache.cleanup ///////////////
 
+  #if !CYTHON_COMPILING_IN_LIMITED_API
   if (__pyx_code_cache.entries) {
       __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;
       int i, count = __pyx_code_cache.count;
@@ -1099,6 +1306,7 @@
       }
       PyMem_Free(entries);
   }
+  #endif
 
 /////////////// CheckBinaryVersion.proto ///////////////
 
@@ -1168,6 +1376,11 @@
   #define __Pyx_RefNannySetupContext(name, acquire_gil) \
           __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
 #endif
+  #define __Pyx_RefNannyFinishContextNogil() { \
+              PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \
+              __Pyx_RefNannyFinishContext(); \
+              PyGILState_Release(__pyx_gilstate_save); \
+          }
   #define __Pyx_RefNannyFinishContext() \
           __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
   #define __Pyx_INCREF(r)  __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
@@ -1181,6 +1394,7 @@
 #else
   #define __Pyx_RefNannyDeclarations
   #define __Pyx_RefNannySetupContext(name, acquire_gil)
+  #define __Pyx_RefNannyFinishContextNogil()
   #define __Pyx_RefNannyFinishContext()
   #define __Pyx_INCREF(r) Py_INCREF(r)
   #define __Pyx_DECREF(r) Py_DECREF(r)
@@ -1192,6 +1406,10 @@
   #define __Pyx_XGIVEREF(r)
 #endif /* CYTHON_REFNANNY */
 
+#define __Pyx_Py_XDECREF_SET(r, v) do {                         \
+        PyObject *tmp = (PyObject *) r;                         \
+        r = v; Py_XDECREF(tmp);                                 \
+    } while (0)
 #define __Pyx_XDECREF_SET(r, v) do {                            \
         PyObject *tmp = (PyObject *) r;                         \
         r = v; __Pyx_XDECREF(tmp);                              \
@@ -1339,6 +1557,8 @@
 /////////////// FastGil.proto ///////////////
 //@proto_block: utility_code_proto_before_types
 
+#if CYTHON_FAST_GIL
+
 struct __Pyx_FastGilVtab {
   PyGILState_STATE (*Fast_PyGILState_Ensure)(void);
   void (*Fast_PyGILState_Release)(PyGILState_STATE oldstate);
@@ -1373,6 +1593,14 @@
   #endif
 #endif
 
+#else
+#define __Pyx_PyGILState_Ensure PyGILState_Ensure
+#define __Pyx_PyGILState_Release PyGILState_Release
+#define __Pyx_FastGIL_Remember()
+#define __Pyx_FastGIL_Forget()
+#define __Pyx_FastGilFuncInit()
+#endif
+
 /////////////// FastGil ///////////////
 //@requires: CommonStructures.c::FetchCommonPointer
 // The implementations of PyGILState_Ensure/Release calls PyThread_get_key_value
@@ -1382,8 +1610,10 @@
 // To make optimal use of this thread local, we attempt to share it between
 // modules.
 
+#if CYTHON_FAST_GIL
+
 #define __Pyx_FastGIL_ABI_module "_cython_" CYTHON_ABI
 #define __Pyx_FastGIL_PyCapsuleName "FastGilFuncs"
 #define __Pyx_FastGIL_PyCapsule \
     __Pyx_FastGIL_ABI_module "." __Pyx_FastGIL_PyCapsuleName
 
@@ -1385,12 +1615,8 @@
 #define __Pyx_FastGIL_ABI_module "_cython_" CYTHON_ABI
 #define __Pyx_FastGIL_PyCapsuleName "FastGilFuncs"
 #define __Pyx_FastGIL_PyCapsule \
     __Pyx_FastGIL_ABI_module "." __Pyx_FastGIL_PyCapsuleName
 
-#if PY_VERSION_HEX < 0x02070000
-  #undef CYTHON_THREAD_LOCAL
-#endif
-
 #ifdef CYTHON_THREAD_LOCAL
 
 #include "pythread.h"
@@ -1484,5 +1710,4 @@
 #endif
 
 static void __Pyx_FastGilFuncInit(void) {
-#if PY_VERSION_HEX >= 0x02070000
   struct __Pyx_FastGilVtab* shared = (struct __Pyx_FastGilVtab*)PyCapsule_Import(__Pyx_FastGIL_PyCapsule, 1);
@@ -1488,7 +1713,4 @@
   struct __Pyx_FastGilVtab* shared = (struct __Pyx_FastGilVtab*)PyCapsule_Import(__Pyx_FastGIL_PyCapsule, 1);
-#else
-  struct __Pyx_FastGilVtab* shared = NULL;
-#endif
   if (shared) {
     __Pyx_FastGilFuncs = *shared;
   } else {
@@ -1496,3 +1718,5 @@
     __Pyx_FastGilFuncInit0();
   }
 }
+
+#endif
diff --git a/Cython/Utility/NumpyImportArray.c b/Cython/Utility/NumpyImportArray.c
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1V0aWxpdHkvTnVtcHlJbXBvcnRBcnJheS5j
--- /dev/null
+++ b/Cython/Utility/NumpyImportArray.c
@@ -0,0 +1,21 @@
+///////////////////////// NumpyImportArray.init ////////////////////
+
+// comment below is deliberately kept in the generated C file to
+// help users debug where this came from:
+/*
+ * Cython has automatically inserted a call to _import_array since
+ * you didn't include one when you cimported numpy. To disable this
+ * add the line
+ *   <void>numpy._import_array
+ */
+#ifdef NPY_NDARRAYOBJECT_H /* numpy headers have been included */
+// NO_IMPORT_ARRAY is Numpy's mechanism for indicating that import_array is handled elsewhere
+#if !NO_IMPORT_ARRAY /* https://docs.scipy.org/doc/numpy-1.17.0/reference/c-api.array.html#c.NO_IMPORT_ARRAY  */
+if (unlikely(_import_array() == -1)) {
+    PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import "
+    "(auto-generated because you didn't call 'numpy.import_array()' after cimporting numpy; "
+    "use '<void>numpy._import_array' to disable if you are certain you don't need it).");
+    {{ err_goto }};
+}
+#endif
+#endif
diff --git a/Cython/Utility/ObjectHandling.c b/Cython/Utility/ObjectHandling.c
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1V0aWxpdHkvT2JqZWN0SGFuZGxpbmcuYw==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1V0aWxpdHkvT2JqZWN0SGFuZGxpbmcuYw== 100644
--- a/Cython/Utility/ObjectHandling.c
+++ b/Cython/Utility/ObjectHandling.c
@@ -199,6 +199,5 @@
         next = iternext(iterator);
         if (likely(next))
             return next;
-        #if PY_VERSION_HEX >= 0x02070000
         if (unlikely(iternext == &_PyObject_NextNotImplemented))
             return NULL;
@@ -203,6 +202,5 @@
         if (unlikely(iternext == &_PyObject_NextNotImplemented))
             return NULL;
-        #endif
 #else
         // Since the slot was set, assume that PyIter_Next() will likely succeed, and properly fail otherwise.
         // Note: PyIter_Next() crashes in CPython if "tp_iternext" is NULL.
@@ -275,10 +273,10 @@
 /////////////// ObjectGetItem.proto ///////////////
 
 #if CYTHON_USE_TYPE_SLOTS
-static CYTHON_INLINE PyObject *__Pyx_PyObject_GetItem(PyObject *obj, PyObject* key);/*proto*/
+static CYTHON_INLINE PyObject *__Pyx_PyObject_GetItem(PyObject *obj, PyObject *key);/*proto*/
 #else
 #define __Pyx_PyObject_GetItem(obj, key)  PyObject_GetItem(obj, key)
 #endif
 
 /////////////// ObjectGetItem ///////////////
 // //@requires: GetItemInt - added in IndexNode as it uses templating.
@@ -279,8 +277,10 @@
 #else
 #define __Pyx_PyObject_GetItem(obj, key)  PyObject_GetItem(obj, key)
 #endif
 
 /////////////// ObjectGetItem ///////////////
 // //@requires: GetItemInt - added in IndexNode as it uses templating.
+//@requires: PyObjectGetAttrStrNoError
+//@requires: PyObjectCallOneArg
 
 #if CYTHON_USE_TYPE_SLOTS
@@ -285,5 +285,6 @@
 
 #if CYTHON_USE_TYPE_SLOTS
-static PyObject *__Pyx_PyObject_GetIndex(PyObject *obj, PyObject* index) {
+static PyObject *__Pyx_PyObject_GetIndex(PyObject *obj, PyObject *index) {
+    // Get element from sequence object `obj` at index `index`.
     PyObject *runerr;
     Py_ssize_t key_value;
@@ -288,11 +289,5 @@
     PyObject *runerr;
     Py_ssize_t key_value;
-    PySequenceMethods *m = Py_TYPE(obj)->tp_as_sequence;
-    if (unlikely(!(m && m->sq_item))) {
-        PyErr_Format(PyExc_TypeError, "'%.200s' object is not subscriptable", Py_TYPE(obj)->tp_name);
-        return NULL;
-    }
-
     key_value = __Pyx_PyIndex_AsSsize_t(index);
     if (likely(key_value != -1 || !(runerr = PyErr_Occurred()))) {
         return __Pyx_GetItemInt_Fast(obj, key_value, 0, 1, 1);
@@ -306,8 +301,13 @@
     return NULL;
 }
 
-static PyObject *__Pyx_PyObject_GetItem(PyObject *obj, PyObject* key) {
-    PyMappingMethods *m = Py_TYPE(obj)->tp_as_mapping;
-    if (likely(m && m->mp_subscript)) {
-        return m->mp_subscript(obj, key);
+static PyObject *__Pyx_PyObject_GetItem_Slow(PyObject *obj, PyObject *key) {
+    // Handles less common slow-path checks for GetItem
+    if (likely(PyType_Check(obj))) {
+        PyObject *meth = __Pyx_PyObject_GetAttrStrNoError(obj, PYIDENT("__class_getitem__"));
+        if (meth) {
+            PyObject *result = __Pyx_PyObject_CallOneArg(meth, key);
+            Py_DECREF(meth);
+            return result;
+        }
     }
@@ -313,5 +313,21 @@
     }
-    return __Pyx_PyObject_GetIndex(obj, key);
+
+    PyErr_Format(PyExc_TypeError, "'%.200s' object is not subscriptable", Py_TYPE(obj)->tp_name);
+    return NULL;
+}
+
+static PyObject *__Pyx_PyObject_GetItem(PyObject *obj, PyObject *key) {
+    PyTypeObject *tp = Py_TYPE(obj);
+    PyMappingMethods *mm = tp->tp_as_mapping;
+    PySequenceMethods *sm = tp->tp_as_sequence;
+
+    if (likely(mm && mm->mp_subscript)) {
+        return mm->mp_subscript(obj, key);
+    }
+    if (likely(sm && sm->sq_item)) {
+        return __Pyx_PyObject_GetIndex(obj, key);
+    }
+    return __Pyx_PyObject_GetItem_Slow(obj, key);
 }
 #endif
 
@@ -358,6 +374,7 @@
 #endif
 
 /////////////// GetItemInt.proto ///////////////
+//@substitute: tempita
 
 #define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
     (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
@@ -380,6 +397,7 @@
                                                      int is_list, int wraparound, int boundscheck);
 
 /////////////// GetItemInt ///////////////
+//@substitute: tempita
 
 static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
     PyObject *r;
@@ -383,7 +401,7 @@
 
 static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
     PyObject *r;
-    if (!j) return NULL;
+    if (unlikely(!j)) return NULL;
     r = PyObject_GetItem(o, j);
     Py_DECREF(j);
     return r;
@@ -431,10 +449,18 @@
         }
     } else {
         // inlined PySequence_GetItem() + special cased length overflow
-        PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
-        if (likely(m && m->sq_item)) {
-            if (wraparound && unlikely(i < 0) && likely(m->sq_length)) {
-                Py_ssize_t l = m->sq_length(o);
+        PyMappingMethods *mm = Py_TYPE(o)->tp_as_mapping;
+        PySequenceMethods *sm = Py_TYPE(o)->tp_as_sequence;
+        if (mm && mm->mp_subscript) {
+            PyObject *r, *key = PyInt_FromSsize_t(i);
+            if (unlikely(!key)) return NULL;
+            r = mm->mp_subscript(o, key);
+            Py_DECREF(key);
+            return r;
+        }
+        if (likely(sm && sm->sq_item)) {
+            if (wraparound && unlikely(i < 0) && likely(sm->sq_length)) {
+                Py_ssize_t l = sm->sq_length(o);
                 if (likely(l >= 0)) {
                     i += l;
                 } else {
@@ -444,7 +470,7 @@
                     PyErr_Clear();
                 }
             }
-            return m->sq_item(o, i);
+            return sm->sq_item(o, i);
         }
     }
 #else
@@ -471,7 +497,7 @@
 
 static int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) {
     int r;
-    if (!j) return -1;
+    if (unlikely(!j)) return -1;
     r = PyObject_SetItem(o, j, v);
     Py_DECREF(j);
     return r;
@@ -491,10 +517,19 @@
         }
     } else {
         // inlined PySequence_SetItem() + special cased length overflow
-        PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
-        if (likely(m && m->sq_ass_item)) {
-            if (wraparound && unlikely(i < 0) && likely(m->sq_length)) {
-                Py_ssize_t l = m->sq_length(o);
+        PyMappingMethods *mm = Py_TYPE(o)->tp_as_mapping;
+        PySequenceMethods *sm = Py_TYPE(o)->tp_as_sequence;
+        if (mm && mm->mp_ass_subscript) {
+            int r;
+            PyObject *key = PyInt_FromSsize_t(i);
+            if (unlikely(!key)) return -1;
+            r = mm->mp_ass_subscript(o, key, v);
+            Py_DECREF(key);
+            return r;
+        }
+        if (likely(sm && sm->sq_ass_item)) {
+            if (wraparound && unlikely(i < 0) && likely(sm->sq_length)) {
+                Py_ssize_t l = sm->sq_length(o);
                 if (likely(l >= 0)) {
                     i += l;
                 } else {
@@ -504,7 +539,7 @@
                     PyErr_Clear();
                 }
             }
-            return m->sq_ass_item(o, i, v);
+            return sm->sq_ass_item(o, i, v);
         }
     }
 #else
@@ -537,10 +572,10 @@
 
 static int __Pyx_DelItem_Generic(PyObject *o, PyObject *j) {
     int r;
-    if (!j) return -1;
+    if (unlikely(!j)) return -1;
     r = PyObject_DelItem(o, j);
     Py_DECREF(j);
     return r;
 }
 
 static CYTHON_INLINE int __Pyx_DelItemInt_Fast(PyObject *o, Py_ssize_t i,
@@ -541,13 +576,13 @@
     r = PyObject_DelItem(o, j);
     Py_DECREF(j);
     return r;
 }
 
 static CYTHON_INLINE int __Pyx_DelItemInt_Fast(PyObject *o, Py_ssize_t i,
-                                               CYTHON_UNUSED int is_list, CYTHON_NCP_UNUSED int wraparound) {
+                                               int is_list, CYTHON_NCP_UNUSED int wraparound) {
 #if !CYTHON_USE_TYPE_SLOTS
     if (is_list || PySequence_Check(o)) {
         return PySequence_DelItem(o, i);
     }
 #else
     // inlined PySequence_DelItem() + special cased length overflow
@@ -548,13 +583,18 @@
 #if !CYTHON_USE_TYPE_SLOTS
     if (is_list || PySequence_Check(o)) {
         return PySequence_DelItem(o, i);
     }
 #else
     // inlined PySequence_DelItem() + special cased length overflow
-    PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
-    if (likely(m && m->sq_ass_item)) {
-        if (wraparound && unlikely(i < 0) && likely(m->sq_length)) {
-            Py_ssize_t l = m->sq_length(o);
+    PyMappingMethods *mm = Py_TYPE(o)->tp_as_mapping;
+    PySequenceMethods *sm = Py_TYPE(o)->tp_as_sequence;
+    if ((!is_list) && mm && mm->mp_ass_subscript) {
+        PyObject *key = PyInt_FromSsize_t(i);
+        return likely(key) ? mm->mp_ass_subscript(o, key, (PyObject *)NULL) : -1;
+    }
+    if (likely(sm && sm->sq_ass_item)) {
+        if (wraparound && unlikely(i < 0) && likely(sm->sq_length)) {
+            Py_ssize_t l = sm->sq_length(o);
             if (likely(l >= 0)) {
                 i += l;
             } else {
@@ -564,7 +604,7 @@
                 PyErr_Clear();
             }
         }
-        return m->sq_ass_item(o, i, (PyObject *)NULL);
+        return sm->sq_ass_item(o, i, (PyObject *)NULL);
     }
 #endif
     return __Pyx_DelItem_Generic(o, PyInt_FromSsize_t(i));
@@ -715,6 +755,55 @@
 }
 
 
+/////////////// TupleAndListFromArray.proto ///////////////
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyList_FromArray(PyObject *const *src, Py_ssize_t n);
+static CYTHON_INLINE PyObject* __Pyx_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n);
+#endif
+
+/////////////// TupleAndListFromArray ///////////////
+//@substitute: naming
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE void __Pyx_copy_object_array(PyObject *const *CYTHON_RESTRICT src, PyObject** CYTHON_RESTRICT dest, Py_ssize_t length) {
+    PyObject *v;
+    Py_ssize_t i;
+    for (i = 0; i < length; i++) {
+        v = dest[i] = src[i];
+        Py_INCREF(v);
+    }
+}
+
+static CYTHON_INLINE PyObject *
+__Pyx_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n)
+{
+    PyObject *res;
+    if (n <= 0) {
+        Py_INCREF($empty_tuple);
+        return $empty_tuple;
+    }
+    res = PyTuple_New(n);
+    if (unlikely(res == NULL)) return NULL;
+    __Pyx_copy_object_array(src, ((PyTupleObject*)res)->ob_item, n);
+    return res;
+}
+
+static CYTHON_INLINE PyObject *
+__Pyx_PyList_FromArray(PyObject *const *src, Py_ssize_t n)
+{
+    PyObject *res;
+    if (n <= 0) {
+        return PyList_New(0);
+    }
+    res = PyList_New(n);
+    if (unlikely(res == NULL)) return NULL;
+    __Pyx_copy_object_array(src, ((PyListObject*)res)->ob_item, n);
+    return res;
+}
+#endif
+
+
 /////////////// SliceTupleAndList.proto ///////////////
 
 #if CYTHON_COMPILING_IN_CPYTHON
@@ -726,6 +815,8 @@
 #endif
 
 /////////////// SliceTupleAndList ///////////////
+//@requires: TupleAndListFromArray
+//@substitute: tempita
 
 #if CYTHON_COMPILING_IN_CPYTHON
 static CYTHON_INLINE void __Pyx_crop_slice(Py_ssize_t* _start, Py_ssize_t* _stop, Py_ssize_t* _length) {
@@ -746,15 +837,6 @@
     *_stop = stop;
 }
 
-static CYTHON_INLINE void __Pyx_copy_object_array(PyObject** CYTHON_RESTRICT src, PyObject** CYTHON_RESTRICT dest, Py_ssize_t length) {
-    PyObject *v;
-    Py_ssize_t i;
-    for (i = 0; i < length; i++) {
-        v = dest[i] = src[i];
-        Py_INCREF(v);
-    }
-}
-
 {{for type in ['List', 'Tuple']}}
 static CYTHON_INLINE PyObject* __Pyx_Py{{type}}_GetSlice(
             PyObject* src, Py_ssize_t start, Py_ssize_t stop) {
@@ -758,6 +840,5 @@
 {{for type in ['List', 'Tuple']}}
 static CYTHON_INLINE PyObject* __Pyx_Py{{type}}_GetSlice(
             PyObject* src, Py_ssize_t start, Py_ssize_t stop) {
-    PyObject* dest;
     Py_ssize_t length = Py{{type}}_GET_SIZE(src);
     __Pyx_crop_slice(&start, &stop, &length);
@@ -762,16 +843,6 @@
     Py_ssize_t length = Py{{type}}_GET_SIZE(src);
     __Pyx_crop_slice(&start, &stop, &length);
-    if (unlikely(length <= 0))
-        return Py{{type}}_New(0);
-
-    dest = Py{{type}}_New(length);
-    if (unlikely(!dest))
-        return NULL;
-    __Pyx_copy_object_array(
-        ((Py{{type}}Object*)src)->ob_item + start,
-        ((Py{{type}}Object*)dest)->ob_item,
-        length);
-    return dest;
+    return __Pyx_Py{{type}}_FromArray(((Py{{type}}Object*)src)->ob_item + start, length);
 }
 {{endfor}}
 #endif
@@ -913,5 +984,5 @@
     PyObject *result;
     PyObject *metaclass;
 
-    if (PyDict_SetItem(dict, PYIDENT("__module__"), modname) < 0)
+    if (unlikely(PyDict_SetItem(dict, PYIDENT("__module__"), modname) < 0))
         return NULL;
@@ -917,3 +988,4 @@
         return NULL;
-    if (PyDict_SetItem(dict, PYIDENT("__qualname__"), qualname) < 0)
+#if PY_VERSION_HEX >= 0x03030000
+    if (unlikely(PyDict_SetItem(dict, PYIDENT("__qualname__"), qualname) < 0))
         return NULL;
@@ -919,4 +991,7 @@
         return NULL;
+#else
+    CYTHON_MAYBE_UNUSED_VAR(qualname);
+#endif
 
     /* Python2 __metaclass__ */
     metaclass = __Pyx_PyDict_GetItemStr(dict, PYIDENT("__metaclass__"));
@@ -945,5 +1020,6 @@
                                       PyObject *mkw, int calculate_metaclass, int allow_py2_metaclass); /*proto*/
 
 /////////////// Py3ClassCreate ///////////////
-//@requires: PyObjectGetAttrStr
+//@substitute: naming
+//@requires: PyObjectGetAttrStrNoError
 //@requires: CalculateMetaclass
@@ -949,6 +1025,11 @@
 //@requires: CalculateMetaclass
+//@requires: PyObjectFastCall
+//@requires: PyObjectCall2Args
+//@requires: PyObjectLookupSpecial
+// only in fallback code:
+//@requires: GetBuiltinName
 
 static PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name,
                                            PyObject *qualname, PyObject *mkw, PyObject *modname, PyObject *doc) {
     PyObject *ns;
     if (metaclass) {
@@ -950,7 +1031,7 @@
 
 static PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name,
                                            PyObject *qualname, PyObject *mkw, PyObject *modname, PyObject *doc) {
     PyObject *ns;
     if (metaclass) {
-        PyObject *prep = __Pyx_PyObject_GetAttrStr(metaclass, PYIDENT("__prepare__"));
+        PyObject *prep = __Pyx_PyObject_GetAttrStrNoError(metaclass, PYIDENT("__prepare__"));
         if (prep) {
@@ -956,5 +1037,7 @@
         if (prep) {
-            PyObject *pargs = PyTuple_Pack(2, name, bases);
-            if (unlikely(!pargs)) {
-                Py_DECREF(prep);
+            PyObject *pargs[3] = {NULL, name, bases};
+            ns = __Pyx_PyObject_FastCallDict(prep, pargs+1, 2 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET, mkw);
+            Py_DECREF(prep);
+        } else {
+            if (unlikely(PyErr_Occurred()))
                 return NULL;
@@ -960,12 +1043,4 @@
                 return NULL;
-            }
-            ns = PyObject_Call(prep, pargs, mkw);
-            Py_DECREF(prep);
-            Py_DECREF(pargs);
-        } else {
-            if (unlikely(!PyErr_ExceptionMatches(PyExc_AttributeError)))
-                return NULL;
-            PyErr_Clear();
             ns = PyDict_New();
         }
     } else {
@@ -977,4 +1052,5 @@
 
     /* Required here to emulate assignment order */
     if (unlikely(PyObject_SetItem(ns, PYIDENT("__module__"), modname) < 0)) goto bad;
+#if PY_VERSION_HEX >= 0x03030000
     if (unlikely(PyObject_SetItem(ns, PYIDENT("__qualname__"), qualname) < 0)) goto bad;
@@ -980,4 +1056,7 @@
     if (unlikely(PyObject_SetItem(ns, PYIDENT("__qualname__"), qualname) < 0)) goto bad;
+#else
+    CYTHON_MAYBE_UNUSED_VAR(qualname);
+#endif
     if (unlikely(doc && PyObject_SetItem(ns, PYIDENT("__doc__"), doc) < 0)) goto bad;
     return ns;
 bad:
@@ -985,6 +1064,155 @@
     return NULL;
 }
 
+#if PY_VERSION_HEX < 0x030600A4 && CYTHON_PEP487_INIT_SUBCLASS
+// https://www.python.org/dev/peps/pep-0487/
+static int __Pyx_SetNamesPEP487(PyObject *type_obj) {
+    PyTypeObject *type = (PyTypeObject*) type_obj;
+    PyObject *names_to_set, *key, *value, *set_name, *tmp;
+    Py_ssize_t i = 0;
+
+#if CYTHON_USE_TYPE_SLOTS
+    names_to_set = PyDict_Copy(type->tp_dict);
+#else
+    {
+        PyObject *d = PyObject_GetAttr(type_obj, PYIDENT("__dict__"));
+        names_to_set = NULL;
+        if (likely(d)) {
+            // d may not be a dict, e.g. PyDictProxy in PyPy2.
+            PyObject *names_to_set = PyDict_New();
+            int ret = likely(names_to_set) ? PyDict_Update(names_to_set, d) : -1;
+            Py_DECREF(d);
+            if (unlikely(ret < 0))
+                Py_CLEAR(names_to_set);
+        }
+    }
+#endif
+    if (unlikely(names_to_set == NULL))
+        goto bad;
+
+    while (PyDict_Next(names_to_set, &i, &key, &value)) {
+        set_name = __Pyx_PyObject_LookupSpecialNoError(value, PYIDENT("__set_name__"));
+        if (unlikely(set_name != NULL)) {
+            tmp = __Pyx_PyObject_Call2Args(set_name, type_obj, key);
+            Py_DECREF(set_name);
+            if (unlikely(tmp == NULL)) {
+                PyErr_Format(PyExc_RuntimeError,
+#if PY_MAJOR_VERSION >= 3
+                    "Error calling __set_name__ on '%.100s' instance %R "
+                    "in '%.100s'",
+                    Py_TYPE(value)->tp_name, key, type->tp_name);
+#else
+                    "Error calling __set_name__ on '%.100s' instance %.100s "
+                    "in '%.100s'",
+                    Py_TYPE(value)->tp_name, PyString_Check(key) ? PyString_AS_STRING(key) : "?", type->tp_name);
+#endif
+                goto bad;
+            } else {
+                Py_DECREF(tmp);
+            }
+        }
+        else if (unlikely(PyErr_Occurred())) {
+            goto bad;
+        }
+    }
+
+    Py_DECREF(names_to_set);
+    return 0;
+bad:
+    Py_XDECREF(names_to_set);
+    return -1;
+}
+
+static PyObject *__Pyx_InitSubclassPEP487(PyObject *type_obj, PyObject *mkw) {
+#if CYTHON_USE_TYPE_SLOTS && CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
+// Stripped-down version of "super(type_obj, type_obj).__init_subclass__(**mkw)" in CPython 3.8.
+    PyTypeObject *type = (PyTypeObject*) type_obj;
+    PyObject *mro = type->tp_mro;
+    Py_ssize_t i, nbases;
+    if (unlikely(!mro)) goto done;
+
+    // avoid "unused" warning
+    (void) __Pyx_GetBuiltinName;
+
+    Py_INCREF(mro);
+    nbases = PyTuple_GET_SIZE(mro);
+
+    // Skip over the type itself and 'object'.
+    assert(PyTuple_GET_ITEM(mro, 0) == type_obj);
+    for (i = 1; i < nbases-1; i++) {
+        PyObject *base, *dict, *meth;
+        base = PyTuple_GET_ITEM(mro, i);
+        dict = ((PyTypeObject *)base)->tp_dict;
+        meth = __Pyx_PyDict_GetItemStrWithError(dict, PYIDENT("__init_subclass__"));
+        if (unlikely(meth)) {
+            descrgetfunc f = Py_TYPE(meth)->tp_descr_get;
+            PyObject *res;
+            Py_INCREF(meth);
+            if (likely(f)) {
+                res = f(meth, NULL, type_obj);
+                Py_DECREF(meth);
+                if (unlikely(!res)) goto bad;
+                meth = res;
+            }
+            res = __Pyx_PyObject_FastCallDict(meth, NULL, 0, mkw);
+            Py_DECREF(meth);
+            if (unlikely(!res)) goto bad;
+            Py_DECREF(res);
+            goto done;
+        } else if (unlikely(PyErr_Occurred())) {
+            goto bad;
+        }
+    }
+
+done:
+    Py_XDECREF(mro);
+    return type_obj;
+
+bad:
+    Py_XDECREF(mro);
+    Py_DECREF(type_obj);
+    return NULL;
+
+// CYTHON_USE_TYPE_SLOTS && CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
+#else
+// Generic fallback: "super(type_obj, type_obj).__init_subclass__(**mkw)", as used in CPython 3.8.
+    PyObject *super_type, *super, *func, *res;
+
+#if CYTHON_COMPILING_IN_PYPY && !defined(PySuper_Type)
+    super_type = __Pyx_GetBuiltinName(PYIDENT("super"));
+#else
+    super_type = (PyObject*) &PySuper_Type;
+    // avoid "unused" warning
+    (void) __Pyx_GetBuiltinName;
+#endif
+    super = likely(super_type) ? __Pyx_PyObject_Call2Args(super_type, type_obj, type_obj) : NULL;
+#if CYTHON_COMPILING_IN_PYPY && !defined(PySuper_Type)
+    Py_XDECREF(super_type);
+#endif
+    if (unlikely(!super)) {
+        Py_CLEAR(type_obj);
+        goto done;
+    }
+    func = __Pyx_PyObject_GetAttrStrNoError(super, PYIDENT("__init_subclass__"));
+    Py_DECREF(super);
+    if (likely(!func)) {
+        if (unlikely(PyErr_Occurred()))
+            Py_CLEAR(type_obj);
+        goto done;
+    }
+    res = __Pyx_PyObject_FastCallDict(func, NULL, 0, mkw);
+    Py_DECREF(func);
+    if (unlikely(!res))
+        Py_CLEAR(type_obj);
+    Py_XDECREF(res);
+done:
+    return type_obj;
+#endif
+}
+
+// PY_VERSION_HEX < 0x030600A4 && CYTHON_PEP487_INIT_SUBCLASS
+#endif
+
 static PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases,
                                       PyObject *dict, PyObject *mkw,
                                       int calculate_metaclass, int allow_py2_metaclass) {
@@ -988,5 +1216,5 @@
 static PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases,
                                       PyObject *dict, PyObject *mkw,
                                       int calculate_metaclass, int allow_py2_metaclass) {
-    PyObject *result, *margs;
+    PyObject *result;
     PyObject *owned_metaclass = NULL;
@@ -992,4 +1220,5 @@
     PyObject *owned_metaclass = NULL;
+    PyObject *margs[4] = {NULL, name, bases, dict};
     if (allow_py2_metaclass) {
         /* honour Python2 __metaclass__ for backward compatibility */
         owned_metaclass = PyObject_GetItem(dict, PYIDENT("__metaclass__"));
@@ -1008,10 +1237,21 @@
             return NULL;
         owned_metaclass = metaclass;
     }
-    margs = PyTuple_Pack(3, name, bases, dict);
-    if (unlikely(!margs)) {
-        result = NULL;
-    } else {
-        result = PyObject_Call(metaclass, margs, mkw);
-        Py_DECREF(margs);
+    result = __Pyx_PyObject_FastCallDict(metaclass, margs+1, 3 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET,
+#if PY_VERSION_HEX < 0x030600A4
+        // Before PEP-487, type(a,b,c) did not accept any keyword arguments, so guard at least against that case.
+        (metaclass == (PyObject*)&PyType_Type) ? NULL : mkw
+#else
+        mkw
+#endif
+    );
+    Py_XDECREF(owned_metaclass);
+
+#if PY_VERSION_HEX < 0x030600A4 && CYTHON_PEP487_INIT_SUBCLASS
+    if (likely(result) && likely(PyType_Check(result))) {
+        if (unlikely(__Pyx_SetNamesPEP487(result) < 0)) {
+            Py_CLEAR(result);
+        } else {
+            result = __Pyx_InitSubclassPEP487(result, mkw);
+        }
     }
@@ -1017,5 +1257,8 @@
     }
-    Py_XDECREF(owned_metaclass);
+#else
+    // avoid "unused" warning
+    (void) __Pyx_GetBuiltinName;
+#endif
     return result;
 }
 
@@ -1101,7 +1344,7 @@
 static PyObject *__Pyx_GetBuiltinName(PyObject *name); /*proto*/
 
 /////////////// GetBuiltinName ///////////////
-//@requires: PyObjectGetAttrStr
+//@requires: PyObjectGetAttrStrNoError
 //@substitute: naming
 
 static PyObject *__Pyx_GetBuiltinName(PyObject *name) {
@@ -1105,8 +1348,8 @@
 //@substitute: naming
 
 static PyObject *__Pyx_GetBuiltinName(PyObject *name) {
-    PyObject* result = __Pyx_PyObject_GetAttrStr($builtins_cname, name);
-    if (unlikely(!result)) {
+    PyObject* result = __Pyx_PyObject_GetAttrStrNoError($builtins_cname, name);
+    if (unlikely(!result) && !PyErr_Occurred()) {
         PyErr_Format(PyExc_NameError,
 #if PY_MAJOR_VERSION >= 3
             "name '%U' is not defined", name);
@@ -1123,5 +1366,4 @@
 static PyObject *__Pyx__GetNameInClass(PyObject *nmspace, PyObject *name); /*proto*/
 
 /////////////// GetNameInClass ///////////////
-//@requires: PyObjectGetAttrStr
 //@requires: GetModuleGlobalName
@@ -1127,18 +1369,4 @@
 //@requires: GetModuleGlobalName
-//@requires: Exceptions.c::PyThreadStateGet
-//@requires: Exceptions.c::PyErrFetchRestore
-//@requires: Exceptions.c::PyErrExceptionMatches
-
-static PyObject *__Pyx_GetGlobalNameAfterAttributeLookup(PyObject *name) {
-    PyObject *result;
-    __Pyx_PyThreadState_declare
-    __Pyx_PyThreadState_assign
-    if (unlikely(!__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError)))
-        return NULL;
-    __Pyx_PyErr_Clear();
-    __Pyx_GetModuleGlobalNameUncached(result, name);
-    return result;
-}
 
 static PyObject *__Pyx__GetNameInClass(PyObject *nmspace, PyObject *name) {
     PyObject *result;
@@ -1142,7 +1370,18 @@
 
 static PyObject *__Pyx__GetNameInClass(PyObject *nmspace, PyObject *name) {
     PyObject *result;
-    result = __Pyx_PyObject_GetAttrStr(nmspace, name);
-    if (!result) {
-        result = __Pyx_GetGlobalNameAfterAttributeLookup(name);
+    PyObject *dict;
+    assert(PyType_Check(nmspace));
+#if CYTHON_USE_TYPE_SLOTS
+    dict = ((PyTypeObject*)nmspace)->tp_dict;
+    Py_XINCREF(dict);
+#else
+    dict = PyObject_GetAttr(nmspace, PYIDENT("__dict__"));
+#endif
+    if (likely(dict)) {
+        result = PyObject_GetItem(dict, name);
+        Py_DECREF(dict);
+        if (result) {
+            return result;
+        }
     }
@@ -1148,4 +1387,6 @@
     }
+    PyErr_Clear();
+    __Pyx_GetModuleGlobalNameUncached(result, name);
     return result;
 }
 
@@ -1163,6 +1404,30 @@
 #define __Pyx_SetNameInClass(ns, name, value)  PyObject_SetItem(ns, name, value)
 #endif
 
+/////////////// SetNewInClass.proto ///////////////
+
+static int __Pyx_SetNewInClass(PyObject *ns, PyObject *name, PyObject *value);
+
+/////////////// SetNewInClass ///////////////
+//@requires: SetNameInClass
+
+// Special-case setting __new__: if it's a Cython function, wrap it in a
+// staticmethod. This is similar to what Python does for a Python function
+// called __new__.
+static int __Pyx_SetNewInClass(PyObject *ns, PyObject *name, PyObject *value) {
+#ifdef __Pyx_CyFunction_USED
+    int ret;
+    if (__Pyx_CyFunction_Check(value)) {
+        PyObject *staticnew = PyStaticMethod_New(value);
+        if (unlikely(!staticnew)) return -1;
+        ret = __Pyx_SetNameInClass(ns, name, staticnew);
+        Py_DECREF(staticnew);
+        return ret;
+    }
+#endif
+    return __Pyx_SetNameInClass(ns, name, value);
+}
+
 
 /////////////// GetModuleGlobalName.proto ///////////////
 //@requires: PyDictVersioning
@@ -1210,6 +1475,14 @@
     } else if (unlikely(PyErr_Occurred())) {
         return NULL;
     }
+#elif CYTHON_COMPILING_IN_LIMITED_API
+    if (unlikely(!$module_cname)) {
+        return NULL;
+    }
+    result = PyObject_GetAttr($module_cname, name);
+    if (likely(result)) {
+        return result;
+    }
 #else
     result = PyDict_GetItem($moddict_cname, name);
     __PYX_UPDATE_DICT_CACHE($moddict_cname, result, *dict_cached_value, *dict_version)
@@ -1247,4 +1520,5 @@
     return PyObject_GetAttr(o, n);
 }
 
+
 /////////////// PyObjectLookupSpecial.proto ///////////////
@@ -1250,4 +1524,3 @@
 /////////////// PyObjectLookupSpecial.proto ///////////////
-//@requires: PyObjectGetAttrStr
 
 #if CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS
@@ -1252,7 +1525,22 @@
 
 #if CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS
-static CYTHON_INLINE PyObject* __Pyx_PyObject_LookupSpecial(PyObject* obj, PyObject* attr_name) {
+#define __Pyx_PyObject_LookupSpecialNoError(obj, attr_name)  __Pyx__PyObject_LookupSpecial(obj, attr_name, 0)
+#define __Pyx_PyObject_LookupSpecial(obj, attr_name)  __Pyx__PyObject_LookupSpecial(obj, attr_name, 1)
+
+static CYTHON_INLINE PyObject* __Pyx__PyObject_LookupSpecial(PyObject* obj, PyObject* attr_name, int with_error); /*proto*/
+
+#else
+#define __Pyx_PyObject_LookupSpecialNoError(o,n) __Pyx_PyObject_GetAttrStrNoError(o,n)
+#define __Pyx_PyObject_LookupSpecial(o,n) __Pyx_PyObject_GetAttrStr(o,n)
+#endif
+
+/////////////// PyObjectLookupSpecial ///////////////
+//@requires: PyObjectGetAttrStr
+//@requires: PyObjectGetAttrStrNoError
+
+#if CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS
+static CYTHON_INLINE PyObject* __Pyx__PyObject_LookupSpecial(PyObject* obj, PyObject* attr_name, int with_error) {
     PyObject *res;
     PyTypeObject *tp = Py_TYPE(obj);
 #if PY_MAJOR_VERSION < 3
     if (unlikely(PyInstance_Check(obj)))
@@ -1255,8 +1543,8 @@
     PyObject *res;
     PyTypeObject *tp = Py_TYPE(obj);
 #if PY_MAJOR_VERSION < 3
     if (unlikely(PyInstance_Check(obj)))
-        return __Pyx_PyObject_GetAttrStr(obj, attr_name);
+        return with_error ? __Pyx_PyObject_GetAttrStr(obj, attr_name) : __Pyx_PyObject_GetAttrStrNoError(obj, attr_name);
 #endif
     // adapted from CPython's special_lookup() in ceval.c
     res = _PyType_Lookup(tp, attr_name);
@@ -1267,8 +1555,8 @@
         } else {
             res = f(res, obj, (PyObject *)tp);
         }
-    } else {
+    } else if (with_error) {
         PyErr_SetObject(PyExc_AttributeError, attr_name);
     }
     return res;
 }
@@ -1271,9 +1559,7 @@
         PyErr_SetObject(PyExc_AttributeError, attr_name);
     }
     return res;
 }
-#else
-#define __Pyx_PyObject_LookupSpecial(o,n) __Pyx_PyObject_GetAttrStr(o,n)
 #endif
 
 
@@ -1304,7 +1590,7 @@
 }
 
 static CYTHON_INLINE PyObject* __Pyx_PyObject_GenericGetAttrNoDict(PyObject* obj, PyObject* attr_name) {
-    // Copied and adapted from _PyObject_GenericGetAttrWithDict() in CPython 2.6/3.7.
+    // Copied and adapted from _PyObject_GenericGetAttrWithDict() in CPython 3.6/3.7.
     // To be used in the "tp_getattro" slot of extension types that have no instance dict and cannot be subclassed.
     PyObject *descr;
     PyTypeObject *tp = Py_TYPE(obj);
@@ -1361,6 +1647,41 @@
 #endif
 
 
+/////////////// PyObjectGetAttrStrNoError.proto ///////////////
+
+static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name);/*proto*/
+
+/////////////// PyObjectGetAttrStrNoError ///////////////
+//@requires: PyObjectGetAttrStr
+//@requires: Exceptions.c::PyThreadStateGet
+//@requires: Exceptions.c::PyErrFetchRestore
+//@requires: Exceptions.c::PyErrExceptionMatches
+
+static void __Pyx_PyObject_GetAttrStr_ClearAttributeError(void) {
+    __Pyx_PyThreadState_declare
+    __Pyx_PyThreadState_assign
+    if (likely(__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError)))
+        __Pyx_PyErr_Clear();
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name) {
+    PyObject *result;
+#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_TYPE_SLOTS && PY_VERSION_HEX >= 0x030700B1
+    // _PyObject_GenericGetAttrWithDict() in CPython 3.7+ can avoid raising the AttributeError.
+    // See https://bugs.python.org/issue32544
+    PyTypeObject* tp = Py_TYPE(obj);
+    if (likely(tp->tp_getattro == PyObject_GenericGetAttr)) {
+        return _PyObject_GenericGetAttrWithDict(obj, attr_name, NULL, 1);
+    }
+#endif
+    result = __Pyx_PyObject_GetAttrStr(obj, attr_name);
+    if (unlikely(!result)) {
+        __Pyx_PyObject_GetAttrStr_ClearAttributeError();
+    }
+    return result;
+}
+
+
 /////////////// PyObjectGetAttrStr.proto ///////////////
 
 #if CYTHON_USE_TYPE_SLOTS
@@ -1441,4 +1762,7 @@
     descr = _PyType_Lookup(tp, name);
     if (likely(descr != NULL)) {
         Py_INCREF(descr);
+#if defined(Py_TPFLAGS_METHOD_DESCRIPTOR) && Py_TPFLAGS_METHOD_DESCRIPTOR
+        if (PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR))
+#elif PY_MAJOR_VERSION >= 3
         // Repeating the condition below accommodates for MSVC's inability to test macros inside of macro expansions.
@@ -1444,3 +1768,2 @@
         // Repeating the condition below accommodates for MSVC's inability to test macros inside of macro expansions.
-#if PY_MAJOR_VERSION >= 3
         #ifdef __Pyx_CyFunction_USED
@@ -1446,3 +1769,3 @@
         #ifdef __Pyx_CyFunction_USED
-        if (likely(PyFunction_Check(descr) || (Py_TYPE(descr) == &PyMethodDescr_Type) || __Pyx_CyFunction_Check(descr)))
+        if (likely(PyFunction_Check(descr) || __Pyx_IS_TYPE(descr, &PyMethodDescr_Type) || __Pyx_CyFunction_Check(descr)))
         #else
@@ -1448,5 +1771,5 @@
         #else
-        if (likely(PyFunction_Check(descr) || (Py_TYPE(descr) == &PyMethodDescr_Type)))
+        if (likely(PyFunction_Check(descr) || __Pyx_IS_TYPE(descr, &PyMethodDescr_Type)))
         #endif
 #else
         // "PyMethodDescr_Type" is not part of the C-API in Py2.
@@ -1492,7 +1815,7 @@
         goto try_unpack;
     }
 
-    if (descr != NULL) {
+    if (likely(descr != NULL)) {
         *method = descr;
         return 0;
     }
@@ -1552,7 +1875,7 @@
     target->method = method;
 #if CYTHON_COMPILING_IN_CPYTHON
     #if PY_MAJOR_VERSION >= 3
-    // method dscriptor type isn't exported in Py2.x, cannot easily check the type there
+    // method descriptor type isn't exported in Py2.x, cannot easily check the type there
     if (likely(__Pyx_TypeCheck(method, &PyMethodDescr_Type)))
     #endif
     {
@@ -1750,6 +2073,104 @@
 }
 
 
+/////////////// PyObjectFastCall.proto ///////////////
+
+#define __Pyx_PyObject_FastCall(func, args, nargs)  __Pyx_PyObject_FastCallDict(func, args, nargs, NULL)
+static CYTHON_INLINE PyObject* __Pyx_PyObject_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs); /*proto*/
+
+/////////////// PyObjectFastCall ///////////////
+//@requires: PyObjectCall
+//@requires: PyFunctionFastCall
+//@requires: PyObjectCallMethO
+//@substitute: naming
+
+static PyObject* __Pyx_PyObject_FastCall_fallback(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs) {
+    PyObject *argstuple;
+    PyObject *result;
+    Py_ssize_t i;
+
+    argstuple = PyTuple_New(nargs);
+    if (unlikely(!argstuple)) return NULL;
+    for (i = 0; i < nargs; i++) {
+        Py_INCREF(args[i]);
+        PyTuple_SET_ITEM(argstuple, i, args[i]);
+    }
+    result = __Pyx_PyObject_Call(func, argstuple, kwargs);
+    Py_DECREF(argstuple);
+    return result;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyObject_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t _nargs, PyObject *kwargs) {
+    // Special fast paths for 0 and 1 arguments
+    // NOTE: in many cases, this is called with a constant value for nargs
+    // which is known at compile-time. So the branches below will typically
+    // be optimized away.
+    Py_ssize_t nargs = __Pyx_PyVectorcall_NARGS(_nargs);
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (nargs == 0 && kwargs == NULL) {
+#ifdef __Pyx_CyFunction_USED
+        if (PyCFunction_Check(func) || __Pyx_CyFunction_Check(func))
+#else
+        if (PyCFunction_Check(func))
+#endif
+        {
+            if (likely(PyCFunction_GET_FLAGS(func) & METH_NOARGS)) {
+                return __Pyx_PyObject_CallMethO(func, NULL);
+            }
+        }
+    }
+    else if (nargs == 1 && kwargs == NULL) {
+        if (PyCFunction_Check(func))
+        {
+            if (likely(PyCFunction_GET_FLAGS(func) & METH_O)) {
+                return __Pyx_PyObject_CallMethO(func, args[0]);
+            }
+        }
+    }
+#endif
+
+    #if PY_VERSION_HEX < 0x030800B1
+    #if CYTHON_FAST_PYCCALL
+    if (PyCFunction_Check(func)) {
+        if (kwargs) {
+            return _PyCFunction_FastCallDict(func, args, nargs, kwargs);
+        } else {
+            return _PyCFunction_FastCallKeywords(func, args, nargs, NULL);
+        }
+    }
+    #if PY_VERSION_HEX >= 0x030700A1
+    if (!kwargs && __Pyx_IS_TYPE(func, &PyMethodDescr_Type)) {
+        return _PyMethodDescr_FastCallKeywords(func, args, nargs, NULL);
+    }
+    #endif
+    #endif
+    #if CYTHON_FAST_PYCALL
+    if (PyFunction_Check(func)) {
+        return __Pyx_PyFunction_FastCallDict(func, args, nargs, kwargs);
+    }
+    #endif
+    #endif
+
+    #if CYTHON_VECTORCALL
+    vectorcallfunc f = _PyVectorcall_Function(func);
+    if (f) {
+        return f(func, args, nargs, kwargs);
+    }
+    #elif __Pyx_CyFunction_USED && CYTHON_BACKPORT_VECTORCALL
+    // exclude fused functions for now
+    if (__Pyx_IS_TYPE(func, __pyx_CyFunctionType)) {
+        __pyx_vectorcallfunc f = __Pyx_CyFunction_func_vectorcall(func);
+        if (f) return f(func, args, nargs, kwargs);
+    }
+    #endif
+
+    if (nargs == 0) {
+        return __Pyx_PyObject_Call(func, $empty_tuple, kwargs);
+    }
+    return __Pyx_PyObject_FastCall_fallback(func, args, nargs, kwargs);
+}
+
+
 /////////////// PyObjectCallMethod0.proto ///////////////
 
 static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name); /*proto*/
@@ -1804,59 +2225,6 @@
 }
 
 
-/////////////// PyObjectCallMethod2.proto ///////////////
-
-static PyObject* __Pyx_PyObject_CallMethod2(PyObject* obj, PyObject* method_name, PyObject* arg1, PyObject* arg2); /*proto*/
-
-/////////////// PyObjectCallMethod2 ///////////////
-//@requires: PyObjectCall
-//@requires: PyFunctionFastCall
-//@requires: PyCFunctionFastCall
-//@requires: PyObjectCall2Args
-
-static PyObject* __Pyx_PyObject_Call3Args(PyObject* function, PyObject* arg1, PyObject* arg2, PyObject* arg3) {
-    #if CYTHON_FAST_PYCALL
-    if (PyFunction_Check(function)) {
-        PyObject *args[3] = {arg1, arg2, arg3};
-        return __Pyx_PyFunction_FastCall(function, args, 3);
-    }
-    #endif
-    #if CYTHON_FAST_PYCCALL
-    if (__Pyx_PyFastCFunction_Check(function)) {
-        PyObject *args[3] = {arg1, arg2, arg3};
-        return __Pyx_PyFunction_FastCall(function, args, 3);
-    }
-    #endif
-
-    args = PyTuple_New(3);
-    if (unlikely(!args)) goto done;
-    Py_INCREF(arg1);
-    PyTuple_SET_ITEM(args, 0, arg1);
-    Py_INCREF(arg2);
-    PyTuple_SET_ITEM(args, 1, arg2);
-    Py_INCREF(arg3);
-    PyTuple_SET_ITEM(args, 2, arg3);
-
-    result = __Pyx_PyObject_Call(function, args, NULL);
-    Py_DECREF(args);
-    return result;
-}
-
-static PyObject* __Pyx_PyObject_CallMethod2(PyObject* obj, PyObject* method_name, PyObject* arg1, PyObject* arg2) {
-    PyObject *args, *method = NULL, *result = NULL;
-    int is_method = __Pyx_PyObject_GetMethod(obj, method_name, &method);
-    if (likely(is_method)) {
-        result = __Pyx_PyObject_Call3Args(method, obj, arg1, arg2);
-        Py_DECREF(method);
-        return result;
-    }
-    if (unlikely(!method)) return NULL;
-    result = __Pyx_PyObject_Call2Args(method, arg1, arg2);
-    Py_DECREF(method);
-    return result;
-}
-
-
 /////////////// tp_new.proto ///////////////
 
 #define __Pyx_tp_new(type_obj, args) __Pyx_tp_new_kwargs(type_obj, args, NULL)
@@ -1928,6 +2296,8 @@
 /////////////// PyFunctionFastCall.proto ///////////////
 
 #if CYTHON_FAST_PYCALL
+
+#if !CYTHON_VECTORCALL
 #define __Pyx_PyFunction_FastCall(func, args, nargs) \
     __Pyx_PyFunction_FastCallDict((func), (args), (nargs), NULL)
 
@@ -1931,6 +2301,4 @@
 #define __Pyx_PyFunction_FastCall(func, args, nargs) \
     __Pyx_PyFunction_FastCallDict((func), (args), (nargs), NULL)
 
-// let's assume that the non-public C-API function might still change during the 3.6 beta phase
-#if 1 || PY_VERSION_HEX < 0x030600B1
 static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs);
@@ -1936,6 +2304,4 @@
 static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs);
-#else
-#define __Pyx_PyFunction_FastCallDict(func, args, nargs, kwargs) _PyFunction_FastCallDict(func, args, nargs, kwargs)
 #endif
 
 // Backport from Python 3
@@ -1947,7 +2313,7 @@
 //       ((char *)(foo)        \
 //        + Py_BUILD_ASSERT_EXPR(offsetof(struct foo, string) == 0))
 //
-//   Written by Rusty Russell, public domain, http://ccodearchive.net/
+//   Written by Rusty Russell, public domain, https://ccodearchive.net/
 #define __Pyx_BUILD_ASSERT_EXPR(cond) \
     (sizeof(char [1 - 2*!(cond)]) - 1)
 
@@ -1976,8 +2342,7 @@
 /////////////// PyFunctionFastCall ///////////////
 // copied from CPython 3.6 ceval.c
 
-#if CYTHON_FAST_PYCALL
-
+#if CYTHON_FAST_PYCALL && !CYTHON_VECTORCALL
 static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args, Py_ssize_t na,
                                                PyObject *globals) {
     PyFrameObject *f;
@@ -2013,7 +2378,6 @@
 }
 
 
-#if 1 || PY_VERSION_HEX < 0x030600B1
 static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs) {
     PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func);
     PyObject *globals = PyFunction_GET_GLOBALS(func);
@@ -2034,7 +2398,7 @@
     assert(kwargs == NULL || PyDict_Check(kwargs));
     nk = kwargs ? PyDict_Size(kwargs) : 0;
 
-    if (Py_EnterRecursiveCall((char*)" while calling a Python object")) {
+    if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) {
         return NULL;
     }
 
@@ -2123,45 +2487,8 @@
     Py_LeaveRecursiveCall();
     return result;
 }
-#endif  /* CPython < 3.6 */
-#endif  /* CYTHON_FAST_PYCALL */
-
-
-/////////////// PyCFunctionFastCall.proto ///////////////
-
-#if CYTHON_FAST_PYCCALL
-static CYTHON_INLINE PyObject *__Pyx_PyCFunction_FastCall(PyObject *func, PyObject **args, Py_ssize_t nargs);
-#else
-#define __Pyx_PyCFunction_FastCall(func, args, nargs)  (assert(0), NULL)
-#endif
-
-/////////////// PyCFunctionFastCall ///////////////
-
-#if CYTHON_FAST_PYCCALL
-static CYTHON_INLINE PyObject * __Pyx_PyCFunction_FastCall(PyObject *func_obj, PyObject **args, Py_ssize_t nargs) {
-    PyCFunctionObject *func = (PyCFunctionObject*)func_obj;
-    PyCFunction meth = PyCFunction_GET_FUNCTION(func);
-    PyObject *self = PyCFunction_GET_SELF(func);
-    int flags = PyCFunction_GET_FLAGS(func);
-
-    assert(PyCFunction_Check(func));
-    assert(METH_FASTCALL == (flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS)));
-    assert(nargs >= 0);
-    assert(nargs == 0 || args != NULL);
-
-    /* _PyCFunction_FastCallDict() must not be called with an exception set,
-       because it may clear it (directly or indirectly) and so the
-       caller loses its exception */
-    assert(!PyErr_Occurred());
-
-    if ((PY_VERSION_HEX < 0x030700A0) || unlikely(flags & METH_KEYWORDS)) {
-        return (*((__Pyx_PyCFunctionFastWithKeywords)(void*)meth)) (self, args, nargs, NULL);
-    } else {
-        return (*((__Pyx_PyCFunctionFast)(void*)meth)) (self, args, nargs);
-    }
-}
-#endif  /* CYTHON_FAST_PYCCALL */
+#endif  /* CYTHON_FAST_PYCALL && !CYTHON_VECTORCALL */
 
 
 /////////////// PyObjectCall2Args.proto ///////////////
 
@@ -2164,7 +2491,7 @@
 
 
 /////////////// PyObjectCall2Args.proto ///////////////
 
-static CYTHON_UNUSED PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2); /*proto*/
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2); /*proto*/
 
 /////////////// PyObjectCall2Args ///////////////
@@ -2169,37 +2496,10 @@
 
 /////////////// PyObjectCall2Args ///////////////
-//@requires: PyObjectCall
-//@requires: PyFunctionFastCall
-//@requires: PyCFunctionFastCall
-
-static CYTHON_UNUSED PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2) {
-    PyObject *args, *result = NULL;
-    #if CYTHON_FAST_PYCALL
-    if (PyFunction_Check(function)) {
-        PyObject *args[2] = {arg1, arg2};
-        return __Pyx_PyFunction_FastCall(function, args, 2);
-    }
-    #endif
-    #if CYTHON_FAST_PYCCALL
-    if (__Pyx_PyFastCFunction_Check(function)) {
-        PyObject *args[2] = {arg1, arg2};
-        return __Pyx_PyCFunction_FastCall(function, args, 2);
-    }
-    #endif
-
-    args = PyTuple_New(2);
-    if (unlikely(!args)) goto done;
-    Py_INCREF(arg1);
-    PyTuple_SET_ITEM(args, 0, arg1);
-    Py_INCREF(arg2);
-    PyTuple_SET_ITEM(args, 1, arg2);
-
-    Py_INCREF(function);
-    result = __Pyx_PyObject_Call(function, args, NULL);
-    Py_DECREF(args);
-    Py_DECREF(function);
-done:
-    return result;
+//@requires: PyObjectFastCall
+
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2) {
+    PyObject *args[3] = {NULL, arg1, arg2};
+    return __Pyx_PyObject_FastCall(function, args+1, 2 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET);
 }
 
 
@@ -2208,21 +2508,6 @@
 static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg); /*proto*/
 
 /////////////// PyObjectCallOneArg ///////////////
-//@requires: PyObjectCallMethO
-//@requires: PyObjectCall
-//@requires: PyFunctionFastCall
-//@requires: PyCFunctionFastCall
-
-#if CYTHON_COMPILING_IN_CPYTHON
-static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) {
-    PyObject *result;
-    PyObject *args = PyTuple_New(1);
-    if (unlikely(!args)) return NULL;
-    Py_INCREF(arg);
-    PyTuple_SET_ITEM(args, 0, arg);
-    result = __Pyx_PyObject_Call(func, args, NULL);
-    Py_DECREF(args);
-    return result;
-}
+//@requires: PyObjectFastCall
 
 static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) {
@@ -2227,19 +2512,5 @@
 
 static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) {
-#if CYTHON_FAST_PYCALL
-    if (PyFunction_Check(func)) {
-        return __Pyx_PyFunction_FastCall(func, &arg, 1);
-    }
-#endif
-    if (likely(PyCFunction_Check(func))) {
-        if (likely(PyCFunction_GET_FLAGS(func) & METH_O)) {
-            // fast and simple case that we are optimising for
-            return __Pyx_PyObject_CallMethO(func, arg);
-#if CYTHON_FAST_PYCCALL
-        } else if (PyCFunction_GET_FLAGS(func) & METH_FASTCALL) {
-            return __Pyx_PyCFunction_FastCall(func, &arg, 1);
-#endif
-        }
-    }
-    return __Pyx__PyObject_CallOneArg(func, arg);
+    PyObject *args[2] = {NULL, arg};
+    return __Pyx_PyObject_FastCall(func, args+1, 1 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET);
 }
@@ -2245,14 +2516,4 @@
 }
-#else
-static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) {
-    PyObject *result;
-    PyObject *args = PyTuple_Pack(1, arg);
-    if (unlikely(!args)) return NULL;
-    result = __Pyx_PyObject_Call(func, args, NULL);
-    Py_DECREF(args);
-    return result;
-}
-#endif
 
 
 /////////////// PyObjectCallNoArg.proto ///////////////
@@ -2256,8 +2517,5 @@
 
 
 /////////////// PyObjectCallNoArg.proto ///////////////
-//@requires: PyObjectCall
-//@substitute: naming
-
-#if CYTHON_COMPILING_IN_CPYTHON
+
 static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func); /*proto*/
@@ -2263,6 +2521,3 @@
 static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func); /*proto*/
-#else
-#define __Pyx_PyObject_CallNoArg(func) __Pyx_PyObject_Call(func, $empty_tuple, NULL)
-#endif
 
 /////////////// PyObjectCallNoArg ///////////////
@@ -2267,9 +2522,5 @@
 
 /////////////// PyObjectCallNoArg ///////////////
-//@requires: PyObjectCallMethO
-//@requires: PyObjectCall
-//@requires: PyFunctionFastCall
-//@substitute: naming
-
-#if CYTHON_COMPILING_IN_CPYTHON
+//@requires: PyObjectFastCall
+
 static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) {
@@ -2275,6 +2526,11 @@
 static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) {
-#if CYTHON_FAST_PYCALL
-    if (PyFunction_Check(func)) {
-        return __Pyx_PyFunction_FastCall(func, NULL, 0);
-    }
+    PyObject *arg = NULL;
+    return __Pyx_PyObject_FastCall(func, (&arg)+1, 0 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET);
+}
+
+
+/////////////// PyVectorcallFastCallDict.proto ///////////////
+
+#if CYTHON_METH_FASTCALL
+static CYTHON_INLINE PyObject *__Pyx_PyVectorcall_FastCallDict(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, Py_ssize_t nargs, PyObject *kw);
 #endif
@@ -2280,12 +2536,32 @@
 #endif
-#ifdef __Pyx_CyFunction_USED
-    if (likely(PyCFunction_Check(func) || __Pyx_CyFunction_Check(func)))
-#else
-    if (likely(PyCFunction_Check(func)))
-#endif
-    {
-        if (likely(PyCFunction_GET_FLAGS(func) & METH_NOARGS)) {
-            // fast and simple case that we are optimising for
-            return __Pyx_PyObject_CallMethO(func, NULL);
-        }
+
+/////////////// PyVectorcallFastCallDict ///////////////
+
+#if CYTHON_METH_FASTCALL
+// Slow path when kw is non-empty
+static PyObject *__Pyx_PyVectorcall_FastCallDict_kw(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, Py_ssize_t nargs, PyObject *kw)
+{
+    // Code based on _PyObject_FastCallDict() and _PyStack_UnpackDict() from CPython
+    PyObject *res = NULL;
+    PyObject *kwnames;
+    PyObject **newargs;
+    PyObject **kwvalues;
+    Py_ssize_t i, pos;
+    PyObject *key, *value;
+    unsigned long keys_are_strings;
+    Py_ssize_t nkw = PyDict_GET_SIZE(kw);
+
+    // Copy positional arguments
+    newargs = (PyObject **)PyMem_Malloc((nargs + nkw) * sizeof(args[0]));
+    if (unlikely(newargs == NULL)) {
+        PyErr_NoMemory();
+        return NULL;
+    }
+    for (i = 0; i < nargs; i++) newargs[i] = args[i];
+
+    // Copy keyword arguments
+    kwnames = PyTuple_New(nkw);
+    if (unlikely(kwnames == NULL)) {
+        PyMem_Free(newargs);
+        return NULL;
     }
@@ -2291,5 +2567,37 @@
     }
-    return __Pyx_PyObject_Call(func, $empty_tuple, NULL);
+    kwvalues = newargs + nargs;
+    pos = i = 0;
+    keys_are_strings = Py_TPFLAGS_UNICODE_SUBCLASS;
+    while (PyDict_Next(kw, &pos, &key, &value)) {
+        keys_are_strings &= Py_TYPE(key)->tp_flags;
+        Py_INCREF(key);
+        Py_INCREF(value);
+        PyTuple_SET_ITEM(kwnames, i, key);
+        kwvalues[i] = value;
+        i++;
+    }
+    if (unlikely(!keys_are_strings)) {
+        PyErr_SetString(PyExc_TypeError, "keywords must be strings");
+        goto cleanup;
+    }
+
+    // The actual call
+    res = vc(func, newargs, nargs, kwnames);
+
+cleanup:
+    Py_DECREF(kwnames);
+    for (i = 0; i < nkw; i++)
+        Py_DECREF(kwvalues[i]);
+    PyMem_Free(newargs);
+    return res;
+}
+
+static CYTHON_INLINE PyObject *__Pyx_PyVectorcall_FastCallDict(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, Py_ssize_t nargs, PyObject *kw)
+{
+    if (likely(kw == NULL) || PyDict_GET_SIZE(kw) == 0) {
+        return vc(func, args, nargs, NULL);
+    }
+    return __Pyx_PyVectorcall_FastCallDict_kw(func, vc, args, nargs, kw);
 }
 #endif
 
@@ -2306,5 +2614,5 @@
 #endif
 
 /////////////// MatrixMultiply ///////////////
-//@requires: PyObjectGetAttrStr
+//@requires: PyObjectGetAttrStrNoError
 //@requires: PyObjectCallOneArg
@@ -2310,6 +2618,5 @@
 //@requires: PyObjectCallOneArg
-//@requires: PyFunctionFastCall
-//@requires: PyCFunctionFastCall
+//@requires: PyObjectCall2Args
 
 #if PY_VERSION_HEX < 0x03050000
 static PyObject* __Pyx_PyObject_CallMatrixMethod(PyObject* method, PyObject* arg) {
@@ -2319,5 +2626,4 @@
     if (likely(PyMethod_Check(method))) {
         PyObject *self = PyMethod_GET_SELF(method);
         if (likely(self)) {
-            PyObject *args;
             PyObject *function = PyMethod_GET_FUNCTION(method);
@@ -2323,30 +2629,6 @@
             PyObject *function = PyMethod_GET_FUNCTION(method);
-            #if CYTHON_FAST_PYCALL
-            if (PyFunction_Check(function)) {
-                PyObject *args[2] = {self, arg};
-                result = __Pyx_PyFunction_FastCall(function, args, 2);
-                goto done;
-            }
-            #endif
-            #if CYTHON_FAST_PYCCALL
-            if (__Pyx_PyFastCFunction_Check(function)) {
-                PyObject *args[2] = {self, arg};
-                result = __Pyx_PyCFunction_FastCall(function, args, 2);
-                goto done;
-            }
-            #endif
-            args = PyTuple_New(2);
-            if (unlikely(!args)) goto done;
-            Py_INCREF(self);
-            PyTuple_SET_ITEM(args, 0, self);
-            Py_INCREF(arg);
-            PyTuple_SET_ITEM(args, 1, arg);
-            Py_INCREF(function);
-            Py_DECREF(method); method = NULL;
-            result = __Pyx_PyObject_Call(function, args, NULL);
-            Py_DECREF(args);
-            Py_DECREF(function);
-            return result;
+            result = __Pyx_PyObject_Call2Args(function, self, arg);
+            goto done;
         }
     }
 #endif
@@ -2356,10 +2638,10 @@
     return result;
 }
 
-#define __Pyx_TryMatrixMethod(x, y, py_method_name) {                   \
-    PyObject *func = __Pyx_PyObject_GetAttrStr(x, py_method_name);      \
+#define __Pyx_TryMatrixMethod(x, y, py_method_name) {                     \
+    PyObject *func = __Pyx_PyObject_GetAttrStrNoError(x, py_method_name); \
     if (func) {                                                         \
         PyObject *result = __Pyx_PyObject_CallMatrixMethod(func, y);    \
         if (result != Py_NotImplemented)                                \
             return result;                                              \
         Py_DECREF(result);                                              \
@@ -2361,12 +2643,10 @@
     if (func) {                                                         \
         PyObject *result = __Pyx_PyObject_CallMatrixMethod(func, y);    \
         if (result != Py_NotImplemented)                                \
             return result;                                              \
         Py_DECREF(result);                                              \
-    } else {                                                            \
-        if (!PyErr_ExceptionMatches(PyExc_AttributeError))              \
-            return NULL;                                                \
-        PyErr_Clear();                                                  \
+    } else if (unlikely(PyErr_Occurred())) {                            \
+        return NULL;                                                    \
     }                                                                   \
 }
 
@@ -2458,3 +2738,140 @@
     return obj_dict_version == __Pyx_get_object_dict_version(obj);
 }
 #endif
+
+
+/////////////// PyMethodNew.proto ///////////////
+
+#if PY_MAJOR_VERSION >= 3
+// This should be an actual function (not a macro), such that we can put it
+// directly in a tp_descr_get slot.
+static PyObject *__Pyx_PyMethod_New(PyObject *func, PyObject *self, CYTHON_UNUSED PyObject *typ) {
+    if (!self) {
+        Py_INCREF(func);
+        return func;
+    }
+    return PyMethod_New(func, self);
+}
+#else
+    #define __Pyx_PyMethod_New PyMethod_New
+#endif
+
+/////////////// UnicodeConcatInPlace.proto ////////////////
+
+# if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+// __Pyx_PyUnicode_ConcatInPlace may modify the first argument 'left'
+// However, unlike `PyUnicode_Append` it will never NULL it.
+// It behaves like a regular function - returns a new reference and NULL on error
+    #if CYTHON_REFNANNY
+        #define __Pyx_PyUnicode_ConcatInPlace(left, right) __Pyx_PyUnicode_ConcatInPlaceImpl(&left, right, __pyx_refnanny)
+    #else
+        #define __Pyx_PyUnicode_ConcatInPlace(left, right) __Pyx_PyUnicode_ConcatInPlaceImpl(&left, right)
+    #endif
+    // __Pyx_PyUnicode_ConcatInPlace is slightly odd because it has the potential to modify the input
+    // argument (but only in cases where no user should notice). Therefore, it needs to keep Cython's
+    // refnanny informed.
+    static CYTHON_INLINE PyObject *__Pyx_PyUnicode_ConcatInPlaceImpl(PyObject **p_left, PyObject *right
+        #if CYTHON_REFNANNY
+        , void* __pyx_refnanny
+        #endif
+    ); /* proto */
+#else
+#define __Pyx_PyUnicode_ConcatInPlace __Pyx_PyUnicode_Concat
+#endif
+#define __Pyx_PyUnicode_ConcatInPlaceSafe(left, right) ((unlikely((left) == Py_None) || unlikely((right) == Py_None)) ? \
+    PyNumber_InPlaceAdd(left, right) : __Pyx_PyUnicode_ConcatInPlace(left, right))
+
+/////////////// UnicodeConcatInPlace ////////////////
+//@substitute: naming
+
+# if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+// copied directly from unicode_object.c "unicode_modifiable
+// removing _PyUnicode_HASH since it's a macro we don't have
+//  - this is OK because trying PyUnicode_Resize on a non-modifyable
+//  object will still work, it just won't happen in place
+static int
+__Pyx_unicode_modifiable(PyObject *unicode)
+{
+    if (Py_REFCNT(unicode) != 1)
+        return 0;
+    if (!PyUnicode_CheckExact(unicode))
+        return 0;
+    if (PyUnicode_CHECK_INTERNED(unicode))
+        return 0;
+    return 1;
+}
+
+static CYTHON_INLINE PyObject *__Pyx_PyUnicode_ConcatInPlaceImpl(PyObject **p_left, PyObject *right
+        #if CYTHON_REFNANNY
+        , void* __pyx_refnanny
+        #endif
+    ) {
+    // heavily based on PyUnicode_Append
+    PyObject *left = *p_left;
+    Py_ssize_t left_len, right_len, new_len;
+
+    if (unlikely(PyUnicode_READY(left) == -1))
+        return NULL;
+    if (unlikely(PyUnicode_READY(right) == -1))
+        return NULL;
+
+    // Shortcuts
+    left_len = PyUnicode_GET_LENGTH(left);
+    if (left_len == 0) {
+        Py_INCREF(right);
+        return right;
+    }
+    right_len = PyUnicode_GET_LENGTH(right);
+    if (right_len == 0) {
+        Py_INCREF(left);
+        return left;
+    }
+    if (unlikely(left_len > PY_SSIZE_T_MAX - right_len)) {
+        PyErr_SetString(PyExc_OverflowError,
+                        "strings are too large to concat");
+        return NULL;
+    }
+    new_len = left_len + right_len;
+
+    if (__Pyx_unicode_modifiable(left)
+            && PyUnicode_CheckExact(right)
+            && PyUnicode_KIND(right) <= PyUnicode_KIND(left)
+            // Don't resize for ascii += latin1. Convert ascii to latin1 requires
+            //   to change the structure size, but characters are stored just after
+            //   the structure, and so it requires to move all characters which is
+            //   not so different than duplicating the string.
+            && !(PyUnicode_IS_ASCII(left) && !PyUnicode_IS_ASCII(right))) {
+
+        __Pyx_GIVEREF(*p_left);
+        if (unlikely(PyUnicode_Resize(p_left, new_len) != 0)) {
+            // on failure PyUnicode_Resize does not deallocate the the input
+            // so left will remain unchanged - simply undo the giveref
+            __Pyx_GOTREF(*p_left);
+            return NULL;
+        }
+        __Pyx_INCREF(*p_left);
+
+        // copy 'right' into the newly allocated area of 'left'
+        _PyUnicode_FastCopyCharacters(*p_left, left_len, right, 0, right_len);
+        return *p_left;
+    } else {
+        return __Pyx_PyUnicode_Concat(left, right);
+    }
+  }
+#endif
+
+////////////// StrConcatInPlace.proto ///////////////////////
+//@requires: UnicodeConcatInPlace
+
+#if PY_MAJOR_VERSION >= 3
+    // allow access to the more efficient versions where we know str_type is unicode
+    #define __Pyx_PyStr_Concat __Pyx_PyUnicode_Concat
+    #define __Pyx_PyStr_ConcatInPlace __Pyx_PyUnicode_ConcatInPlace
+#else
+    #define __Pyx_PyStr_Concat PyNumber_Add
+    #define __Pyx_PyStr_ConcatInPlace PyNumber_InPlaceAdd
+#endif
+#define __Pyx_PyStr_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ? \
+    PyNumber_Add(a, b) : __Pyx_PyStr_Concat(a, b))
+#define __Pyx_PyStr_ConcatInPlaceSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ? \
+    PyNumber_InPlaceAdd(a, b) : __Pyx_PyStr_ConcatInPlace(a, b))
diff --git a/Cython/Utility/Optimize.c b/Cython/Utility/Optimize.c
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1V0aWxpdHkvT3B0aW1pemUuYw==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1V0aWxpdHkvT3B0aW1pemUuYw== 100644
--- a/Cython/Utility/Optimize.c
+++ b/Cython/Utility/Optimize.c
@@ -94,7 +94,7 @@
 //@requires: ObjectHandling.c::PyObjectCallMethod0
 
 static CYTHON_INLINE PyObject* __Pyx__PyObject_Pop(PyObject* L) {
-    if (Py_TYPE(L) == &PySet_Type) {
+    if (__Pyx_IS_TYPE(L, &PySet_Type)) {
         return PySet_Pop(L);
     }
     return __Pyx_PyObject_CallMethod0(L, PYIDENT("pop"));
@@ -190,7 +190,7 @@
 
 static PyObject* __Pyx_PyDict_GetItemDefault(PyObject* d, PyObject* key, PyObject* default_value) {
     PyObject* value;
-#if PY_MAJOR_VERSION >= 3 && !CYTHON_COMPILING_IN_PYPY
+#if PY_MAJOR_VERSION >= 3 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07020000)
     value = PyDict_GetItemWithError(d, key);
     if (unlikely(!value)) {
         if (unlikely(PyErr_Occurred()))
@@ -238,7 +238,7 @@
 #else
     if (is_safe_type == 1 || (is_safe_type == -1 &&
         /* the following builtins presumably have repeatably safe and fast hash functions */
-#if PY_MAJOR_VERSION >= 3 && !CYTHON_COMPILING_IN_PYPY
+#if PY_MAJOR_VERSION >= 3 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07020000)
             (PyUnicode_CheckExact(key) || PyString_CheckExact(key) || PyLong_CheckExact(key)))) {
         value = PyDict_GetItemWithError(d, key);
         if (unlikely(!value)) {
@@ -596,8 +596,9 @@
 #endif
 
 /////////////// pyobject_as_double ///////////////
+//@requires: ObjectHandling.c::PyObjectCallOneArg
 
 static double __Pyx__PyObject_AsDouble(PyObject* obj) {
     PyObject* float_value;
 #if !CYTHON_USE_TYPE_SLOTS
     float_value = PyNumber_Float(obj);  if ((0)) goto bad;
@@ -599,8 +600,10 @@
 
 static double __Pyx__PyObject_AsDouble(PyObject* obj) {
     PyObject* float_value;
 #if !CYTHON_USE_TYPE_SLOTS
     float_value = PyNumber_Float(obj);  if ((0)) goto bad;
+    // avoid "unused" warnings
+    (void)__Pyx_PyObject_CallOneArg;
 #else
     PyNumberMethods *nb = Py_TYPE(obj)->tp_as_number;
     if (likely(nb) && likely(nb->nb_float)) {
@@ -619,12 +622,7 @@
         float_value = PyFloat_FromString(obj, 0);
 #endif
     } else {
-        PyObject* args = PyTuple_New(1);
-        if (unlikely(!args)) goto bad;
-        PyTuple_SET_ITEM(args, 0, obj);
-        float_value = PyObject_Call((PyObject*)&PyFloat_Type, args, 0);
-        PyTuple_SET_ITEM(args, 0, 0);
-        Py_DECREF(args);
+        float_value = __Pyx_PyObject_CallOneArg((PyObject*)&PyFloat_Type, obj);
     }
 #endif
     if (likely(float_value)) {
@@ -648,7 +646,7 @@
 
 static PyObject* __Pyx__PyNumber_PowerOf2(PyObject *two, PyObject *exp, PyObject *none, int inplace) {
 // in CPython, 1<<N is substantially faster than 2**N
-// see http://bugs.python.org/issue21420
+// see https://bugs.python.org/issue21420
 #if !CYTHON_COMPILING_IN_PYPY
     Py_ssize_t shiftby;
 #if PY_MAJOR_VERSION < 3
@@ -776,4 +774,7 @@
 
     if (PyFloat_CheckExact({{pyval}})) {
         const long {{'a' if order == 'CObj' else 'b'}} = intval;
+#if CYTHON_COMPILING_IN_LIMITED_API
+        double {{ival}} = __pyx_PyFloat_AsDouble({{pyval}});
+#else
         double {{ival}} = PyFloat_AS_DOUBLE({{pyval}});
@@ -779,4 +780,5 @@
         double {{ival}} = PyFloat_AS_DOUBLE({{pyval}});
+#endif
         {{return_compare('(double)a', '(double)b', c_op)}}
     }
 
@@ -807,6 +809,5 @@
 {{py: return_false = 'Py_RETURN_FALSE' if ret_type.is_pyobject else 'return 0'}}
 {{py: slot_name = {'TrueDivide': 'true_divide', 'FloorDivide': 'floor_divide'}.get(op, op.lower()) }}
 {{py: cfunc_name = '__Pyx_PyInt_%s%s%s' % ('' if ret_type.is_pyobject else 'Bool', op, order)}}
-{{py: zerodiv_check = lambda operand, _cfunc_name=cfunc_name: '%s_ZeroDivisionError(%s)' % (_cfunc_name, operand)}}
 {{py:
 c_op = {
@@ -811,7 +812,7 @@
 {{py:
 c_op = {
-    'Add': '+', 'Subtract': '-', 'Remainder': '%', 'TrueDivide': '/', 'FloorDivide': '/',
+    'Add': '+', 'Subtract': '-', 'Multiply': '*', 'Remainder': '%', 'TrueDivide': '/', 'FloorDivide': '/',
     'Or': '|', 'Xor': '^', 'And': '&', 'Rshift': '>>', 'Lshift': '<<',
     'Eq': '==', 'Ne': '!=',
     }[op]
 }}
@@ -814,17 +815,16 @@
     'Or': '|', 'Xor': '^', 'And': '&', 'Rshift': '>>', 'Lshift': '<<',
     'Eq': '==', 'Ne': '!=',
     }[op]
 }}
-
-{{if op in ('TrueDivide', 'FloorDivide', 'Remainder')}}
-#if PY_MAJOR_VERSION < 3 || CYTHON_USE_PYLONG_INTERNALS
-#define {{zerodiv_check('operand')}} \
-    if (unlikely(zerodivision_check && ((operand) == 0))) { \
-        PyErr_SetString(PyExc_ZeroDivisionError, "integer division{{if op == 'Remainder'}} or modulo{{endif}} by zero"); \
-        return NULL; \
-    }
-#endif
-{{endif}}
+{{py:
+def zerodiv_check(operand, optype='integer', _is_mod=op == 'Remainder', _needs_check=(order == 'CObj' and c_op in '%/')):
+    return (((
+    'if (unlikely(zerodivision_check && ((%s) == 0))) {'
+    ' PyErr_SetString(PyExc_ZeroDivisionError, "%s division%s by zero");'
+    ' return NULL;'
+    '}') % (operand, optype, ' or modulo' if _is_mod else '')
+    ) if _needs_check else '')
+}}
 
 static {{c_ret_type}} {{cfunc_name}}(PyObject *op1, PyObject *op2, CYTHON_UNUSED long intval, int inplace, int zerodivision_check) {
     // Prevent "unused" warnings.
@@ -828,8 +828,7 @@
 
 static {{c_ret_type}} {{cfunc_name}}(PyObject *op1, PyObject *op2, CYTHON_UNUSED long intval, int inplace, int zerodivision_check) {
     // Prevent "unused" warnings.
-    (void)inplace;
-    (void)zerodivision_check;
+    (void)inplace; (void)zerodivision_check;
 
     {{if op in ('Eq', 'Ne')}}
     if (op1 == op2) {
@@ -844,6 +843,7 @@
         long x;
         {{endif}}
         long {{ival}} = PyInt_AS_LONG({{pyval}});
+        {{zerodiv_check('b')}}
 
         {{if op in ('Eq', 'Ne')}}
         if (a {{c_op}} b) {
@@ -859,9 +859,8 @@
                 return PyInt_FromLong(x);
             return PyLong_Type.tp_as_number->nb_{{slot_name}}(op1, op2);
         {{elif c_op == '%'}}
-            {{zerodiv_check('b')}}
             // see ExprNodes.py :: mod_int_utility_code
             x = a % b;
             x += ((x != 0) & ((x ^ b) < 0)) * b;
             return PyInt_FromLong(x);
         {{elif op == 'TrueDivide'}}
@@ -863,12 +862,11 @@
             // see ExprNodes.py :: mod_int_utility_code
             x = a % b;
             x += ((x != 0) & ((x ^ b) < 0)) * b;
             return PyInt_FromLong(x);
         {{elif op == 'TrueDivide'}}
-            {{zerodiv_check('b')}}
             if (8 * sizeof(long) <= 53 || likely(labs({{ival}}) <= ((PY_LONG_LONG)1 << 53))) {
                 return PyFloat_FromDouble((double)a / (double)b);
             }
             // let Python do the rounding
             return PyInt_Type.tp_as_number->nb_{{slot_name}}(op1, op2);
         {{elif op == 'FloorDivide'}}
@@ -869,11 +867,10 @@
             if (8 * sizeof(long) <= 53 || likely(labs({{ival}}) <= ((PY_LONG_LONG)1 << 53))) {
                 return PyFloat_FromDouble((double)a / (double)b);
             }
             // let Python do the rounding
             return PyInt_Type.tp_as_number->nb_{{slot_name}}(op1, op2);
         {{elif op == 'FloorDivide'}}
-            // INT_MIN / -1  is the only case that overflows, b == 0 is an error case
-            {{zerodiv_check('b')}}
+            // INT_MIN / -1  is the only case that overflows
             if (unlikely(b == -1 && ((unsigned long)a) == 0-(unsigned long)a))
                 return PyInt_Type.tp_as_number->nb_{{slot_name}}(op1, op2);
             else {
@@ -889,6 +886,19 @@
             if (likely(b < (long) (sizeof(long)*8) && a == (a << b) >> b) || !a) {
                 return PyInt_FromLong(a {{c_op}} b);
             }
+        {{elif c_op == '*'}}
+#ifdef HAVE_LONG_LONG
+            if (sizeof(PY_LONG_LONG) > sizeof(long)) {
+                PY_LONG_LONG result = (PY_LONG_LONG)a {{c_op}} (PY_LONG_LONG)b;
+                return (result >= LONG_MIN && result <= LONG_MAX) ?
+                    PyInt_FromLong((long)result) : PyLong_FromLongLong(result);
+            }
+#endif
+#if CYTHON_USE_TYPE_SLOTS
+            return PyInt_Type.tp_as_number->nb_{{slot_name}}(op1, op2);
+#else
+            return PyNumber_{{op}}(op1, op2);
+#endif
         {{else}}
             // other operations are safe, no overflow
             return PyInt_FromLong(a {{c_op}} b);
@@ -908,6 +918,38 @@
         {{endif}}
         const digit* digits = ((PyLongObject*){{pyval}})->ob_digit;
         const Py_ssize_t size = Py_SIZE({{pyval}});
+        {{if c_op == '&'}}
+        // special case for &-ing arbitrarily large numbers with known single digit operands
+        if ((intval & PyLong_MASK) == intval) {
+            long result = 0;
+            if(likely(size)) {
+                result = intval & (likely(size>0) ? digits[0] : (PyLong_MASK - digits[0] + 1));
+            }
+            return PyLong_FromLong(result);
+        }
+        {{endif}}
+        // special cases for 0: + - * % / // | ^ & >> <<
+        if (unlikely(size == 0)) {
+            {{if order == 'CObj' and c_op in '%/'}}
+            // division by zero!
+            {{zerodiv_check('0')}}
+            {{elif order == 'CObj' and c_op in '+-|^>><<'}}
+            // x == x+0 == x-0 == x|0 == x^0 == x>>0 == x<<0
+            return __Pyx_NewRef(op1);
+            {{elif order == 'CObj' and c_op in '*&'}}
+            // 0 == x*0 == x&0
+            return __Pyx_NewRef(op2);
+            {{elif order == 'ObjC' and c_op in '+|^'}}
+            // x == 0+x == 0|x == 0^x
+            return __Pyx_NewRef(op2);
+            {{elif order == 'ObjC' and c_op == '-'}}
+            // -x == 0-x
+            return PyLong_FromLong(-intval);
+            {{elif order == 'ObjC' and (c_op in '*%&>><<' or op == 'FloorDivide')}}
+            // 0 == 0*x == 0%x == 0&x == 0>>x == 0<<x == 0//x
+            return __Pyx_NewRef(op1);
+            {{endif}}
+        }
         // handle most common case first to avoid indirect branch and optimise branch prediction
         if (likely(__Pyx_sst_abs(size) <= 1)) {
             {{ival}} = likely(size) ? digits[0] : 0;
@@ -917,7 +959,7 @@
                 {{for _size in range(2, 5)}}
                 {{for _case in (-_size, _size)}}
                 case {{_case}}:
-                    if (8 * sizeof(long) - 1 > {{_size}} * PyLong_SHIFT{{if op == 'TrueDivide'}} && {{_size-1}} * PyLong_SHIFT < 53{{endif}}) {
+                    if (8 * sizeof(long) - 1 > {{_size}} * PyLong_SHIFT{{if c_op == '*'}}+30{{endif}}{{if op == 'TrueDivide'}} && {{_size-1}} * PyLong_SHIFT < 53{{endif}}) {
                         {{ival}} = {{'-' if _case < 0 else ''}}(long) {{pylong_join(_size, 'digits')}};
                         break;
                     {{if op not in ('Eq', 'Ne', 'TrueDivide')}}
@@ -921,7 +963,7 @@
                         {{ival}} = {{'-' if _case < 0 else ''}}(long) {{pylong_join(_size, 'digits')}};
                         break;
                     {{if op not in ('Eq', 'Ne', 'TrueDivide')}}
-#ifdef HAVE_LONG_LONG
-                    } else if (8 * sizeof(PY_LONG_LONG) - 1 > {{_size}} * PyLong_SHIFT) {
+                    #ifdef HAVE_LONG_LONG
+                    } else if (8 * sizeof(PY_LONG_LONG) - 1 > {{_size}} * PyLong_SHIFT{{if c_op == '*'}}+30{{endif}}) {
                         ll{{ival}} = {{'-' if _case < 0 else ''}}(PY_LONG_LONG) {{pylong_join(_size, 'digits', 'unsigned PY_LONG_LONG')}};
                         goto long_long;
@@ -926,6 +968,6 @@
                         ll{{ival}} = {{'-' if _case < 0 else ''}}(PY_LONG_LONG) {{pylong_join(_size, 'digits', 'unsigned PY_LONG_LONG')}};
                         goto long_long;
-#endif
+                    #endif
                     {{endif}}
                     }
                     // if size doesn't fit into a long or PY_LONG_LONG anymore, fall through to default
@@ -954,9 +996,16 @@
                 {{return_false}};
             }
         {{else}}
-            {{if c_op == '%'}}
-                {{zerodiv_check('b')}}
+            {{if c_op == '*'}}
+                (void)a; (void)b;
+                #ifdef HAVE_LONG_LONG
+                ll{{ival}} = {{ival}};
+                goto long_long;
+                #else
+                return PyLong_Type.tp_as_number->nb_{{slot_name}}(op1, op2);
+                #endif
+            {{elif c_op == '%'}}
                 // see ExprNodes.py :: mod_int_utility_code
                 x = a % b;
                 x += ((x != 0) & ((x ^ b) < 0)) * b;
             {{elif op == 'TrueDivide'}}
@@ -959,11 +1008,10 @@
                 // see ExprNodes.py :: mod_int_utility_code
                 x = a % b;
                 x += ((x != 0) & ((x ^ b) < 0)) * b;
             {{elif op == 'TrueDivide'}}
-                {{zerodiv_check('b')}}
                 if ((8 * sizeof(long) <= 53 || likely(labs({{ival}}) <= ((PY_LONG_LONG)1 << 53)))
                         || __Pyx_sst_abs(size) <= 52 / PyLong_SHIFT) {
                     return PyFloat_FromDouble((double)a / (double)b);
                 }
                 return PyLong_Type.tp_as_number->nb_{{slot_name}}(op1, op2);
             {{elif op == 'FloorDivide'}}
@@ -964,10 +1012,9 @@
                 if ((8 * sizeof(long) <= 53 || likely(labs({{ival}}) <= ((PY_LONG_LONG)1 << 53)))
                         || __Pyx_sst_abs(size) <= 52 / PyLong_SHIFT) {
                     return PyFloat_FromDouble((double)a / (double)b);
                 }
                 return PyLong_Type.tp_as_number->nb_{{slot_name}}(op1, op2);
             {{elif op == 'FloorDivide'}}
-                {{zerodiv_check('b')}}
                 {
                     long q, r;
                     // see ExprNodes.py :: div_int_utility_code
@@ -1020,6 +1067,6 @@
     }
     #endif
 
-    {{if c_op in '+-' or op in ('TrueDivide', 'Eq', 'Ne')}}
+    {{if c_op in '+-*' or op in ('TrueDivide', 'Eq', 'Ne')}}
     if (PyFloat_CheckExact({{pyval}})) {
         const long {{'a' if order == 'CObj' else 'b'}} = intval;
@@ -1024,3 +1071,6 @@
     if (PyFloat_CheckExact({{pyval}})) {
         const long {{'a' if order == 'CObj' else 'b'}} = intval;
+#if CYTHON_COMPILING_IN_LIMITED_API
+        double {{ival}} = __pyx_PyFloat_AsDouble({{pyval}});
+#else
         double {{ival}} = PyFloat_AS_DOUBLE({{pyval}});
@@ -1026,4 +1076,5 @@
         double {{ival}} = PyFloat_AS_DOUBLE({{pyval}});
+#endif
         {{if op in ('Eq', 'Ne')}}
             if ((double)a {{c_op}} (double)b) {
                 {{return_true}};
@@ -1032,12 +1083,7 @@
             }
         {{else}}
             double result;
-            {{if op == 'TrueDivide'}}
-            if (unlikely(zerodivision_check && b == 0)) {
-                PyErr_SetString(PyExc_ZeroDivisionError, "float division by zero");
-                return NULL;
-            }
-            {{endif}}
+            {{zerodiv_check('b', 'float')}}
             // copied from floatobject.c in Py3.5:
             PyFPE_START_PROTECT("{{op.lower() if not op.endswith('Divide') else 'divide'}}", return NULL)
             result = ((double)a) {{c_op}} (double)b;
@@ -1078,10 +1124,9 @@
 {{py: return_false = 'Py_RETURN_FALSE' if ret_type.is_pyobject else 'return 0'}}
 {{py: pyval, fval = ('op2', 'b') if order == 'CObj' else ('op1', 'a') }}
 {{py: cfunc_name = '__Pyx_PyFloat_%s%s%s' % ('' if ret_type.is_pyobject else 'Bool', op, order) }}
-{{py: zerodiv_check = lambda operand, _cfunc_name=cfunc_name: '%s_ZeroDivisionError(%s)' % (_cfunc_name, operand)}}
 {{py:
 c_op = {
     'Add': '+', 'Subtract': '-', 'TrueDivide': '/', 'Divide': '/', 'Remainder': '%',
     'Eq': '==', 'Ne': '!=',
     }[op]
 }}
@@ -1082,18 +1127,20 @@
 {{py:
 c_op = {
     'Add': '+', 'Subtract': '-', 'TrueDivide': '/', 'Divide': '/', 'Remainder': '%',
     'Eq': '==', 'Ne': '!=',
     }[op]
 }}
-
-{{if order == 'CObj' and c_op in '%/'}}
-#define {{zerodiv_check('operand')}} if (unlikely(zerodivision_check && ((operand) == 0))) { \
-    PyErr_SetString(PyExc_ZeroDivisionError, "float division{{if op == 'Remainder'}} or modulo{{endif}} by zero"); \
-    return NULL; \
-}
-{{endif}}
+{{py:
+def zerodiv_check(operand, _is_mod=op == 'Remainder', _needs_check=(order == 'CObj' and c_op in '%/')):
+    return (((
+        'if (unlikely(zerodivision_check && ((%s) == 0.0))) {'
+        ' PyErr_SetString(PyExc_ZeroDivisionError, "float division%s by zero");'
+        ' return NULL;'
+        '}') % (operand, ' or modulo' if _is_mod else '')
+    ) if _needs_check else '')
+}}
 
 static {{c_ret_type}} {{cfunc_name}}(PyObject *op1, PyObject *op2, double floatval, int inplace, int zerodivision_check) {
     const double {{'a' if order == 'CObj' else 'b'}} = floatval;
     double {{fval}}{{if op not in ('Eq', 'Ne')}}, result{{endif}};
     // Prevent "unused" warnings.
@@ -1095,10 +1142,9 @@
 
 static {{c_ret_type}} {{cfunc_name}}(PyObject *op1, PyObject *op2, double floatval, int inplace, int zerodivision_check) {
     const double {{'a' if order == 'CObj' else 'b'}} = floatval;
     double {{fval}}{{if op not in ('Eq', 'Ne')}}, result{{endif}};
     // Prevent "unused" warnings.
-    (void)inplace;
-    (void)zerodivision_check;
+    (void)inplace; (void)zerodivision_check;
 
     {{if op in ('Eq', 'Ne')}}
     if (op1 == op2) {
@@ -1107,4 +1153,7 @@
     {{endif}}
 
     if (likely(PyFloat_CheckExact({{pyval}}))) {
+#if CYTHON_COMPILING_IN_LIMITED_API
+        {{fval}} = __pyx_PyFloat_AsDouble({{pyval}});
+#else
         {{fval}} = PyFloat_AS_DOUBLE({{pyval}});
@@ -1110,7 +1159,8 @@
         {{fval}} = PyFloat_AS_DOUBLE({{pyval}});
-        {{if order == 'CObj' and c_op in '%/'}}{{zerodiv_check(fval)}}{{endif}}
+#endif
+        {{zerodiv_check(fval)}}
     } else
 
     #if PY_MAJOR_VERSION < 3
     if (likely(PyInt_CheckExact({{pyval}}))) {
         {{fval}} = (double) PyInt_AS_LONG({{pyval}});
@@ -1112,9 +1162,9 @@
     } else
 
     #if PY_MAJOR_VERSION < 3
     if (likely(PyInt_CheckExact({{pyval}}))) {
         {{fval}} = (double) PyInt_AS_LONG({{pyval}});
-        {{if order == 'CObj' and c_op in '%/'}}{{zerodiv_check(fval)}}{{endif}}
+        {{zerodiv_check(fval)}}
     } else
     #endif
 
@@ -1123,7 +1173,7 @@
         const digit* digits = ((PyLongObject*){{pyval}})->ob_digit;
         const Py_ssize_t size = Py_SIZE({{pyval}});
         switch (size) {
-            case  0: {{if order == 'CObj' and c_op in '%/'}}{{zerodiv_check('0')}}{{else}}{{fval}} = 0.0;{{endif}} break;
+            case  0: {{fval}} = 0.0; {{zerodiv_check(fval)}} break;
             case -1: {{fval}} = -(double) digits[0]; break;
             case  1: {{fval}} = (double) digits[0]; break;
             {{for _size in (2, 3, 4)}}
@@ -1155,7 +1205,11 @@
         {{else}}
             {{fval}} = PyLong_AsDouble({{pyval}});
             if (unlikely({{fval}} == -1.0 && PyErr_Occurred())) return NULL;
-            {{if order == 'CObj' and c_op in '%/'}}{{zerodiv_check(fval)}}{{endif}}
+            {{if zerodiv_check(fval)}}
+            #if !CYTHON_USE_PYLONG_INTERNALS
+            {{zerodiv_check(fval)}}
+            #endif
+            {{endif}}
         {{endif}}
         }
     } else {
@@ -1177,7 +1231,6 @@
         }
     {{else}}
         // copied from floatobject.c in Py3.5:
-        {{if order == 'CObj' and c_op in '%/'}}{{zerodiv_check('b')}}{{endif}}
         PyFPE_START_PROTECT("{{op.lower() if not op.endswith('Divide') else 'divide'}}", return NULL)
         {{if c_op == '%'}}
         result = fmod(a, b);
diff --git a/Cython/Utility/Overflow.c b/Cython/Utility/Overflow.c
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1V0aWxpdHkvT3ZlcmZsb3cuYw==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1V0aWxpdHkvT3ZlcmZsb3cuYw== 100644
--- a/Cython/Utility/Overflow.c
+++ b/Cython/Utility/Overflow.c
@@ -305,5 +305,4 @@
 
 /////////////// UnaryNegOverflows.proto ///////////////
 
-//FIXME: shouldn't the macro name be prefixed by "__Pyx_" ?  Too late now, I guess...
 // from intobject.c
@@ -309,3 +308,3 @@
 // from intobject.c
-#define UNARY_NEG_WOULD_OVERFLOW(x)    \
+#define __Pyx_UNARY_NEG_WOULD_OVERFLOW(x)    \
         (((x) < 0) & ((unsigned long)(x) == 0-(unsigned long)(x)))
diff --git a/Cython/Utility/Profile.c b/Cython/Utility/Profile.c
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1V0aWxpdHkvUHJvZmlsZS5j..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1V0aWxpdHkvUHJvZmlsZS5j 100644
--- a/Cython/Utility/Profile.c
+++ b/Cython/Utility/Profile.c
@@ -6,7 +6,7 @@
 // but maybe some other profilers don't.
 
 #ifndef CYTHON_PROFILE
-#if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_PYSTON
+#if CYTHON_COMPILING_IN_LIMITED_API || CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_PYSTON
   #define CYTHON_PROFILE 0
 #else
   #define CYTHON_PROFILE 1
@@ -197,8 +197,8 @@
           if (CYTHON_TRACE_NOGIL) {                                                        \
               int ret = 0;                                                                 \
               PyThreadState *tstate;                                                       \
-              PyGILState_STATE state = PyGILState_Ensure();                                \
+              PyGILState_STATE state = __Pyx_PyGILState_Ensure();                          \
               tstate = __Pyx_PyThreadState_Current;                                        \
               if (unlikely(tstate->use_tracing && tstate->c_tracefunc && $frame_cname->f_trace)) { \
                   ret = __Pyx_call_line_trace_func(tstate, $frame_cname, lineno);          \
               }                                                                            \
@@ -201,8 +201,8 @@
               tstate = __Pyx_PyThreadState_Current;                                        \
               if (unlikely(tstate->use_tracing && tstate->c_tracefunc && $frame_cname->f_trace)) { \
                   ret = __Pyx_call_line_trace_func(tstate, $frame_cname, lineno);          \
               }                                                                            \
-              PyGILState_Release(state);                                                   \
+              __Pyx_PyGILState_Release(state);                                             \
               if (unlikely(ret)) goto_error;                                               \
           }                                                                                \
       } else {                                                                             \
diff --git a/Cython/Utility/StringTools.c b/Cython/Utility/StringTools.c
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1V0aWxpdHkvU3RyaW5nVG9vbHMuYw==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1V0aWxpdHkvU3RyaW5nVG9vbHMuYw== 100644
--- a/Cython/Utility/StringTools.c
+++ b/Cython/Utility/StringTools.c
@@ -7,5 +7,39 @@
 
 #include <string>
 
+
+//////////////////// ssize_strlen.proto ////////////////////
+
+static CYTHON_INLINE Py_ssize_t __Pyx_ssize_strlen(const char *s);/*proto*/
+
+//////////////////// ssize_strlen ////////////////////
+//@requires: IncludeStringH
+
+static CYTHON_INLINE Py_ssize_t __Pyx_ssize_strlen(const char *s) {
+    size_t len = strlen(s);
+    if (unlikely(len > PY_SSIZE_T_MAX)) {
+        PyErr_SetString(PyExc_OverflowError, "byte string is too long");
+        return -1;
+    }
+    return (Py_ssize_t) len;
+}
+
+
+//////////////////// ssize_pyunicode_strlen.proto ////////////////////
+
+static CYTHON_INLINE Py_ssize_t __Pyx_Py_UNICODE_ssize_strlen(const Py_UNICODE *u);/*proto*/
+
+//////////////////// ssize_pyunicode_strlen ////////////////////
+
+static CYTHON_INLINE Py_ssize_t __Pyx_Py_UNICODE_ssize_strlen(const Py_UNICODE *u) {
+    size_t len = __Pyx_Py_UNICODE_strlen(u);
+    if (unlikely(len > PY_SSIZE_T_MAX)) {
+        PyErr_SetString(PyExc_OverflowError, "Py_UNICODE string is too long");
+        return -1;
+    }
+    return (Py_ssize_t) len;
+}
+
+
 //////////////////// InitStrings.proto ////////////////////
 
@@ -10,3 +44,6 @@
 //////////////////// InitStrings.proto ////////////////////
 
+#if CYTHON_COMPILING_IN_LIMITED_API
+static int __Pyx_InitString(__Pyx_StringTabEntry t, PyObject **str); /*proto*/
+#else
 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
@@ -12,4 +49,5 @@
 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
+#endif
 
 //////////////////// InitStrings ////////////////////
 
@@ -13,5 +51,28 @@
 
 //////////////////// InitStrings ////////////////////
 
+#if PY_MAJOR_VERSION >= 3
+static int __Pyx_InitString(__Pyx_StringTabEntry t, PyObject **str) {
+    if (t.is_unicode | t.is_str) {
+        if (t.intern) {
+            *str = PyUnicode_InternFromString(t.s);
+        } else if (t.encoding) {
+            *str = PyUnicode_Decode(t.s, t.n - 1, t.encoding, NULL);
+        } else {
+            *str = PyUnicode_FromStringAndSize(t.s, t.n - 1);
+        }
+    } else {
+        *str = PyBytes_FromStringAndSize(t.s, t.n - 1);
+    }
+    if (!*str)
+        return -1;
+    // initialise cached hash value
+    if (PyObject_Hash(*str) == -1)
+        return -1;
+    return 0;
+}
+#endif
+
+#if !CYTHON_COMPILING_IN_LIMITED_API
 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
     while (t->p) {
@@ -16,6 +77,8 @@
 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
     while (t->p) {
-        #if PY_MAJOR_VERSION < 3
+        #if PY_MAJOR_VERSION >= 3  /* Python 3+ has unicode identifiers */
+        __Pyx_InitString(*t, t->p);
+        #else
         if (t->is_unicode) {
             *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
         } else if (t->intern) {
@@ -23,21 +86,8 @@
         } else {
             *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
         }
-        #else  /* Python 3+ has unicode identifiers */
-        if (t->is_unicode | t->is_str) {
-            if (t->intern) {
-                *t->p = PyUnicode_InternFromString(t->s);
-            } else if (t->encoding) {
-                *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
-            } else {
-                *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
-            }
-        } else {
-            *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
-        }
-        #endif
         if (!*t->p)
             return -1;
         // initialise cached hash value
         if (PyObject_Hash(*t->p) == -1)
             return -1;
@@ -39,9 +89,10 @@
         if (!*t->p)
             return -1;
         // initialise cached hash value
         if (PyObject_Hash(*t->p) == -1)
             return -1;
+        #endif
         ++t;
     }
     return 0;
 }
@@ -44,7 +95,8 @@
         ++t;
     }
     return 0;
 }
+#endif
 
 //////////////////// BytesContains.proto ////////////////////
 
@@ -155,7 +207,7 @@
 //@requires: BytesEquals
 
 static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) {
-#if CYTHON_COMPILING_IN_PYPY
+#if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API
     return PyObject_RichCompareBool(s1, s2, equals);
 #else
 #if PY_MAJOR_VERSION < 3
@@ -266,7 +318,7 @@
 //@requires: IncludeStringH
 
 static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) {
-#if CYTHON_COMPILING_IN_PYPY
+#if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API
     return PyObject_RichCompareBool(s1, s2, equals);
 #else
     if (s1 == s2) {
@@ -466,4 +518,6 @@
         if (stop < 0)
             stop += length;
     }
+    if (unlikely(stop <= start))
+        return PyUnicode_FromUnicode(NULL, 0);
     length = stop - start;
@@ -469,6 +523,4 @@
     length = stop - start;
-    if (unlikely(length <= 0))
-        return PyUnicode_FromUnicode(NULL, 0);
     cstring += start;
     if (decode_func) {
         return decode_func(cstring, length, errors);
@@ -502,4 +554,6 @@
     }
     if (stop > length)
         stop = length;
+    if (unlikely(stop <= start))
+        return PyUnicode_FromUnicode(NULL, 0);
     length = stop - start;
@@ -505,6 +559,4 @@
     length = stop - start;
-    if (unlikely(length <= 0))
-        return PyUnicode_FromUnicode(NULL, 0);
     cstring += start;
     if (decode_func) {
         return decode_func(cstring, length, errors);
@@ -543,6 +595,7 @@
             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) {
@@ -558,9 +611,10 @@
         stop += length;
     else if (stop > length)
         stop = length;
-    length = stop - start;
-    if (length <= 0)
-        return PyUnicode_FromUnicode(NULL, 0);
+    if (stop <= start)
+        return __Pyx_NewRef($empty_unicode);
+    if (start == 0 && stop == length)
+        return __Pyx_NewRef(text);
 #if CYTHON_PEP393_ENABLED
     return PyUnicode_FromKindAndData(PyUnicode_KIND(text),
         PyUnicode_1BYTE_DATA(text) + start*PyUnicode_KIND(text), stop-start);
@@ -808,7 +862,7 @@
                                       CYTHON_UNUSED Py_UCS4 max_char) {
 #if CYTHON_USE_UNICODE_INTERNALS && CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
     PyObject *result_uval;
-    int result_ukind;
+    int result_ukind, kind_shift;
     Py_ssize_t i, char_pos;
     void *result_udata;
 #if CYTHON_PEP393_ENABLED
@@ -816,9 +870,10 @@
     result_uval = PyUnicode_New(result_ulength, max_char);
     if (unlikely(!result_uval)) return NULL;
     result_ukind = (max_char <= 255) ? PyUnicode_1BYTE_KIND : (max_char <= 65535) ? PyUnicode_2BYTE_KIND : PyUnicode_4BYTE_KIND;
+    kind_shift = (result_ukind == PyUnicode_4BYTE_KIND) ? 2 : result_ukind - 1;
     result_udata = PyUnicode_DATA(result_uval);
 #else
     // Py 2.x/3.2  (pre PEP-393)
     result_uval = PyUnicode_FromUnicode(NULL, result_ulength);
     if (unlikely(!result_uval)) return NULL;
     result_ukind = sizeof(Py_UNICODE);
@@ -819,8 +874,9 @@
     result_udata = PyUnicode_DATA(result_uval);
 #else
     // Py 2.x/3.2  (pre PEP-393)
     result_uval = PyUnicode_FromUnicode(NULL, result_ulength);
     if (unlikely(!result_uval)) return NULL;
     result_ukind = sizeof(Py_UNICODE);
+    kind_shift = (result_ukind == 4) ? 2 : result_ukind - 1;
     result_udata = PyUnicode_AS_UNICODE(result_uval);
 #endif
@@ -825,5 +881,6 @@
     result_udata = PyUnicode_AS_UNICODE(result_uval);
 #endif
+    assert(kind_shift == 2 || kind_shift == 1 || kind_shift == 0);
 
     char_pos = 0;
     for (i=0; i < value_count; i++) {
@@ -836,8 +893,8 @@
         ulength = __Pyx_PyUnicode_GET_LENGTH(uval);
         if (unlikely(!ulength))
             continue;
-        if (unlikely(char_pos + ulength < 0))
+        if (unlikely((PY_SSIZE_T_MAX >> kind_shift) - ulength < char_pos))
             goto overflow;
         ukind = __Pyx_PyUnicode_KIND(uval);
         udata = __Pyx_PyUnicode_DATA(uval);
         if (!CYTHON_PEP393_ENABLED || ukind == result_ukind) {
@@ -840,8 +897,8 @@
             goto overflow;
         ukind = __Pyx_PyUnicode_KIND(uval);
         udata = __Pyx_PyUnicode_DATA(uval);
         if (!CYTHON_PEP393_ENABLED || ukind == result_ukind) {
-            memcpy((char *)result_udata + char_pos * result_ukind, udata, (size_t) (ulength * result_ukind));
+            memcpy((char *)result_udata + (char_pos << kind_shift), udata, (size_t) (ulength << kind_shift));
         } else {
             #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030300F0 || defined(_PyUnicode_FastCopyCharacters)
             _PyUnicode_FastCopyCharacters(result_uval, char_pos, uval, 0, ulength);
@@ -1100,6 +1157,7 @@
         likely(PyString_CheckExact(s)) ? PyUnicode_FromEncodedObject(s, NULL, "strict") : \
         PyObject_Format(s, f))
 #elif CYTHON_USE_TYPE_SLOTS
-    // Py3 nicely returns unicode strings from str() which makes this quite efficient for builtin types
+    // Py3 nicely returns unicode strings from str() and repr(), which makes this quite efficient for builtin types.
+    // In Py3.8+, tp_str() delegates to tp_repr(), so we call tp_repr() directly here.
     #define __Pyx_PyObject_FormatSimple(s, f) ( \
         likely(PyUnicode_CheckExact(s)) ? (Py_INCREF(s), s) : \
@@ -1104,7 +1162,7 @@
     #define __Pyx_PyObject_FormatSimple(s, f) ( \
         likely(PyUnicode_CheckExact(s)) ? (Py_INCREF(s), s) : \
-        likely(PyLong_CheckExact(s)) ? PyLong_Type.tp_str(s) : \
-        likely(PyFloat_CheckExact(s)) ? PyFloat_Type.tp_str(s) : \
+        likely(PyLong_CheckExact(s)) ? PyLong_Type.tp_repr(s) : \
+        likely(PyFloat_CheckExact(s)) ? PyFloat_Type.tp_repr(s) : \
         PyObject_Format(s, f))
 #else
     #define __Pyx_PyObject_FormatSimple(s, f) ( \
@@ -1163,3 +1221,22 @@
 #define __Pyx_PyObject_Unicode(obj) \
     (likely(PyUnicode_CheckExact(obj)) ? __Pyx_NewRef(obj) : PyObject_Unicode(obj))
 #endif
+
+
+//////////////////// PyStr_Str.proto ////////////////////
+
+static CYTHON_INLINE PyObject* __Pyx_PyStr_Str(PyObject *obj);/*proto*/
+
+//////////////////// PyStr_Str ////////////////////
+
+static CYTHON_INLINE PyObject* __Pyx_PyStr_Str(PyObject *obj) {
+    if (unlikely(obj == Py_None))
+        obj = PYIDENT("None");
+    return __Pyx_NewRef(obj);
+}
+
+
+//////////////////// PyObject_Str.proto ////////////////////
+
+#define __Pyx_PyObject_Str(obj) \
+    (likely(PyString_CheckExact(obj)) ? __Pyx_NewRef(obj) : PyObject_Str(obj))
diff --git a/Cython/Utility/TestCythonScope.pyx b/Cython/Utility/TestCythonScope.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1V0aWxpdHkvVGVzdEN5dGhvblNjb3BlLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1V0aWxpdHkvVGVzdEN5dGhvblNjb3BlLnB5eA== 100644
--- a/Cython/Utility/TestCythonScope.pyx
+++ b/Cython/Utility/TestCythonScope.pyx
@@ -1,6 +1,8 @@
 ########## TestClass ##########
 # These utilities are for testing purposes
 
+from __future__ import print_function
+
 cdef extern from *:
     cdef object __pyx_test_dep(object)
 
@@ -12,6 +14,6 @@
         self.value = value
 
     def __str__(self):
-        return 'TestClass(%d)' % self.value
+        return f'TestClass({self.value})'
 
     cdef cdef_method(self, int value):
@@ -16,5 +18,5 @@
 
     cdef cdef_method(self, int value):
-        print 'Hello from cdef_method', value
+        print('Hello from cdef_method', value)
 
     cpdef cpdef_method(self, int value):
@@ -19,5 +21,5 @@
 
     cpdef cpdef_method(self, int value):
-        print 'Hello from cpdef_method', value
+        print('Hello from cpdef_method', value)
 
     def def_method(self, int value):
@@ -22,6 +24,6 @@
 
     def def_method(self, int value):
-        print 'Hello from def_method', value
+        print('Hello from def_method', value)
 
     @cname('cdef_cname')
     cdef cdef_cname_method(self, int value):
@@ -25,7 +27,7 @@
 
     @cname('cdef_cname')
     cdef cdef_cname_method(self, int value):
-        print "Hello from cdef_cname_method", value
+        print("Hello from cdef_cname_method", value)
 
     @cname('cpdef_cname')
     cpdef cpdef_cname_method(self, int value):
@@ -29,7 +31,7 @@
 
     @cname('cpdef_cname')
     cpdef cpdef_cname_method(self, int value):
-        print "Hello from cpdef_cname_method", value
+        print("Hello from cpdef_cname_method", value)
 
     @cname('def_cname')
     def def_cname_method(self, int value):
@@ -33,7 +35,7 @@
 
     @cname('def_cname')
     def def_cname_method(self, int value):
-        print "Hello from def_cname_method", value
+        print("Hello from def_cname_method", value)
 
 @cname('__pyx_test_call_other_cy_util')
 cdef test_call(obj):
@@ -37,7 +39,7 @@
 
 @cname('__pyx_test_call_other_cy_util')
 cdef test_call(obj):
-    print 'test_call'
+    print('test_call')
     __pyx_test_dep(obj)
 
 @cname('__pyx_TestClass_New')
@@ -46,5 +48,7 @@
 
 ########### TestDep ##########
 
+from __future__ import print_function
+
 @cname('__pyx_test_dep')
 cdef test_dep(obj):
@@ -49,8 +53,8 @@
 @cname('__pyx_test_dep')
 cdef test_dep(obj):
-    print 'test_dep', obj
+    print('test_dep', obj)
 
 ########## TestScope ##########
 
 @cname('__pyx_testscope')
 cdef object _testscope(int value):
@@ -52,11 +56,11 @@
 
 ########## TestScope ##########
 
 @cname('__pyx_testscope')
 cdef object _testscope(int value):
-    return "hello from cython scope, value=%d" % value
+    return f"hello from cython scope, value={value}"
 
 ########## View.TestScope ##########
 
 @cname('__pyx_view_testscope')
 cdef object _testscope(int value):
@@ -58,7 +62,6 @@
 
 ########## View.TestScope ##########
 
 @cname('__pyx_view_testscope')
 cdef object _testscope(int value):
-    return "hello from cython.view scope, value=%d" % value
-
+    return f"hello from cython.view scope, value={value}"
diff --git a/Cython/Utility/TypeConversion.c b/Cython/Utility/TypeConversion.c
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1V0aWxpdHkvVHlwZUNvbnZlcnNpb24uYw==..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1V0aWxpdHkvVHlwZUNvbnZlcnNpb24uYw== 100644
--- a/Cython/Utility/TypeConversion.c
+++ b/Cython/Utility/TypeConversion.c
@@ -68,9 +68,9 @@
 #define __Pyx_PyBytes_AsString(s)     ((const char*) PyBytes_AS_STRING(s))
 #define __Pyx_PyBytes_AsSString(s)    ((const signed char*) PyBytes_AS_STRING(s))
 #define __Pyx_PyBytes_AsUString(s)    ((const unsigned char*) PyBytes_AS_STRING(s))
-#define __Pyx_PyObject_AsWritableString(s)    ((char*) __Pyx_PyObject_AsString(s))
-#define __Pyx_PyObject_AsWritableSString(s)    ((signed char*) __Pyx_PyObject_AsString(s))
-#define __Pyx_PyObject_AsWritableUString(s)    ((unsigned char*) __Pyx_PyObject_AsString(s))
+#define __Pyx_PyObject_AsWritableString(s)    ((char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s))
+#define __Pyx_PyObject_AsWritableSString(s)    ((signed char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s))
+#define __Pyx_PyObject_AsWritableUString(s)    ((unsigned char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s))
 #define __Pyx_PyObject_AsSString(s)    ((const signed char*) __Pyx_PyObject_AsString(s))
 #define __Pyx_PyObject_AsUString(s)    ((const unsigned char*) __Pyx_PyObject_AsString(s))
 #define __Pyx_PyObject_FromCString(s)  __Pyx_PyObject_FromString((const char*)s)
@@ -80,8 +80,17 @@
 #define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s)
 
 // There used to be a Py_UNICODE_strlen() in CPython 3.x, but it is deprecated since Py3.3.
-static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) {
+#if CYTHON_COMPILING_IN_LIMITED_API
+static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const wchar_t *u)
+{
+    const wchar_t *u_end = u;
+    while (*u_end++) ;
+    return (size_t)(u_end - u - 1);
+}
+#else
+static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u)
+{
     const Py_UNICODE *u_end = u;
     while (*u_end++) ;
     return (size_t)(u_end - u - 1);
 }
@@ -84,7 +93,8 @@
     const Py_UNICODE *u_end = u;
     while (*u_end++) ;
     return (size_t)(u_end - u - 1);
 }
+#endif
 
 #define __Pyx_PyUnicode_FromUnicode(u)       PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u))
 #define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode
@@ -102,6 +112,7 @@
 
 static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
 static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
+static CYTHON_INLINE Py_hash_t __Pyx_PyIndex_AsHash_t(PyObject*);
 
 #if CYTHON_ASSUME_SAFE_MACROS
 #define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
@@ -270,7 +281,7 @@
     } else
 #endif /* __PYX_DEFAULT_STRING_ENCODING_IS_ASCII  || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT */
 
-#if (!CYTHON_COMPILING_IN_PYPY) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE))
+#if (!CYTHON_COMPILING_IN_PYPY && !CYTHON_COMPILING_IN_LIMITED_API) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE))
     if (PyByteArray_Check(o)) {
         *length = PyByteArray_GET_SIZE(o);
         return PyByteArray_AS_STRING(o);
@@ -310,7 +321,7 @@
                 "__int__ returned non-int (type %.200s).  "
                 "The ability to return an instance of a strict subclass of int "
                 "is deprecated, and may be removed in a future version of Python.",
-                Py_TYPE(result)->tp_name)) {
+                __Pyx_PyType_Name(Py_TYPE(result)))) {
             Py_DECREF(result);
             return NULL;
         }
@@ -319,7 +330,7 @@
 #endif
     PyErr_Format(PyExc_TypeError,
                  "__%.4s__ returned non-%.4s (type %.200s)",
-                 type_name, type_name, Py_TYPE(result)->tp_name);
+                 type_name, type_name, __Pyx_PyType_Name(Py_TYPE(result)));
     Py_DECREF(result);
     return NULL;
 }
@@ -420,6 +431,25 @@
 }
 
 
+static CYTHON_INLINE Py_hash_t __Pyx_PyIndex_AsHash_t(PyObject* o) {
+  if (sizeof(Py_hash_t) == sizeof(Py_ssize_t)) {
+    return __Pyx_PyIndex_AsSsize_t(o);
+#if PY_MAJOR_VERSION < 3
+  } else if (likely(PyInt_CheckExact(o))) {
+    return PyInt_AS_LONG(o);
+#endif
+  } else {
+    Py_ssize_t ival;
+    PyObject *x;
+    x = PyNumber_Index(o);
+    if (!x) return -1;
+    ival = PyInt_AsLong(x);
+    Py_DECREF(x);
+    return ival;
+  }
+}
+
+
 static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b) {
   return b ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False);
 }
@@ -688,18 +718,6 @@
 //@requires: StringTools.c::BuildPyUnicode
 //@requires: CIntToDigits
 
-#ifdef _MSC_VER
-    #ifndef _MSC_STDINT_H_
-        #if _MSC_VER < 1300
-           typedef unsigned short    uint16_t;
-        #else
-           typedef unsigned __int16  uint16_t;
-        #endif
-    #endif
-#else
-   #include <stdint.h>
-#endif
-
 // NOTE: inlining because most arguments are constant, which collapses lots of code below
 
 // GCC diagnostic pragmas were introduced in GCC 4.6
@@ -761,10 +779,10 @@
         }
     } while (unlikely(remaining != 0));
 
-    if (last_one_off) {
-        assert(*dpos == '0');
-        dpos++;
-    }
+    // Correct dpos by 1 if we read an excess digit.
+    assert(!last_one_off || *dpos == '0');
+    dpos += last_one_off;
+
     length = end - dpos;
     ulength = length;
     prepend_sign = 0;
@@ -939,5 +957,5 @@
             }
         }
         {
-#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+#if (CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API) && !defined(_PyLong_AsByteArray)
             PyErr_SetString(PyExc_RuntimeError,
@@ -943,5 +961,5 @@
             PyErr_SetString(PyExc_RuntimeError,
-                            "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+                            "_PyLong_AsByteArray() not available, cannot convert large numbers");
 #else
             {{TYPE}} val;
             PyObject *v = __Pyx_PyNumber_IntOrLong(x);
diff --git a/Cython/Utils.py b/Cython/Utils.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_Q3l0aG9uL1V0aWxzLnB5..162972e7c0335748b70e02edc37e5e3bbb4858ae_Q3l0aG9uL1V0aWxzLnB5 100644
--- a/Cython/Utils.py
+++ b/Cython/Utils.py
@@ -1,7 +1,7 @@
-#
-#   Cython -- Things that don't belong
-#            anywhere else in particular
-#
+"""
+Cython -- Things that don't belong
+          anywhere else in particular
+"""
 
 from __future__ import absolute_import
 
@@ -23,6 +23,8 @@
 import shutil
 from contextlib import contextmanager
 
+PACKAGE_FILES = ("__init__.py", "__init__.pyc", "__init__.pyx", "__init__.pxd")
+
 modification_time = os.path.getmtime
 
 _function_caches = []
@@ -26,7 +28,9 @@
 modification_time = os.path.getmtime
 
 _function_caches = []
+
+
 def clear_function_caches():
     for cache in _function_caches:
         cache.clear()
 
@@ -29,8 +33,9 @@
 def clear_function_caches():
     for cache in _function_caches:
         cache.clear()
 
+
 def cached_function(f):
     cache = {}
     _function_caches.append(cache)
     uncomputed = object()
@@ -33,9 +38,10 @@
 def cached_function(f):
     cache = {}
     _function_caches.append(cache)
     uncomputed = object()
+
     def wrapper(*args):
         res = cache.get(args, uncomputed)
         if res is uncomputed:
             res = cache[args] = f(*args)
         return res
@@ -37,8 +43,9 @@
     def wrapper(*args):
         res = cache.get(args, uncomputed)
         if res is uncomputed:
             res = cache[args] = f(*args)
         return res
+
     wrapper.uncached = f
     return wrapper
 
@@ -42,5 +49,6 @@
     wrapper.uncached = f
     return wrapper
 
+
 def cached_method(f):
     cache_name = '__%s_cache' % f.__name__
@@ -45,5 +53,6 @@
 def cached_method(f):
     cache_name = '__%s_cache' % f.__name__
+
     def wrapper(self, *args):
         cache = getattr(self, cache_name, None)
         if cache is None:
@@ -53,5 +62,6 @@
             return cache[args]
         res = cache[args] = f(self, *args)
         return res
+
     return wrapper
 
@@ -56,5 +66,6 @@
     return wrapper
 
+
 def replace_suffix(path, newsuf):
     base, _ = os.path.splitext(path)
     return base + newsuf
@@ -91,6 +102,7 @@
         if st:
             os.utime(path, (st.st_atime, st.st_mtime-1))
 
+
 def file_newer_than(path, time):
     ftime = modification_time(path)
     return ftime > time
@@ -133,12 +145,5 @@
     else:
         return dir
 
-@cached_function
-def check_package_dir(dir, package_names):
-    for dirname in package_names:
-        dir = os.path.join(dir, dirname)
-        if not is_package_dir(dir):
-            return None
-    return dir
 
 @cached_function
@@ -143,11 +148,21 @@
 
 @cached_function
-def is_package_dir(dir_path):
-    for filename in ("__init__.py",
-                     "__init__.pyc",
-                     "__init__.pyx",
-                     "__init__.pxd"):
+def check_package_dir(dir_path, package_names):
+    namespace = True
+    for dirname in package_names:
+        dir_path = os.path.join(dir_path, dirname)
+        has_init = contains_init(dir_path)
+        if not namespace and not has_init:
+            return None, False
+        elif has_init:
+            namespace = False
+    return dir_path, namespace
+
+
+@cached_function
+def contains_init(dir_path):
+    for filename in PACKAGE_FILES:
         path = os.path.join(dir_path, filename)
         if path_exists(path):
             return 1
 
@@ -150,7 +165,13 @@
         path = os.path.join(dir_path, filename)
         if path_exists(path):
             return 1
 
+
+def is_package_dir(dir_path):
+    if contains_init(dir_path):
+        return 1
+
+
 @cached_function
 def path_exists(path):
     # try on the filesystem first
@@ -175,6 +196,7 @@
         pass
     return False
 
+
 # file name encodings
 
 def decode_filename(filename):
@@ -188,8 +210,9 @@
             pass
     return filename
 
+
 # support for source file encoding detection
 
 _match_file_encoding = re.compile(br"(\w*coding)[:=]\s*([-\w.]+)").search
 
 
@@ -191,9 +214,9 @@
 # support for source file encoding detection
 
 _match_file_encoding = re.compile(br"(\w*coding)[:=]\s*([-\w.]+)").search
 
 
-def detect_opened_file_encoding(f):
+def detect_opened_file_encoding(f, default='UTF-8'):
     # PEPs 263 and 3120
     # Most of the time the first two lines fall in the first couple of hundred chars,
     # and this bulk read/split is much faster.
@@ -205,6 +228,7 @@
         lines = start.split(b"\n")
         if not data:
             break
+
     m = _match_file_encoding(lines[0])
     if m and m.group(1) != b'c_string_encoding':
         return m.group(2).decode('iso8859-1')
@@ -212,7 +236,7 @@
         m = _match_file_encoding(lines[1])
         if m:
             return m.group(2).decode('iso8859-1')
-    return "UTF-8"
+    return default
 
 
 def skip_bom(f):
@@ -387,6 +411,7 @@
     if flush:
         out.flush()
 
+
 class LazyStr:
     def __init__(self, callback):
         self.callback = callback
@@ -390,5 +415,6 @@
 class LazyStr:
     def __init__(self, callback):
         self.callback = callback
+
     def __str__(self):
         return self.callback()
@@ -393,4 +419,5 @@
     def __str__(self):
         return self.callback()
+
     def __repr__(self):
         return self.callback()
@@ -395,4 +422,5 @@
     def __repr__(self):
         return self.callback()
+
     def __add__(self, right):
         return self.callback() + right
@@ -397,7 +425,8 @@
     def __add__(self, right):
         return self.callback() + right
+
     def __radd__(self, left):
         return left + self.callback()
 
 
 class OrderedSet(object):
@@ -399,21 +428,24 @@
     def __radd__(self, left):
         return left + self.callback()
 
 
 class OrderedSet(object):
-  def __init__(self, elements=()):
-    self._list = []
-    self._set = set()
-    self.update(elements)
-  def __iter__(self):
-    return iter(self._list)
-  def update(self, elements):
-    for e in elements:
-      self.add(e)
-  def add(self, e):
-    if e not in self._set:
-      self._list.append(e)
-      self._set.add(e)
+    def __init__(self, elements=()):
+        self._list = []
+        self._set = set()
+        self.update(elements)
+
+    def __iter__(self):
+        return iter(self._list)
+
+    def update(self, elements):
+        for e in elements:
+            self.add(e)
+
+    def add(self, e):
+        if e not in self._set:
+            self._list.append(e)
+            self._set.add(e)
 
 
 # Class decorator that adds a metaclass and recreates the class with it.
@@ -435,7 +467,7 @@
 
 
 def raise_error_if_module_name_forbidden(full_module_name):
-    #it is bad idea to call the pyx-file cython.pyx, so fail early
+    # it is bad idea to call the pyx-file cython.pyx, so fail early
     if full_module_name == 'cython' or full_module_name.startswith('cython.'):
         raise ValueError('cython is a special module, cannot be used as a module name')
 
diff --git a/Demos/benchmarks/bpnn3.py b/Demos/benchmarks/bpnn3.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_RGVtb3MvYmVuY2htYXJrcy9icG5uMy5weQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_RGVtb3MvYmVuY2htYXJrcy9icG5uMy5weQ== 100644
--- a/Demos/benchmarks/bpnn3.py
+++ b/Demos/benchmarks/bpnn3.py
@@ -1,7 +1,7 @@
 #!/usr/bin/python
 # Back-Propagation Neural Networks
 #
-# Written in Python.  See http://www.python.org/
+# Written in Python.  See https://www.python.org/
 #
 # Neil Schemenauer <nascheme@enme.ucalgary.ca>
 
diff --git a/Demos/benchmarks/nqueens.py b/Demos/benchmarks/nqueens.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_RGVtb3MvYmVuY2htYXJrcy9ucXVlZW5zLnB5..162972e7c0335748b70e02edc37e5e3bbb4858ae_RGVtb3MvYmVuY2htYXJrcy9ucXVlZW5zLnB5 100644
--- a/Demos/benchmarks/nqueens.py
+++ b/Demos/benchmarks/nqueens.py
@@ -43,7 +43,7 @@
         else:
             return
 
-# From http://code.activestate.com/recipes/576647/
+# From https://code.activestate.com/recipes/576647/
 @cython.locals(queen_count=int, i=int, vec=list)
 def n_queens(queen_count):
     """N-Queens solver.
diff --git a/Demos/embed/Makefile b/Demos/embed/Makefile
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_RGVtb3MvZW1iZWQvTWFrZWZpbGU=..162972e7c0335748b70e02edc37e5e3bbb4858ae_RGVtb3MvZW1iZWQvTWFrZWZpbGU= 100644
--- a/Demos/embed/Makefile
+++ b/Demos/embed/Makefile
@@ -15,6 +15,23 @@
 LIBS := $(shell $(PYTHON) -c "import distutils.sysconfig; print(distutils.sysconfig.get_config_var('LIBS'))")
 SYSLIBS :=  $(shell $(PYTHON) -c "import distutils.sysconfig; print(distutils.sysconfig.get_config_var('SYSLIBS'))")
 
+.PHONY: paths all clean test
+
+paths:
+	@echo "PYTHON=$(PYTHON)"
+	@echo "PYVERSION=$(PYVERSION)"
+	@echo "PYPREFIX=$(PYPREFIX)"
+	@echo "INCDIR=$(INCDIR)"
+	@echo "PLATINCDIR=$(PLATINCDIR)"
+	@echo "LIBDIR1=$(LIBDIR1)"
+	@echo "LIBDIR2=$(LIBDIR2)"
+	@echo "PYLIB=$(PYLIB)"
+	@echo "CC=$(CC)"
+	@echo "LINKCC=$(LINKCC)"
+	@echo "LINKFORSHARED=$(LINKFORSHARED)"
+	@echo "LIBS=$(LIBS)"
+	@echo "SYSLIBS=$(SYSLIBS)"
+
 embedded: embedded.o
 	$(LINKCC) -o $@ $^ -L$(LIBDIR1) -L$(LIBDIR2) -l$(PYLIB) $(LIBS) $(SYSLIBS) $(LINKFORSHARED)
 
diff --git a/Demos/freeze/README.rst b/Demos/freeze/README.rst
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_RGVtb3MvZnJlZXplL1JFQURNRS5yc3Q=..162972e7c0335748b70e02edc37e5e3bbb4858ae_RGVtb3MvZnJlZXplL1JFQURNRS5yc3Q= 100644
--- a/Demos/freeze/README.rst
+++ b/Demos/freeze/README.rst
@@ -106,5 +106,5 @@
 SEE ALSO
 ========
 
-* `Python <http://www.python.org>`_
+* `Python <https://www.python.org/>`_
 * `Cython <http://www.cython.org>`_
@@ -110,2 +110,2 @@
 * `Cython <http://www.cython.org>`_
-* `freeze.py <http://wiki.python.org/moin/Freeze>`_
+* `freeze.py <https://wiki.python.org/moin/Freeze>`_
diff --git a/Demos/pyprimes.py b/Demos/pyprimes.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_RGVtb3MvcHlwcmltZXMucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_RGVtb3MvcHlwcmltZXMucHk= 100644
--- a/Demos/pyprimes.py
+++ b/Demos/pyprimes.py
@@ -5,6 +5,6 @@
     while k < kmax:
         i = 0
         while i < k and n % p[i] != 0:
-            i = i + 1
+            i += 1
         if i == k:
             p.append(n)
@@ -9,5 +9,5 @@
         if i == k:
             p.append(n)
-            k = k + 1
-        n = n + 1
+            k += 1
+        n += 1
     return p
diff --git a/Doc/s5/cython-ep2008.txt b/Doc/s5/cython-ep2008.txt
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_RG9jL3M1L2N5dGhvbi1lcDIwMDgudHh0..162972e7c0335748b70e02edc37e5e3bbb4858ae_RG9jL3M1L2N5dGhvbi1lcDIwMDgudHh0 100644
--- a/Doc/s5/cython-ep2008.txt
+++ b/Doc/s5/cython-ep2008.txt
@@ -51,7 +51,7 @@
 
 * an Open-Source project
 
-  * http://cython.org
+  * https://cython.org/
 
 * a Python compiler (almost)
 
@@ -115,7 +115,7 @@
 
 * many, *many* others - see
 
-  * http://cython.org/
+  * https://cython.org/
 
   * the mailing list archives of Cython and Pyrex
 
@@ -398,4 +398,4 @@
 
   \... use it, and join the project!
 
-  http://cython.org/
+  https://cython.org/
diff --git a/Doc/s5/ui/default/cython-logo64.png b/Doc/s5/ui/default/cython-logo64.png
index 7ff4f6e927faf79f828a456aa6a0a7743be75ed3..c24c9e6d557af99a1f2931c1f3ec040a7eb8082f
GIT binary patch
literal 3583
zc$@+M4FK|qP)<h;3K|Lk000e1NJLTq002M$002M;1^@s7-EKih00001b5ch_0Itp)
z=>Px#24YJ`L;(K){{a7>y{D4^01c-}L_t(|+T~k&RMd4A*R4FZt*s~9?4`BV+1lzP
ziYPB}<S`6jXd1?vsTuMT7+wk_>YzLZF?Bt(FtGxO%BUzpnxbItwp;t?Y;|-1MMOo=
zZP%5PR#sbg@BO{_G5j9$`vK-T`^P;nGvCL(_jm98-uwC9-!K3erbNO&QBhIgOu_*1
z7smXCr@8Mg(09TBekI?m-KCQg%7oAK<4qc1Dm-TMTU7&7lD5Ibc$+V@M*u%yEWd)m
zQZW)PE(JI<3*eN`DQ6!3!7SSnKtF!LegC+#6#uTPtD6)P6BEvT{`s(h=-~v<<UL|B
zohS5B(o9Qz>9o|UK7)k;0qfocuk@YZ7FP;zVF~mb;JvaMpgR%Z+{*yXGy4qqO5mX_
zoOE!V*MXo1eifU|Hh%l|?Z52zG^Gd!>~RwNd!$iHdWv?o6*<+&+LP48nQIS#Z{}{8
zmbx883t4!g4<*hE1Q#3y|D1Z5{>EPLOxpqOiN9yn+ieE87}f7N)QcAgT7NKOM)p4N
zUa_kTE~f%RozVatuK={o0cZ(=emam9;rt?iv-1F2P55}GgBD}EL*eQ487DPhfs_Y}
z=qpJM^pYH#Pf6@tq`CkOx}w5<KSj$a=R*muo^%@XjO1e^4;QUI+?ab{oZM634ar-I
zJ(KkqI{CrN6zsfK>=c{vL}ybL?>?3v7_|OSsUdrRsrSlV;9;%+*{9&Vd+3HH2+DmA
z46AFwC!-psCRc)6yba(=N+ev02h|0Pd56KU<^cF)+F@$SJ1}Ya+pHsXE<=A<fc_93
zuDHO=wRPZ|wTGPO8^)2k5-`ZU2GBkq;B*+qGlQq%0_egwJ=3aKFT4~BaDE{=)Qjj)
zMv8ZmB3u_O^0n~e#n&-{M&e2G0`BS$il!`SWoKVPmO}s>en{SlqQ^LnkGR6&g8zi6
z#Y0&`68*4H{9{5wg3)fb{~GDJl9G}K@VhUiHc^ed5_JEd#)Bb=Cr%QLK<aQMOvq4;
zo`Ck43kz>SnvHZH(sM`&lr*?7?=Gc)I9XxhV_MaVb3Rg7?_Oss{7Pn^#d+b-qT`>L
ztVbaT<3>QvyG-n$ut)L3YsD^;2E+VNZNLsG$&C3&DAra`+@V7pvrpQXNgt+|%R!S7
z;wE#{&YrN%A4~|rFdJOZ0D<cdfxo35W~|<ismC5BaiiGfkz4`p30w+7p_k7px|dH@
zW8g1J44}GaGwQ||&#JqYRd<FRJkxhDA=^E18%)BOPn$CgbR`xuft0f9^RHqUUoujO
zfi@)ujCn_nqq>2zG{05*m`n|ixOBLZ8UWoXvAvWO3zy<5nIKFl5d~sOizpbM4#`tu
zpiq$kJd|f-?`O^!Iv(BAcHQ5rUd;CBl%tIA{9@enH^2mON|h;)Q`tblTrCbL7~vv*
zpl5p3e2<ih%!r6RcR<&2_JpKto=(a3h)igkoe8HyGod9g6C4I4-%L2^GuNd^h#URF
zl_W?YN>%BErF4}}SxQ+Q2Bvb6Iy7A^h3;0+#Pj_ow-^hUa)mbJ$>AHVA*%i$cbdJU
zz=)@YDEN%RI#X2-BOLUr0USV5bWPW3C}L<7Qn8Dh{VR$!pn)I9KYBiJTQPuIjYaxg
zMg1Qmg$`y$6f*$Bqw;>TE(UPoD}(F>PiRTW{-&~+11Sl~jq{FKNE<ncmF8_yWq=}-
z!UEG>w3S9B7gfp$Z^%q)(UA{6q`<^yQfGlfW^k+ACc%~?_XXu0ax+-oA1TAcqY6xH
z7N3UWT|EuM3;*<R$c9D;&gav!IyOCH^Mz{?Oe88WF<dPlNbi>sZ)j>Y<~Pi8w|#t9
zZ*I6($PK3?S0qa?VUeK(`tcDhxj=Bi(H_hXulwiJw^Dvcn+y42awR6F<&|2q;zL>(
z2+TXYDIn)ysbS6jQolF$mEz{7z4+ub36s<1WttgKt?9xx9zRI93jr8Rf+`duOoGa6
zJ|(G~12jr1MLFZSfiSR?-TcJvkV4x02ngA6HlH2$79*3FmvL!1$3Ryi=8Z9wnuqIU
zAb<vh6gC1?LS*s1l@OaD)8+&s5hl;q1a5J*Xy}UPlGeqPwEm!%fhQTGlXSP<YG^W7
z4RLe{3z9sxHh7h*4d#Mg2D}-_3@ajXHv{i(8PzvCI+902cUpAc!X&{AozWNBRGqTs
z2rg?5)y+U84e;m6G2Y$aa>}!UkqN~~99Nty;))Zhh{9R0xH&*K16!G!lQp&93Z-}Y
zPTI6X*qk>sLgG3Wvb6$%YG=Y&V6E9e>H4Q?49J~+S80IXssrPEMec?h_rPTgc6|*E
zH>Z+pHdm4bvLzW)qzoIb#z2u;Ao5vR{jg_hRffBHTPCW!hpl`CL)#1O^RP5~0ZTI@
zmS+BJS$4{MCA3T(<4PPDsqh$n)^Ad0bdRK=G3D6|lDblJQtAu>Dq-JfXjf$o?UYXg
zIJ~#%VPLG%k=bX`*_R`st)HO*ob*mY)%W1vCnQe8$EC<QA^B8>fgAm+<2j?z(0T+z
zW9ck>?0%QT=GSD_4V6mC<UFE5Ptk$%tTO8zm&*x%qVOorY24hQIVlxQ{zi_G=;&zM
zTW`JfpxthNqNb+i`P$lAx2meDr%Fmn9<f@jV{pta1tE@VDNO!4$c0Iq=F*INBy9uS
zxM)y{Q(TDdz|Xk2sohm<`A09$|1a<f3Z_U8a@Pt5q?b6TA)C8)upt#7r6Dcm?x3bo
zK`p+_ysZ_0jNZvzU++Zf9%Kg=(|6o8NIufjKbitKSd|cp&LI?53mr!C9cqMZgmdG@
zZAv{zFAkalaIp|dkaaTiK9U(}f(|Qtkh_ZfqYK!V?4=xCcI#3AB}_>F)wp37(%c~o
zsIMy|cuGXQZV$VPP>$CT$S5$4xmCv(cUkSwp@=4OWhI1ky^g5tp~f&_h@l(bj|#Ci
z)|jkEyMptNd>52^n86(AB6Oyuj;X$9WbeCyMR1Ex=AI3HtE$JjpophApVz`OS+$!~
zHeRi9AxabPRAVx1!*Ls3Ih(A<&Y21tRv7aR*E52zdzZmH2<sxyg{ptLh9=C5z!xgS
zr=?Y0o0hoaQ57ZJf%J(EYlspr@`1+5H(fRPkiuhE>Au~V->{e|@(b%m`RCMsK{y+=
zIuX`JxC@~V)b>PzQyU-yeI-|dM^bs&kS0Q0R;E>Z;jV6C%s)byZm+qo70jI#JZldF
zIuYJSI4=oK5DejdOg}(^Hpo>gJWHLiUuzWpqTGU^8=D?Ob2pl-jgh9jhDbE`$bfYR
zS+dkc8dekSk3_*4^3JeFqTqiZ&<o975S;pq33n7A-){4GrW=Fl$VizF-D&RNu#6ZC
z1+3BW^s~f^%-YoSNZ6YvE>H)bsqh%nUP4$l)9JD9AnWIAc|Y$pciztlXywhFaBk{=
zWd*nOLeAn=6awbDlYnhqh;^ueZ)yst)u904oDbj9I5xDX>05%aO$A38D4Q{N5?s>U
zcQfWr*t%fuB)GYpF?WKx#Vs%#6~mR}C_!k#VyVlQz(K<3&M*4&KooF6hXUM%0B3DV
zr@kJ7(W#Y+_j7;YSYxBR*w3BK-93pH{B38!iMnHpiXK3r&#*#Au~;wx(F9HsM#%J!
zL_DKc0X;et@T|}>ThP#C<OT0%?lsQle#I+w$APJ-m4zND6;=;(xfRXbiso*e6jv(H
z#JJL&iLoW~&0DsNh0d5F6#9F(u#{~LA`qMxn($}>!<jarS*dyz@R1G$ga{En_r14S
zb7uvYI@UbX>>+R^br$;X=Y6gg`cN|a?f`-Agnbk6PMu!_zBAol3)uGx1fgfM?^+NT
zPXKLe;A?snP_9D(@xrZPPW?QwpF5lTv=uvya5=47UTEI0d7*i~=7o-AF?hOZVuXHy
z#o}9o*;@!|5hhIj6T@h|3eeLQaiUL}OIN03?j(4ooi+D#Ho7x!#xPeZywEA25X?Bg
z=7pZeUOosyo7hVTUTAt#fo<1{7-%B&sSYLdNl$&V?5}xeRDbE5#Tk~60#bUIn>1=G
z7lf7xW`fY+Y*U;dG_?U5dWB}`pZM8lFfzd)9SW#(d8145J?xb+FLb|Pwinu8WZMth
zLNnpCiM#6xL^5PT^YpMG#{`v{I2CBVOB-EW+QSC3h3dhK_3LId@l&EFU3p7DQLgJq
zs}j_oPRD{1>cMO#=hwbAVV=YHx15is-7-`d1$tA55*Dd$c4m$lg}x>o%zXRyp!QM+
zobn2G0TYPO$nRDD;zVx22}u9ZxM(|}G%joZGsC0M>>J3usB+Th4W#+t@R|gzKBF{3
z@gHjBGfxX9XwhK}yZKiXh7b<>DN=<-zPiQlY-vS>*Xq2$$mU)g8E&yyMidnl-LrM;
z)_XT?+H{}IX1kwW5-KYz8%sq07Z(?g*}Qr4=)%InQ8?yqoO7pB?{I=bKY<)ID<RTa
zHSae7cpR23Th<;E6Jv{yk6&jto0Bs#GG5Kj&JN4X&7F~zl{FW?i^bno<CtO`TjT1R
zhBEX!SKzvVm?6DJbn-U347tt$x}$IT-5?i?mT|b^cehC3Gu*NL&~1G?%(cWUL0Uzv
zvPf0jJ>K8Bx8!bckX$F1k~ebq`^8)kj_2Mn8$J~L{SQ<89dzol%0U1C002ovPDHLk
FV1fb^!B_wQ

diff --git a/Doc/s5/ui/default/iepngfix.htc b/Doc/s5/ui/default/iepngfix.htc
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_RG9jL3M1L3VpL2RlZmF1bHQvaWVwbmdmaXguaHRj..162972e7c0335748b70e02edc37e5e3bbb4858ae_RG9jL3M1L3VpL2RlZmF1bHQvaWVwbmdmaXguaHRj 100644
--- a/Doc/s5/ui/default/iepngfix.htc
+++ b/Doc/s5/ui/default/iepngfix.htc
@@ -3,7 +3,7 @@
 
 <script>
 
-// IE5.5+ PNG Alpha Fix v1.0 by Angus Turnbull http://www.twinhelix.com
+// IE5.5+ PNG Alpha Fix v1.0 by Angus Turnbull https://www.twinhelix.com/
 // Free usage permitted as long as this notice remains intact.
 
 // This must be a path to a blank image. That's all the configuration you need here.
diff --git a/Doc/s5/ui/default/slides.js b/Doc/s5/ui/default/slides.js
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_RG9jL3M1L3VpL2RlZmF1bHQvc2xpZGVzLmpz..162972e7c0335748b70e02edc37e5e3bbb4858ae_RG9jL3M1L3VpL2RlZmF1bHQvc2xpZGVzLmpz 100644
--- a/Doc/s5/ui/default/slides.js
+++ b/Doc/s5/ui/default/slides.js
@@ -1,6 +1,6 @@
 // S5 v1.1 slides.js -- released into the Public Domain
 //
-// Please see http://www.meyerweb.com/eric/tools/s5/credits.html for information
+// Please see https://meyerweb.com/eric/tools/s5/credits.html for information
 // about all the wonderful and talented contributors to this code!
 
 var undef;
diff --git a/LICENSE.txt b/LICENSE.txt
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_TElDRU5TRS50eHQ=..162972e7c0335748b70e02edc37e5e3bbb4858ae_TElDRU5TRS50eHQ= 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -1,6 +1,6 @@
                                  Apache License
                            Version 2.0, January 2004
-                        http://www.apache.org/licenses/
+                        https://www.apache.org/licenses/
 
    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 
diff --git a/Makefile b/Makefile
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_TWFrZWZpbGU=..162972e7c0335748b70e02edc37e5e3bbb4858ae_TWFrZWZpbGU= 100644
--- a/Makefile
+++ b/Makefile
@@ -4,8 +4,8 @@
 REPO = git://github.com/cython/cython.git
 VERSION?=$(shell sed -ne 's|^__version__\s*=\s*"\([^"]*\)".*|\1|p' Cython/Shadow.py)
 
-MANYLINUX_IMAGE_X86_64=quay.io/pypa/manylinux1_x86_64
-MANYLINUX_IMAGE_686=quay.io/pypa/manylinux1_i686
+MANYLINUX_IMAGE_X86_64=quay.io/pypa/manylinux2010_x86_64
+MANYLINUX_IMAGE_686=quay.io/pypa/manylinux2010_i686
 
 all:    local
 
@@ -44,6 +44,7 @@
 	@rm -f *.pyd */*.pyd */*/*.pyd
 	@rm -f *~ */*~ */*/*~
 	@rm -f core */core
+	@rm -f Cython/*.c
 	@rm -f Cython/Compiler/*.c
 	@rm -f Cython/Plex/*.c
 	@rm -f Cython/Tempita/*.c
diff --git a/README.rst b/README.rst
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_UkVBRE1FLnJzdA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_UkVBRE1FLnJzdA== 100644
--- a/README.rst
+++ b/README.rst
@@ -1,4 +1,4 @@
-Welcome to Cython!  
+Welcome to Cython!
 ==================
 
 Cython is a language that makes writing C extensions for
@@ -14,8 +14,8 @@
 This makes Cython the ideal language for wrapping external C libraries, and
 for fast C modules that speed up the execution of Python code.
 
-* Official website: http://cython.org/
-* Documentation: http://docs.cython.org/en/latest/
+* Official website: https://cython.org/
+* Documentation: http://docs.cython.org/
 * Github repository: https://github.com/cython/cython
 * Wiki: https://github.com/cython/cython/wiki
 
@@ -19,6 +19,10 @@
 * Github repository: https://github.com/cython/cython
 * Wiki: https://github.com/cython/cython/wiki
 
+You can **support the Cython project** via
+`Github Sponsors <https://github.com/users/scoder/sponsorship>`_ or
+`Tidelift <https://tidelift.com/subscription/pkg/pypi-cython>`_.
+
 
 Installation:
 -------------
@@ -45,6 +49,10 @@
 Want to contribute to the Cython project?
 Here is some `help to get you started <https://github.com/cython/cython/blob/master/docs/CONTRIBUTING.rst>`_.
 
+We are currently building the next great Cython edition:
+`Cython 3.0 <https://github.com/cython/cython/milestone/58>`_.
+You can help us make the life of Python 3.x users easier.
+
 
 Get the full source history:
 ----------------------------
diff --git a/Tools/BUILD.bazel b/Tools/BUILD.bazel
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_VG9vbHMvQlVJTEQuYmF6ZWw=..162972e7c0335748b70e02edc37e5e3bbb4858ae_VG9vbHMvQlVJTEQuYmF6ZWw= 100644
--- a/Tools/BUILD.bazel
+++ b/Tools/BUILD.bazel
@@ -0,0 +1,1 @@
+
diff --git a/Tools/cython-mode.el b/Tools/cython-mode.el
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_VG9vbHMvY3l0aG9uLW1vZGUuZWw=..162972e7c0335748b70e02edc37e5e3bbb4858ae_VG9vbHMvY3l0aG9uLW1vZGUuZWw= 100644
--- a/Tools/cython-mode.el
+++ b/Tools/cython-mode.el
@@ -103,7 +103,7 @@
 (defgroup cython nil "Major mode for editing and compiling Cython files"
   :group 'languages
   :prefix "cython-"
-  :link '(url-link :tag "Homepage" "http://cython.org"))
+  :link '(url-link :tag "Homepage" "https://cython.org/"))
 
 ;;;###autoload
 (defcustom cython-default-compile-format "cython -a %s"
diff --git a/Tools/rules.bzl b/Tools/rules.bzl
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_VG9vbHMvcnVsZXMuYnps..162972e7c0335748b70e02edc37e5e3bbb4858ae_VG9vbHMvcnVsZXMuYnps 100644
--- a/Tools/rules.bzl
+++ b/Tools/rules.bzl
@@ -11,8 +11,8 @@
 
 pyx_library(name = 'mylib',
             srcs = ['a.pyx', 'a.pxd', 'b.py', 'pkg/__init__.py', 'pkg/c.pyx'],
-            py_deps = ['//py_library/dep'],
-            data = ['//other/data'],
+            # python library deps passed to py_library
+            deps = ['//py_library/dep']
 )
 
 The __init__.py file must be in your srcs list so that Cython can resolve
diff --git a/appveyor.yml b/appveyor.yml
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_YXBwdmV5b3IueW1s..162972e7c0335748b70e02edc37e5e3bbb4858ae_YXBwdmV5b3IueW1s 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -5,5 +5,5 @@
   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
+    # See: https://stackoverflow.com/questions/11267463/compiling-python-modules-on-windows-x64/13751649#13751649
     WITH_ENV: "cmd /E:ON /V:ON /C .\\appveyor\\run_with_env.cmd"
@@ -9,6 +9,8 @@
     WITH_ENV: "cmd /E:ON /V:ON /C .\\appveyor\\run_with_env.cmd"
+    BACKEND: c
+    PARALLEL: "-j4"
 
   matrix:
     - PYTHON: "C:\\Python27"
       PYTHON_VERSION: "2.7"
       PYTHON_ARCH: "32"
@@ -10,9 +12,11 @@
 
   matrix:
     - PYTHON: "C:\\Python27"
       PYTHON_VERSION: "2.7"
       PYTHON_ARCH: "32"
+      PYTHONIOENCODING: "utf-8"
+      PARALLEL: ""
 
     - PYTHON: "C:\\Python27-x64"
       PYTHON_VERSION: "2.7"
       PYTHON_ARCH: "64"
@@ -15,7 +19,17 @@
 
     - PYTHON: "C:\\Python27-x64"
       PYTHON_VERSION: "2.7"
       PYTHON_ARCH: "64"
+      PYTHONIOENCODING: "utf-8"
+      PARALLEL: ""
+
+    - 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"
@@ -25,6 +39,11 @@
       PYTHON_VERSION: "3.7"
       PYTHON_ARCH: "64"
 
+    - PYTHON: "C:\\Python37-x64"
+      PYTHON_VERSION: "3.7"
+      PYTHON_ARCH: "64"
+      BACKEND: cpp
+
     - PYTHON: "C:\\Python36"
       PYTHON_VERSION: "3.6"
       PYTHON_ARCH: "32"
@@ -44,7 +63,8 @@
     - PYTHON: "C:\\Python34"
       PYTHON_VERSION: "3.4"
       PYTHON_ARCH: "32"
+      PARALLEL: ""
 
     - PYTHON: "C:\\Python34-x64"
       PYTHON_VERSION: "3.4"
       PYTHON_ARCH: "64"
@@ -47,7 +67,15 @@
 
     - PYTHON: "C:\\Python34-x64"
       PYTHON_VERSION: "3.4"
       PYTHON_ARCH: "64"
+      PARALLEL: ""
+
+    - PYTHON: "C:\\Python27-x64"
+      PYTHON_VERSION: "2.7"
+      PYTHON_ARCH: "64"
+      BACKEND: cpp
+      PYTHONIOENCODING: "utf-8"
+      PARALLEL: ""
 
 clone_depth: 5
 
@@ -67,9 +95,9 @@
 
 build: off
 build_script:
-  - "%WITH_ENV% %PYTHON%\\python.exe setup.py build_ext --inplace"
+  - "%WITH_ENV% %PYTHON%\\python.exe setup.py build_ext --inplace %PARALLEL%"
   - "%WITH_ENV% %PYTHON%\\python.exe setup.py bdist_wheel"
 
 test: off
 test_script:
   - "%PYTHON%\\Scripts\\pip.exe install -r test-requirements.txt"
@@ -71,10 +99,11 @@
   - "%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"
+  - "%PYTHON%\\Scripts\\pip.exe install win_unicode_console"
+  - "set CFLAGS=/Od /W3"
+  - "%WITH_ENV% %PYTHON%\\python.exe runtests.py -vv --backend=%BACKEND% --no-code-style -j5"
 
 artifacts:
   - path: dist\*
diff --git a/appveyor/install.ps1 b/appveyor/install.ps1
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_YXBwdmV5b3IvaW5zdGFsbC5wczE=..162972e7c0335748b70e02edc37e5e3bbb4858ae_YXBwdmV5b3IvaW5zdGFsbC5wczE= 100644
--- a/appveyor/install.ps1
+++ b/appveyor/install.ps1
@@ -1,6 +1,6 @@
 # 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/
+# License: CC0 1.0 Universal: https://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"
diff --git a/bin/cython-generate-lexicon.py b/bin/cython-generate-lexicon.py
new file mode 100755
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_YmluL2N5dGhvbi1nZW5lcmF0ZS1sZXhpY29uLnB5
--- /dev/null
+++ b/bin/cython-generate-lexicon.py
@@ -0,0 +1,132 @@
+#!/usr/bin/env python3
+
+#
+#   Updates Cython's Lexicon.py with the unicode characters that are accepted as
+#   identifiers. Should be run with the most recent version of Python possible
+#   to ensure that Lexicon is as complete as possible.
+#
+#   Python3 only (it relies on str.isidentifier which is a Python 3 addition)
+#
+#   Run with either
+#    --overwrite    to update the existing Lexicon.py file
+#    --here         to create a copy of Lexicon.py in the current directory
+
+import functools
+import re
+import os
+import sys
+
+# Make sure we import the right Cython
+cythonpath, _ = os.path.split(os.path.realpath(__file__)) # bin directory
+cythonpath, _ = os.path.split(cythonpath)
+if os.path.exists(os.path.join(cythonpath, "Cython")):
+    sys.path.insert(0, cythonpath)
+    print("Found (and using) local cython directory")
+# else we aren't in a development directory
+
+from Cython.Compiler import Lexicon
+
+
+def main():
+    arg = '--overwrite'
+    if len(sys.argv) == 2:
+        arg = sys.argv[1]
+    if len(sys.argv) > 2 or arg not in ['--overwrite','--here']:
+        print("""Call the script with either:
+  --overwrite    to update the existing Lexicon.py file (default)
+  --here         to create an version of Lexicon.py in the current directory
+""")
+        return
+
+    generated_code = (
+        f"# generated with:\n"
+        f"# {sys.implementation.name} {sys.version.splitlines()[0].strip()}\n"
+        "\n"
+        f"{generate_character_sets()}\n"
+    )
+
+    print("Reading file", Lexicon.__file__)
+    with open(Lexicon.__file__, 'r') as f:
+        parts = re.split(r"(# (?:BEGIN|END) GENERATED CODE\n?)", f.read())
+
+    if len(parts) not in (4,5) or ' GENERATED CODE' not in parts[1] or ' GENERATED CODE' not in parts[3]:
+        print("Warning: generated code section not found - code not inserted")
+        return
+
+    parts[2] = generated_code
+    output = "".join(parts)
+
+    if arg == "--here":
+        outfile = "Lexicon.py"
+    else:
+        assert arg == "--overwrite"
+        outfile = Lexicon.__file__
+
+    print("Writing to file", outfile)
+    with open(outfile, 'w') as f:
+        f.write(output)
+
+
+# The easiest way to generate an appropriate character set is just to use the str.isidentifier method
+# An alternative approach for getting character sets is at https://stackoverflow.com/a/49332214/4657412
+@functools.lru_cache()
+def get_start_characters_as_number():
+    return [ i for i in range(sys.maxunicode) if str.isidentifier(chr(i)) ]
+
+
+def get_continue_characters_as_number():
+    return [ i for i in range(sys.maxunicode) if str.isidentifier('a'+chr(i)) ]
+
+
+def get_continue_not_start_as_number():
+    start = get_start_characters_as_number()
+    cont = get_continue_characters_as_number()
+    assert set(start) <= set(cont), \
+        "We assume that all identifier start characters are also continuation characters."
+    return sorted(set(cont).difference(start))
+
+
+def to_ranges(char_num_list):
+    # Convert the large lists of character digits to
+    #  list of characters
+    #  a list pairs of characters representing closed ranges
+    char_num_list = sorted(char_num_list)
+    first_good_val = char_num_list[0]
+
+    single_chars = []
+    ranges = []
+    for n in range(1, len(char_num_list)):
+        if char_num_list[n]-1 != char_num_list[n-1]:
+            # discontinuous
+            if first_good_val == char_num_list[n-1]:
+                single_chars.append(chr(char_num_list[n-1]))
+            else:
+                ranges.append(chr(first_good_val) + chr(char_num_list[n-1]))
+            first_good_val = char_num_list[n]
+
+    return ''.join(single_chars), ''.join(ranges)
+
+
+def make_split_strings(chars, splitby=60, indent="    "):
+    lines = [f'u"{chars[i:i+splitby]}"' for i in range(0, len(chars), splitby)]
+    return indent + f"\n{indent}".join(lines)
+
+
+def generate_character_sets():
+    declarations = []
+    for char_type, char_generator in [
+        ("unicode_start_ch", get_start_characters_as_number),
+        ("unicode_continuation_ch", get_continue_not_start_as_number),
+    ]:
+        for set_type, chars in zip(("any", "range"), to_ranges(char_generator())):
+            declarations.append(
+                f"{char_type}_{set_type} = (\n"
+                f"{make_split_strings(chars)}\n"
+                f")\n"
+            )
+
+    return "".join(declarations)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs/CONTRIBUTING.rst b/docs/CONTRIBUTING.rst
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9DT05UUklCVVRJTkcucnN0..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9DT05UUklCVVRJTkcucnN0 100644
--- a/docs/CONTRIBUTING.rst
+++ b/docs/CONTRIBUTING.rst
@@ -5,7 +5,7 @@
 
 * have a look at the `Cython Hacker Guide <https://github.com/cython/cython/wiki/HackerGuide>`_,
   especially the section on `getting started <https://github.com/cython/cython/wiki/HackerGuide#getting-started>`_.
-* look through the `issues that need help <https://github.com/cython/cython/issues?q=is%3Aissue+is%3Aopen+view+label%3A%22help+wanted%22>`_.
-* look through the `issues that are a good entry point for beginners <https://github.com/cython/cython/issues?q=is%3Aissue+is%3Aopen+view+label%3A%22good+first+issue%22>`_.
+* look through the `issues that need help <https://github.com/cython/cython/labels/help%20wanted>`_.
+* look through the `issues that are a good entry point for beginners <https://github.com/cython/cython/labels/good%20first%20issue>`_.
 * ask on the `core developers mailing list <https://mail.python.org/mailman/listinfo/cython-devel>`_ for guidance.
 
@@ -10,4 +10,11 @@
 * ask on the `core developers mailing list <https://mail.python.org/mailman/listinfo/cython-devel>`_ for guidance.
 
+Note that some (but not all) "good first issue"s also require an understanding of C
+and a bit of the CPython C-API – usually those that also have the ``Code Generation``
+label. We generally consider a ticket a "good first issue" if it has a limited scope
+that new contributors will have to learn about, e.g. only needs changes to the parser,
+the type analysis or the code generation, but does not require changes all across the
+compiler pipeline.
+
 If you have code that you want to contribute, please make sure that it
 
@@ -12,6 +19,6 @@
 If you have code that you want to contribute, please make sure that it
 
-* includes tests in the `tests/` directory (see the `Hacker Guide on Testing <https://github.com/cython/cython/wiki/HackerGuide#the-test-suite>`_)
+* includes tests in the ``tests/`` directory (see the `Hacker Guide on Testing <https://github.com/cython/cython/wiki/HackerGuide#the-test-suite>`_)
 * comes in form of a pull request
 
 We use `travis <https://travis-ci.org/cython/cython>`_ and `appveyor <https://ci.appveyor.com/project/cython/cython>`_ for cross-platform testing, including pull requests.
diff --git a/docs/README b/docs/README
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9SRUFETUU=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9SRUFETUU= 100644
--- a/docs/README
+++ b/docs/README
@@ -11,7 +11,7 @@
 You can then see the documentation by opening in a browser ``cython/docs/build/html/index.html``.
 
 The current Cython documentation files are hosted at
-https://cython.readthedocs.io/en/latest/
+https://cython.readthedocs.io/
 
 
 Notes
diff --git a/docs/TODO b/docs/TODO
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9UT0RP..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9UT0RP 100644
--- a/docs/TODO
+++ b/docs/TODO
@@ -17,7 +17,7 @@
 down into independent tutorial topics. Much discussion of what we'd
 like to see is at
 
-http://www.mail-archive.com/cython-dev@codespeak.net/msg06945.html
+https://www.mail-archive.com/cython-dev@codespeak.net/msg06945.html
 
 There is currently a huge amount of redundancy, but no one section has
 it all.
diff --git a/docs/conf.py b/docs/conf.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9jb25mLnB5..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9jb25mLnB5 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -41,7 +41,7 @@
 extensions = [
     'ipython_console_highlighting',
     'cython_highlighting',
-    'sphinx.ext.pngmath',
+    'sphinx.ext.imgmath',
     'sphinx.ext.todo',
     'sphinx.ext.intersphinx',
     'sphinx.ext.autodoc'
@@ -132,6 +132,9 @@
 # If true, keep warnings as "system message" paragraphs in the built documents.
 #keep_warnings = False
 
+# The output image format. The default is 'png'. It should be either 'png' or 'svg'.
+imgmath_image_format = "svg"
+
 
 # -- Options for HTML output ---------------------------------------------------
 
diff --git a/docs/examples/README.rst b/docs/examples/README.rst
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy9SRUFETUUucnN0..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy9SRUFETUUucnN0 100644
--- a/docs/examples/README.rst
+++ b/docs/examples/README.rst
@@ -1,3 +1,3 @@
-This example directory is organized like the ``Cython/docs/src/`` directory,
-with one directory per ``.rst`` file. All files in this directory are tested
-in the :file:`runtests.py` with the mode `compile`.
+This example directory is organized like the ``Cython/docs/src/`` directory,
+with one directory per ``.rst`` file. All files in this directory are tested
+in the :file:`runtests.py` with the mode `compile`.
diff --git a/docs/examples/quickstart/build/hello.pyx b/docs/examples/quickstart/build/hello.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy9xdWlja3N0YXJ0L2J1aWxkL2hlbGxvLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy9xdWlja3N0YXJ0L2J1aWxkL2hlbGxvLnB5eA== 100644
--- a/docs/examples/quickstart/build/hello.pyx
+++ b/docs/examples/quickstart/build/hello.pyx
@@ -1,2 +1,2 @@
-def say_hello_to(name):
-    print("Hello %s!" % name)
+def say_hello_to(name):
+    print("Hello %s!" % name)
diff --git a/docs/examples/quickstart/build/setup.py b/docs/examples/quickstart/build/setup.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy9xdWlja3N0YXJ0L2J1aWxkL3NldHVwLnB5..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy9xdWlja3N0YXJ0L2J1aWxkL3NldHVwLnB5 100644
--- a/docs/examples/quickstart/build/setup.py
+++ b/docs/examples/quickstart/build/setup.py
@@ -1,5 +1,8 @@
-from distutils.core import setup
-from Cython.Build import cythonize
-
-setup(name='Hello world app',
-      ext_modules=cythonize("hello.pyx"))
+from setuptools import setup
+from Cython.Build import cythonize
+
+setup(
+    name='Hello world app',
+    ext_modules=cythonize("hello.pyx"),
+    zip_safe=False,
+)
diff --git a/docs/examples/quickstart/cythonize/cdef_keyword.pyx b/docs/examples/quickstart/cythonize/cdef_keyword.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy9xdWlja3N0YXJ0L2N5dGhvbml6ZS9jZGVmX2tleXdvcmQucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy9xdWlja3N0YXJ0L2N5dGhvbml6ZS9jZGVmX2tleXdvcmQucHl4 100644
--- a/docs/examples/quickstart/cythonize/cdef_keyword.pyx
+++ b/docs/examples/quickstart/cythonize/cdef_keyword.pyx
@@ -1,2 +1,2 @@
-cdef double f(double x) except? -2:
-    return x ** 2 - x
+cdef double f(double x) except? -2:
+    return x ** 2 - x
diff --git a/docs/examples/quickstart/cythonize/integrate.py b/docs/examples/quickstart/cythonize/integrate.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy9xdWlja3N0YXJ0L2N5dGhvbml6ZS9pbnRlZ3JhdGUucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy9xdWlja3N0YXJ0L2N5dGhvbml6ZS9pbnRlZ3JhdGUucHk= 100644
--- a/docs/examples/quickstart/cythonize/integrate.py
+++ b/docs/examples/quickstart/cythonize/integrate.py
@@ -1,10 +1,10 @@
-def f(x):
-    return x ** 2 - x
-
-
-def integrate_f(a, b, N):
-    s = 0
-    dx = (b - a) / N
-    for i in range(N):
-        s += f(a + i * dx)
-    return s * dx
+def f(x):
+    return x ** 2 - x
+
+
+def integrate_f(a, b, N):
+    s = 0
+    dx = (b - a) / N
+    for i in range(N):
+        s += f(a + i * dx)
+    return s * dx
diff --git a/docs/examples/quickstart/cythonize/integrate_cy.pyx b/docs/examples/quickstart/cythonize/integrate_cy.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy9xdWlja3N0YXJ0L2N5dGhvbml6ZS9pbnRlZ3JhdGVfY3kucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy9xdWlja3N0YXJ0L2N5dGhvbml6ZS9pbnRlZ3JhdGVfY3kucHl4 100644
--- a/docs/examples/quickstart/cythonize/integrate_cy.pyx
+++ b/docs/examples/quickstart/cythonize/integrate_cy.pyx
@@ -1,12 +1,12 @@
-def f(double x):
-    return x ** 2 - x
-
-
-def integrate_f(double a, double b, int N):
-    cdef int i
-    cdef double s, dx
-    s = 0
-    dx = (b - a) / N
-    for i in range(N):
-        s += f(a + i * dx)
-    return s * dx
+def f(double x):
+    return x ** 2 - x
+
+
+def integrate_f(double a, double b, int N):
+    cdef int i
+    cdef double s, dx
+    s = 0
+    dx = (b - a) / N
+    for i in range(N):
+        s += f(a + i * dx)
+    return s * dx
diff --git a/docs/examples/tutorial/array/clone.pyx b/docs/examples/tutorial/array/clone.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9hcnJheS9jbG9uZS5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9hcnJheS9jbG9uZS5weXg= 100644
--- a/docs/examples/tutorial/array/clone.pyx
+++ b/docs/examples/tutorial/array/clone.pyx
@@ -1,8 +1,8 @@
-from cpython cimport array
-import array
-
-cdef array.array int_array_template = array.array('i', [])
-cdef array.array newarray
-
-# create an array with 3 elements with same type as template
-newarray = array.clone(int_array_template, 3, zero=False)
+from cpython cimport array
+import array
+
+cdef array.array int_array_template = array.array('i', [])
+cdef array.array newarray
+
+# create an array with 3 elements with same type as template
+newarray = array.clone(int_array_template, 3, zero=False)
diff --git a/docs/examples/tutorial/array/overhead.pyx b/docs/examples/tutorial/array/overhead.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9hcnJheS9vdmVyaGVhZC5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9hcnJheS9vdmVyaGVhZC5weXg= 100644
--- a/docs/examples/tutorial/array/overhead.pyx
+++ b/docs/examples/tutorial/array/overhead.pyx
@@ -1,15 +1,15 @@
-from cpython cimport array
-import array
-
-cdef array.array a = array.array('i', [1, 2, 3])
-cdef int[:] ca = a
-
-cdef int overhead(object a):
-    cdef int[:] ca = a
-    return ca[0]
-
-cdef int no_overhead(int[:] ca):
-    return ca[0]
-
-print(overhead(a))  # new memory view will be constructed, overhead
-print(no_overhead(ca))  # ca is already a memory view, so no overhead
+from cpython cimport array
+import array
+
+cdef array.array a = array.array('i', [1, 2, 3])
+cdef int[:] ca = a
+
+cdef int overhead(object a):
+    cdef int[:] ca = a
+    return ca[0]
+
+cdef int no_overhead(int[:] ca):
+    return ca[0]
+
+print(overhead(a))  # new memory view will be constructed, overhead
+print(no_overhead(ca))  # ca is already a memory view, so no overhead
diff --git a/docs/examples/tutorial/array/resize.pyx b/docs/examples/tutorial/array/resize.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9hcnJheS9yZXNpemUucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9hcnJheS9yZXNpemUucHl4 100644
--- a/docs/examples/tutorial/array/resize.pyx
+++ b/docs/examples/tutorial/array/resize.pyx
@@ -1,10 +1,10 @@
-from cpython cimport array
-import array
-
-cdef array.array a = array.array('i', [1, 2, 3])
-cdef array.array b = array.array('i', [4, 5, 6])
-
-# extend a with b, resize as needed
-array.extend(a, b)
-# resize a, leaving just original three elements
-array.resize(a, len(a) - len(b))
+from cpython cimport array
+import array
+
+cdef array.array a = array.array('i', [1, 2, 3])
+cdef array.array b = array.array('i', [4, 5, 6])
+
+# extend a with b, resize as needed
+array.extend(a, b)
+# resize a, leaving just original three elements
+array.resize(a, len(a) - len(b))
diff --git a/docs/examples/tutorial/array/safe_usage.pyx b/docs/examples/tutorial/array/safe_usage.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9hcnJheS9zYWZlX3VzYWdlLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9hcnJheS9zYWZlX3VzYWdlLnB5eA== 100644
--- a/docs/examples/tutorial/array/safe_usage.pyx
+++ b/docs/examples/tutorial/array/safe_usage.pyx
@@ -1,6 +1,6 @@
-from cpython cimport array
-import array
-cdef array.array a = array.array('i', [1, 2, 3])
-cdef int[:] ca = a
-
-print(ca[0])
+from cpython cimport array
+import array
+cdef array.array a = array.array('i', [1, 2, 3])
+cdef int[:] ca = a
+
+print(ca[0])
diff --git a/docs/examples/tutorial/array/unsafe_usage.pyx b/docs/examples/tutorial/array/unsafe_usage.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9hcnJheS91bnNhZmVfdXNhZ2UucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9hcnJheS91bnNhZmVfdXNhZ2UucHl4 100644
--- a/docs/examples/tutorial/array/unsafe_usage.pyx
+++ b/docs/examples/tutorial/array/unsafe_usage.pyx
@@ -1,11 +1,11 @@
-from cpython cimport array
-import array
-
-cdef array.array a = array.array('i', [1, 2, 3])
-
-# access underlying pointer:
-print(a.data.as_ints[0])
-
-from libc.string cimport memset
-
-memset(a.data.as_voidptr, 0, len(a) * sizeof(int))
+from cpython cimport array
+import array
+
+cdef array.array a = array.array('i', [1, 2, 3])
+
+# access underlying pointer:
+print(a.data.as_ints[0])
+
+from libc.string cimport memset
+
+memset(a.data.as_voidptr, 0, len(a) * sizeof(int))
diff --git a/docs/examples/tutorial/cdef_classes/integrate.pyx b/docs/examples/tutorial/cdef_classes/integrate.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9jZGVmX2NsYXNzZXMvaW50ZWdyYXRlLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9jZGVmX2NsYXNzZXMvaW50ZWdyYXRlLnB5eA== 100644
--- a/docs/examples/tutorial/cdef_classes/integrate.pyx
+++ b/docs/examples/tutorial/cdef_classes/integrate.pyx
@@ -1,14 +1,14 @@
-from sin_of_square cimport Function, SinOfSquareFunction
-
-def integrate(Function f, double a, double b, int N):
-    cdef int i
-    cdef double s, dx
-    if f is None:
-        raise ValueError("f cannot be None")
-    s = 0
-    dx = (b - a) / N
-    for i in range(N):
-        s += f.evaluate(a + i * dx)
-    return s * dx
-
-print(integrate(SinOfSquareFunction(), 0, 1, 10000))
+from sin_of_square cimport Function, SinOfSquareFunction
+
+def integrate(Function f, double a, double b, int N):
+    cdef int i
+    cdef double s, dx
+    if f is None:
+        raise ValueError("f cannot be None")
+    s = 0
+    dx = (b - a) / N
+    for i in range(N):
+        s += f.evaluate(a + i * dx)
+    return s * dx
+
+print(integrate(SinOfSquareFunction(), 0, 1, 10000))
diff --git a/docs/examples/tutorial/cdef_classes/math_function.py b/docs/examples/tutorial/cdef_classes/math_function.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9jZGVmX2NsYXNzZXMvbWF0aF9mdW5jdGlvbi5weQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9jZGVmX2NsYXNzZXMvbWF0aF9mdW5jdGlvbi5weQ== 100644
--- a/docs/examples/tutorial/cdef_classes/math_function.py
+++ b/docs/examples/tutorial/cdef_classes/math_function.py
@@ -1,7 +1,7 @@
-class MathFunction(object):
-    def __init__(self, name, operator):
-        self.name = name
-        self.operator = operator
-
-    def __call__(self, *operands):
-        return self.operator(*operands)
+class MathFunction(object):
+    def __init__(self, name, operator):
+        self.name = name
+        self.operator = operator
+
+    def __call__(self, *operands):
+        return self.operator(*operands)
diff --git a/docs/examples/tutorial/cdef_classes/math_function_2.pyx b/docs/examples/tutorial/cdef_classes/math_function_2.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9jZGVmX2NsYXNzZXMvbWF0aF9mdW5jdGlvbl8yLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9jZGVmX2NsYXNzZXMvbWF0aF9mdW5jdGlvbl8yLnB5eA== 100644
--- a/docs/examples/tutorial/cdef_classes/math_function_2.pyx
+++ b/docs/examples/tutorial/cdef_classes/math_function_2.pyx
@@ -1,3 +1,3 @@
-cdef class Function:
-    cpdef double evaluate(self, double x) except *:
-        return 0
+cdef class Function:
+    cpdef double evaluate(self, double x) except *:
+        return 0
diff --git a/docs/examples/tutorial/cdef_classes/nonecheck.pyx b/docs/examples/tutorial/cdef_classes/nonecheck.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9jZGVmX2NsYXNzZXMvbm9uZWNoZWNrLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9jZGVmX2NsYXNzZXMvbm9uZWNoZWNrLnB5eA== 100644
--- a/docs/examples/tutorial/cdef_classes/nonecheck.pyx
+++ b/docs/examples/tutorial/cdef_classes/nonecheck.pyx
@@ -1,19 +1,19 @@
-# cython: nonecheck=True
-#        ^^^ Turns on nonecheck globally
-
-import cython
-
-cdef class MyClass:
-    pass
-
-# Turn off nonecheck locally for the function
-@cython.nonecheck(False)
-def func():
-    cdef MyClass obj = None
-    try:
-        # Turn nonecheck on again for a block
-        with cython.nonecheck(True):
-            print(obj.myfunc())  # Raises exception
-    except AttributeError:
-        pass
-    print(obj.myfunc())  # Hope for a crash!
+# cython: nonecheck=True
+#        ^^^ Turns on nonecheck globally
+
+import cython
+
+cdef class MyClass:
+    pass
+
+# Turn off nonecheck locally for the function
+@cython.nonecheck(False)
+def func():
+    cdef MyClass obj = None
+    try:
+        # Turn nonecheck on again for a block
+        with cython.nonecheck(True):
+            print(obj.myfunc())  # Raises exception
+    except AttributeError:
+        pass
+    print(obj.myfunc())  # Hope for a crash!
diff --git a/docs/examples/tutorial/cdef_classes/sin_of_square.pyx b/docs/examples/tutorial/cdef_classes/sin_of_square.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9jZGVmX2NsYXNzZXMvc2luX29mX3NxdWFyZS5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9jZGVmX2NsYXNzZXMvc2luX29mX3NxdWFyZS5weXg= 100644
--- a/docs/examples/tutorial/cdef_classes/sin_of_square.pyx
+++ b/docs/examples/tutorial/cdef_classes/sin_of_square.pyx
@@ -1,9 +1,9 @@
-from libc.math cimport sin
-
-cdef class Function:
-    cpdef double evaluate(self, double x) except *:
-        return 0
-
-cdef class SinOfSquareFunction(Function):
-    cpdef double evaluate(self, double x) except *:
-        return sin(x ** 2)
+from libc.math cimport sin
+
+cdef class Function:
+    cpdef double evaluate(self, double x) except *:
+        return 0
+
+cdef class SinOfSquareFunction(Function):
+    cpdef double evaluate(self, double x) except *:
+        return sin(x ** 2)
diff --git a/docs/examples/tutorial/cdef_classes/wave_function.pyx b/docs/examples/tutorial/cdef_classes/wave_function.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9jZGVmX2NsYXNzZXMvd2F2ZV9mdW5jdGlvbi5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9jZGVmX2NsYXNzZXMvd2F2ZV9mdW5jdGlvbi5weXg= 100644
--- a/docs/examples/tutorial/cdef_classes/wave_function.pyx
+++ b/docs/examples/tutorial/cdef_classes/wave_function.pyx
@@ -1,21 +1,21 @@
-from sin_of_square cimport Function
-
-cdef class WaveFunction(Function):
-
-    # Not available in Python-space:
-    cdef double offset
-
-    # Available in Python-space:
-    cdef public double freq
-
-    # Available in Python-space, but only for reading:
-    cdef readonly double scale
-
-    # Available in Python-space:
-    @property
-    def period(self):
-        return 1.0 / self.freq
-
-    @period.setter
-    def period(self, value):
-        self.freq = 1.0 / value
+from sin_of_square cimport Function
+
+cdef class WaveFunction(Function):
+
+    # Not available in Python-space:
+    cdef double offset
+
+    # Available in Python-space:
+    cdef public double freq
+
+    # Available in Python-space, but only for reading:
+    cdef readonly double scale
+
+    # Available in Python-space:
+    @property
+    def period(self):
+        return 1.0 / self.freq
+
+    @period.setter
+    def period(self, value):
+        self.freq = 1.0 / value
diff --git a/docs/examples/tutorial/clibraries/queue.pyx b/docs/examples/tutorial/clibraries/queue.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9jbGlicmFyaWVzL3F1ZXVlLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9jbGlicmFyaWVzL3F1ZXVlLnB5eA== 100644
--- a/docs/examples/tutorial/clibraries/queue.pyx
+++ b/docs/examples/tutorial/clibraries/queue.pyx
@@ -1,9 +1,9 @@
-# queue.pyx
-
-cimport cqueue
-
-cdef class Queue:
-    cdef cqueue.Queue* _c_queue
-
-    def __cinit__(self):
-        self._c_queue = cqueue.queue_new()
+# queue.pyx
+
+cimport cqueue
+
+cdef class Queue:
+    cdef cqueue.Queue* _c_queue
+
+    def __cinit__(self):
+        self._c_queue = cqueue.queue_new()
diff --git a/docs/examples/tutorial/clibraries/queue2.pyx b/docs/examples/tutorial/clibraries/queue2.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9jbGlicmFyaWVzL3F1ZXVlMi5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9jbGlicmFyaWVzL3F1ZXVlMi5weXg= 100644
--- a/docs/examples/tutorial/clibraries/queue2.pyx
+++ b/docs/examples/tutorial/clibraries/queue2.pyx
@@ -1,11 +1,11 @@
-# queue.pyx
-
-cimport cqueue
-
-cdef class Queue:
-    cdef cqueue.Queue* _c_queue
-
-    def __cinit__(self):
-        self._c_queue = cqueue.queue_new()
-        if self._c_queue is NULL:
-            raise MemoryError()
+# queue.pyx
+
+cimport cqueue
+
+cdef class Queue:
+    cdef cqueue.Queue* _c_queue
+
+    def __cinit__(self):
+        self._c_queue = cqueue.queue_new()
+        if self._c_queue is NULL:
+            raise MemoryError()
diff --git a/docs/examples/tutorial/clibraries/test_queue.py b/docs/examples/tutorial/clibraries/test_queue.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9jbGlicmFyaWVzL3Rlc3RfcXVldWUucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9jbGlicmFyaWVzL3Rlc3RfcXVldWUucHk= 100644
--- a/docs/examples/tutorial/clibraries/test_queue.py
+++ b/docs/examples/tutorial/clibraries/test_queue.py
@@ -1,36 +1,36 @@
-from __future__ import print_function
-
-import time
-
-import queue
-
-Q = queue.Queue()
-
-Q.append(10)
-Q.append(20)
-print(Q.peek())
-print(Q.pop())
-print(Q.pop())
-try:
-    print(Q.pop())
-except IndexError as e:
-    print("Error message:", e)  # Prints "Queue is empty"
-
-i = 10000
-
-values = range(i)
-
-start_time = time.time()
-
-Q.extend(values)
-
-end_time = time.time() - start_time
-
-print("Adding {} items took {:1.3f} msecs.".format(i, 1000 * end_time))
-
-for i in range(41):
-    Q.pop()
-
-Q.pop()
-print("The answer is:")
-print(Q.pop())
+from __future__ import print_function
+
+import time
+
+import queue
+
+Q = queue.Queue()
+
+Q.append(10)
+Q.append(20)
+print(Q.peek())
+print(Q.pop())
+print(Q.pop())
+try:
+    print(Q.pop())
+except IndexError as e:
+    print("Error message:", e)  # Prints "Queue is empty"
+
+i = 10000
+
+values = range(i)
+
+start_time = time.time()
+
+Q.extend(values)
+
+end_time = time.time() - start_time
+
+print("Adding {} items took {:1.3f} msecs.".format(i, 1000 * end_time))
+
+for i in range(41):
+    Q.pop()
+
+Q.pop()
+print("The answer is:")
+print(Q.pop())
diff --git a/docs/examples/tutorial/cython_tutorial/primes_cpp.pyx b/docs/examples/tutorial/cython_tutorial/primes_cpp.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9jeXRob25fdHV0b3JpYWwvcHJpbWVzX2NwcC5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9jeXRob25fdHV0b3JpYWwvcHJpbWVzX2NwcC5weXg= 100644
--- a/docs/examples/tutorial/cython_tutorial/primes_cpp.pyx
+++ b/docs/examples/tutorial/cython_tutorial/primes_cpp.pyx
@@ -1,21 +1,21 @@
-# distutils: language=c++
-
-from libcpp.vector cimport vector
-
-def primes(unsigned int nb_primes):
-    cdef int n, i
-    cdef vector[int] p
-    p.reserve(nb_primes)  # allocate memory for 'nb_primes' elements.
-
-    n = 2
-    while p.size() < nb_primes:  # size() for vectors is similar to len()
-        for i in p:
-            if n % i == 0:
-                break
-        else:
-            p.push_back(n)  # push_back is similar to append()
-        n += 1
-
-    # Vectors are automatically converted to Python
-    # lists when converted to Python objects.
-    return p
+# distutils: language=c++
+
+from libcpp.vector cimport vector
+
+def primes(unsigned int nb_primes):
+    cdef int n, i
+    cdef vector[int] p
+    p.reserve(nb_primes)  # allocate memory for 'nb_primes' elements.
+
+    n = 2
+    while p.size() < nb_primes:  # size() for vectors is similar to len()
+        for i in p:
+            if n % i == 0:
+                break
+        else:
+            p.push_back(n)  # push_back is similar to append()
+        n += 1
+
+    # Vectors are automatically converted to Python
+    # lists when converted to Python objects.
+    return p
diff --git a/docs/examples/tutorial/cython_tutorial/setup.py b/docs/examples/tutorial/cython_tutorial/setup.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9jeXRob25fdHV0b3JpYWwvc2V0dXAucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9jeXRob25fdHV0b3JpYWwvc2V0dXAucHk= 100644
--- a/docs/examples/tutorial/cython_tutorial/setup.py
+++ b/docs/examples/tutorial/cython_tutorial/setup.py
@@ -1,4 +1,4 @@
-from distutils.core import setup
+from setuptools import setup
 from Cython.Build import cythonize
 
 setup(
diff --git a/docs/examples/tutorial/embedding/spam.pyx b/docs/examples/tutorial/embedding/spam.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9lbWJlZGRpbmcvc3BhbS5weXg=
--- /dev/null
+++ b/docs/examples/tutorial/embedding/spam.pyx
@@ -0,0 +1,11 @@
+# spam.pyx
+
+# The following two lines are for test purposed only, please ignore them.
+# distutils: sources = spam_main.c
+# tag: py3only
+
+TEXT_TO_SAY = 'Hello from Python!'
+
+cdef public int say_hello_from_python() except -1:
+    print(TEXT_TO_SAY)
+    return 0
diff --git a/docs/examples/tutorial/embedding/spam_main.c b/docs/examples/tutorial/embedding/spam_main.c
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9lbWJlZGRpbmcvc3BhbV9tYWluLmM=
--- /dev/null
+++ b/docs/examples/tutorial/embedding/spam_main.c
@@ -0,0 +1,61 @@
+/* spam_main.c */
+
+/* This include file is automatically generated by Cython for 'public' functions. */
+#include "spam.h"
+
+int
+main(int argc, char *argv[])
+{
+    PyObject *pmodule;
+    wchar_t *program;
+
+    program = Py_DecodeLocale(argv[0], NULL);
+    if (program == NULL) {
+        fprintf(stderr, "Fatal error: cannot decode argv[0], got %d arguments\n", argc);
+        exit(1);
+    }
+
+    /* Add a built-in module, before Py_Initialize */
+    if (PyImport_AppendInittab("spam", PyInit_spam) == -1) {
+        fprintf(stderr, "Error: could not extend in-built modules table\n");
+        exit(1);
+    }
+
+    /* Pass argv[0] to the Python interpreter */
+    Py_SetProgramName(program);
+
+    /* Initialize the Python interpreter.  Required.
+       If this step fails, it will be a fatal error. */
+    Py_Initialize();
+
+    /* Optionally import the module; alternatively,
+       import can be deferred until the embedded script
+       imports it. */
+    pmodule = PyImport_ImportModule("spam");
+    if (!pmodule) {
+        PyErr_Print();
+        fprintf(stderr, "Error: could not import module 'spam'\n");
+        goto exit_with_error;
+    }
+
+    /* Now call into your module code. */
+    if (say_hello_from_python() < 0) {
+        PyErr_Print();
+        fprintf(stderr, "Error in Python code, exception was printed.\n");
+        goto exit_with_error;
+    }
+
+    /* ... */
+
+    /* Clean up after using CPython. */
+    PyMem_RawFree(program);
+    Py_Finalize();
+
+    return 0;
+
+    /* Clean up in the error cases above. */
+exit_with_error:
+    PyMem_RawFree(program);
+    Py_Finalize();
+    return 1;
+}
diff --git a/docs/examples/tutorial/external/atoi.pyx b/docs/examples/tutorial/external/atoi.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9leHRlcm5hbC9hdG9pLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9leHRlcm5hbC9hdG9pLnB5eA== 100644
--- a/docs/examples/tutorial/external/atoi.pyx
+++ b/docs/examples/tutorial/external/atoi.pyx
@@ -1,5 +1,5 @@
-from libc.stdlib cimport atoi
-
-cdef parse_charptr_to_py_int(char* s):
-    assert s is not NULL, "byte string value is NULL"
-    return atoi(s)  # note: atoi() has no error detection!
+from libc.stdlib cimport atoi
+
+cdef parse_charptr_to_py_int(char* s):
+    assert s is not NULL, "byte string value is NULL"
+    return atoi(s)  # note: atoi() has no error detection!
diff --git a/docs/examples/tutorial/external/cpdef_sin.pyx b/docs/examples/tutorial/external/cpdef_sin.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9leHRlcm5hbC9jcGRlZl9zaW4ucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9leHRlcm5hbC9jcGRlZl9zaW4ucHl4 100644
--- a/docs/examples/tutorial/external/cpdef_sin.pyx
+++ b/docs/examples/tutorial/external/cpdef_sin.pyx
@@ -1,7 +1,7 @@
-"""
->>> sin(0)
-0.0
-"""
-
-cdef extern from "math.h":
-    cpdef double sin(double x)
+"""
+>>> sin(0)
+0.0
+"""
+
+cdef extern from "math.h":
+    cpdef double sin(double x)
diff --git a/docs/examples/tutorial/external/keyword_args.pyx b/docs/examples/tutorial/external/keyword_args.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9leHRlcm5hbC9rZXl3b3JkX2FyZ3MucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9leHRlcm5hbC9rZXl3b3JkX2FyZ3MucHl4 100644
--- a/docs/examples/tutorial/external/keyword_args.pyx
+++ b/docs/examples/tutorial/external/keyword_args.pyx
@@ -1,2 +1,2 @@
-cdef extern from "string.h":
-    char* strstr(const char *haystack, const char *needle)
+cdef extern from "string.h":
+    char* strstr(const char *haystack, const char *needle)
diff --git a/docs/examples/tutorial/external/keyword_args_call.pyx b/docs/examples/tutorial/external/keyword_args_call.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9leHRlcm5hbC9rZXl3b3JkX2FyZ3NfY2FsbC5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9leHRlcm5hbC9rZXl3b3JkX2FyZ3NfY2FsbC5weXg= 100644
--- a/docs/examples/tutorial/external/keyword_args_call.pyx
+++ b/docs/examples/tutorial/external/keyword_args_call.pyx
@@ -1,7 +1,7 @@
-cdef extern from "string.h":
-    char* strstr(const char *haystack, const char *needle)
-
-cdef char* data = "hfvcakdfagbcffvschvxcdfgccbcfhvgcsnfxjh"
-
-cdef char* pos = strstr(needle='akd', haystack=data)
-print(pos is not NULL)
+cdef extern from "string.h":
+    char* strstr(const char *haystack, const char *needle)
+
+cdef char* data = "hfvcakdfagbcffvschvxcdfgccbcfhvgcsnfxjh"
+
+cdef char* pos = strstr(needle='akd', haystack=data)
+print(pos is not NULL)
diff --git a/docs/examples/tutorial/external/libc_sin.pyx b/docs/examples/tutorial/external/libc_sin.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9leHRlcm5hbC9saWJjX3Npbi5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9leHRlcm5hbC9saWJjX3Npbi5weXg= 100644
--- a/docs/examples/tutorial/external/libc_sin.pyx
+++ b/docs/examples/tutorial/external/libc_sin.pyx
@@ -1,4 +1,4 @@
-from libc.math cimport sin
-
-cdef double f(double x):
-    return sin(x * x)
+from libc.math cimport sin
+
+cdef double f(double x):
+    return sin(x * x)
diff --git a/docs/examples/tutorial/external/py_version_hex.pyx b/docs/examples/tutorial/external/py_version_hex.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9leHRlcm5hbC9weV92ZXJzaW9uX2hleC5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9leHRlcm5hbC9weV92ZXJzaW9uX2hleC5weXg= 100644
--- a/docs/examples/tutorial/external/py_version_hex.pyx
+++ b/docs/examples/tutorial/external/py_version_hex.pyx
@@ -1,4 +1,4 @@
-from cpython.version cimport PY_VERSION_HEX
-
-# Python version >= 3.2 final ?
-print(PY_VERSION_HEX >= 0x030200F0)
+from cpython.version cimport PY_VERSION_HEX
+
+# Python version >= 3.2 final ?
+print(PY_VERSION_HEX >= 0x030200F0)
diff --git a/docs/examples/tutorial/external/setup.py b/docs/examples/tutorial/external/setup.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9leHRlcm5hbC9zZXR1cC5weQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9leHRlcm5hbC9zZXR1cC5weQ== 100644
--- a/docs/examples/tutorial/external/setup.py
+++ b/docs/examples/tutorial/external/setup.py
@@ -1,13 +1,12 @@
-from distutils.core import setup
-from distutils.extension import Extension
-from Cython.Build import cythonize
-
-ext_modules = [
-    Extension("demo",
-              sources=["demo.pyx"],
-              libraries=["m"]  # Unix-like specific
-              )
-]
-
-setup(name="Demos",
-      ext_modules=cythonize(ext_modules))
+from setuptools import Extension, setup
+from Cython.Build import cythonize
+
+ext_modules = [
+    Extension("demo",
+              sources=["demo.pyx"],
+              libraries=["m"]  # Unix-like specific
+              )
+]
+
+setup(name="Demos",
+      ext_modules=cythonize(ext_modules))
diff --git a/docs/examples/tutorial/memory_allocation/malloc.pyx b/docs/examples/tutorial/memory_allocation/malloc.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9tZW1vcnlfYWxsb2NhdGlvbi9tYWxsb2MucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9tZW1vcnlfYWxsb2NhdGlvbi9tYWxsb2MucHl4 100644
--- a/docs/examples/tutorial/memory_allocation/malloc.pyx
+++ b/docs/examples/tutorial/memory_allocation/malloc.pyx
@@ -1,23 +1,23 @@
-import random
-from libc.stdlib cimport malloc, free
-
-def random_noise(int number=1):
-    cdef int i
-    # allocate number * sizeof(double) bytes of memory
-    cdef double *my_array = <double *> malloc(number * sizeof(double))
-    if not my_array:
-        raise MemoryError()
-
-    try:
-        ran = random.normalvariate
-        for i in range(number):
-            my_array[i] = ran(0, 1)
-
-        # ... let's just assume we do some more heavy C calculations here to make up
-        # for the work that it takes to pack the C double values into Python float
-        # objects below, right after throwing away the existing objects above.
-
-        return [x for x in my_array[:number]]
-    finally:
-        # return the previously allocated memory to the system
-        free(my_array)
+import random
+from libc.stdlib cimport malloc, free
+
+def random_noise(int number=1):
+    cdef int i
+    # allocate number * sizeof(double) bytes of memory
+    cdef double *my_array = <double *> malloc(number * sizeof(double))
+    if not my_array:
+        raise MemoryError()
+
+    try:
+        ran = random.normalvariate
+        for i in range(number):
+            my_array[i] = ran(0, 1)
+
+        # ... let's just assume we do some more heavy C calculations here to make up
+        # for the work that it takes to pack the C double values into Python float
+        # objects below, right after throwing away the existing objects above.
+
+        return [x for x in my_array[:number]]
+    finally:
+        # return the previously allocated memory to the system
+        free(my_array)
diff --git a/docs/examples/tutorial/memory_allocation/some_memory.pyx b/docs/examples/tutorial/memory_allocation/some_memory.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9tZW1vcnlfYWxsb2NhdGlvbi9zb21lX21lbW9yeS5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9tZW1vcnlfYWxsb2NhdGlvbi9zb21lX21lbW9yeS5weXg= 100644
--- a/docs/examples/tutorial/memory_allocation/some_memory.pyx
+++ b/docs/examples/tutorial/memory_allocation/some_memory.pyx
@@ -1,25 +1,25 @@
-from cpython.mem cimport PyMem_Malloc, PyMem_Realloc, PyMem_Free
-
-cdef class SomeMemory:
-
-    cdef double* data
-
-    def __cinit__(self, size_t number):
-        # allocate some memory (uninitialised, may contain arbitrary data)
-        self.data = <double*> PyMem_Malloc(number * sizeof(double))
-        if not self.data:
-            raise MemoryError()
-
-    def resize(self, size_t new_number):
-        # Allocates new_number * sizeof(double) bytes,
-        # preserving the current content and making a best-effort to
-        # re-use the original data location.
-        mem = <double*> PyMem_Realloc(self.data, new_number * sizeof(double))
-        if not mem:
-            raise MemoryError()
-        # Only overwrite the pointer if the memory was really reallocated.
-        # On error (mem is NULL), the originally memory has not been freed.
-        self.data = mem
-
-    def __dealloc__(self):
-        PyMem_Free(self.data)  # no-op if self.data is NULL
+from cpython.mem cimport PyMem_Malloc, PyMem_Realloc, PyMem_Free
+
+cdef class SomeMemory:
+
+    cdef double* data
+
+    def __cinit__(self, size_t number):
+        # allocate some memory (uninitialised, may contain arbitrary data)
+        self.data = <double*> PyMem_Malloc(number * sizeof(double))
+        if not self.data:
+            raise MemoryError()
+
+    def resize(self, size_t new_number):
+        # Allocates new_number * sizeof(double) bytes,
+        # preserving the current content and making a best-effort to
+        # re-use the original data location.
+        mem = <double*> PyMem_Realloc(self.data, new_number * sizeof(double))
+        if not mem:
+            raise MemoryError()
+        # Only overwrite the pointer if the memory was really reallocated.
+        # On error (mem is NULL), the originally memory has not been freed.
+        self.data = mem
+
+    def __dealloc__(self):
+        PyMem_Free(self.data)  # no-op if self.data is NULL
diff --git a/docs/examples/tutorial/numpy/convolve2.pyx b/docs/examples/tutorial/numpy/convolve2.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9udW1weS9jb252b2x2ZTIucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9udW1weS9jb252b2x2ZTIucHl4 100644
--- a/docs/examples/tutorial/numpy/convolve2.pyx
+++ b/docs/examples/tutorial/numpy/convolve2.pyx
@@ -1,4 +1,4 @@
-# tag: numpy_old
+# tag: numpy
 # You can ignore the previous line.
 # It's for internal testing of the cython documentation.
 
diff --git a/docs/examples/tutorial/numpy/convolve_py.py b/docs/examples/tutorial/numpy/convolve_py.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9udW1weS9jb252b2x2ZV9weS5weQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9udW1weS9jb252b2x2ZV9weS5weQ== 100644
--- a/docs/examples/tutorial/numpy/convolve_py.py
+++ b/docs/examples/tutorial/numpy/convolve_py.py
@@ -1,43 +1,43 @@
-import numpy as np
-
-
-def naive_convolve(f, g):
-    # f is an image and is indexed by (v, w)
-    # g is a filter kernel and is indexed by (s, t),
-    #   it needs odd dimensions
-    # h is the output image and is indexed by (x, y),
-    #   it is not cropped
-    if g.shape[0] % 2 != 1 or g.shape[1] % 2 != 1:
-        raise ValueError("Only odd dimensions on filter supported")
-    # smid and tmid are number of pixels between the center pixel
-    # and the edge, ie for a 5x5 filter they will be 2.
-    #
-    # The output size is calculated by adding smid, tmid to each
-    # side of the dimensions of the input image.
-    vmax = f.shape[0]
-    wmax = f.shape[1]
-    smax = g.shape[0]
-    tmax = g.shape[1]
-    smid = smax // 2
-    tmid = tmax // 2
-    xmax = vmax + 2 * smid
-    ymax = wmax + 2 * tmid
-    # Allocate result image.
-    h = np.zeros([xmax, ymax], dtype=f.dtype)
-    # Do convolution
-    for x in range(xmax):
-        for y in range(ymax):
-            # Calculate pixel value for h at (x,y). Sum one component
-            # for each pixel (s, t) of the filter g.
-            s_from = max(smid - x, -smid)
-            s_to = min((xmax - x) - smid, smid + 1)
-            t_from = max(tmid - y, -tmid)
-            t_to = min((ymax - y) - tmid, tmid + 1)
-            value = 0
-            for s in range(s_from, s_to):
-                for t in range(t_from, t_to):
-                    v = x - smid + s
-                    w = y - tmid + t
-                    value += g[smid - s, tmid - t] * f[v, w]
-            h[x, y] = value
-    return h
+import numpy as np
+
+
+def naive_convolve(f, g):
+    # f is an image and is indexed by (v, w)
+    # g is a filter kernel and is indexed by (s, t),
+    #   it needs odd dimensions
+    # h is the output image and is indexed by (x, y),
+    #   it is not cropped
+    if g.shape[0] % 2 != 1 or g.shape[1] % 2 != 1:
+        raise ValueError("Only odd dimensions on filter supported")
+    # smid and tmid are number of pixels between the center pixel
+    # and the edge, ie for a 5x5 filter they will be 2.
+    #
+    # The output size is calculated by adding smid, tmid to each
+    # side of the dimensions of the input image.
+    vmax = f.shape[0]
+    wmax = f.shape[1]
+    smax = g.shape[0]
+    tmax = g.shape[1]
+    smid = smax // 2
+    tmid = tmax // 2
+    xmax = vmax + 2 * smid
+    ymax = wmax + 2 * tmid
+    # Allocate result image.
+    h = np.zeros([xmax, ymax], dtype=f.dtype)
+    # Do convolution
+    for x in range(xmax):
+        for y in range(ymax):
+            # Calculate pixel value for h at (x,y). Sum one component
+            # for each pixel (s, t) of the filter g.
+            s_from = max(smid - x, -smid)
+            s_to = min((xmax - x) - smid, smid + 1)
+            t_from = max(tmid - y, -tmid)
+            t_to = min((ymax - y) - tmid, tmid + 1)
+            value = 0
+            for s in range(s_from, s_to):
+                for t in range(t_from, t_to):
+                    v = x - smid + s
+                    w = y - tmid + t
+                    value += g[smid - s, tmid - t] * f[v, w]
+            h[x, y] = value
+    return h
diff --git a/docs/examples/tutorial/profiling_tutorial/calc_pi.py b/docs/examples/tutorial/profiling_tutorial/calc_pi.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9wcm9maWxpbmdfdHV0b3JpYWwvY2FsY19waS5weQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9wcm9maWxpbmdfdHV0b3JpYWwvY2FsY19waS5weQ== 100644
--- a/docs/examples/tutorial/profiling_tutorial/calc_pi.py
+++ b/docs/examples/tutorial/profiling_tutorial/calc_pi.py
@@ -1,10 +1,10 @@
-# calc_pi.py
-
-def recip_square(i):
-    return 1. / i ** 2
-
-def approx_pi(n=10000000):
-    val = 0.
-    for k in range(1, n + 1):
-        val += recip_square(k)
-    return (6 * val) ** .5
+# calc_pi.py
+
+def recip_square(i):
+    return 1. / i ** 2
+
+def approx_pi(n=10000000):
+    val = 0.
+    for k in range(1, n + 1):
+        val += recip_square(k)
+    return (6 * val) ** .5
diff --git a/docs/examples/tutorial/profiling_tutorial/calc_pi_2.pyx b/docs/examples/tutorial/profiling_tutorial/calc_pi_2.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9wcm9maWxpbmdfdHV0b3JpYWwvY2FsY19waV8yLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9wcm9maWxpbmdfdHV0b3JpYWwvY2FsY19waV8yLnB5eA== 100644
--- a/docs/examples/tutorial/profiling_tutorial/calc_pi_2.pyx
+++ b/docs/examples/tutorial/profiling_tutorial/calc_pi_2.pyx
@@ -1,13 +1,13 @@
-# cython: profile=True
-
-# calc_pi.pyx
-
-def recip_square(int i):
-    return 1. / i ** 2
-
-def approx_pi(int n=10000000):
-    cdef double val = 0.
-    cdef int k
-    for k in range(1, n + 1):
-        val += recip_square(k)
-    return (6 * val) ** .5
+# cython: profile=True
+
+# calc_pi.pyx
+
+def recip_square(int i):
+    return 1. / i ** 2
+
+def approx_pi(int n=10000000):
+    cdef double val = 0.
+    cdef int k
+    for k in range(1, n + 1):
+        val += recip_square(k)
+    return (6 * val) ** .5
diff --git a/docs/examples/tutorial/profiling_tutorial/calc_pi_3.pyx b/docs/examples/tutorial/profiling_tutorial/calc_pi_3.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9wcm9maWxpbmdfdHV0b3JpYWwvY2FsY19waV8zLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9wcm9maWxpbmdfdHV0b3JpYWwvY2FsY19waV8zLnB5eA== 100644
--- a/docs/examples/tutorial/profiling_tutorial/calc_pi_3.pyx
+++ b/docs/examples/tutorial/profiling_tutorial/calc_pi_3.pyx
@@ -1,13 +1,13 @@
-# cython: profile=True
-
-# calc_pi.pyx
-
-cdef inline double recip_square(int i):
-    return 1. / (i * i)
-
-def approx_pi(int n=10000000):
-    cdef double val = 0.
-    cdef int k
-    for k in range(1, n + 1):
-        val += recip_square(k)
-    return (6 * val) ** .5
+# cython: profile=True
+
+# calc_pi.pyx
+
+cdef inline double recip_square(int i):
+    return 1. / (i * i)
+
+def approx_pi(int n=10000000):
+    cdef double val = 0.
+    cdef int k
+    for k in range(1, n + 1):
+        val += recip_square(k)
+    return (6 * val) ** .5
diff --git a/docs/examples/tutorial/profiling_tutorial/calc_pi_4.pyx b/docs/examples/tutorial/profiling_tutorial/calc_pi_4.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9wcm9maWxpbmdfdHV0b3JpYWwvY2FsY19waV80LnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9wcm9maWxpbmdfdHV0b3JpYWwvY2FsY19waV80LnB5eA== 100644
--- a/docs/examples/tutorial/profiling_tutorial/calc_pi_4.pyx
+++ b/docs/examples/tutorial/profiling_tutorial/calc_pi_4.pyx
@@ -1,16 +1,16 @@
-# cython: profile=True
-
-# calc_pi.pyx
-
-cimport cython
-
-@cython.profile(False)
-cdef inline double recip_square(int i):
-    return 1. / (i * i)
-
-def approx_pi(int n=10000000):
-    cdef double val = 0.
-    cdef int k
-    for k in range(1, n + 1):
-        val += recip_square(k)
-    return (6 * val) ** .5
+# cython: profile=True
+
+# calc_pi.pyx
+
+cimport cython
+
+@cython.profile(False)
+cdef inline double recip_square(int i):
+    return 1. / (i * i)
+
+def approx_pi(int n=10000000):
+    cdef double val = 0.
+    cdef int k
+    for k in range(1, n + 1):
+        val += recip_square(k)
+    return (6 * val) ** .5
diff --git a/docs/examples/tutorial/profiling_tutorial/often_called.pyx b/docs/examples/tutorial/profiling_tutorial/often_called.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9wcm9maWxpbmdfdHV0b3JpYWwvb2Z0ZW5fY2FsbGVkLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9wcm9maWxpbmdfdHV0b3JpYWwvb2Z0ZW5fY2FsbGVkLnB5eA== 100644
--- a/docs/examples/tutorial/profiling_tutorial/often_called.pyx
+++ b/docs/examples/tutorial/profiling_tutorial/often_called.pyx
@@ -1,5 +1,5 @@
-cimport cython
-
-@cython.profile(False)
-def my_often_called_function():
-    pass
+cimport cython
+
+@cython.profile(False)
+def my_often_called_function():
+    pass
diff --git a/docs/examples/tutorial/profiling_tutorial/profile.py b/docs/examples/tutorial/profiling_tutorial/profile.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9wcm9maWxpbmdfdHV0b3JpYWwvcHJvZmlsZS5weQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9wcm9maWxpbmdfdHV0b3JpYWwvcHJvZmlsZS5weQ== 100644
--- a/docs/examples/tutorial/profiling_tutorial/profile.py
+++ b/docs/examples/tutorial/profiling_tutorial/profile.py
@@ -1,10 +1,10 @@
-# profile.py
-
-import pstats, cProfile
-
-import calc_pi
-
-cProfile.runctx("calc_pi.approx_pi()", globals(), locals(), "Profile.prof")
-
-s = pstats.Stats("Profile.prof")
-s.strip_dirs().sort_stats("time").print_stats()
+# profile.py
+
+import pstats, cProfile
+
+import calc_pi
+
+cProfile.runctx("calc_pi.approx_pi()", globals(), locals(), "Profile.prof")
+
+s = pstats.Stats("Profile.prof")
+s.strip_dirs().sort_stats("time").print_stats()
diff --git a/docs/examples/tutorial/profiling_tutorial/profile_2.py b/docs/examples/tutorial/profiling_tutorial/profile_2.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9wcm9maWxpbmdfdHV0b3JpYWwvcHJvZmlsZV8yLnB5..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9wcm9maWxpbmdfdHV0b3JpYWwvcHJvZmlsZV8yLnB5 100644
--- a/docs/examples/tutorial/profiling_tutorial/profile_2.py
+++ b/docs/examples/tutorial/profiling_tutorial/profile_2.py
@@ -1,13 +1,13 @@
-# profile.py
-
-import pstats, cProfile
-
-import pyximport
-pyximport.install()
-
-import calc_pi
-
-cProfile.runctx("calc_pi.approx_pi()", globals(), locals(), "Profile.prof")
-
-s = pstats.Stats("Profile.prof")
-s.strip_dirs().sort_stats("time").print_stats()
+# profile.py
+
+import pstats, cProfile
+
+import pyximport
+pyximport.install()
+
+import calc_pi
+
+cProfile.runctx("calc_pi.approx_pi()", globals(), locals(), "Profile.prof")
+
+s = pstats.Stats("Profile.prof")
+s.strip_dirs().sort_stats("time").print_stats()
diff --git a/docs/examples/tutorial/pure/A.py b/docs/examples/tutorial/pure/A.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9wdXJlL0EucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9wdXJlL0EucHk= 100644
--- a/docs/examples/tutorial/pure/A.py
+++ b/docs/examples/tutorial/pure/A.py
@@ -1,14 +1,14 @@
-def myfunction(x, y=2):
-    a = x - y
-    return a + x * y
-
-def _helper(a):
-    return a + 1
-
-class A:
-    def __init__(self, b=0):
-        self.a = 3
-        self.b = b
-
-    def foo(self, x):
-        print(x + _helper(1.0))
+def myfunction(x, y=2):
+    a = x - y
+    return a + x * y
+
+def _helper(a):
+    return a + 1
+
+class A:
+    def __init__(self, b=0):
+        self.a = 3
+        self.b = b
+
+    def foo(self, x):
+        print(x + _helper(1.0))
diff --git a/docs/examples/tutorial/pure/A_equivalent.pyx b/docs/examples/tutorial/pure/A_equivalent.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9wdXJlL0FfZXF1aXZhbGVudC5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9wdXJlL0FfZXF1aXZhbGVudC5weXg= 100644
--- a/docs/examples/tutorial/pure/A_equivalent.pyx
+++ b/docs/examples/tutorial/pure/A_equivalent.pyx
@@ -1,15 +1,15 @@
-cpdef int myfunction(int x, int y=2):
-    a = x - y
-    return a + x * y
-
-cdef double _helper(double a):
-    return a + 1
-
-cdef class A:
-    cdef public int a, b
-    def __init__(self, b=0):
-        self.a = 3
-        self.b = b
-
-    cpdef foo(self, double x):
-        print(x + _helper(1.0))
+cpdef int myfunction(int x, int y=2):
+    a = x - y
+    return a + x * y
+
+cdef double _helper(double a):
+    return a + 1
+
+cdef class A:
+    cdef public int a, b
+    def __init__(self, b=0):
+        self.a = 3
+        self.b = b
+
+    cpdef foo(self, double x):
+        print(x + _helper(1.0))
diff --git a/docs/examples/tutorial/pure/annotations.py b/docs/examples/tutorial/pure/annotations.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9wdXJlL2Fubm90YXRpb25zLnB5..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9wdXJlL2Fubm90YXRpb25zLnB5 100644
--- a/docs/examples/tutorial/pure/annotations.py
+++ b/docs/examples/tutorial/pure/annotations.py
@@ -1,5 +1,5 @@
-import cython
-
-def func(foo: dict, bar: cython.int) -> tuple:
-    foo["hello world"] = 3 + bar
-    return foo, 5
+import cython
+
+def func(foo: dict, bar: cython.int) -> tuple:
+    foo["hello world"] = 3 + bar
+    return foo, 5
diff --git a/docs/examples/tutorial/pure/c_arrays.py b/docs/examples/tutorial/pure/c_arrays.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9wdXJlL2NfYXJyYXlzLnB5..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9wdXJlL2NfYXJyYXlzLnB5 100644
--- a/docs/examples/tutorial/pure/c_arrays.py
+++ b/docs/examples/tutorial/pure/c_arrays.py
@@ -1,15 +1,15 @@
-import cython
-
-
-@cython.locals(counts=cython.int[10], digit=cython.int)
-def count_digits(digits):
-    """
-    >>> digits = '01112222333334445667788899'
-    >>> count_digits(map(int, digits))
-    [1, 3, 4, 5, 3, 1, 2, 2, 3, 2]
-    """
-    counts = [0] * 10
-    for digit in digits:
-        assert 0 <= digit <= 9
-        counts[digit] += 1
-    return counts
+import cython
+
+
+@cython.locals(counts=cython.int[10], digit=cython.int)
+def count_digits(digits):
+    """
+    >>> digits = '01112222333334445667788899'
+    >>> count_digits(map(int, digits))
+    [1, 3, 4, 5, 3, 1, 2, 2, 3, 2]
+    """
+    counts = [0] * 10
+    for digit in digits:
+        assert 0 <= digit <= 9
+        counts[digit] += 1
+    return counts
diff --git a/docs/examples/tutorial/pure/cclass.py b/docs/examples/tutorial/pure/cclass.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9wdXJlL2NjbGFzcy5weQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9wdXJlL2NjbGFzcy5weQ== 100644
--- a/docs/examples/tutorial/pure/cclass.py
+++ b/docs/examples/tutorial/pure/cclass.py
@@ -1,16 +1,16 @@
-import cython
-
-
-@cython.cclass
-class A:
-    cython.declare(a=cython.int, b=cython.int)
-    c = cython.declare(cython.int, visibility='public')
-    d = cython.declare(cython.int)  # private by default.
-    e = cython.declare(cython.int, visibility='readonly')
-
-    def __init__(self, a, b, c, d=5, e=3):
-        self.a = a
-        self.b = b
-        self.c = c
-        self.d = d
-        self.e = e
+import cython
+
+
+@cython.cclass
+class A:
+    cython.declare(a=cython.int, b=cython.int)
+    c = cython.declare(cython.int, visibility='public')
+    d = cython.declare(cython.int)  # private by default.
+    e = cython.declare(cython.int, visibility='readonly')
+
+    def __init__(self, a, b, c, d=5, e=3):
+        self.a = a
+        self.b = b
+        self.c = c
+        self.d = d
+        self.e = e
diff --git a/docs/examples/tutorial/pure/compiled_switch.py b/docs/examples/tutorial/pure/compiled_switch.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9wdXJlL2NvbXBpbGVkX3N3aXRjaC5weQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9wdXJlL2NvbXBpbGVkX3N3aXRjaC5weQ== 100644
--- a/docs/examples/tutorial/pure/compiled_switch.py
+++ b/docs/examples/tutorial/pure/compiled_switch.py
@@ -1,6 +1,6 @@
-import cython
-
-if cython.compiled:
-    print("Yep, I'm compiled.")
-else:
-    print("Just a lowly interpreted script.")
+import cython
+
+if cython.compiled:
+    print("Yep, I'm compiled.")
+else:
+    print("Just a lowly interpreted script.")
diff --git a/docs/examples/tutorial/pure/cython_declare.py b/docs/examples/tutorial/pure/cython_declare.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9wdXJlL2N5dGhvbl9kZWNsYXJlLnB5..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9wdXJlL2N5dGhvbl9kZWNsYXJlLnB5 100644
--- a/docs/examples/tutorial/pure/cython_declare.py
+++ b/docs/examples/tutorial/pure/cython_declare.py
@@ -1,4 +1,4 @@
-import cython
-
-x = cython.declare(cython.int)              # cdef int x
-y = cython.declare(cython.double, 0.57721)  # cdef double y = 0.57721
+import cython
+
+x = cython.declare(cython.int)              # cdef int x
+y = cython.declare(cython.double, 0.57721)  # cdef double y = 0.57721
diff --git a/docs/examples/tutorial/pure/cython_declare2.py b/docs/examples/tutorial/pure/cython_declare2.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9wdXJlL2N5dGhvbl9kZWNsYXJlMi5weQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9wdXJlL2N5dGhvbl9kZWNsYXJlMi5weQ== 100644
--- a/docs/examples/tutorial/pure/cython_declare2.py
+++ b/docs/examples/tutorial/pure/cython_declare2.py
@@ -1,3 +1,3 @@
-import cython
-
-cython.declare(x=cython.int, y=cython.double)  # cdef int x; cdef double y
+import cython
+
+cython.declare(x=cython.int, y=cython.double)  # cdef int x; cdef double y
diff --git a/docs/examples/tutorial/pure/dostuff.py b/docs/examples/tutorial/pure/dostuff.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9wdXJlL2Rvc3R1ZmYucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9wdXJlL2Rvc3R1ZmYucHk= 100644
--- a/docs/examples/tutorial/pure/dostuff.py
+++ b/docs/examples/tutorial/pure/dostuff.py
@@ -1,5 +1,5 @@
-def dostuff(n):
-    t = 0
-    for i in range(n):
-        t += i
-    return t
+def dostuff(n):
+    t = 0
+    for i in range(n):
+        t += i
+    return t
diff --git a/docs/examples/tutorial/pure/exceptval.py b/docs/examples/tutorial/pure/exceptval.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9wdXJlL2V4Y2VwdHZhbC5weQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9wdXJlL2V4Y2VwdHZhbC5weQ== 100644
--- a/docs/examples/tutorial/pure/exceptval.py
+++ b/docs/examples/tutorial/pure/exceptval.py
@@ -1,7 +1,7 @@
-import cython
-
-@cython.exceptval(-1)
-def func(x: cython.int) -> cython.int:
-    if x < 0:
-        raise ValueError("need integer >= 0")
-    return x + 1
+import cython
+
+@cython.exceptval(-1)
+def func(x: cython.int) -> cython.int:
+    if x < 0:
+        raise ValueError("need integer >= 0")
+    return x + 1
diff --git a/docs/examples/tutorial/pure/locals.py b/docs/examples/tutorial/pure/locals.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9wdXJlL2xvY2Fscy5weQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9wdXJlL2xvY2Fscy5weQ== 100644
--- a/docs/examples/tutorial/pure/locals.py
+++ b/docs/examples/tutorial/pure/locals.py
@@ -1,6 +1,6 @@
-import cython
-
-@cython.locals(a=cython.long, b=cython.long, n=cython.longlong)
-def foo(a, b, x, y):
-    n = a * b
-    # ...
+import cython
+
+@cython.locals(a=cython.long, b=cython.long, n=cython.longlong)
+def foo(a, b, x, y):
+    n = a * b
+    # ...
diff --git a/docs/examples/tutorial/pure/mymodule.py b/docs/examples/tutorial/pure/mymodule.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9wdXJlL215bW9kdWxlLnB5..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9wdXJlL215bW9kdWxlLnB5 100644
--- a/docs/examples/tutorial/pure/mymodule.py
+++ b/docs/examples/tutorial/pure/mymodule.py
@@ -1,10 +1,10 @@
-# mymodule.py
-
-import cython
-
-# override with Python import if not in compiled code
-if not cython.compiled:
-    from math import sin
-
-# calls sin() from math.h when compiled with Cython and math.sin() in Python
-print(sin(0))
+# mymodule.py
+
+import cython
+
+# override with Python import if not in compiled code
+if not cython.compiled:
+    from math import sin
+
+# calls sin() from math.h when compiled with Cython and math.sin() in Python
+print(sin(0))
diff --git a/docs/examples/tutorial/pure/pep_526.py b/docs/examples/tutorial/pure/pep_526.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9wdXJlL3BlcF81MjYucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9wdXJlL3BlcF81MjYucHk= 100644
--- a/docs/examples/tutorial/pure/pep_526.py
+++ b/docs/examples/tutorial/pure/pep_526.py
@@ -1,22 +1,22 @@
-import cython
-
-def func():
-    # Cython types are evaluated as for cdef declarations
-    x: cython.int               # cdef int x
-    y: cython.double = 0.57721  # cdef double y = 0.57721
-    z: cython.float = 0.57721   # cdef float z  = 0.57721
-
-    # Python types shadow Cython types for compatibility reasons
-    a: float = 0.54321          # cdef double a = 0.54321
-    b: int = 5                  # cdef object b = 5
-    c: long = 6                 # cdef object c = 6
-    pass
-
-@cython.cclass
-class A:
-    a: cython.int
-    b: cython.int
-
-    def __init__(self, b=0):
-        self.a = 3
-        self.b = b
+import cython
+
+def func():
+    # Cython types are evaluated as for cdef declarations
+    x: cython.int               # cdef int x
+    y: cython.double = 0.57721  # cdef double y = 0.57721
+    z: cython.float = 0.57721   # cdef float z  = 0.57721
+
+    # Python types shadow Cython types for compatibility reasons
+    a: float = 0.54321          # cdef double a = 0.54321
+    b: int = 5                  # cdef object b = 5
+    c: long = 6                 # cdef object c = 6
+    pass
+
+@cython.cclass
+class A:
+    a: cython.int
+    b: cython.int
+
+    def __init__(self, b=0):
+        self.a = 3
+        self.b = b
diff --git a/docs/examples/tutorial/string/api_func.pyx b/docs/examples/tutorial/string/api_func.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvYXBpX2Z1bmMucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvYXBpX2Z1bmMucHl4 100644
--- a/docs/examples/tutorial/string/api_func.pyx
+++ b/docs/examples/tutorial/string/api_func.pyx
@@ -1,5 +1,5 @@
-from to_unicode cimport _text
-
-def api_func(s):
-    text_input = _text(s)
-    # ...
+from to_unicode cimport _text
+
+def api_func(s):
+    text_input = _text(s)
+    # ...
diff --git a/docs/examples/tutorial/string/arg_memview.pyx b/docs/examples/tutorial/string/arg_memview.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvYXJnX21lbXZpZXcucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvYXJnX21lbXZpZXcucHl4 100644
--- a/docs/examples/tutorial/string/arg_memview.pyx
+++ b/docs/examples/tutorial/string/arg_memview.pyx
@@ -1,5 +1,5 @@
-def process_byte_data(unsigned char[:] data):
-    length = data.shape[0]
-    first_byte = data[0]
-    slice_view = data[1:-1]
-    # ...
+def process_byte_data(unsigned char[:] data):
+    length = data.shape[0]
+    first_byte = data[0]
+    slice_view = data[1:-1]
+    # ...
diff --git a/docs/examples/tutorial/string/auto_conversion_1.pyx b/docs/examples/tutorial/string/auto_conversion_1.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvYXV0b19jb252ZXJzaW9uXzEucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvYXV0b19jb252ZXJzaW9uXzEucHl4 100644
--- a/docs/examples/tutorial/string/auto_conversion_1.pyx
+++ b/docs/examples/tutorial/string/auto_conversion_1.pyx
@@ -1,9 +1,9 @@
-# cython: c_string_type=unicode, c_string_encoding=utf8
-
-cdef char* c_string = 'abcdefg'
-
-# implicit decoding:
-cdef object py_unicode_object = c_string
-
-# explicit conversion to Python bytes:
-py_bytes_object = <bytes>c_string
+# cython: c_string_type=unicode, c_string_encoding=utf8
+
+cdef char* c_string = 'abcdefg'
+
+# implicit decoding:
+cdef object py_unicode_object = c_string
+
+# explicit conversion to Python bytes:
+py_bytes_object = <bytes>c_string
diff --git a/docs/examples/tutorial/string/auto_conversion_2.pyx b/docs/examples/tutorial/string/auto_conversion_2.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvYXV0b19jb252ZXJzaW9uXzIucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvYXV0b19jb252ZXJzaW9uXzIucHl4 100644
--- a/docs/examples/tutorial/string/auto_conversion_2.pyx
+++ b/docs/examples/tutorial/string/auto_conversion_2.pyx
@@ -1,12 +1,12 @@
-# cython: c_string_type=str, c_string_encoding=ascii
-
-cdef char* c_string = 'abcdefg'
-
-# implicit decoding in Py3, bytes conversion in Py2:
-cdef object py_str_object = c_string
-
-# explicit conversion to Python bytes:
-py_bytes_object = <bytes>c_string
-
-# explicit conversion to Python unicode:
-py_bytes_object = <unicode>c_string
+# cython: c_string_type=str, c_string_encoding=ascii
+
+cdef char* c_string = 'abcdefg'
+
+# implicit decoding in Py3, bytes conversion in Py2:
+cdef object py_str_object = c_string
+
+# explicit conversion to Python bytes:
+py_bytes_object = <bytes>c_string
+
+# explicit conversion to Python unicode:
+py_bytes_object = <unicode>c_string
diff --git a/docs/examples/tutorial/string/auto_conversion_3.pyx b/docs/examples/tutorial/string/auto_conversion_3.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvYXV0b19jb252ZXJzaW9uXzMucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvYXV0b19jb252ZXJzaW9uXzMucHl4 100644
--- a/docs/examples/tutorial/string/auto_conversion_3.pyx
+++ b/docs/examples/tutorial/string/auto_conversion_3.pyx
@@ -1,6 +1,6 @@
-# cython: c_string_type=unicode, c_string_encoding=ascii
-
-def func():
-    ustring = u'abc'
-    cdef char* s = ustring
-    return s[0]    # returns u'a'
+# cython: c_string_type=unicode, c_string_encoding=ascii
+
+def func():
+    ustring = u'abc'
+    cdef char* s = ustring
+    return s[0]    # returns u'a'
diff --git a/docs/examples/tutorial/string/c_func.pyx b/docs/examples/tutorial/string/c_func.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvY19mdW5jLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvY19mdW5jLnB5eA== 100644
--- a/docs/examples/tutorial/string/c_func.pyx
+++ b/docs/examples/tutorial/string/c_func.pyx
@@ -1,22 +1,22 @@
-from libc.stdlib cimport malloc
-from libc.string cimport strcpy, strlen
-
-cdef char* hello_world = 'hello world'
-cdef Py_ssize_t n = strlen(hello_world)
-
-
-cdef char* c_call_returning_a_c_string():
-    cdef char* c_string = <char *> malloc((n + 1) * sizeof(char))
-    if not c_string:
-        raise MemoryError()
-    strcpy(c_string, hello_world)
-    return c_string
-
-
-cdef void get_a_c_string(char** c_string_ptr, Py_ssize_t *length):
-    c_string_ptr[0] = <char *> malloc((n + 1) * sizeof(char))
-    if not c_string_ptr[0]:
-        raise MemoryError()
-
-    strcpy(c_string_ptr[0], hello_world)
-    length[0] = n
+from libc.stdlib cimport malloc
+from libc.string cimport strcpy, strlen
+
+cdef char* hello_world = 'hello world'
+cdef Py_ssize_t n = strlen(hello_world)
+
+
+cdef char* c_call_returning_a_c_string():
+    cdef char* c_string = <char *> malloc((n + 1) * sizeof(char))
+    if not c_string:
+        raise MemoryError()
+    strcpy(c_string, hello_world)
+    return c_string
+
+
+cdef void get_a_c_string(char** c_string_ptr, Py_ssize_t *length):
+    c_string_ptr[0] = <char *> malloc((n + 1) * sizeof(char))
+    if not c_string_ptr[0]:
+        raise MemoryError()
+
+    strcpy(c_string_ptr[0], hello_world)
+    length[0] = n
diff --git a/docs/examples/tutorial/string/const.pyx b/docs/examples/tutorial/string/const.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvY29uc3QucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvY29uc3QucHl4 100644
--- a/docs/examples/tutorial/string/const.pyx
+++ b/docs/examples/tutorial/string/const.pyx
@@ -1,4 +1,4 @@
-cdef extern from "someheader.h":
-    ctypedef const char specialChar
-    int process_string(const char* s)
-    const unsigned char* look_up_cached_string(const unsigned char* key)
+cdef extern from "someheader.h":
+    ctypedef const char specialChar
+    int process_string(const char* s)
+    const unsigned char* look_up_cached_string(const unsigned char* key)
diff --git a/docs/examples/tutorial/string/cpp_string.pyx b/docs/examples/tutorial/string/cpp_string.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvY3BwX3N0cmluZy5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvY3BwX3N0cmluZy5weXg= 100644
--- a/docs/examples/tutorial/string/cpp_string.pyx
+++ b/docs/examples/tutorial/string/cpp_string.pyx
@@ -1,12 +1,12 @@
-# distutils: language = c++
-
-from libcpp.string cimport string
-
-def get_bytes():
-    py_bytes_object = b'hello world'
-    cdef string s = py_bytes_object
-
-    s.append('abc')
-    py_bytes_object = s
-    return py_bytes_object
-
+# distutils: language = c++
+
+from libcpp.string cimport string
+
+def get_bytes():
+    py_bytes_object = b'hello world'
+    cdef string s = py_bytes_object
+
+    s.append('abc')
+    py_bytes_object = s
+    return py_bytes_object
+
diff --git a/docs/examples/tutorial/string/decode.pyx b/docs/examples/tutorial/string/decode.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvZGVjb2RlLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvZGVjb2RlLnB5eA== 100644
--- a/docs/examples/tutorial/string/decode.pyx
+++ b/docs/examples/tutorial/string/decode.pyx
@@ -1,9 +1,9 @@
-from c_func cimport get_a_c_string
-
-cdef char* c_string = NULL
-cdef Py_ssize_t length = 0
-
-# get pointer and length from a C function
-get_a_c_string(&c_string, &length)
-
-ustring = c_string[:length].decode('UTF-8')
+from c_func cimport get_a_c_string
+
+cdef char* c_string = NULL
+cdef Py_ssize_t length = 0
+
+# get pointer and length from a C function
+get_a_c_string(&c_string, &length)
+
+ustring = c_string[:length].decode('UTF-8')
diff --git a/docs/examples/tutorial/string/decode_cpp_string.pyx b/docs/examples/tutorial/string/decode_cpp_string.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvZGVjb2RlX2NwcF9zdHJpbmcucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvZGVjb2RlX2NwcF9zdHJpbmcucHl4 100644
--- a/docs/examples/tutorial/string/decode_cpp_string.pyx
+++ b/docs/examples/tutorial/string/decode_cpp_string.pyx
@@ -1,10 +1,10 @@
-# distutils: language = c++
-
-from libcpp.string cimport string
-
-def get_ustrings():
-    cdef string s = string(b'abcdefg')
-
-    ustring1 = s.decode('UTF-8')
-    ustring2 = s[2:-2].decode('UTF-8')
-    return ustring1, ustring2
+# distutils: language = c++
+
+from libcpp.string cimport string
+
+def get_ustrings():
+    cdef string s = string(b'abcdefg')
+
+    ustring1 = s.decode('UTF-8')
+    ustring2 = s[2:-2].decode('UTF-8')
+    return ustring1, ustring2
diff --git a/docs/examples/tutorial/string/for_bytes.pyx b/docs/examples/tutorial/string/for_bytes.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvZm9yX2J5dGVzLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvZm9yX2J5dGVzLnB5eA== 100644
--- a/docs/examples/tutorial/string/for_bytes.pyx
+++ b/docs/examples/tutorial/string/for_bytes.pyx
@@ -1,6 +1,6 @@
-cdef bytes bytes_string = b"hello to A bytes' world"
-
-cdef char c
-for c in bytes_string:
-    if c == 'A':
-        print("Found the letter A")
+cdef bytes bytes_string = b"hello to A bytes' world"
+
+cdef char c
+for c in bytes_string:
+    if c == 'A':
+        print("Found the letter A")
diff --git a/docs/examples/tutorial/string/for_char.pyx b/docs/examples/tutorial/string/for_char.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvZm9yX2NoYXIucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvZm9yX2NoYXIucHl4 100644
--- a/docs/examples/tutorial/string/for_char.pyx
+++ b/docs/examples/tutorial/string/for_char.pyx
@@ -1,6 +1,6 @@
-cdef char* c_string = "Hello to A C-string's world"
-
-cdef char c
-for c in c_string[:11]:
-    if c == 'A':
-        print("Found the letter A")
+cdef char* c_string = "Hello to A C-string's world"
+
+cdef char c
+for c in c_string[:11]:
+    if c == 'A':
+        print("Found the letter A")
diff --git a/docs/examples/tutorial/string/for_unicode.pyx b/docs/examples/tutorial/string/for_unicode.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvZm9yX3VuaWNvZGUucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvZm9yX3VuaWNvZGUucHl4 100644
--- a/docs/examples/tutorial/string/for_unicode.pyx
+++ b/docs/examples/tutorial/string/for_unicode.pyx
@@ -1,6 +1,6 @@
-cdef unicode ustring = u'Hello world'
-
-# NOTE: no typing required for 'uchar' !
-for uchar in ustring:
-    if uchar == u'A':
-        print("Found the letter A")
+cdef unicode ustring = u'Hello world'
+
+# NOTE: no typing required for 'uchar' !
+for uchar in ustring:
+    if uchar == u'A':
+        print("Found the letter A")
diff --git a/docs/examples/tutorial/string/if_char_in.pyx b/docs/examples/tutorial/string/if_char_in.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvaWZfY2hhcl9pbi5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvaWZfY2hhcl9pbi5weXg= 100644
--- a/docs/examples/tutorial/string/if_char_in.pyx
+++ b/docs/examples/tutorial/string/if_char_in.pyx
@@ -1,5 +1,5 @@
-cpdef void is_in(Py_UCS4 uchar_val):
-    if uchar_val in u'abcABCxY':
-        print("The character is in the string.")
-    else:
-        print("The character is not in the string")
+cpdef void is_in(Py_UCS4 uchar_val):
+    if uchar_val in u'abcABCxY':
+        print("The character is in the string.")
+    else:
+        print("The character is not in the string")
diff --git a/docs/examples/tutorial/string/naive_decode.pyx b/docs/examples/tutorial/string/naive_decode.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvbmFpdmVfZGVjb2RlLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvbmFpdmVfZGVjb2RlLnB5eA== 100644
--- a/docs/examples/tutorial/string/naive_decode.pyx
+++ b/docs/examples/tutorial/string/naive_decode.pyx
@@ -1,4 +1,4 @@
-from c_func cimport c_call_returning_a_c_string
-
-cdef char* some_c_string = c_call_returning_a_c_string()
-ustring = some_c_string.decode('UTF-8')
+from c_func cimport c_call_returning_a_c_string
+
+cdef char* some_c_string = c_call_returning_a_c_string()
+ustring = some_c_string.decode('UTF-8')
diff --git a/docs/examples/tutorial/string/return_memview.pyx b/docs/examples/tutorial/string/return_memview.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvcmV0dXJuX21lbXZpZXcucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvcmV0dXJuX21lbXZpZXcucHl4 100644
--- a/docs/examples/tutorial/string/return_memview.pyx
+++ b/docs/examples/tutorial/string/return_memview.pyx
@@ -1,9 +1,9 @@
-def process_byte_data(unsigned char[:] data):
-    # ... process the data, here, dummy processing.
-    cdef bint return_all = (data[0] == 108)
-
-    if return_all:
-        return bytes(data)
-    else:
-        # example for returning a slice
-        return bytes(data[5:7])
+def process_byte_data(unsigned char[:] data):
+    # ... process the data, here, dummy processing.
+    cdef bint return_all = (data[0] == 108)
+
+    if return_all:
+        return bytes(data)
+    else:
+        # example for returning a slice
+        return bytes(data[5:7])
diff --git a/docs/examples/tutorial/string/slicing_c_string.pyx b/docs/examples/tutorial/string/slicing_c_string.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvc2xpY2luZ19jX3N0cmluZy5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvc2xpY2luZ19jX3N0cmluZy5weXg= 100644
--- a/docs/examples/tutorial/string/slicing_c_string.pyx
+++ b/docs/examples/tutorial/string/slicing_c_string.pyx
@@ -1,15 +1,15 @@
-from libc.stdlib cimport free
-from c_func cimport get_a_c_string
-
-
-def main():
-    cdef char* c_string = NULL
-    cdef Py_ssize_t length = 0
-
-    # get pointer and length from a C function
-    get_a_c_string(&c_string, &length)
-
-    try:
-        py_bytes_string = c_string[:length]  # Performs a copy of the data
-    finally:
-        free(c_string)
+from libc.stdlib cimport free
+from c_func cimport get_a_c_string
+
+
+def main():
+    cdef char* c_string = NULL
+    cdef Py_ssize_t length = 0
+
+    # get pointer and length from a C function
+    get_a_c_string(&c_string, &length)
+
+    try:
+        py_bytes_string = c_string[:length]  # Performs a copy of the data
+    finally:
+        free(c_string)
diff --git a/docs/examples/tutorial/string/to_char.pyx b/docs/examples/tutorial/string/to_char.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvdG9fY2hhci5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvdG9fY2hhci5weXg= 100644
--- a/docs/examples/tutorial/string/to_char.pyx
+++ b/docs/examples/tutorial/string/to_char.pyx
@@ -1,8 +1,8 @@
-# define a global name for whatever char type is used in the module
-ctypedef unsigned char char_type
-
-cdef char_type[:] _chars(s):
-    if isinstance(s, unicode):
-        # encode to the specific encoding used inside of the module
-        s = (<unicode>s).encode('utf8')
-    return s
+# define a global name for whatever char type is used in the module
+ctypedef unsigned char char_type
+
+cdef char_type[:] _chars(s):
+    if isinstance(s, unicode):
+        # encode to the specific encoding used inside of the module
+        s = (<unicode>s).encode('utf8')
+    return s
diff --git a/docs/examples/tutorial/string/to_unicode.pyx b/docs/examples/tutorial/string/to_unicode.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvdG9fdW5pY29kZS5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvdG9fdW5pY29kZS5weXg= 100644
--- a/docs/examples/tutorial/string/to_unicode.pyx
+++ b/docs/examples/tutorial/string/to_unicode.pyx
@@ -1,22 +1,22 @@
-# to_unicode.pyx
-
-from cpython.version cimport PY_MAJOR_VERSION
-
-cdef unicode _text(s):
-    if type(s) is unicode:
-        # Fast path for most common case(s).
-        return <unicode>s
-
-    elif PY_MAJOR_VERSION < 3 and isinstance(s, bytes):
-        # Only accept byte strings as text input in Python 2.x, not in Py3.
-        return (<bytes>s).decode('ascii')
-
-    elif isinstance(s, unicode):
-        # We know from the fast path above that 's' can only be a subtype here.
-        # An evil cast to <unicode> might still work in some(!) cases,
-        # depending on what the further processing does.  To be safe,
-        # we can always create a copy instead.
-        return unicode(s)
-
-    else:
-        raise TypeError("Could not convert to unicode.")
+# to_unicode.pyx
+
+from cpython.version cimport PY_MAJOR_VERSION
+
+cdef unicode _text(s):
+    if type(s) is unicode:
+        # Fast path for most common case(s).
+        return <unicode>s
+
+    elif PY_MAJOR_VERSION < 3 and isinstance(s, bytes):
+        # Only accept byte strings as text input in Python 2.x, not in Py3.
+        return (<bytes>s).decode('ascii')
+
+    elif isinstance(s, unicode):
+        # We know from the fast path above that 's' can only be a subtype here.
+        # An evil cast to <unicode> might still work in some(!) cases,
+        # depending on what the further processing does.  To be safe,
+        # we can always create a copy instead.
+        return unicode(s)
+
+    else:
+        raise TypeError("Could not convert to unicode.")
diff --git a/docs/examples/tutorial/string/try_finally.pyx b/docs/examples/tutorial/string/try_finally.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvdHJ5X2ZpbmFsbHkucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvdHJ5X2ZpbmFsbHkucHl4 100644
--- a/docs/examples/tutorial/string/try_finally.pyx
+++ b/docs/examples/tutorial/string/try_finally.pyx
@@ -1,9 +1,9 @@
-from libc.stdlib cimport free
-from c_func cimport c_call_returning_a_c_string
-
-cdef bytes py_string
-cdef char* c_string = c_call_returning_a_c_string()
-try:
-    py_string = c_string
-finally:
-    free(c_string)
+from libc.stdlib cimport free
+from c_func cimport c_call_returning_a_c_string
+
+cdef bytes py_string
+cdef char* c_string = c_call_returning_a_c_string()
+try:
+    py_string = c_string
+finally:
+    free(c_string)
diff --git a/docs/examples/tutorial/string/utf_eight.pyx b/docs/examples/tutorial/string/utf_eight.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvdXRmX2VpZ2h0LnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy90dXRvcmlhbC9zdHJpbmcvdXRmX2VpZ2h0LnB5eA== 100644
--- a/docs/examples/tutorial/string/utf_eight.pyx
+++ b/docs/examples/tutorial/string/utf_eight.pyx
@@ -1,15 +1,15 @@
-from libc.stdlib cimport free
-
-cdef unicode tounicode(char* s):
-    return s.decode('UTF-8', 'strict')
-
-cdef unicode tounicode_with_length(
-        char* s, size_t length):
-    return s[:length].decode('UTF-8', 'strict')
-
-cdef unicode tounicode_with_length_and_free(
-        char* s, size_t length):
-    try:
-        return s[:length].decode('UTF-8', 'strict')
-    finally:
+from libc.stdlib cimport free
+
+cdef unicode tounicode(char* s):
+    return s.decode('UTF-8', 'strict')
+
+cdef unicode tounicode_with_length(
+        char* s, size_t length):
+    return s[:length].decode('UTF-8', 'strict')
+
+cdef unicode tounicode_with_length_and_free(
+        char* s, size_t length):
+    try:
+        return s[:length].decode('UTF-8', 'strict')
+    finally:
         free(s)
\ No newline at end of file
diff --git a/docs/examples/userguide/buffer/matrix.pyx b/docs/examples/userguide/buffer/matrix.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvYnVmZmVyL21hdHJpeC5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvYnVmZmVyL21hdHJpeC5weXg= 100644
--- a/docs/examples/userguide/buffer/matrix.pyx
+++ b/docs/examples/userguide/buffer/matrix.pyx
@@ -1,16 +1,16 @@
-# distutils: language = c++
-
-# matrix.pyx
-
-from libcpp.vector cimport vector
-
-cdef class Matrix:
-    cdef unsigned ncols
-    cdef vector[float] v
-
-    def __cinit__(self, unsigned ncols):
-        self.ncols = ncols
-
-    def add_row(self):
-        """Adds a row, initially zero-filled."""
-        self.v.resize(self.v.size() + self.ncols)
+# distutils: language = c++
+
+# matrix.pyx
+
+from libcpp.vector cimport vector
+
+cdef class Matrix:
+    cdef unsigned ncols
+    cdef vector[float] v
+
+    def __cinit__(self, unsigned ncols):
+        self.ncols = ncols
+
+    def add_row(self):
+        """Adds a row, initially zero-filled."""
+        self.v.resize(self.v.size() + self.ncols)
diff --git a/docs/examples/userguide/buffer/matrix_with_buffer.pyx b/docs/examples/userguide/buffer/matrix_with_buffer.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvYnVmZmVyL21hdHJpeF93aXRoX2J1ZmZlci5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvYnVmZmVyL21hdHJpeF93aXRoX2J1ZmZlci5weXg= 100644
--- a/docs/examples/userguide/buffer/matrix_with_buffer.pyx
+++ b/docs/examples/userguide/buffer/matrix_with_buffer.pyx
@@ -1,45 +1,45 @@
-# distutils: language = c++
-
-from cpython cimport Py_buffer
-from libcpp.vector cimport vector
-
-cdef class Matrix:
-    cdef Py_ssize_t ncols
-    cdef Py_ssize_t shape[2]
-    cdef Py_ssize_t strides[2]
-    cdef vector[float] v
-
-    def __cinit__(self, Py_ssize_t ncols):
-        self.ncols = ncols
-
-    def add_row(self):
-        """Adds a row, initially zero-filled."""
-        self.v.resize(self.v.size() + self.ncols)
-
-    def __getbuffer__(self, Py_buffer *buffer, int flags):
-        cdef Py_ssize_t itemsize = sizeof(self.v[0])
-
-        self.shape[0] = self.v.size() / self.ncols
-        self.shape[1] = self.ncols
-
-        # Stride 1 is the distance, in bytes, between two items in a row;
-        # this is the distance between two adjacent items in the vector.
-        # Stride 0 is the distance between the first elements of adjacent rows.
-        self.strides[1] = <Py_ssize_t>(  <char *>&(self.v[1])
-                                       - <char *>&(self.v[0]))
-        self.strides[0] = self.ncols * self.strides[1]
-
-        buffer.buf = <char *>&(self.v[0])
-        buffer.format = 'f'                     # float
-        buffer.internal = NULL                  # see References
-        buffer.itemsize = itemsize
-        buffer.len = self.v.size() * itemsize   # product(shape) * itemsize
-        buffer.ndim = 2
-        buffer.obj = self
-        buffer.readonly = 0
-        buffer.shape = self.shape
-        buffer.strides = self.strides
-        buffer.suboffsets = NULL                # for pointer arrays only
-
-    def __releasebuffer__(self, Py_buffer *buffer):
-        pass
+# distutils: language = c++
+
+from cpython cimport Py_buffer
+from libcpp.vector cimport vector
+
+cdef class Matrix:
+    cdef Py_ssize_t ncols
+    cdef Py_ssize_t shape[2]
+    cdef Py_ssize_t strides[2]
+    cdef vector[float] v
+
+    def __cinit__(self, Py_ssize_t ncols):
+        self.ncols = ncols
+
+    def add_row(self):
+        """Adds a row, initially zero-filled."""
+        self.v.resize(self.v.size() + self.ncols)
+
+    def __getbuffer__(self, Py_buffer *buffer, int flags):
+        cdef Py_ssize_t itemsize = sizeof(self.v[0])
+
+        self.shape[0] = self.v.size() / self.ncols
+        self.shape[1] = self.ncols
+
+        # Stride 1 is the distance, in bytes, between two items in a row;
+        # this is the distance between two adjacent items in the vector.
+        # Stride 0 is the distance between the first elements of adjacent rows.
+        self.strides[1] = <Py_ssize_t>(  <char *>&(self.v[1])
+                                       - <char *>&(self.v[0]))
+        self.strides[0] = self.ncols * self.strides[1]
+
+        buffer.buf = <char *>&(self.v[0])
+        buffer.format = 'f'                     # float
+        buffer.internal = NULL                  # see References
+        buffer.itemsize = itemsize
+        buffer.len = self.v.size() * itemsize   # product(shape) * itemsize
+        buffer.ndim = 2
+        buffer.obj = self
+        buffer.readonly = 0
+        buffer.shape = self.shape
+        buffer.strides = self.strides
+        buffer.suboffsets = NULL                # for pointer arrays only
+
+    def __releasebuffer__(self, Py_buffer *buffer):
+        pass
diff --git a/docs/examples/userguide/buffer/view_count.pyx b/docs/examples/userguide/buffer/view_count.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvYnVmZmVyL3ZpZXdfY291bnQucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvYnVmZmVyL3ZpZXdfY291bnQucHl4 100644
--- a/docs/examples/userguide/buffer/view_count.pyx
+++ b/docs/examples/userguide/buffer/view_count.pyx
@@ -1,29 +1,29 @@
-# distutils: language = c++
-
-from cpython cimport Py_buffer
-from libcpp.vector cimport vector
-
-cdef class Matrix:
-
-    cdef int view_count
-
-    cdef Py_ssize_t ncols
-    cdef vector[float] v
-    # ...
-
-    def __cinit__(self, Py_ssize_t ncols):
-        self.ncols = ncols
-        self.view_count = 0
-
-    def add_row(self):
-        if self.view_count > 0:
-            raise ValueError("can't add row while being viewed")
-        self.v.resize(self.v.size() + self.ncols)
-
-    def __getbuffer__(self, Py_buffer *buffer, int flags):
-        # ... as before
-
-        self.view_count += 1
-
-    def __releasebuffer__(self, Py_buffer *buffer):
+# distutils: language = c++
+
+from cpython cimport Py_buffer
+from libcpp.vector cimport vector
+
+cdef class Matrix:
+
+    cdef int view_count
+
+    cdef Py_ssize_t ncols
+    cdef vector[float] v
+    # ...
+
+    def __cinit__(self, Py_ssize_t ncols):
+        self.ncols = ncols
+        self.view_count = 0
+
+    def add_row(self):
+        if self.view_count > 0:
+            raise ValueError("can't add row while being viewed")
+        self.v.resize(self.v.size() + self.ncols)
+
+    def __getbuffer__(self, Py_buffer *buffer, int flags):
+        # ... as before
+
+        self.view_count += 1
+
+    def __releasebuffer__(self, Py_buffer *buffer):
         self.view_count -= 1
\ No newline at end of file
diff --git a/docs/examples/userguide/early_binding_for_speed/rectangle.pyx b/docs/examples/userguide/early_binding_for_speed/rectangle.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvZWFybHlfYmluZGluZ19mb3Jfc3BlZWQvcmVjdGFuZ2xlLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvZWFybHlfYmluZGluZ19mb3Jfc3BlZWQvcmVjdGFuZ2xlLnB5eA== 100644
--- a/docs/examples/userguide/early_binding_for_speed/rectangle.pyx
+++ b/docs/examples/userguide/early_binding_for_speed/rectangle.pyx
@@ -1,19 +1,19 @@
-cdef class Rectangle:
-    cdef int x0, y0
-    cdef int x1, y1
-
-    def __init__(self, int x0, int y0, int x1, int y1):
-        self.x0 = x0
-        self.y0 = y0
-        self.x1 = x1
-        self.y1 = y1
-
-    def area(self):
-        area = (self.x1 - self.x0) * (self.y1 - self.y0)
-        if area < 0:
-            area = -area
-        return area
-
-def rectArea(x0, y0, x1, y1):
-    rect = Rectangle(x0, y0, x1, y1)
-    return rect.area()
+cdef class Rectangle:
+    cdef int x0, y0
+    cdef int x1, y1
+
+    def __init__(self, int x0, int y0, int x1, int y1):
+        self.x0 = x0
+        self.y0 = y0
+        self.x1 = x1
+        self.y1 = y1
+
+    def area(self):
+        area = (self.x1 - self.x0) * (self.y1 - self.y0)
+        if area < 0:
+            area = -area
+        return area
+
+def rectArea(x0, y0, x1, y1):
+    rect = Rectangle(x0, y0, x1, y1)
+    return rect.area()
diff --git a/docs/examples/userguide/early_binding_for_speed/rectangle_cdef.pyx b/docs/examples/userguide/early_binding_for_speed/rectangle_cdef.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvZWFybHlfYmluZGluZ19mb3Jfc3BlZWQvcmVjdGFuZ2xlX2NkZWYucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvZWFybHlfYmluZGluZ19mb3Jfc3BlZWQvcmVjdGFuZ2xlX2NkZWYucHl4 100644
--- a/docs/examples/userguide/early_binding_for_speed/rectangle_cdef.pyx
+++ b/docs/examples/userguide/early_binding_for_speed/rectangle_cdef.pyx
@@ -1,22 +1,22 @@
-cdef class Rectangle:
-    cdef int x0, y0
-    cdef int x1, y1
-
-    def __init__(self, int x0, int y0, int x1, int y1):
-        self.x0 = x0
-        self.y0 = y0
-        self.x1 = x1
-        self.y1 = y1
-
-    cdef int _area(self):
-        area = (self.x1 - self.x0) * (self.y1 - self.y0)
-        if area < 0:
-            area = -area
-        return area
-
-    def area(self):
-        return self._area()
-
-def rectArea(x0, y0, x1, y1):
-    rect = Rectangle(x0, y0, x1, y1)
-    return rect.area()
+cdef class Rectangle:
+    cdef int x0, y0
+    cdef int x1, y1
+
+    def __init__(self, int x0, int y0, int x1, int y1):
+        self.x0 = x0
+        self.y0 = y0
+        self.x1 = x1
+        self.y1 = y1
+
+    cdef int _area(self):
+        area = (self.x1 - self.x0) * (self.y1 - self.y0)
+        if area < 0:
+            area = -area
+        return area
+
+    def area(self):
+        return self._area()
+
+def rectArea(x0, y0, x1, y1):
+    cdef Rectangle rect = Rectangle(x0, y0, x1, y1)
+    return rect._area()
diff --git a/docs/examples/userguide/early_binding_for_speed/rectangle_cpdef.pyx b/docs/examples/userguide/early_binding_for_speed/rectangle_cpdef.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvZWFybHlfYmluZGluZ19mb3Jfc3BlZWQvcmVjdGFuZ2xlX2NwZGVmLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvZWFybHlfYmluZGluZ19mb3Jfc3BlZWQvcmVjdGFuZ2xlX2NwZGVmLnB5eA== 100644
--- a/docs/examples/userguide/early_binding_for_speed/rectangle_cpdef.pyx
+++ b/docs/examples/userguide/early_binding_for_speed/rectangle_cpdef.pyx
@@ -1,19 +1,19 @@
-cdef class Rectangle:
-    cdef int x0, y0
-    cdef int x1, y1
-
-    def __init__(self, int x0, int y0, int x1, int y1):
-        self.x0 = x0
-        self.y0 = y0
-        self.x1 = x1
-        self.y1 = y1
-
-    cpdef int area(self):
-        area = (self.x1 - self.x0) * (self.y1 - self.y0)
-        if area < 0:
-            area = -area
-        return area
-
-def rectArea(x0, y0, x1, y1):
-    rect = Rectangle(x0, y0, x1, y1)
-    return rect.area()
+cdef class Rectangle:
+    cdef int x0, y0
+    cdef int x1, y1
+
+    def __init__(self, int x0, int y0, int x1, int y1):
+        self.x0 = x0
+        self.y0 = y0
+        self.x1 = x1
+        self.y1 = y1
+
+    cpdef int area(self):
+        area = (self.x1 - self.x0) * (self.y1 - self.y0)
+        if area < 0:
+            area = -area
+        return area
+
+def rectArea(x0, y0, x1, y1):
+    cdef Rectangle rect = Rectangle(x0, y0, x1, y1)
+    return rect.area()
diff --git a/docs/examples/userguide/extension_types/dict_animal.pyx b/docs/examples/userguide/extension_types/dict_animal.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvZXh0ZW5zaW9uX3R5cGVzL2RpY3RfYW5pbWFsLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvZXh0ZW5zaW9uX3R5cGVzL2RpY3RfYW5pbWFsLnB5eA== 100644
--- a/docs/examples/userguide/extension_types/dict_animal.pyx
+++ b/docs/examples/userguide/extension_types/dict_animal.pyx
@@ -1,11 +1,11 @@
-cdef class Animal:
-
-    cdef int number_of_legs
-    cdef dict __dict__
-
-    def __cinit__(self, int number_of_legs):
-        self.number_of_legs = number_of_legs
-
-
-dog = Animal(4)
-dog.has_tail = True
+cdef class Animal:
+
+    cdef int number_of_legs
+    cdef dict __dict__
+
+    def __cinit__(self, int number_of_legs):
+        self.number_of_legs = number_of_legs
+
+
+dog = Animal(4)
+dog.has_tail = True
diff --git a/docs/examples/userguide/extension_types/extendable_animal.pyx b/docs/examples/userguide/extension_types/extendable_animal.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvZXh0ZW5zaW9uX3R5cGVzL2V4dGVuZGFibGVfYW5pbWFsLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvZXh0ZW5zaW9uX3R5cGVzL2V4dGVuZGFibGVfYW5pbWFsLnB5eA== 100644
--- a/docs/examples/userguide/extension_types/extendable_animal.pyx
+++ b/docs/examples/userguide/extension_types/extendable_animal.pyx
@@ -1,14 +1,14 @@
-cdef class Animal:
-
-    cdef int number_of_legs
-
-    def __cinit__(self, int number_of_legs):
-        self.number_of_legs = number_of_legs
-
-
-class ExtendableAnimal(Animal):  # Note that we use class, not cdef class
-    pass
-
-
-dog = ExtendableAnimal(4)
+cdef class Animal:
+
+    cdef int number_of_legs
+
+    def __cinit__(self, int number_of_legs):
+        self.number_of_legs = number_of_legs
+
+
+class ExtendableAnimal(Animal):  # Note that we use class, not cdef class
+    pass
+
+
+dog = ExtendableAnimal(4)
 dog.has_tail = True
\ No newline at end of file
diff --git a/docs/examples/userguide/extension_types/my_module.pyx b/docs/examples/userguide/extension_types/my_module.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvZXh0ZW5zaW9uX3R5cGVzL215X21vZHVsZS5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvZXh0ZW5zaW9uX3R5cGVzL215X21vZHVsZS5weXg= 100644
--- a/docs/examples/userguide/extension_types/my_module.pyx
+++ b/docs/examples/userguide/extension_types/my_module.pyx
@@ -1,11 +1,11 @@
-from __future__ import print_function
-
-cdef class Shrubbery:
-
-    def __init__(self, w, h):
-        self.width = w
-        self.height = h
-
-    def describe(self):
-        print("This shrubbery is", self.width,
-              "by", self.height, "cubits.")
+from __future__ import print_function
+
+cdef class Shrubbery:
+
+    def __init__(self, w, h):
+        self.width = w
+        self.height = h
+
+    def describe(self):
+        print("This shrubbery is", self.width,
+              "by", self.height, "cubits.")
diff --git a/docs/examples/userguide/extension_types/python_access.pyx b/docs/examples/userguide/extension_types/python_access.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvZXh0ZW5zaW9uX3R5cGVzL3B5dGhvbl9hY2Nlc3MucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvZXh0ZW5zaW9uX3R5cGVzL3B5dGhvbl9hY2Nlc3MucHl4 100644
--- a/docs/examples/userguide/extension_types/python_access.pyx
+++ b/docs/examples/userguide/extension_types/python_access.pyx
@@ -1,3 +1,3 @@
-cdef class Shrubbery:
-    cdef public int width, height
-    cdef readonly float depth
+cdef class Shrubbery:
+    cdef public int width, height
+    cdef readonly float depth
diff --git a/docs/examples/userguide/extension_types/shrubbery.pyx b/docs/examples/userguide/extension_types/shrubbery.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvZXh0ZW5zaW9uX3R5cGVzL3NocnViYmVyeS5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvZXh0ZW5zaW9uX3R5cGVzL3NocnViYmVyeS5weXg= 100644
--- a/docs/examples/userguide/extension_types/shrubbery.pyx
+++ b/docs/examples/userguide/extension_types/shrubbery.pyx
@@ -1,12 +1,12 @@
-from __future__ import print_function
-
-cdef class Shrubbery:
-    cdef int width, height
-
-    def __init__(self, w, h):
-        self.width = w
-        self.height = h
-
-    def describe(self):
-        print("This shrubbery is", self.width,
-              "by", self.height, "cubits.")
+from __future__ import print_function
+
+cdef class Shrubbery:
+    cdef int width, height
+
+    def __init__(self, w, h):
+        self.width = w
+        self.height = h
+
+    def describe(self):
+        print("This shrubbery is", self.width,
+              "by", self.height, "cubits.")
diff --git a/docs/examples/userguide/extension_types/shrubbery_2.pyx b/docs/examples/userguide/extension_types/shrubbery_2.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvZXh0ZW5zaW9uX3R5cGVzL3NocnViYmVyeV8yLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvZXh0ZW5zaW9uX3R5cGVzL3NocnViYmVyeV8yLnB5eA== 100644
--- a/docs/examples/userguide/extension_types/shrubbery_2.pyx
+++ b/docs/examples/userguide/extension_types/shrubbery_2.pyx
@@ -1,8 +1,8 @@
-from my_module cimport Shrubbery
-
-cdef Shrubbery another_shrubbery(Shrubbery sh1):
-    cdef Shrubbery sh2
-    sh2 = Shrubbery()
-    sh2.width = sh1.width
-    sh2.height = sh1.height
-    return sh2
+from my_module cimport Shrubbery
+
+cdef Shrubbery another_shrubbery(Shrubbery sh1):
+    cdef Shrubbery sh2
+    sh2 = Shrubbery()
+    sh2.width = sh1.width
+    sh2.height = sh1.height
+    return sh2
diff --git a/docs/examples/userguide/extension_types/widen_shrubbery.pyx b/docs/examples/userguide/extension_types/widen_shrubbery.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvZXh0ZW5zaW9uX3R5cGVzL3dpZGVuX3NocnViYmVyeS5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvZXh0ZW5zaW9uX3R5cGVzL3dpZGVuX3NocnViYmVyeS5weXg= 100644
--- a/docs/examples/userguide/extension_types/widen_shrubbery.pyx
+++ b/docs/examples/userguide/extension_types/widen_shrubbery.pyx
@@ -1,4 +1,4 @@
-from my_module cimport Shrubbery
-
-cdef widen_shrubbery(Shrubbery sh, extra_width):
-    sh.width = sh.width + extra_width
+from my_module cimport Shrubbery
+
+cdef widen_shrubbery(Shrubbery sh, extra_width):
+    sh.width = sh.width + extra_width
diff --git a/docs/examples/userguide/external_C_code/c_code_docstring.pyx b/docs/examples/userguide/external_C_code/c_code_docstring.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvZXh0ZXJuYWxfQ19jb2RlL2NfY29kZV9kb2NzdHJpbmcucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvZXh0ZXJuYWxfQ19jb2RlL2NfY29kZV9kb2NzdHJpbmcucHl4 100644
--- a/docs/examples/userguide/external_C_code/c_code_docstring.pyx
+++ b/docs/examples/userguide/external_C_code/c_code_docstring.pyx
@@ -1,9 +1,9 @@
-cdef extern from *:
-    """
-    /* This is C code which will be put
-     * in the .c file output by Cython */
-    static long square(long x) {return x * x;}
-    #define assign(x, y) ((x) = (y))
-    """
-    long square(long x)
-    void assign(long& x, long y)
+cdef extern from *:
+    """
+    /* This is C code which will be put
+     * in the .c file output by Cython */
+    static long square(long x) {return x * x;}
+    #define assign(x, y) ((x) = (y))
+    """
+    long square(long x)
+    void assign(long& x, long y)
diff --git a/docs/examples/userguide/external_C_code/delorean.pyx b/docs/examples/userguide/external_C_code/delorean.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvZXh0ZXJuYWxfQ19jb2RlL2RlbG9yZWFuLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvZXh0ZXJuYWxfQ19jb2RlL2RlbG9yZWFuLnB5eA== 100644
--- a/docs/examples/userguide/external_C_code/delorean.pyx
+++ b/docs/examples/userguide/external_C_code/delorean.pyx
@@ -1,9 +1,9 @@
-# delorean.pyx
-
-cdef public struct Vehicle:
-    int speed
-    float power
-
-cdef api void activate(Vehicle *v):
-    if v.speed >= 88 and v.power >= 1.21:
+# delorean.pyx
+
+cdef public struct Vehicle:
+    int speed
+    float power
+
+cdef api void activate(Vehicle *v):
+    if v.speed >= 88 and v.power >= 1.21:
         print("Time travel achieved")
\ No newline at end of file
diff --git a/docs/examples/userguide/fusedtypes/char_or_float.pyx b/docs/examples/userguide/fusedtypes/char_or_float.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvZnVzZWR0eXBlcy9jaGFyX29yX2Zsb2F0LnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvZnVzZWR0eXBlcy9jaGFyX29yX2Zsb2F0LnB5eA== 100644
--- a/docs/examples/userguide/fusedtypes/char_or_float.pyx
+++ b/docs/examples/userguide/fusedtypes/char_or_float.pyx
@@ -1,17 +1,17 @@
-from __future__ import print_function
-
-ctypedef fused char_or_float:
-    char
-    float
-
-
-cpdef char_or_float plus_one(char_or_float var):
-    return var + 1
-
-
-def show_me():
-    cdef:
-        char a = 127
-        float b = 127
-    print('char', plus_one(a))
-    print('float', plus_one(b))
+from __future__ import print_function
+
+ctypedef fused char_or_float:
+    char
+    float
+
+
+cpdef char_or_float plus_one(char_or_float var):
+    return var + 1
+
+
+def show_me():
+    cdef:
+        char a = 127
+        float b = 127
+    print('char', plus_one(a))
+    print('float', plus_one(b))
diff --git a/docs/examples/userguide/language_basics/casting_python.pyx b/docs/examples/userguide/language_basics/casting_python.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbGFuZ3VhZ2VfYmFzaWNzL2Nhc3RpbmdfcHl0aG9uLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbGFuZ3VhZ2VfYmFzaWNzL2Nhc3RpbmdfcHl0aG9uLnB5eA== 100644
--- a/docs/examples/userguide/language_basics/casting_python.pyx
+++ b/docs/examples/userguide/language_basics/casting_python.pyx
@@ -1,19 +1,19 @@
-from cpython.ref cimport PyObject
-
-cdef extern from *:
-    ctypedef Py_ssize_t Py_intptr_t
-
-python_string = "foo"
-
-cdef void* ptr = <void*>python_string
-cdef Py_intptr_t adress_in_c = <Py_intptr_t>ptr
-address_from_void = adress_in_c        # address_from_void is a python int
-
-cdef PyObject* ptr2 = <PyObject*>python_string
-cdef Py_intptr_t address_in_c2 = <Py_intptr_t>ptr2
-address_from_PyObject = address_in_c2  # address_from_PyObject is a python int
-
-assert address_from_void == address_from_PyObject == id(python_string)
-
-print(<object>ptr)                     # Prints "foo"
-print(<object>ptr2)                    # prints "foo"
+from cpython.ref cimport PyObject
+
+cdef extern from *:
+    ctypedef Py_ssize_t Py_intptr_t
+
+python_string = "foo"
+
+cdef void* ptr = <void*>python_string
+cdef Py_intptr_t adress_in_c = <Py_intptr_t>ptr
+address_from_void = adress_in_c        # address_from_void is a python int
+
+cdef PyObject* ptr2 = <PyObject*>python_string
+cdef Py_intptr_t address_in_c2 = <Py_intptr_t>ptr2
+address_from_PyObject = address_in_c2  # address_from_PyObject is a python int
+
+assert address_from_void == address_from_PyObject == id(python_string)
+
+print(<object>ptr)                     # Prints "foo"
+print(<object>ptr2)                    # prints "foo"
diff --git a/docs/examples/userguide/language_basics/cdef_block.pyx b/docs/examples/userguide/language_basics/cdef_block.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbGFuZ3VhZ2VfYmFzaWNzL2NkZWZfYmxvY2sucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbGFuZ3VhZ2VfYmFzaWNzL2NkZWZfYmxvY2sucHl4 100644
--- a/docs/examples/userguide/language_basics/cdef_block.pyx
+++ b/docs/examples/userguide/language_basics/cdef_block.pyx
@@ -1,12 +1,12 @@
-from __future__ import print_function
-
-cdef:
-    struct Spam:
-        int tons
-
-    int i
-    float a
-    Spam *p
-
-    void f(Spam *s):
-        print(s.tons, "Tons of spam")
+from __future__ import print_function
+
+cdef:
+    struct Spam:
+        int tons
+
+    int i
+    float a
+    Spam *p
+
+    void f(Spam *s):
+        print(s.tons, "Tons of spam")
diff --git a/docs/examples/userguide/language_basics/compile_time.pyx b/docs/examples/userguide/language_basics/compile_time.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbGFuZ3VhZ2VfYmFzaWNzL2NvbXBpbGVfdGltZS5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbGFuZ3VhZ2VfYmFzaWNzL2NvbXBpbGVfdGltZS5weXg= 100644
--- a/docs/examples/userguide/language_basics/compile_time.pyx
+++ b/docs/examples/userguide/language_basics/compile_time.pyx
@@ -1,9 +1,9 @@
-from __future__ import print_function
-
-DEF FavouriteFood = u"spam"
-DEF ArraySize = 42
-DEF OtherArraySize = 2 * ArraySize + 17
-
-cdef int a1[ArraySize]
-cdef int a2[OtherArraySize]
+from __future__ import print_function
+
+DEF FavouriteFood = u"spam"
+DEF ArraySize = 42
+DEF OtherArraySize = 2 * ArraySize + 17
+
+cdef int a1[ArraySize]
+cdef int a2[OtherArraySize]
 print("I like", FavouriteFood)
\ No newline at end of file
diff --git a/docs/examples/userguide/language_basics/kwargs_1.pyx b/docs/examples/userguide/language_basics/kwargs_1.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbGFuZ3VhZ2VfYmFzaWNzL2t3YXJnc18xLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbGFuZ3VhZ2VfYmFzaWNzL2t3YXJnc18xLnB5eA== 100644
--- a/docs/examples/userguide/language_basics/kwargs_1.pyx
+++ b/docs/examples/userguide/language_basics/kwargs_1.pyx
@@ -1,6 +1,6 @@
-def f(a, b, *args, c, d = 42, e, **kwds):
-    ...
-
-
-# We cannot call f with less verbosity than this.
-foo = f(4, "bar", c=68, e=1.0)
+def f(a, b, *args, c, d = 42, e, **kwds):
+    ...
+
+
+# We cannot call f with less verbosity than this.
+foo = f(4, "bar", c=68, e=1.0)
diff --git a/docs/examples/userguide/language_basics/kwargs_2.pyx b/docs/examples/userguide/language_basics/kwargs_2.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbGFuZ3VhZ2VfYmFzaWNzL2t3YXJnc18yLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbGFuZ3VhZ2VfYmFzaWNzL2t3YXJnc18yLnB5eA== 100644
--- a/docs/examples/userguide/language_basics/kwargs_2.pyx
+++ b/docs/examples/userguide/language_basics/kwargs_2.pyx
@@ -1,5 +1,5 @@
-def g(a, b, *, c, d):
-    ...
-
-# We cannot call g with less verbosity than this.
-foo = g(4.0, "something", c=68, d="other")
+def g(a, b, *, c, d):
+    ...
+
+# We cannot call g with less verbosity than this.
+foo = g(4.0, "something", c=68, d="other")
diff --git a/docs/examples/userguide/language_basics/open_file.pyx b/docs/examples/userguide/language_basics/open_file.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbGFuZ3VhZ2VfYmFzaWNzL29wZW5fZmlsZS5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbGFuZ3VhZ2VfYmFzaWNzL29wZW5fZmlsZS5weXg= 100644
--- a/docs/examples/userguide/language_basics/open_file.pyx
+++ b/docs/examples/userguide/language_basics/open_file.pyx
@@ -1,18 +1,18 @@
-from libc.stdio cimport FILE, fopen
-from libc.stdlib cimport malloc, free
-from cpython.exc cimport PyErr_SetFromErrnoWithFilenameObject
-
-def open_file():
-    cdef FILE* p
-    p = fopen("spam.txt", "r")
-    if p is NULL:
-        PyErr_SetFromErrnoWithFilenameObject(OSError, "spam.txt")
-    ...
-
-
-def allocating_memory(number=10):
-    cdef double *my_array = <double *> malloc(number * sizeof(double))
-    if not my_array:  # same as 'is NULL' above
-        raise MemoryError()
-    ...
-    free(my_array)
+from libc.stdio cimport FILE, fopen
+from libc.stdlib cimport malloc, free
+from cpython.exc cimport PyErr_SetFromErrnoWithFilenameObject
+
+def open_file():
+    cdef FILE* p
+    p = fopen("spam.txt", "r")
+    if p is NULL:
+        PyErr_SetFromErrnoWithFilenameObject(OSError, "spam.txt")
+    ...
+
+
+def allocating_memory(number=10):
+    cdef double *my_array = <double *> malloc(number * sizeof(double))
+    if not my_array:  # same as 'is NULL' above
+        raise MemoryError()
+    ...
+    free(my_array)
diff --git a/docs/examples/userguide/language_basics/optional_subclassing.pyx b/docs/examples/userguide/language_basics/optional_subclassing.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbGFuZ3VhZ2VfYmFzaWNzL29wdGlvbmFsX3N1YmNsYXNzaW5nLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbGFuZ3VhZ2VfYmFzaWNzL29wdGlvbmFsX3N1YmNsYXNzaW5nLnB5eA== 100644
--- a/docs/examples/userguide/language_basics/optional_subclassing.pyx
+++ b/docs/examples/userguide/language_basics/optional_subclassing.pyx
@@ -1,13 +1,13 @@
-from __future__ import print_function
-
-cdef class A:
-    cdef foo(self):
-        print("A")
-
-cdef class B(A):
-    cdef foo(self, x=None):
-        print("B", x)
-
-cdef class C(B):
-    cpdef foo(self, x=True, int k=3):
-        print("C", x, k)
+from __future__ import print_function
+
+cdef class A:
+    cdef foo(self):
+        print("A")
+
+cdef class B(A):
+    cdef foo(self, x=None):
+        print("B", x)
+
+cdef class C(B):
+    cpdef foo(self, x=True, int k=3):
+        print("C", x, k)
diff --git a/docs/examples/userguide/language_basics/override.pyx b/docs/examples/userguide/language_basics/override.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbGFuZ3VhZ2VfYmFzaWNzL292ZXJyaWRlLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbGFuZ3VhZ2VfYmFzaWNzL292ZXJyaWRlLnB5eA== 100644
--- a/docs/examples/userguide/language_basics/override.pyx
+++ b/docs/examples/userguide/language_basics/override.pyx
@@ -1,13 +1,13 @@
-from __future__ import print_function
-
-cdef class A:
-    cdef foo(self):
-        print("A")
-
-cdef class B(A):
-    cpdef foo(self):
-        print("B")
-
-class C(B):  # NOTE: not cdef class
-    def foo(self):
-        print("C")
+from __future__ import print_function
+
+cdef class A:
+    cdef foo(self):
+        print("A")
+
+cdef class B(A):
+    cpdef foo(self):
+        print("B")
+
+class C(B):  # NOTE: not cdef class
+    def foo(self):
+        print("C")
diff --git a/docs/examples/userguide/language_basics/parameter_refcount.pyx b/docs/examples/userguide/language_basics/parameter_refcount.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbGFuZ3VhZ2VfYmFzaWNzL3BhcmFtZXRlcl9yZWZjb3VudC5weXg=
--- /dev/null
+++ b/docs/examples/userguide/language_basics/parameter_refcount.pyx
@@ -0,0 +1,20 @@
+from __future__ import print_function
+
+from cpython.ref cimport PyObject
+
+import sys
+
+python_dict = {"abc": 123}
+python_dict_refcount = sys.getrefcount(python_dict)
+
+cdef owned_reference(object obj):
+    refcount = sys.getrefcount(python_dict)
+    print('Inside owned_reference: {refcount}'.format(refcount=refcount))
+
+cdef borrowed_reference(PyObject * obj):
+    refcount = obj.ob_refcnt
+    print('Inside borrowed_reference: {refcount}'.format(refcount=refcount))
+
+print('Initial refcount: {refcount}'.format(refcount=python_dict_refcount))
+owned_reference(python_dict)
+borrowed_reference(<PyObject *>python_dict)
diff --git a/docs/examples/userguide/language_basics/struct_union_enum.pyx b/docs/examples/userguide/language_basics/struct_union_enum.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbGFuZ3VhZ2VfYmFzaWNzL3N0cnVjdF91bmlvbl9lbnVtLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbGFuZ3VhZ2VfYmFzaWNzL3N0cnVjdF91bmlvbl9lbnVtLnB5eA== 100644
--- a/docs/examples/userguide/language_basics/struct_union_enum.pyx
+++ b/docs/examples/userguide/language_basics/struct_union_enum.pyx
@@ -1,16 +1,16 @@
-cdef struct Grail:
-    int age
-    float volume
-
-cdef union Food:
-    char *spam
-    float *eggs
-
-cdef enum CheeseType:
-    cheddar, edam,
-    camembert
-
-cdef enum CheeseState:
-    hard = 1
-    soft = 2
-    runny = 3
+cdef struct Grail:
+    int age
+    float volume
+
+cdef union Food:
+    char *spam
+    float *eggs
+
+cdef enum CheeseType:
+    cheddar, edam,
+    camembert
+
+cdef enum CheeseState:
+    hard = 1
+    soft = 2
+    runny = 3
diff --git a/docs/examples/userguide/memoryviews/add_one.pyx b/docs/examples/userguide/memoryviews/add_one.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbWVtb3J5dmlld3MvYWRkX29uZS5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbWVtb3J5dmlld3MvYWRkX29uZS5weXg= 100644
--- a/docs/examples/userguide/memoryviews/add_one.pyx
+++ b/docs/examples/userguide/memoryviews/add_one.pyx
@@ -1,12 +1,12 @@
-import numpy as np
-
-def add_one(int[:,:] buf):
-    for x in range(buf.shape[0]):
-        for y in range(buf.shape[1]):
-            buf[x, y] += 1
-
-# exporting_object must be a Python object
-# implementing the buffer interface, e.g. a numpy array.
-exporting_object = np.zeros((10, 20), dtype=np.intc)
-
-add_one(exporting_object)
+import numpy as np
+
+def add_one(int[:,:] buf):
+    for x in range(buf.shape[0]):
+        for y in range(buf.shape[1]):
+            buf[x, y] += 1
+
+# exporting_object must be a Python object
+# implementing the buffer interface, e.g. a numpy array.
+exporting_object = np.zeros((10, 20), dtype=np.intc)
+
+add_one(exporting_object)
diff --git a/docs/examples/userguide/memoryviews/copy.pyx b/docs/examples/userguide/memoryviews/copy.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbWVtb3J5dmlld3MvY29weS5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbWVtb3J5dmlld3MvY29weS5weXg= 100644
--- a/docs/examples/userguide/memoryviews/copy.pyx
+++ b/docs/examples/userguide/memoryviews/copy.pyx
@@ -1,12 +1,12 @@
-import numpy as np
-
-cdef int[:, :, :] to_view, from_view
-to_view = np.empty((20, 15, 30), dtype=np.intc)
-from_view = np.ones((20, 15, 30), dtype=np.intc)
-
-# copy the elements in from_view to to_view
-to_view[...] = from_view
-# or
-to_view[:] = from_view
-# or
-to_view[:, :, :] = from_view
+import numpy as np
+
+cdef int[:, :, :] to_view, from_view
+to_view = np.empty((20, 15, 30), dtype=np.intc)
+from_view = np.ones((20, 15, 30), dtype=np.intc)
+
+# copy the elements in from_view to to_view
+to_view[...] = from_view
+# or
+to_view[:] = from_view
+# or
+to_view[:, :, :] = from_view
diff --git a/docs/examples/userguide/memoryviews/memory_layout.pyx b/docs/examples/userguide/memoryviews/memory_layout.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbWVtb3J5dmlld3MvbWVtb3J5X2xheW91dC5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbWVtb3J5dmlld3MvbWVtb3J5X2xheW91dC5weXg= 100644
--- a/docs/examples/userguide/memoryviews/memory_layout.pyx
+++ b/docs/examples/userguide/memoryviews/memory_layout.pyx
@@ -1,11 +1,11 @@
-from cython cimport view
-
-# direct access in both dimensions, strided in the first dimension, contiguous in the last
-cdef int[:, ::view.contiguous] a
-
-# contiguous list of pointers to contiguous lists of ints
-cdef int[::view.indirect_contiguous, ::1] b
-
-# direct or indirect in the first dimension, direct in the second dimension
-# strided in both dimensions
-cdef int[::view.generic, :] c
+from cython cimport view
+
+# direct access in both dimensions, strided in the first dimension, contiguous in the last
+cdef int[:, ::view.contiguous] a
+
+# contiguous list of pointers to contiguous lists of ints
+cdef int[::view.indirect_contiguous, ::1] b
+
+# direct or indirect in the first dimension, direct in the second dimension
+# strided in both dimensions
+cdef int[::view.generic, :] c
diff --git a/docs/examples/userguide/memoryviews/memory_layout_2.pyx b/docs/examples/userguide/memoryviews/memory_layout_2.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbWVtb3J5dmlld3MvbWVtb3J5X2xheW91dF8yLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbWVtb3J5dmlld3MvbWVtb3J5X2xheW91dF8yLnB5eA== 100644
--- a/docs/examples/userguide/memoryviews/memory_layout_2.pyx
+++ b/docs/examples/userguide/memoryviews/memory_layout_2.pyx
@@ -1,6 +1,6 @@
-from cython cimport view
-
-# VALID
-cdef int[::view.indirect, ::1, :] a
-cdef int[::view.indirect, :, ::1] b
-cdef int[::view.indirect_contiguous, ::1, :] c
+from cython cimport view
+
+# VALID
+cdef int[::view.indirect, ::1, :] a
+cdef int[::view.indirect, :, ::1] b
+cdef int[::view.indirect_contiguous, ::1, :] c
diff --git a/docs/examples/userguide/memoryviews/memview_to_c.pyx b/docs/examples/userguide/memoryviews/memview_to_c.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbWVtb3J5dmlld3MvbWVtdmlld190b19jLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbWVtb3J5dmlld3MvbWVtdmlld190b19jLnB5eA== 100644
--- a/docs/examples/userguide/memoryviews/memview_to_c.pyx
+++ b/docs/examples/userguide/memoryviews/memview_to_c.pyx
@@ -1,28 +1,28 @@
-cdef extern from "C_func_file.c":
-    # C is include here so that it doesn't need to be compiled externally
-    pass
-
-cdef extern from "C_func_file.h":
-    void multiply_by_10_in_C(double *, unsigned int)
-
-import numpy as np
-
-def multiply_by_10(arr): # 'arr' is a one-dimensional numpy array
-
-    if not arr.flags['C_CONTIGUOUS']:
-        arr = np.ascontiguousarray(arr) # Makes a contiguous copy of the numpy array.
-
-    cdef double[::1] arr_memview = arr
-
-    multiply_by_10_in_C(&arr_memview[0], arr_memview.shape[0])
-
-    return arr
-
-
-a = np.ones(5, dtype=np.double)
-print(multiply_by_10(a))
-
-b = np.ones(10, dtype=np.double)
-b = b[::2]  # b is not contiguous.
-
-print(multiply_by_10(b))  # but our function still works as expected.
+cdef extern from "C_func_file.c":
+    # C is include here so that it doesn't need to be compiled externally
+    pass
+
+cdef extern from "C_func_file.h":
+    void multiply_by_10_in_C(double *, unsigned int)
+
+import numpy as np
+
+def multiply_by_10(arr): # 'arr' is a one-dimensional numpy array
+
+    if not arr.flags['C_CONTIGUOUS']:
+        arr = np.ascontiguousarray(arr) # Makes a contiguous copy of the numpy array.
+
+    cdef double[::1] arr_memview = arr
+
+    multiply_by_10_in_C(&arr_memview[0], arr_memview.shape[0])
+
+    return arr
+
+
+a = np.ones(5, dtype=np.double)
+print(multiply_by_10(a))
+
+b = np.ones(10, dtype=np.double)
+b = b[::2]  # b is not contiguous.
+
+print(multiply_by_10(b))  # but our function still works as expected.
diff --git a/docs/examples/userguide/memoryviews/not_none.pyx b/docs/examples/userguide/memoryviews/not_none.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbWVtb3J5dmlld3Mvbm90X25vbmUucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbWVtb3J5dmlld3Mvbm90X25vbmUucHl4 100644
--- a/docs/examples/userguide/memoryviews/not_none.pyx
+++ b/docs/examples/userguide/memoryviews/not_none.pyx
@@ -1,11 +1,11 @@
-import numpy as np
-
-def process_buffer(int[:,:] input_view not None,
-                   int[:,:] output_view=None):
-
-   if output_view is None:
-       # Creating a default view, e.g.
-       output_view = np.empty_like(input_view)
-
-   # process 'input_view' into 'output_view'
-   return output_view
+import numpy as np
+
+def process_buffer(int[:,:] input_view not None,
+                   int[:,:] output_view=None):
+
+   if output_view is None:
+       # Creating a default view, e.g.
+       output_view = np.empty_like(input_view)
+
+   # process 'input_view' into 'output_view'
+   return output_view
diff --git a/docs/examples/userguide/memoryviews/np_flag_const.pyx b/docs/examples/userguide/memoryviews/np_flag_const.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbWVtb3J5dmlld3MvbnBfZmxhZ19jb25zdC5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbWVtb3J5dmlld3MvbnBfZmxhZ19jb25zdC5weXg= 100644
--- a/docs/examples/userguide/memoryviews/np_flag_const.pyx
+++ b/docs/examples/userguide/memoryviews/np_flag_const.pyx
@@ -1,7 +1,7 @@
-import numpy as np
-
-cdef const double[:] myslice   # const item type => read-only view
-
-a = np.linspace(0, 10, num=50)
-a.setflags(write=False)
-myslice = a
+import numpy as np
+
+cdef const double[:] myslice   # const item type => read-only view
+
+a = np.linspace(0, 10, num=50)
+a.setflags(write=False)
+myslice = a
diff --git a/docs/examples/userguide/memoryviews/slicing.pyx b/docs/examples/userguide/memoryviews/slicing.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbWVtb3J5dmlld3Mvc2xpY2luZy5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbWVtb3J5dmlld3Mvc2xpY2luZy5weXg= 100644
--- a/docs/examples/userguide/memoryviews/slicing.pyx
+++ b/docs/examples/userguide/memoryviews/slicing.pyx
@@ -1,10 +1,10 @@
-import numpy as np
-
-exporting_object = np.arange(0, 15 * 10 * 20, dtype=np.intc).reshape((15, 10, 20))
-
-cdef int[:, :, :] my_view = exporting_object
-
-# These are all equivalent
-my_view[10]
-my_view[10, :, :]
-my_view[10, ...]
+import numpy as np
+
+exporting_object = np.arange(0, 15 * 10 * 20, dtype=np.intc).reshape((15, 10, 20))
+
+cdef int[:, :, :] my_view = exporting_object
+
+# These are all equivalent
+my_view[10]
+my_view[10, :, :]
+my_view[10, ...]
diff --git a/docs/examples/userguide/memoryviews/transpose.pyx b/docs/examples/userguide/memoryviews/transpose.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbWVtb3J5dmlld3MvdHJhbnNwb3NlLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbWVtb3J5dmlld3MvdHJhbnNwb3NlLnB5eA== 100644
--- a/docs/examples/userguide/memoryviews/transpose.pyx
+++ b/docs/examples/userguide/memoryviews/transpose.pyx
@@ -1,6 +1,6 @@
-import numpy as np
-
-array = np.arange(20, dtype=np.intc).reshape((2, 10))
-
-cdef int[:, ::1] c_contig = array
-cdef int[::1, :] f_contig = c_contig.T
+import numpy as np
+
+array = np.arange(20, dtype=np.intc).reshape((2, 10))
+
+cdef int[:, ::1] c_contig = array
+cdef int[::1, :] f_contig = c_contig.T
diff --git a/docs/examples/userguide/memoryviews/view_string.pyx b/docs/examples/userguide/memoryviews/view_string.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbWVtb3J5dmlld3Mvdmlld19zdHJpbmcucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbWVtb3J5dmlld3Mvdmlld19zdHJpbmcucHl4 100644
--- a/docs/examples/userguide/memoryviews/view_string.pyx
+++ b/docs/examples/userguide/memoryviews/view_string.pyx
@@ -1,9 +1,9 @@
-cdef bint is_y_in(const unsigned char[:] string_view):
-    cdef int i
-    for i in range(string_view.shape[0]):
-        if string_view[i] == b'y':
-            return True
-    return False
-
-print(is_y_in(b'hello world'))   # False
-print(is_y_in(b'hello Cython'))  # True
+cdef bint is_y_in(const unsigned char[:] string_view):
+    cdef int i
+    for i in range(string_view.shape[0]):
+        if string_view[i] == b'y':
+            return True
+    return False
+
+print(is_y_in(b'hello world'))   # False
+print(is_y_in(b'hello Cython'))  # True
diff --git a/docs/examples/userguide/numpy_tutorial/compute_fused_types.pyx b/docs/examples/userguide/numpy_tutorial/compute_fused_types.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbnVtcHlfdHV0b3JpYWwvY29tcHV0ZV9mdXNlZF90eXBlcy5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbnVtcHlfdHV0b3JpYWwvY29tcHV0ZV9mdXNlZF90eXBlcy5weXg= 100644
--- a/docs/examples/userguide/numpy_tutorial/compute_fused_types.pyx
+++ b/docs/examples/userguide/numpy_tutorial/compute_fused_types.pyx
@@ -1,44 +1,44 @@
-# cython: infer_types=True
-import numpy as np
-cimport cython
-
-ctypedef fused my_type:
-    int
-    double
-    long long
-
-
-cdef my_type clip(my_type a, my_type min_value, my_type max_value):
-    return min(max(a, min_value), max_value)
-
-
-@cython.boundscheck(False)
-@cython.wraparound(False)
-def compute(my_type[:, ::1] array_1, my_type[:, ::1] array_2, my_type a, my_type b, my_type c):
-     
-    x_max = array_1.shape[0]
-    y_max = array_1.shape[1]
-    
-    assert tuple(array_1.shape) == tuple(array_2.shape)
-
-    if my_type is int:
-        dtype = np.intc
-    elif my_type is double:
-        dtype = np.double
-    elif my_type is cython.longlong:
-        dtype = np.longlong
-
-    result = np.zeros((x_max, y_max), dtype=dtype)
-    cdef my_type[:, ::1] result_view = result
-
-    cdef my_type tmp
-    cdef Py_ssize_t x, y
-
-    for x in range(x_max):
-        for y in range(y_max):
-
-            tmp = clip(array_1[x, y], 2, 10)
-            tmp = tmp * a + array_2[x, y] * b
-            result_view[x, y] = tmp + c
-
-    return result
+# cython: infer_types=True
+import numpy as np
+cimport cython
+
+ctypedef fused my_type:
+    int
+    double
+    long long
+
+
+cdef my_type clip(my_type a, my_type min_value, my_type max_value):
+    return min(max(a, min_value), max_value)
+
+
+@cython.boundscheck(False)
+@cython.wraparound(False)
+def compute(my_type[:, ::1] array_1, my_type[:, ::1] array_2, my_type a, my_type b, my_type c):
+
+    x_max = array_1.shape[0]
+    y_max = array_1.shape[1]
+
+    assert tuple(array_1.shape) == tuple(array_2.shape)
+
+    if my_type is int:
+        dtype = np.intc
+    elif my_type is double:
+        dtype = np.double
+    elif my_type is cython.longlong:
+        dtype = np.longlong
+
+    result = np.zeros((x_max, y_max), dtype=dtype)
+    cdef my_type[:, ::1] result_view = result
+
+    cdef my_type tmp
+    cdef Py_ssize_t x, y
+
+    for x in range(x_max):
+        for y in range(y_max):
+
+            tmp = clip(array_1[x, y], 2, 10)
+            tmp = tmp * a + array_2[x, y] * b
+            result_view[x, y] = tmp + c
+
+    return result
diff --git a/docs/examples/userguide/numpy_tutorial/compute_infer_types.pyx b/docs/examples/userguide/numpy_tutorial/compute_infer_types.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbnVtcHlfdHV0b3JpYWwvY29tcHV0ZV9pbmZlcl90eXBlcy5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbnVtcHlfdHV0b3JpYWwvY29tcHV0ZV9pbmZlcl90eXBlcy5weXg= 100644
--- a/docs/examples/userguide/numpy_tutorial/compute_infer_types.pyx
+++ b/docs/examples/userguide/numpy_tutorial/compute_infer_types.pyx
@@ -1,34 +1,34 @@
-# cython: infer_types=True
-import numpy as np
-cimport cython
-
-DTYPE = np.intc
-
-
-cdef int clip(int a, int min_value, int max_value):
-    return min(max(a, min_value), max_value)
-
-
-@cython.boundscheck(False)
-@cython.wraparound(False)
-def compute(int[:, ::1] array_1, int[:, ::1] array_2, int a, int b, int c):
-     
-    x_max = array_1.shape[0]
-    y_max = array_1.shape[1]
-    
-    assert tuple(array_1.shape) == tuple(array_2.shape)
-
-    result = np.zeros((x_max, y_max), dtype=DTYPE)
-    cdef int[:, ::1] result_view = result
-
-    cdef int tmp
-    cdef Py_ssize_t x, y
-
-    for x in range(x_max):
-        for y in range(y_max):
-
-            tmp = clip(array_1[x, y], 2, 10)
-            tmp = tmp * a + array_2[x, y] * b
-            result_view[x, y] = tmp + c
-
-    return result
+# cython: infer_types=True
+import numpy as np
+cimport cython
+
+DTYPE = np.intc
+
+
+cdef int clip(int a, int min_value, int max_value):
+    return min(max(a, min_value), max_value)
+
+
+@cython.boundscheck(False)
+@cython.wraparound(False)
+def compute(int[:, ::1] array_1, int[:, ::1] array_2, int a, int b, int c):
+
+    x_max = array_1.shape[0]
+    y_max = array_1.shape[1]
+
+    assert tuple(array_1.shape) == tuple(array_2.shape)
+
+    result = np.zeros((x_max, y_max), dtype=DTYPE)
+    cdef int[:, ::1] result_view = result
+
+    cdef int tmp
+    cdef Py_ssize_t x, y
+
+    for x in range(x_max):
+        for y in range(y_max):
+
+            tmp = clip(array_1[x, y], 2, 10)
+            tmp = tmp * a + array_2[x, y] * b
+            result_view[x, y] = tmp + c
+
+    return result
diff --git a/docs/examples/userguide/numpy_tutorial/compute_memview.pyx b/docs/examples/userguide/numpy_tutorial/compute_memview.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbnVtcHlfdHV0b3JpYWwvY29tcHV0ZV9tZW12aWV3LnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbnVtcHlfdHV0b3JpYWwvY29tcHV0ZV9tZW12aWV3LnB5eA== 100644
--- a/docs/examples/userguide/numpy_tutorial/compute_memview.pyx
+++ b/docs/examples/userguide/numpy_tutorial/compute_memview.pyx
@@ -1,34 +1,34 @@
-import numpy as np
-
-DTYPE = np.intc
-
-
-cdef int clip(int a, int min_value, int max_value):
-    return min(max(a, min_value), max_value)
-
-
-def compute(int[:, :] array_1, int[:, :] array_2, int a, int b, int c):
-     
-    cdef Py_ssize_t x_max = array_1.shape[0]
-    cdef Py_ssize_t y_max = array_1.shape[1]
-
-    # array_1.shape is now a C array, no it's not possible
-    # to compare it simply by using == without a for-loop.
-    # To be able to compare it to array_2.shape easily,
-    # we convert them both to Python tuples.
-    assert tuple(array_1.shape) == tuple(array_2.shape)
-
-    result = np.zeros((x_max, y_max), dtype=DTYPE)
-    cdef int[:, :] result_view = result
-
-    cdef int tmp
-    cdef Py_ssize_t x, y
-
-    for x in range(x_max):
-        for y in range(y_max):
-
-            tmp = clip(array_1[x, y], 2, 10)
-            tmp = tmp * a + array_2[x, y] * b
-            result_view[x, y] = tmp + c
-
-    return result
+import numpy as np
+
+DTYPE = np.intc
+
+
+cdef int clip(int a, int min_value, int max_value):
+    return min(max(a, min_value), max_value)
+
+
+def compute(int[:, :] array_1, int[:, :] array_2, int a, int b, int c):
+
+    cdef Py_ssize_t x_max = array_1.shape[0]
+    cdef Py_ssize_t y_max = array_1.shape[1]
+
+    # array_1.shape is now a C array, no it's not possible
+    # to compare it simply by using == without a for-loop.
+    # To be able to compare it to array_2.shape easily,
+    # we convert them both to Python tuples.
+    assert tuple(array_1.shape) == tuple(array_2.shape)
+
+    result = np.zeros((x_max, y_max), dtype=DTYPE)
+    cdef int[:, :] result_view = result
+
+    cdef int tmp
+    cdef Py_ssize_t x, y
+
+    for x in range(x_max):
+        for y in range(y_max):
+
+            tmp = clip(array_1[x, y], 2, 10)
+            tmp = tmp * a + array_2[x, y] * b
+            result_view[x, y] = tmp + c
+
+    return result
diff --git a/docs/examples/userguide/numpy_tutorial/compute_prange.pyx b/docs/examples/userguide/numpy_tutorial/compute_prange.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbnVtcHlfdHV0b3JpYWwvY29tcHV0ZV9wcmFuZ2UucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbnVtcHlfdHV0b3JpYWwvY29tcHV0ZV9wcmFuZ2UucHl4 100644
--- a/docs/examples/userguide/numpy_tutorial/compute_prange.pyx
+++ b/docs/examples/userguide/numpy_tutorial/compute_prange.pyx
@@ -1,53 +1,53 @@
-# tag: openmp
-# You can ignore the previous line.
-# It's for internal testing of the cython documentation.
-
-# distutils: extra_compile_args=-fopenmp
-# distutils: extra_link_args=-fopenmp
-
-import numpy as np
-cimport cython
-from cython.parallel import prange
-
-ctypedef fused my_type:
-    int
-    double
-    long long
-
-
-# We declare our plain c function nogil
-cdef my_type clip(my_type a, my_type min_value, my_type max_value) nogil:
-    return min(max(a, min_value), max_value)
-
-
-@cython.boundscheck(False)
-@cython.wraparound(False)
-def compute(my_type[:, ::1] array_1, my_type[:, ::1] array_2, my_type a, my_type b, my_type c):
-
-    cdef Py_ssize_t x_max = array_1.shape[0]
-    cdef Py_ssize_t y_max = array_1.shape[1]
-
-    assert tuple(array_1.shape) == tuple(array_2.shape)
-
-    if my_type is int:
-        dtype = np.intc
-    elif my_type is double:
-        dtype = np.double
-    elif my_type is cython.longlong:
-        dtype = np.longlong
-
-    result = np.zeros((x_max, y_max), dtype=dtype)
-    cdef my_type[:, ::1] result_view = result
-
-    cdef my_type tmp
-    cdef Py_ssize_t x, y
-
-    # We use prange here.
-    for x in prange(x_max, nogil=True):
-        for y in range(y_max):
-
-            tmp = clip(array_1[x, y], 2, 10)
-            tmp = tmp * a + array_2[x, y] * b
-            result_view[x, y] = tmp + c
-
-    return result
+# tag: openmp
+# You can ignore the previous line.
+# It's for internal testing of the cython documentation.
+
+# distutils: extra_compile_args=-fopenmp
+# distutils: extra_link_args=-fopenmp
+
+import numpy as np
+cimport cython
+from cython.parallel import prange
+
+ctypedef fused my_type:
+    int
+    double
+    long long
+
+
+# We declare our plain c function nogil
+cdef my_type clip(my_type a, my_type min_value, my_type max_value) nogil:
+    return min(max(a, min_value), max_value)
+
+
+@cython.boundscheck(False)
+@cython.wraparound(False)
+def compute(my_type[:, ::1] array_1, my_type[:, ::1] array_2, my_type a, my_type b, my_type c):
+
+    cdef Py_ssize_t x_max = array_1.shape[0]
+    cdef Py_ssize_t y_max = array_1.shape[1]
+
+    assert tuple(array_1.shape) == tuple(array_2.shape)
+
+    if my_type is int:
+        dtype = np.intc
+    elif my_type is double:
+        dtype = np.double
+    elif my_type is cython.longlong:
+        dtype = np.longlong
+
+    result = np.zeros((x_max, y_max), dtype=dtype)
+    cdef my_type[:, ::1] result_view = result
+
+    cdef my_type tmp
+    cdef Py_ssize_t x, y
+
+    # We use prange here.
+    for x in prange(x_max, nogil=True):
+        for y in range(y_max):
+
+            tmp = clip(array_1[x, y], 2, 10)
+            tmp = tmp * a + array_2[x, y] * b
+            result_view[x, y] = tmp + c
+
+    return result
diff --git a/docs/examples/userguide/numpy_tutorial/compute_py.py b/docs/examples/userguide/numpy_tutorial/compute_py.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbnVtcHlfdHV0b3JpYWwvY29tcHV0ZV9weS5weQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbnVtcHlfdHV0b3JpYWwvY29tcHV0ZV9weS5weQ== 100644
--- a/docs/examples/userguide/numpy_tutorial/compute_py.py
+++ b/docs/examples/userguide/numpy_tutorial/compute_py.py
@@ -1,28 +1,28 @@
-import numpy as np
-
-
-def clip(a, min_value, max_value):
-    return min(max(a, min_value), max_value)
-
-
-def compute(array_1, array_2, a, b, c):
-    """
-    This function must implement the formula
-    np.clip(array_1, 2, 10) * a + array_2 * b + c
-
-    array_1 and array_2 are 2D.
-    """
-    x_max = array_1.shape[0]
-    y_max = array_1.shape[1]
-
-    assert array_1.shape == array_2.shape
-
-    result = np.zeros((x_max, y_max), dtype=array_1.dtype)
-
-    for x in range(x_max):
-        for y in range(y_max):
-            tmp = clip(array_1[x, y], 2, 10)
-            tmp = tmp * a + array_2[x, y] * b
-            result[x, y] = tmp + c
-
-    return result
+import numpy as np
+
+
+def clip(a, min_value, max_value):
+    return min(max(a, min_value), max_value)
+
+
+def compute(array_1, array_2, a, b, c):
+    """
+    This function must implement the formula
+    np.clip(array_1, 2, 10) * a + array_2 * b + c
+
+    array_1 and array_2 are 2D.
+    """
+    x_max = array_1.shape[0]
+    y_max = array_1.shape[1]
+
+    assert array_1.shape == array_2.shape
+
+    result = np.zeros((x_max, y_max), dtype=array_1.dtype)
+
+    for x in range(x_max):
+        for y in range(y_max):
+            tmp = clip(array_1[x, y], 2, 10)
+            tmp = tmp * a + array_2[x, y] * b
+            result[x, y] = tmp + c
+
+    return result
diff --git a/docs/examples/userguide/numpy_tutorial/compute_typed.pyx b/docs/examples/userguide/numpy_tutorial/compute_typed.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbnVtcHlfdHV0b3JpYWwvY29tcHV0ZV90eXBlZC5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvbnVtcHlfdHV0b3JpYWwvY29tcHV0ZV90eXBlZC5weXg= 100644
--- a/docs/examples/userguide/numpy_tutorial/compute_typed.pyx
+++ b/docs/examples/userguide/numpy_tutorial/compute_typed.pyx
@@ -1,50 +1,50 @@
-import numpy as np
-
-# We now need to fix a datatype for our arrays. I've used the variable
-# DTYPE for this, which is assigned to the usual NumPy runtime
-# type info object.
-DTYPE = np.intc
-
-# cdef means here that this function is a plain C function (so faster).
-# To get all the benefits, we type the arguments and the return value.
-cdef int clip(int a, int min_value, int max_value):
-    return min(max(a, min_value), max_value)
-
-
-def compute(array_1, array_2, int a, int b, int c):
-    
-    # The "cdef" keyword is also used within functions to type variables. It
-    # can only be used at the top indentation level (there are non-trivial
-    # problems with allowing them in other places, though we'd love to see
-    # good and thought out proposals for it).
-    cdef Py_ssize_t x_max = array_1.shape[0]
-    cdef Py_ssize_t y_max = array_1.shape[1]
-    
-    assert array_1.shape == array_2.shape
-    assert array_1.dtype == DTYPE
-    assert array_2.dtype == DTYPE
-
-    result = np.zeros((x_max, y_max), dtype=DTYPE)
-    
-    # It is very important to type ALL your variables. You do not get any
-    # warnings if not, only much slower code (they are implicitly typed as
-    # Python objects).
-    # For the "tmp" variable, we want to use the same data type as is
-    # stored in the array, so we use int because it correspond to np.intc.
-    # NB! An important side-effect of this is that if "tmp" overflows its
-    # datatype size, it will simply wrap around like in C, rather than raise
-    # an error like in Python.
-
-    cdef int tmp
-
-    # Py_ssize_t is the proper C type for Python array indices.
-    cdef Py_ssize_t x, y
-
-    for x in range(x_max):
-        for y in range(y_max):
-
-            tmp = clip(array_1[x, y], 2, 10)
-            tmp = tmp * a + array_2[x, y] * b
-            result[x, y] = tmp + c
-
-    return result
+import numpy as np
+
+# We now need to fix a datatype for our arrays. I've used the variable
+# DTYPE for this, which is assigned to the usual NumPy runtime
+# type info object.
+DTYPE = np.intc
+
+# cdef means here that this function is a plain C function (so faster).
+# To get all the benefits, we type the arguments and the return value.
+cdef int clip(int a, int min_value, int max_value):
+    return min(max(a, min_value), max_value)
+
+
+def compute(array_1, array_2, int a, int b, int c):
+
+    # The "cdef" keyword is also used within functions to type variables. It
+    # can only be used at the top indentation level (there are non-trivial
+    # problems with allowing them in other places, though we'd love to see
+    # good and thought out proposals for it).
+    cdef Py_ssize_t x_max = array_1.shape[0]
+    cdef Py_ssize_t y_max = array_1.shape[1]
+
+    assert array_1.shape == array_2.shape
+    assert array_1.dtype == DTYPE
+    assert array_2.dtype == DTYPE
+
+    result = np.zeros((x_max, y_max), dtype=DTYPE)
+
+    # It is very important to type ALL your variables. You do not get any
+    # warnings if not, only much slower code (they are implicitly typed as
+    # Python objects).
+    # For the "tmp" variable, we want to use the same data type as is
+    # stored in the array, so we use int because it correspond to np.intc.
+    # NB! An important side-effect of this is that if "tmp" overflows its
+    # datatype size, it will simply wrap around like in C, rather than raise
+    # an error like in Python.
+
+    cdef int tmp
+
+    # Py_ssize_t is the proper C type for Python array indices.
+    cdef Py_ssize_t x, y
+
+    for x in range(x_max):
+        for y in range(y_max):
+
+            tmp = clip(array_1[x, y], 2, 10)
+            tmp = tmp * a + array_2[x, y] * b
+            result[x, y] = tmp + c
+
+    return result
diff --git a/docs/examples/userguide/parallelism/breaking_loop.pyx b/docs/examples/userguide/parallelism/breaking_loop.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvcGFyYWxsZWxpc20vYnJlYWtpbmdfbG9vcC5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvcGFyYWxsZWxpc20vYnJlYWtpbmdfbG9vcC5weXg= 100644
--- a/docs/examples/userguide/parallelism/breaking_loop.pyx
+++ b/docs/examples/userguide/parallelism/breaking_loop.pyx
@@ -1,13 +1,13 @@
-from cython.parallel import prange
-
-cdef int func(Py_ssize_t n):
-    cdef Py_ssize_t i
-
-    for i in prange(n, nogil=True):
-        if i == 8:
-            with gil:
-                raise Exception()
-        elif i == 4:
-            break
-        elif i == 2:
-            return i
+from cython.parallel import prange
+
+cdef int func(Py_ssize_t n):
+    cdef Py_ssize_t i
+
+    for i in prange(n, nogil=True):
+        if i == 8:
+            with gil:
+                raise Exception()
+        elif i == 4:
+            break
+        elif i == 2:
+            return i
diff --git a/docs/examples/userguide/parallelism/cimport_openmp.pyx b/docs/examples/userguide/parallelism/cimport_openmp.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvcGFyYWxsZWxpc20vY2ltcG9ydF9vcGVubXAucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvcGFyYWxsZWxpc20vY2ltcG9ydF9vcGVubXAucHl4 100644
--- a/docs/examples/userguide/parallelism/cimport_openmp.pyx
+++ b/docs/examples/userguide/parallelism/cimport_openmp.pyx
@@ -1,13 +1,13 @@
-# tag: openmp
-# You can ignore the previous line.
-# It's for internal testing of the Cython documentation.
-
-from cython.parallel cimport parallel
-cimport openmp
-
-cdef int num_threads
-
-openmp.omp_set_dynamic(1)
-with nogil, parallel():
-    num_threads = openmp.omp_get_num_threads()
-    # ...
+# tag: openmp
+# You can ignore the previous line.
+# It's for internal testing of the Cython documentation.
+
+from cython.parallel cimport parallel
+cimport openmp
+
+cdef int num_threads
+
+openmp.omp_set_dynamic(1)
+with nogil, parallel():
+    num_threads = openmp.omp_get_num_threads()
+    # ...
diff --git a/docs/examples/userguide/parallelism/setup.py b/docs/examples/userguide/parallelism/setup.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvcGFyYWxsZWxpc20vc2V0dXAucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvcGFyYWxsZWxpc20vc2V0dXAucHk= 100644
--- a/docs/examples/userguide/parallelism/setup.py
+++ b/docs/examples/userguide/parallelism/setup.py
@@ -1,17 +1,16 @@
-from distutils.core import setup
-from distutils.extension import Extension
-from Cython.Build import cythonize
-
-ext_modules = [
-    Extension(
-        "hello",
-        ["hello.pyx"],
-        extra_compile_args=['-fopenmp'],
-        extra_link_args=['-fopenmp'],
-    )
-]
-
-setup(
-    name='hello-parallel-world',
-    ext_modules=cythonize(ext_modules),
-)
+from setuptools import Extension, setup
+from Cython.Build import cythonize
+
+ext_modules = [
+    Extension(
+        "hello",
+        ["hello.pyx"],
+        extra_compile_args=['-fopenmp'],
+        extra_link_args=['-fopenmp'],
+    )
+]
+
+setup(
+    name='hello-parallel-world',
+    ext_modules=cythonize(ext_modules),
+)
diff --git a/docs/examples/userguide/parallelism/simple_sum.pyx b/docs/examples/userguide/parallelism/simple_sum.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvcGFyYWxsZWxpc20vc2ltcGxlX3N1bS5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvcGFyYWxsZWxpc20vc2ltcGxlX3N1bS5weXg= 100644
--- a/docs/examples/userguide/parallelism/simple_sum.pyx
+++ b/docs/examples/userguide/parallelism/simple_sum.pyx
@@ -1,10 +1,10 @@
-from cython.parallel import prange
-
-cdef int i
-cdef int n = 30
-cdef int sum = 0
-
-for i in prange(n, nogil=True):
-    sum += i
-
-print(sum)
+from cython.parallel import prange
+
+cdef int i
+cdef int n = 30
+cdef int sum = 0
+
+for i in prange(n, nogil=True):
+    sum += i
+
+print(sum)
diff --git a/docs/examples/userguide/sharing_declarations/landscaping.pyx b/docs/examples/userguide/sharing_declarations/landscaping.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvc2hhcmluZ19kZWNsYXJhdGlvbnMvbGFuZHNjYXBpbmcucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvc2hhcmluZ19kZWNsYXJhdGlvbnMvbGFuZHNjYXBpbmcucHl4 100644
--- a/docs/examples/userguide/sharing_declarations/landscaping.pyx
+++ b/docs/examples/userguide/sharing_declarations/landscaping.pyx
@@ -1,7 +1,7 @@
-cimport shrubbing
-import shrubbing
-
-def main():
-    cdef shrubbing.Shrubbery sh
-    sh = shrubbing.standard_shrubbery()
-    print("Shrubbery size is", sh.width, 'x', sh.length)
+cimport shrubbing
+import shrubbing
+
+def main():
+    cdef shrubbing.Shrubbery sh
+    sh = shrubbing.standard_shrubbery()
+    print("Shrubbery size is", sh.width, 'x', sh.length)
diff --git a/docs/examples/userguide/sharing_declarations/lunch.pyx b/docs/examples/userguide/sharing_declarations/lunch.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvc2hhcmluZ19kZWNsYXJhdGlvbnMvbHVuY2gucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvc2hhcmluZ19kZWNsYXJhdGlvbnMvbHVuY2gucHl4 100644
--- a/docs/examples/userguide/sharing_declarations/lunch.pyx
+++ b/docs/examples/userguide/sharing_declarations/lunch.pyx
@@ -1,4 +1,4 @@
-cimport c_lunch
-
-def eject_tomato(float speed):
-    c_lunch.eject_tomato(speed)
+cimport c_lunch
+
+def eject_tomato(float speed):
+    c_lunch.eject_tomato(speed)
diff --git a/docs/examples/userguide/sharing_declarations/restaurant.pyx b/docs/examples/userguide/sharing_declarations/restaurant.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvc2hhcmluZ19kZWNsYXJhdGlvbnMvcmVzdGF1cmFudC5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvc2hhcmluZ19kZWNsYXJhdGlvbnMvcmVzdGF1cmFudC5weXg= 100644
--- a/docs/examples/userguide/sharing_declarations/restaurant.pyx
+++ b/docs/examples/userguide/sharing_declarations/restaurant.pyx
@@ -1,12 +1,12 @@
-from __future__ import print_function
-cimport dishes
-from dishes cimport spamdish
-
-cdef void prepare(spamdish *d):
-    d.oz_of_spam = 42
-    d.filler = dishes.sausage
-
-def serve():
-    cdef spamdish d
-    prepare(&d)
-    print(f'{d.oz_of_spam} oz spam, filler no. {d.filler}')
+from __future__ import print_function
+cimport dishes
+from dishes cimport spamdish
+
+cdef void prepare(spamdish *d):
+    d.oz_of_spam = 42
+    d.filler = dishes.sausage
+
+def serve():
+    cdef spamdish d
+    prepare(&d)
+    print(f'{d.oz_of_spam} oz spam, filler no. {d.filler}')
diff --git a/docs/examples/userguide/sharing_declarations/setup.py b/docs/examples/userguide/sharing_declarations/setup.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvc2hhcmluZ19kZWNsYXJhdGlvbnMvc2V0dXAucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvc2hhcmluZ19kZWNsYXJhdGlvbnMvc2V0dXAucHk= 100644
--- a/docs/examples/userguide/sharing_declarations/setup.py
+++ b/docs/examples/userguide/sharing_declarations/setup.py
@@ -1,4 +1,4 @@
-from distutils.core import setup
-from Cython.Build import cythonize
-
-setup(ext_modules=cythonize(["landscaping.pyx", "shrubbing.pyx"]))
+from setuptools import setup
+from Cython.Build import cythonize
+
+setup(ext_modules=cythonize(["landscaping.pyx", "shrubbing.pyx"]))
diff --git a/docs/examples/userguide/sharing_declarations/shrubbing.pyx b/docs/examples/userguide/sharing_declarations/shrubbing.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvc2hhcmluZ19kZWNsYXJhdGlvbnMvc2hydWJiaW5nLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvc2hhcmluZ19kZWNsYXJhdGlvbnMvc2hydWJiaW5nLnB5eA== 100644
--- a/docs/examples/userguide/sharing_declarations/shrubbing.pyx
+++ b/docs/examples/userguide/sharing_declarations/shrubbing.pyx
@@ -1,7 +1,7 @@
-cdef class Shrubbery:
-    def __cinit__(self, int w, int l):
-        self.width = w
-        self.length = l
-
-def standard_shrubbery():
-    return Shrubbery(3, 7)
+cdef class Shrubbery:
+    def __cinit__(self, int w, int l):
+        self.width = w
+        self.length = l
+
+def standard_shrubbery():
+    return Shrubbery(3, 7)
diff --git a/docs/examples/userguide/sharing_declarations/spammery.pyx b/docs/examples/userguide/sharing_declarations/spammery.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvc2hhcmluZ19kZWNsYXJhdGlvbnMvc3BhbW1lcnkucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvc2hhcmluZ19kZWNsYXJhdGlvbnMvc3BhbW1lcnkucHl4 100644
--- a/docs/examples/userguide/sharing_declarations/spammery.pyx
+++ b/docs/examples/userguide/sharing_declarations/spammery.pyx
@@ -1,11 +1,11 @@
-from __future__ import print_function
-
-from volume cimport cube
-
-def menu(description, size):
-    print(description, ":", cube(size),
-          "cubic metres of spam")
-
-menu("Entree", 1)
-menu("Main course", 3)
-menu("Dessert", 2)
+from __future__ import print_function
+
+from volume cimport cube
+
+def menu(description, size):
+    print(description, ":", cube(size),
+          "cubic metres of spam")
+
+menu("Entree", 1)
+menu("Main course", 3)
+menu("Dessert", 2)
diff --git a/docs/examples/userguide/sharing_declarations/volume.pyx b/docs/examples/userguide/sharing_declarations/volume.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvc2hhcmluZ19kZWNsYXJhdGlvbnMvdm9sdW1lLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvc2hhcmluZ19kZWNsYXJhdGlvbnMvdm9sdW1lLnB5eA== 100644
--- a/docs/examples/userguide/sharing_declarations/volume.pyx
+++ b/docs/examples/userguide/sharing_declarations/volume.pyx
@@ -1,2 +1,2 @@
-cdef float cube(float x):
-    return x * x * x
+cdef float cube(float x):
+    return x * x * x
diff --git a/docs/examples/userguide/wrapping_CPlusPlus/Rectangle.pxd b/docs/examples/userguide/wrapping_CPlusPlus/Rectangle.pxd
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvd3JhcHBpbmdfQ1BsdXNQbHVzL1JlY3RhbmdsZS5weGQ=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvd3JhcHBpbmdfQ1BsdXNQbHVzL1JlY3RhbmdsZS5weGQ= 100644
--- a/docs/examples/userguide/wrapping_CPlusPlus/Rectangle.pxd
+++ b/docs/examples/userguide/wrapping_CPlusPlus/Rectangle.pxd
@@ -1,7 +1,7 @@
 cdef extern from "Rectangle.cpp":
     pass
 
-# Decalre the class with cdef
+# Declare the class with cdef
 cdef extern from "Rectangle.h" namespace "shapes":
     cdef cppclass Rectangle:
         Rectangle() except +
diff --git a/docs/examples/userguide/wrapping_CPlusPlus/cython_usage.pyx b/docs/examples/userguide/wrapping_CPlusPlus/cython_usage.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvd3JhcHBpbmdfQ1BsdXNQbHVzL2N5dGhvbl91c2FnZS5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvd3JhcHBpbmdfQ1BsdXNQbHVzL2N5dGhvbl91c2FnZS5weXg= 100644
--- a/docs/examples/userguide/wrapping_CPlusPlus/cython_usage.pyx
+++ b/docs/examples/userguide/wrapping_CPlusPlus/cython_usage.pyx
@@ -1,12 +1,12 @@
-# distutils: language = c++
-
-from Rectangle cimport Rectangle
-
-def main():
-    rec_ptr = new Rectangle(1, 2, 3, 4)  # Instantiate a Rectangle object on the heap
-    try:
-        rec_area = rec_ptr.getArea()
-    finally:
-        del rec_ptr  # delete heap allocated object
-
-    cdef Rectangle rec_stack  # Instantiate a Rectangle object on the stack
+# distutils: language = c++
+
+from Rectangle cimport Rectangle
+
+def main():
+    rec_ptr = new Rectangle(1, 2, 3, 4)  # Instantiate a Rectangle object on the heap
+    try:
+        rec_area = rec_ptr.getArea()
+    finally:
+        del rec_ptr  # delete heap allocated object
+
+    cdef Rectangle rec_stack  # Instantiate a Rectangle object on the stack
diff --git a/docs/examples/userguide/wrapping_CPlusPlus/function_templates.pyx b/docs/examples/userguide/wrapping_CPlusPlus/function_templates.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvd3JhcHBpbmdfQ1BsdXNQbHVzL2Z1bmN0aW9uX3RlbXBsYXRlcy5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvd3JhcHBpbmdfQ1BsdXNQbHVzL2Z1bmN0aW9uX3RlbXBsYXRlcy5weXg= 100644
--- a/docs/examples/userguide/wrapping_CPlusPlus/function_templates.pyx
+++ b/docs/examples/userguide/wrapping_CPlusPlus/function_templates.pyx
@@ -1,7 +1,7 @@
-# distutils: language = c++
-
-cdef extern from "<algorithm>" namespace "std":
-    T max[T](T a, T b)
-
-print(max[long](3, 4))
-print(max(1.5, 2.5))  # simple template argument deduction
+# distutils: language = c++
+
+cdef extern from "<algorithm>" namespace "std":
+    T max[T](T a, T b)
+
+print(max[long](3, 4))
+print(max(1.5, 2.5))  # simple template argument deduction
diff --git a/docs/examples/userguide/wrapping_CPlusPlus/iterate.pyx b/docs/examples/userguide/wrapping_CPlusPlus/iterate.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvd3JhcHBpbmdfQ1BsdXNQbHVzL2l0ZXJhdGUucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvd3JhcHBpbmdfQ1BsdXNQbHVzL2l0ZXJhdGUucHl4 100644
--- a/docs/examples/userguide/wrapping_CPlusPlus/iterate.pyx
+++ b/docs/examples/userguide/wrapping_CPlusPlus/iterate.pyx
@@ -1,12 +1,12 @@
-# distutils: language = c++
-
-from libcpp.vector cimport vector
-
-def main():
-    cdef vector[int] v = [4, 6, 5, 10, 3]
-
-    cdef int value
-    for value in v:
-        print(value)
-
-    return [x*x for x in v if x % 2 == 0]
+# distutils: language = c++
+
+from libcpp.vector cimport vector
+
+def main():
+    cdef vector[int] v = [4, 6, 5, 10, 3]
+
+    cdef int value
+    for value in v:
+        print(value)
+
+    return [x*x for x in v if x % 2 == 0]
diff --git a/docs/examples/userguide/wrapping_CPlusPlus/nested_class.pyx b/docs/examples/userguide/wrapping_CPlusPlus/nested_class.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvd3JhcHBpbmdfQ1BsdXNQbHVzL25lc3RlZF9jbGFzcy5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvd3JhcHBpbmdfQ1BsdXNQbHVzL25lc3RlZF9jbGFzcy5weXg= 100644
--- a/docs/examples/userguide/wrapping_CPlusPlus/nested_class.pyx
+++ b/docs/examples/userguide/wrapping_CPlusPlus/nested_class.pyx
@@ -1,17 +1,17 @@
-# distutils: language = c++
-
-cdef extern from "<vector>" namespace "std":
-    cdef cppclass vector[T]:
-        cppclass iterator:
-            T operator*()
-            iterator operator++()
-            bint operator==(iterator)
-            bint operator!=(iterator)
-        vector()
-        void push_back(T&)
-        T& operator[](int)
-        T& at(int)
-        iterator begin()
-        iterator end()
-
-cdef vector[int].iterator iter  #iter is declared as being of type vector<int>::iterator
+# distutils: language = c++
+
+cdef extern from "<vector>" namespace "std":
+    cdef cppclass vector[T]:
+        cppclass iterator:
+            T operator*()
+            iterator operator++()
+            bint operator==(iterator)
+            bint operator!=(iterator)
+        vector()
+        void push_back(T&)
+        T& operator[](int)
+        T& at(int)
+        iterator begin()
+        iterator end()
+
+cdef vector[int].iterator iter  #iter is declared as being of type vector<int>::iterator
diff --git a/docs/examples/userguide/wrapping_CPlusPlus/python_to_cpp.pyx b/docs/examples/userguide/wrapping_CPlusPlus/python_to_cpp.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvd3JhcHBpbmdfQ1BsdXNQbHVzL3B5dGhvbl90b19jcHAucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvd3JhcHBpbmdfQ1BsdXNQbHVzL3B5dGhvbl90b19jcHAucHl4 100644
--- a/docs/examples/userguide/wrapping_CPlusPlus/python_to_cpp.pyx
+++ b/docs/examples/userguide/wrapping_CPlusPlus/python_to_cpp.pyx
@@ -1,19 +1,19 @@
-# distutils: language = c++
-
-from libcpp.string cimport string
-from libcpp.vector cimport vector
-
-py_bytes_object = b'The knights who say ni'
-py_unicode_object = u'Those who hear them seldom live to tell the tale.'
-
-cdef string s = py_bytes_object
-print(s)  # b'The knights who say ni'
-
-cdef string cpp_string = <string> py_unicode_object.encode('utf-8')
-print(cpp_string)  # b'Those who hear them seldom live to tell the tale.'
-
-cdef vector[int] vect = range(1, 10, 2)
-print(vect)  # [1, 3, 5, 7, 9]
-
-cdef vector[string] cpp_strings = b'It is a good shrubbery'.split()
-print(cpp_strings[1])   # b'is'
+# distutils: language = c++
+
+from libcpp.string cimport string
+from libcpp.vector cimport vector
+
+py_bytes_object = b'The knights who say ni'
+py_unicode_object = u'Those who hear them seldom live to tell the tale.'
+
+cdef string s = py_bytes_object
+print(s)  # b'The knights who say ni'
+
+cdef string cpp_string = <string> py_unicode_object.encode('utf-8')
+print(cpp_string)  # b'Those who hear them seldom live to tell the tale.'
+
+cdef vector[int] vect = range(1, 10, 2)
+print(vect)  # [1, 3, 5, 7, 9]
+
+cdef vector[string] cpp_strings = b'It is a good shrubbery'.split()
+print(cpp_strings[1])   # b'is'
diff --git a/docs/examples/userguide/wrapping_CPlusPlus/rect_ptr.pyx b/docs/examples/userguide/wrapping_CPlusPlus/rect_ptr.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvd3JhcHBpbmdfQ1BsdXNQbHVzL3JlY3RfcHRyLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvd3JhcHBpbmdfQ1BsdXNQbHVzL3JlY3RfcHRyLnB5eA== 100644
--- a/docs/examples/userguide/wrapping_CPlusPlus/rect_ptr.pyx
+++ b/docs/examples/userguide/wrapping_CPlusPlus/rect_ptr.pyx
@@ -1,12 +1,12 @@
-# distutils: language = c++
-
-from Rectangle cimport Rectangle
-
-cdef class PyRectangle:
-    cdef Rectangle*c_rect  # hold a pointer to the C++ instance which we're wrapping
-
-    def __cinit__(self, int x0, int y0, int x1, int y1):
-        self.c_rect = new Rectangle(x0, y0, x1, y1)
-
-    def __dealloc__(self):
-        del self.c_rect
+# distutils: language = c++
+
+from Rectangle cimport Rectangle
+
+cdef class PyRectangle:
+    cdef Rectangle*c_rect  # hold a pointer to the C++ instance which we're wrapping
+
+    def __cinit__(self, int x0, int y0, int x1, int y1):
+        self.c_rect = new Rectangle(x0, y0, x1, y1)
+
+    def __dealloc__(self):
+        del self.c_rect
diff --git a/docs/examples/userguide/wrapping_CPlusPlus/setup.py b/docs/examples/userguide/wrapping_CPlusPlus/setup.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvd3JhcHBpbmdfQ1BsdXNQbHVzL3NldHVwLnB5..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvd3JhcHBpbmdfQ1BsdXNQbHVzL3NldHVwLnB5 100644
--- a/docs/examples/userguide/wrapping_CPlusPlus/setup.py
+++ b/docs/examples/userguide/wrapping_CPlusPlus/setup.py
@@ -1,4 +1,4 @@
-from distutils.core import setup
+from setuptools import setup
 
 from Cython.Build import cythonize
 
diff --git a/docs/examples/userguide/wrapping_CPlusPlus/templates.pyx b/docs/examples/userguide/wrapping_CPlusPlus/templates.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvd3JhcHBpbmdfQ1BsdXNQbHVzL3RlbXBsYXRlcy5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvd3JhcHBpbmdfQ1BsdXNQbHVzL3RlbXBsYXRlcy5weXg= 100644
--- a/docs/examples/userguide/wrapping_CPlusPlus/templates.pyx
+++ b/docs/examples/userguide/wrapping_CPlusPlus/templates.pyx
@@ -1,30 +1,30 @@
-# distutils: language = c++
-
-# import dereference and increment operators
-from cython.operator cimport dereference as deref, preincrement as inc
-
-cdef extern from "<vector>" namespace "std":
-    cdef cppclass vector[T]:
-        cppclass iterator:
-            T operator*()
-            iterator operator++()
-            bint operator==(iterator)
-            bint operator!=(iterator)
-        vector()
-        void push_back(T&)
-        T& operator[](int)
-        T& at(int)
-        iterator begin()
-        iterator end()
-
-cdef vector[int] *v = new vector[int]()
-cdef int i
-for i in range(10):
-    v.push_back(i)
-
-cdef vector[int].iterator it = v.begin()
-while it != v.end():
-    print(deref(it))
-    inc(it)
-
-del v
+# distutils: language = c++
+
+# import dereference and increment operators
+from cython.operator cimport dereference as deref, preincrement as inc
+
+cdef extern from "<vector>" namespace "std":
+    cdef cppclass vector[T]:
+        cppclass iterator:
+            T operator*()
+            iterator operator++()
+            bint operator==(iterator)
+            bint operator!=(iterator)
+        vector()
+        void push_back(T&)
+        T& operator[](int)
+        T& at(int)
+        iterator begin()
+        iterator end()
+
+cdef vector[int] *v = new vector[int]()
+cdef int i
+for i in range(10):
+    v.push_back(i)
+
+cdef vector[int].iterator it = v.begin()
+while it != v.end():
+    print(deref(it))
+    inc(it)
+
+del v
diff --git a/docs/examples/userguide/wrapping_CPlusPlus/vector_demo.pyx b/docs/examples/userguide/wrapping_CPlusPlus/vector_demo.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvd3JhcHBpbmdfQ1BsdXNQbHVzL3ZlY3Rvcl9kZW1vLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvd3JhcHBpbmdfQ1BsdXNQbHVzL3ZlY3Rvcl9kZW1vLnB5eA== 100644
--- a/docs/examples/userguide/wrapping_CPlusPlus/vector_demo.pyx
+++ b/docs/examples/userguide/wrapping_CPlusPlus/vector_demo.pyx
@@ -1,15 +1,15 @@
-# distutils: language = c++
-
-from libcpp.vector cimport vector
-
-cdef vector[int] vect
-cdef int i, x
-
-for i in range(10):
-    vect.push_back(i)
-
-for i in range(10):
-    print(vect[i])
-
-for x in vect:
-    print(x)
+# distutils: language = c++
+
+from libcpp.vector cimport vector
+
+cdef vector[int] vect
+cdef int i, x
+
+for i in range(10):
+    vect.push_back(i)
+
+for i in range(10):
+    print(vect[i])
+
+for x in vect:
+    print(x)
diff --git a/docs/examples/userguide/wrapping_CPlusPlus/wrapper_vector.pyx b/docs/examples/userguide/wrapping_CPlusPlus/wrapper_vector.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvd3JhcHBpbmdfQ1BsdXNQbHVzL3dyYXBwZXJfdmVjdG9yLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9leGFtcGxlcy91c2VyZ3VpZGUvd3JhcHBpbmdfQ1BsdXNQbHVzL3dyYXBwZXJfdmVjdG9yLnB5eA== 100644
--- a/docs/examples/userguide/wrapping_CPlusPlus/wrapper_vector.pyx
+++ b/docs/examples/userguide/wrapping_CPlusPlus/wrapper_vector.pyx
@@ -1,17 +1,17 @@
-# distutils: language = c++
-
-from libcpp.vector cimport vector
-
-
-cdef class VectorStack:
-    cdef vector[int] v
-
-    def push(self, x):
-        self.v.push_back(x)
-
-    def pop(self):
-        if self.v.empty():
-            raise IndexError()
-        x = self.v.back()
-        self.v.pop_back()
-        return x
+# distutils: language = c++
+
+from libcpp.vector cimport vector
+
+
+cdef class VectorStack:
+    cdef vector[int] v
+
+    def push(self, x):
+        self.v.push_back(x)
+
+    def pop(self):
+        if self.v.empty():
+            raise IndexError()
+        x = self.v.back()
+        self.v.pop_back()
+        return x
diff --git a/docs/index.rst b/docs/index.rst
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9pbmRleC5yc3Q=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9pbmRleC5yc3Q= 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -2,7 +2,7 @@
 Welcome to Cython's Documentation
 =================================
 
-Also see the `Cython project homepage <http://cython.org/>`_.
+Also see the `Cython project homepage <https://cython.org/>`_.
 
 .. toctree::
    :maxdepth: 2
diff --git a/docs/sphinxext/cython_highlighting.py b/docs/sphinxext/cython_highlighting.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9zcGhpbnhleHQvY3l0aG9uX2hpZ2hsaWdodGluZy5weQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9zcGhpbnhleHQvY3l0aG9uX2hpZ2hsaWdodGluZy5weQ== 100644
--- a/docs/sphinxext/cython_highlighting.py
+++ b/docs/sphinxext/cython_highlighting.py
@@ -14,7 +14,7 @@
 
 class CythonLexer(RegexLexer):
     """
-    For `Cython <http://cython.org>`_ source code.
+    For `Cython <https://cython.org/>`_ source code.
     """
 
     name = 'Cython'
diff --git a/docs/src/quickstart/build.rst b/docs/src/quickstart/build.rst
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9zcmMvcXVpY2tzdGFydC9idWlsZC5yc3Q=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9zcmMvcXVpY2tzdGFydC9idWlsZC5yc3Q= 100644
--- a/docs/src/quickstart/build.rst
+++ b/docs/src/quickstart/build.rst
@@ -8,5 +8,5 @@
  - The ``.c`` file is compiled by a C compiler to
    a ``.so`` file (or ``.pyd`` on Windows) which can be
    ``import``-ed directly into a Python session.
-   Distutils or setuptools take care of this part.
+   `setuptools <https://setuptools.readthedocs.io/>`_ takes care of this part.
    Although Cython can call them for you in certain cases.
@@ -12,8 +12,8 @@
    Although Cython can call them for you in certain cases.
-
-To understand fully the Cython + distutils/setuptools build process,
+   
+To understand fully the Cython + setuptools build process,
 one may want to read more about
 `distributing Python modules <https://docs.python.org/3/distributing/index.html>`_.
 
 There are several ways to build Cython code:
 
@@ -15,7 +15,7 @@
 one may want to read more about
 `distributing Python modules <https://docs.python.org/3/distributing/index.html>`_.
 
 There are several ways to build Cython code:
 
- - Write a distutils/setuptools ``setup.py``. This is the normal and recommended way.
+ - Write a setuptools ``setup.py``. This is the normal and recommended way.
  - Use :ref:`Pyximport<pyximport>`, importing Cython ``.pyx`` files as if they
@@ -21,5 +21,5 @@
  - Use :ref:`Pyximport<pyximport>`, importing Cython ``.pyx`` files as if they
-   were ``.py`` files (using distutils to compile and build in the background).
+   were ``.py`` files (using setuptools to compile and build in the background).
    This method is easier than writing a ``setup.py``, but is not very flexible.
    So you'll need to write a ``setup.py`` if, for example, you need certain compilations options.
  - Run the ``cython`` command-line utility manually to produce the ``.c`` file
@@ -30,7 +30,7 @@
    both of which allow Cython code inline.
    This is the easiest way to get started writing Cython code and running it.
 
-Currently, using distutils or setuptools is the most common way Cython files are built and distributed.
+Currently, using setuptools is the most common way Cython files are built and distributed.
 The other methods are described in more detail in the :ref:`compilation` section of the reference manual.
 
 
@@ -34,8 +34,8 @@
 The other methods are described in more detail in the :ref:`compilation` section of the reference manual.
 
 
-Building a Cython module using distutils
-----------------------------------------
+Building a Cython module using setuptools
+-----------------------------------------
 
 Imagine a simple "hello world" script in a file ``hello.pyx``:
 
@@ -49,11 +49,10 @@
 start a Python session and do ``from hello import say_hello_to`` and
 use the imported function as you see fit.
 
-One caveat if you use setuptools instead of distutils, the default
-action when running ``python setup.py install`` is to create a zipped
-``egg`` file which will not work with ``cimport`` for ``pxd`` files
-when you try to use them from a dependent package.
-To prevent this, include ``zip_safe=False`` in the arguments to ``setup()``.
+One caveat: the default action when running ``python setup.py install`` is to
+create a zipped ``egg`` file which will not work with ``cimport`` for ``pxd``
+files when you try to use them from a dependent package.  To prevent this,
+include ``zip_safe=False`` in the arguments to ``setup()``.
 
 .. _jupyter-notebook:
 
@@ -104,5 +103,6 @@
   functions defined in a Cython cell imported into the running session.
 
 
-.. [Jupyter] http://jupyter.org/
-.. [Sage] W. Stein et al., Sage Mathematics Software, http://www.sagemath.org/
+.. [Jupyter] https://jupyter.org/
+..
+   [Sage] W. Stein et al., Sage Mathematics Software, https://www.sagemath.org/
diff --git a/docs/src/quickstart/htmlreport.png b/docs/src/quickstart/htmlreport.png
index cc30cec9fd2c812082521886aee7190d64b99009..0fc5e7bbeeef8ba5f1e5bcef4a95b32fbbac49c9
GIT binary patch
literal 19181
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

diff --git a/docs/src/quickstart/install.rst b/docs/src/quickstart/install.rst
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9zcmMvcXVpY2tzdGFydC9pbnN0YWxsLnJzdA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9zcmMvcXVpY2tzdGFydC9pbnN0YWxsLnJzdA== 100644
--- a/docs/src/quickstart/install.rst
+++ b/docs/src/quickstart/install.rst
@@ -7,9 +7,7 @@
 Enthought Canopy [Canopy]_, and Sage [Sage]_,
 bundle Cython and no setup is needed.  Note however that if your
 distribution ships a version of Cython which is too old you can still
-use the instructions below to update Cython.  Everything in this
-tutorial should work with Cython 0.11.2 and newer, unless a footnote
-says otherwise.
+use the instructions below to update Cython.
 
 Unlike most Python software, Cython requires a C compiler to be
 present on the system. The details of getting a C compiler varies
@@ -41,7 +39,7 @@
 
 
 The newest Cython release can always be downloaded from
-http://cython.org.  Unpack the tarball or zip file, enter the
+https://cython.org/.  Unpack the tarball or zip file, enter the
 directory, and then run::
 
   python setup.py install
@@ -59,4 +57,4 @@
 
 .. [Anaconda] https://docs.anaconda.com/anaconda/
 .. [Canopy] https://www.enthought.com/product/canopy/
-.. [Sage] W. Stein et al., Sage Mathematics Software, http://www.sagemath.org/
+.. [Sage] W. Stein et al., Sage Mathematics Software, https://www.sagemath.org/
diff --git a/docs/src/quickstart/jupyter.png b/docs/src/quickstart/jupyter.png
index 84b3543adb28b9911d56f31da7efb5a0a7904d9d..34b38df6dc20102ac5e2c0ddc44135fbd5e633a7
GIT binary patch
literal 59558
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
WGArLN8@}PS-Mn#IvsB|=_<sPr^!<(i

diff --git a/docs/src/quickstart/overview.rst b/docs/src/quickstart/overview.rst
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9zcmMvcXVpY2tzdGFydC9vdmVydmlldy5yc3Q=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9zcmMvcXVpY2tzdGFydC9vdmVydmlldy5yc3Q= 100644
--- a/docs/src/quickstart/overview.rst
+++ b/docs/src/quickstart/overview.rst
@@ -1,7 +1,7 @@
 Cython - an overview
 ====================
 
-[Cython] is a programming language that makes writing C extensions
+[Cython]_ is a programming language that makes writing C extensions
 for the Python language as easy as Python itself.  It aims to become
 a superset of the [Python]_ language which gives it high-level,
 object-oriented, functional, and dynamic programming.  Its main feature
@@ -44,8 +44,8 @@
 language.
 
 .. [Cython] G. Ewing, R. W. Bradshaw, S. Behnel, D. S. Seljebotn et al.,
-   The Cython compiler, http://cython.org.
+   The Cython compiler, https://cython.org/.
 .. [IronPython] Jim Hugunin et al., https://archive.codeplex.com/?p=IronPython.
 .. [Jython] J. Huginin, B. Warsaw, F. Bock, et al.,
    Jython: Python for the Java platform, http://www.jython.org.
 .. [PyPy] The PyPy Group, PyPy: a Python implementation written in Python,
@@ -48,6 +48,6 @@
 .. [IronPython] Jim Hugunin et al., https://archive.codeplex.com/?p=IronPython.
 .. [Jython] J. Huginin, B. Warsaw, F. Bock, et al.,
    Jython: Python for the Java platform, http://www.jython.org.
 .. [PyPy] The PyPy Group, PyPy: a Python implementation written in Python,
-   http://pypy.org.
+   https://pypy.org/.
 .. [Pyrex] G. Ewing, Pyrex: C-Extensions for Python,
@@ -53,4 +53,4 @@
 .. [Pyrex] G. Ewing, Pyrex: C-Extensions for Python,
-   http://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/
+   https://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/
 .. [Python] G. van Rossum et al., The Python programming language,
    https://www.python.org/.
diff --git a/docs/src/tutorial/appendix.rst b/docs/src/tutorial/appendix.rst
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9zcmMvdHV0b3JpYWwvYXBwZW5kaXgucnN0..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9zcmMvdHV0b3JpYWwvYXBwZW5kaXgucnN0 100644
--- a/docs/src/tutorial/appendix.rst
+++ b/docs/src/tutorial/appendix.rst
@@ -28,4 +28,65 @@
 process smoother is welcomed; it is an unfortunate fact that none of
 the regular Cython developers have convenient access to Windows.
 
+Python 3.8+
+-----------
+
+Since Python 3.8, the search paths of DLL dependencies has been reset.
+(`changelog <https://docs.python.org/3/whatsnew/3.8.html#changes-in-the-python-api>`_)
+
+Only the system paths, the directory containing the DLL or PYD file
+are searched for load-time dependencies.
+Instead, a new function `os.add_dll_directory() <https://docs.python.org/3.8/library/os.html#os.add_dll_directory>`_
+was added to supply additional search paths.  But such a runtime update is not applicable in all situations.
+
+Unlike MSVC, MinGW has its owned standard libraries such as ``libstdc++-6.dll``,
+which are not placed in the system path (such as ``C:\Windows\System32``).
+For a C++ example, you can check the dependencies by MSVC tool ``dumpbin``::
+
+    > dumpbin /dependents my_gnu_extension.cp38-win_amd64.pyd
+    ...
+    Dump of file my_gnu_extension.cp38-win_amd64.pyd
+    
+    File Type: DLL
+    
+      Image has the following dependencies:
+      
+          python38.dll
+          KERNEL32.dll
+          msvcrt.dll
+          libgcc_s_seh-1.dll
+          libstdc++-6.dll
+          ...
+
+These standard libraries can be embedded via static linking, by adding the following options to the linker::
+
+    -static-libgcc -static-libstdc++ -Wl,-Bstatic,--whole-archive -lwinpthread -Wl,--no-whole-archive
+
+In ``setup.py``, a cross platform config can be added through
+extending ``build_ext`` class::
+
+    from setuptools import setup
+    from setuptools.command.build_ext import build_ext
+
+    link_args = ['-static-libgcc',
+                 '-static-libstdc++',
+                 '-Wl,-Bstatic,--whole-archive',
+                 '-lwinpthread',
+                 '-Wl,--no-whole-archive']
+
+    ...  # Add extensions
+
+    class Build(build_ext):
+        def build_extensions(self):
+            if self.compiler.compiler_type == 'mingw32':
+                for e in self.extensions:
+                    e.extra_link_args = link_args
+            super(Build, self).build_extensions()
+
+    setup(
+        ...
+        cmdclass={'build_ext': Build},
+        ...
+    )
+
 .. [WinInst] https://github.com/cython/cython/wiki/CythonExtensionsOnWindows
diff --git a/docs/src/tutorial/caveats.rst b/docs/src/tutorial/caveats.rst
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9zcmMvdHV0b3JpYWwvY2F2ZWF0cy5yc3Q=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9zcmMvdHV0b3JpYWwvY2F2ZWF0cy5yc3Q= 100644
--- a/docs/src/tutorial/caveats.rst
+++ b/docs/src/tutorial/caveats.rst
@@ -5,7 +5,6 @@
 surprising or unintuitive. Work always goes on to make Cython more natural
 for Python users, so this list may change in the future.
 
- - ``10**-2 == 0``, instead of ``0.01`` like in Python.
  - Given two typed ``int`` variables ``a`` and ``b``, ``a % b`` has the
    same sign as the second argument (following Python semantics) rather than
    having the same sign as the first (as in C).  The C behavior can be
diff --git a/docs/src/tutorial/clibraries.rst b/docs/src/tutorial/clibraries.rst
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9zcmMvdHV0b3JpYWwvY2xpYnJhcmllcy5yc3Q=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9zcmMvdHV0b3JpYWwvY2xpYnJhcmllcy5yc3Q= 100644
--- a/docs/src/tutorial/clibraries.rst
+++ b/docs/src/tutorial/clibraries.rst
@@ -180,6 +180,6 @@
 =====================
 
 At this point, we have a working Cython module that we can test.  To
-compile it, we need to configure a ``setup.py`` script for distutils.
+compile it, we need to configure a ``setup.py`` script for setuptools.
 Here is the most basic script for compiling a Cython module::
 
@@ -184,7 +184,6 @@
 Here is the most basic script for compiling a Cython module::
 
-    from distutils.core import setup
-    from distutils.extension import Extension
+    from setuptools import Extension, setup
     from Cython.Build import cythonize
 
     setup(
@@ -193,7 +192,7 @@
 
 
 To build against the external C library, we need to make sure Cython finds the necessary libraries.
-There are two ways to archive this. First we can tell distutils where to find
+There are two ways to archive this. First we can tell setuptools where to find
 the c-source to compile the :file:`queue.c` implementation automatically. Alternatively,
 we can build and install C-Alg as system library and dynamically link it. The latter is useful
 if other applications also use C-Alg.
@@ -221,7 +220,7 @@
                 cqueue.queue_free(self._c_queue)
 
 The ``sources`` compiler directive gives the path of the C
-files that distutils is going to compile and
+files that setuptools is going to compile and
 link (statically) into the resulting extension module.
 In general all relevant header files should be found in ``include_dirs``.
 Now we can build the project using::
diff --git a/docs/src/tutorial/cython_tutorial.rst b/docs/src/tutorial/cython_tutorial.rst
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9zcmMvdHV0b3JpYWwvY3l0aG9uX3R1dG9yaWFsLnJzdA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9zcmMvdHV0b3JpYWwvY3l0aG9uX3R1dG9yaWFsLnJzdA== 100644
--- a/docs/src/tutorial/cython_tutorial.rst
+++ b/docs/src/tutorial/cython_tutorial.rst
@@ -40,7 +40,7 @@
 the :file:`setup.py`, which is like a python Makefile (for more information
 see :ref:`compilation`). Your :file:`setup.py` should look like::
 
-    from distutils.core import setup
+    from setuptools import setup
     from Cython.Build import cythonize
 
     setup(
@@ -273,7 +273,7 @@
 file to ``example_py_cy.py`` to differentiate it from the others.
 Now the ``setup.py`` looks like this::
 
-    from distutils.core import setup
+    from setuptools import setup
     from Cython.Build import cythonize
 
     setup(
diff --git a/docs/src/tutorial/embedding.rst b/docs/src/tutorial/embedding.rst
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9zcmMvdHV0b3JpYWwvZW1iZWRkaW5nLnJzdA==
--- /dev/null
+++ b/docs/src/tutorial/embedding.rst
@@ -0,0 +1,77 @@
+.. highlight:: cython
+
+.. _embedding:
+
+**********************************************
+Embedding Cython modules in C/C++ applications
+**********************************************
+
+**This is a stub documentation page. PRs very welcome.**
+
+Quick links:
+
+* `CPython docs <https://docs.python.org/3/extending/embedding.html>`_
+
+* `Cython Wiki <https://github.com/cython/cython/wiki/EmbeddingCython>`_
+
+* See the ``--embed`` option to the ``cython`` and ``cythonize`` frontends
+  for generating a C main function and the
+  `cython_freeze <https://github.com/cython/cython/blob/master/bin/cython_freeze>`_
+  script for merging multiple extension modules into one library.
+
+* `Embedding demo program <https://github.com/cython/cython/tree/master/Demos/embed>`_
+
+* See the documentation of the `module init function
+  <https://docs.python.org/3/extending/extending.html#the-module-s-method-table-and-initialization-function>`_
+  in CPython and `PEP 489 <https://www.python.org/dev/peps/pep-0489/>`_ regarding the module
+  initialisation mechanism in CPython 3.5 and later.
+
+
+Initialising your main module
+=============================
+
+Most importantly, DO NOT call the module init function instead of importing
+the module.  This is not the right way to initialise an extension module.
+(It was always wrong but used to work before, but since Python 3.5, it is
+wrong *and* no longer works.)
+
+For details, see the documentation of the
+`module init function <https://docs.python.org/3/extending/extending.html#the-module-s-method-table-and-initialization-function>`_
+in CPython and `PEP 489 <https://www.python.org/dev/peps/pep-0489/>`_ regarding the module
+initialisation mechanism in CPython 3.5 and later.
+
+The `PyImport_AppendInittab() <https://docs.python.org/3/c-api/import.html#c.PyImport_AppendInittab>`_
+function in CPython allows registering statically (or dynamically) linked extension
+modules for later imports.  An example is given in the documentation of the module
+init function that is linked above.
+
+
+Embedding example code
+======================
+
+The following is a simple example that shows the main steps for embedding a
+Cython module (``spam.pyx``) in Python 3.x.
+
+First, here is a Cython module that exports a C function to be called by external
+code.  Note that the ``say_hello_from_python()`` function is declared as ``public``
+to export it as a linker symbol that can be used by other C files, which in this
+case is ``spam_main.c``.
+
+.. literalinclude:: ../../examples/tutorial/embedding/spam.pyx
+
+The C ``main()`` function of your program could look like this:
+
+.. literalinclude:: ../../examples/tutorial/embedding/spam_main.c
+    :linenos:
+    :language: c
+
+(Adapted from the `CPython documentation
+<https://docs.python.org/3/extending/extending.html#the-module-s-method-table-and-initialization-function>`_.)
+
+Instead of writing such a ``main()`` function yourself, you can also let
+Cython generate one into your module's C file with the ``cython --embed``
+option.  Or use the
+`cython_freeze <https://github.com/cython/cython/blob/master/bin/cython_freeze>`_
+script to embed multiple modules.  See the
+`embedding demo program <https://github.com/cython/cython/tree/master/Demos/embed>`_
+for a complete example setup.
diff --git a/docs/src/tutorial/external.rst b/docs/src/tutorial/external.rst
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9zcmMvdHV0b3JpYWwvZXh0ZXJuYWwucnN0..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9zcmMvdHV0b3JpYWwvZXh0ZXJuYWwucnN0 100644
--- a/docs/src/tutorial/external.rst
+++ b/docs/src/tutorial/external.rst
@@ -41,7 +41,7 @@
 The libc math library is special in that it is not linked by default
 on some Unix-like systems, such as Linux. In addition to cimporting the
 declarations, you must configure your build system to link against the
-shared library ``m``.  For distutils, it is enough to add it to the
+shared library ``m``.  For setuptools, it is enough to add it to the
 ``libraries`` parameter of the ``Extension()`` setup:
 
 .. literalinclude:: ../../examples/tutorial/external/setup.py
diff --git a/docs/src/tutorial/htmlreport.png b/docs/src/tutorial/htmlreport.png
index 4fc98f3e020b5e6ec0785e01ebae4cbe09ad4f8a..08c3d3472f368756966d75d4273bf92223097e78
GIT binary patch
literal 20564
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%0DIyw*z9eg=GxoS>G^Xx;{`NS|
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

diff --git a/docs/src/tutorial/index.rst b/docs/src/tutorial/index.rst
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9zcmMvdHV0b3JpYWwvaW5kZXgucnN0..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9zcmMvdHV0b3JpYWwvaW5kZXgucnN0 100644
--- a/docs/src/tutorial/index.rst
+++ b/docs/src/tutorial/index.rst
@@ -13,9 +13,10 @@
    profiling_tutorial
    strings
    memory_allocation
+   embedding
    pure
    numpy
    array
    readings
    related_work
    appendix
@@ -16,7 +17,6 @@
    pure
    numpy
    array
    readings
    related_work
    appendix
-
diff --git a/docs/src/tutorial/profiling_tutorial.rst b/docs/src/tutorial/profiling_tutorial.rst
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9zcmMvdHV0b3JpYWwvcHJvZmlsaW5nX3R1dG9yaWFsLnJzdA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9zcmMvdHV0b3JpYWwvcHJvZmlsaW5nX3R1dG9yaWFsLnJzdA== 100644
--- a/docs/src/tutorial/profiling_tutorial.rst
+++ b/docs/src/tutorial/profiling_tutorial.rst
@@ -75,8 +75,8 @@
 --------------------------
 
 Since Cython 0.23, line tracing (see above) also enables support for coverage
-reporting with the `coverage.py <http://coverage.readthedocs.io/>`_ tool.
-To make the coverage analysis understand Cython modules, you also need to enable
+reporting with the `coverage.py <https://coverage.readthedocs.io/>`_ tool. To
+make the coverage analysis understand Cython modules, you also need to enable
 Cython's coverage plugin in your ``.coveragerc`` file as follows:
 
 .. code-block:: ini
@@ -274,5 +274,3 @@
 Even so, the result we achieved here is quite satisfactory: we came up with a
 solution that is much faster then our original Python version while retaining
 functionality and readability.
-
-
diff --git a/docs/src/tutorial/pxd_files.rst b/docs/src/tutorial/pxd_files.rst
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9zcmMvdHV0b3JpYWwvcHhkX2ZpbGVzLnJzdA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9zcmMvdHV0b3JpYWwvcHhkX2ZpbGVzLnJzdA== 100644
--- a/docs/src/tutorial/pxd_files.rst
+++ b/docs/src/tutorial/pxd_files.rst
@@ -11,11 +11,10 @@
 
 ``pxd`` files have many use-cases:
 
- 1. They can be used for sharing external C declarations.
- 2. They can contain functions which are well suited for inlining by
-    the C compiler. Such functions should be marked ``inline``, example:
-    ::
+1.  They can be used for sharing external C declarations.
+2.  They can contain functions which are well suited for inlining by
+    the C compiler. Such functions should be marked ``inline``, example::
 
        cdef inline int int_min(int a, int b):
            return b if b < a else a
 
@@ -18,11 +17,11 @@
 
        cdef inline int int_min(int a, int b):
            return b if b < a else a
 
- 3. When accompanying an equally named ``pyx`` file, they
+3.  When accompanying an equally named ``pyx`` file, they
     provide a Cython interface to the Cython module so that other
     Cython modules can communicate with it using a more efficient
     protocol than the Python one.
 
 In our integration example, we might break it up into ``pxd`` files like this:
 
@@ -23,9 +22,9 @@
     provide a Cython interface to the Cython module so that other
     Cython modules can communicate with it using a more efficient
     protocol than the Python one.
 
 In our integration example, we might break it up into ``pxd`` files like this:
 
- 1. Add a ``cmath.pxd`` function which defines the C functions available from
+1.  Add a ``cmath.pxd`` function which defines the C functions available from
     the C ``math.h`` header file, like ``sin``. Then one would simply do
     ``from cmath cimport sin`` in ``integrate.pyx``.
@@ -30,8 +29,7 @@
     the C ``math.h`` header file, like ``sin``. Then one would simply do
     ``from cmath cimport sin`` in ``integrate.pyx``.
- 2. Add a ``integrate.pxd`` so that other modules written in Cython
-    can define fast custom functions to integrate.
-    ::
+2.  Add a ``integrate.pxd`` so that other modules written in Cython
+    can define fast custom functions to integrate::
 
        cdef class Function:
            cpdef evaluate(self, double x)
@@ -41,3 +39,35 @@
     Note that if you have a cdef class with attributes, the attributes must
     be declared in the class declaration ``pxd`` file (if you use one), not
     the ``pyx`` file. The compiler will tell you about this.
+
+
+__init__.pxd
+^^^^^^^^^^^^
+
+Cython also supports ``__init__.pxd`` files for declarations in package's
+namespaces, similar to ``__init__.py`` files in Python.
+
+Continuing the integration example, we could package the module as follows:
+
+1.  Place the module files in a directory tree as one usually would for
+    Python::
+
+        CyIntegration/
+        ├── __init__.pyx
+        ├── __init__.pxd
+        ├── integrate.pyx
+        └── integrate.pxd
+
+2.  In ``__init__.pxd``, use ``cimport`` for any declarations that one
+    would want to be available from the package's main namespace::
+
+        from CyIntegration cimport integrate
+
+    Other modules would then be able to use ``cimport`` on the package in
+    order to recursively gain faster, Cython access to the entire package
+    and the data declared in its modules::
+
+        cimport CyIntegration
+        
+        cpdef do_integration(CyIntegration.integrate.Function f):
+            return CyIntegration.integrate.integrate(f, 0., 2., 1)
diff --git a/docs/src/tutorial/python_division.png b/docs/src/tutorial/python_division.png
index 617be942c42615acbb8fd92e4355dc6f70a23cfa..0fe83f05348f91a1306de6d797c789e76b9f19ac
GIT binary patch
literal 8162
zc$|G%c|26#`@f}#2uYSgjgUQL-&#fnS+Zs)OAT3K7{*p9+gO@pZ%78&WjAK1Ci|9=
zZEV?%7+Hqwzt{MDm*4N7-yipNo_p^(_uTuObD!t^yx-AA2HGr4yi5Q9u;@U*#sF|K
z765>sXHEhDkj6153jn|gUt{e%KxxlqG5`Rl9^cl#4FI1L&h9&&1^|H38)E4T0Ots_
z<3y|1CuaZ<fa`#7n+A|p(A^1RZGn+{UTa5h&eZSxfD`D>Jh|0&6;jT1S8n8eT#_33
z?$)53x5LBdzo<%rK`Vq?En5@8pQq9Q{%$~J){X9EO%mae<M70p-Qjacf#%%+q=drA
z_|vV8=@(zJhn+t|2FoUD8}HeN?#vC@haK!ve=B-T;6nDc#v9<PlTAm$)j|=D+!2nW
zmF%E6nh|yL_&n;SE2(p5n_pvpVgae3d9+0sY1XSaPq<NR2*L;W+|XU7)LVYB=TGoa
zZ5#`iu(Ihg4nb`7du5HAUWWT7U$<;u9x(!|RL*YoL755Vhf!7MXJ+(r`y(JlnrA%>
z&M5^{a0i?dVp7ZqL%DgsqD*wr7df|=Pz&Z?IC4jbpo@G&i7EYkUw6*pJyb@J8x5ts
z_&trPxywU)tsRdK$Z@})&o`B9y2ypuGCCsu7<!4>ZjH#HYd#vhQQ0MBNSB(uFONNe
z;X)+eEAO2r>%dCx*xTwBV&&CnucLw7L~exlZOTq6DK&{5Ue1F^cRqxJ9wdFH7{4{C
zRsA%Q6zZ0p(yT=Ql@y(A_ZR+TAFLtXTn%aIwnX@en-yS1!t$ykO_!0Ee(LzWwf!mQ
zog>3c@V|{IJI`gMM}@Vm5VeX`QD3;DiEp8LUa<xlUuT^grbTpJsAij-Nj?mP>^jqN
zrgJ9(g_f57?ptxPEKTUs{C;o&D)JruiTcClvEEtqLpa*JAPZu}e{~?Q()uU!H=k0&
z+_HyL!J`E}>BAeEcST!oFcbWBFx@?m#2P(dmoGWg?addTIc-rePkd&4>Cl3*?4~(9
zR+{YV=iF#J70i_qs@xQiXPAk^u08(1bSK}FnNS`Y1JgKkn`N%kZB~+RaNqs|-gPzq
zj&%=S48Hd4w&?rM>OEa=eEb5G-GgeRXRBW$ub%k&LIGQBUHj`MM3BfG;TS^2e9lzf
zu3~fIj<`yUf(gX6I587$fO%1rB0+T|U;k@I+70fA|2F>&<c@%>zO>DZyT@wMqmp4O
zX{#gQSy7`Y5w=q@=XLmFjxQ<vcj1tXiCjnAzRQn6r@0@EWKL<m2*-!7AV@v47}ZEO
zWH0Oaz)b(~Y{VXjuc>SC-a?XzaU8^nJ7NcPFgnu*58KL5&lPJ%--YKyDrhRxwt3A4
z$oAr*9gpP7<yo<ZZy}l)^L?w4IpL4&*yp@^d$^=~S(gu9%12*4nz!zVt5G92uMf3n
zH5nfj9_{AO9hvX`?k|F2si?U+2C&MXQz59qTBC@(#G?DX$m<BI*i5$RX)q#nl{3PT
z8#LaNuSYjd&#>S||5S)jPoM9G*80{T&U&ur=Zd!S<QfH<*HHrzS>M;}+=T@2n)VJI
zDG1woi4t`aq{ls+=8~}0eRm4(U}TsHr%;D8B9lDITj7(6Tx7@eoVqmbtR{(Tg^T)w
zb!03Wa<pqf_J0LQIiG6tnQh*Dic(Z?Q0nZH5d|x4*zylIJq_k1++a4u(i!ri2KOSR
zh~K=}Y5#*Aax=6_C;uwNsIH+E<PmLO<P9fXSs^dFfg~Af8R1Uc5d+AoI#U;igO0gF
z*k!rVLcidK7ZBB{>6pvn=~?ne_$LxX7gN%c-8fFNk#YCIPLC@{GLH$>a)Y^u4Js_h
zlO8x;QK*IJEMPj0FrYYyAn{)o^$x}<@3aSejohZlNzaOjf!>y3COD%G%ZAE&CviJF
zqqUl0+Z3+V$*|pS#hAJE6aWCqCE1_=0DyS`0AM2@CdMzP+hF$u(7l_*zY?tM=R`IV
zG>o=p1oFZT|7Z&YE7_ao>9WMHo16v!`~`AzqAK~}FyXc6H8}OkkoK%YBnVBx`5so}
z6paOICM|$7n!+mg=eiR#|MuzI7Ago4bsqV2in9TLkswi1iT~iB_s}#3h83GLC0AV~
zwrABVG%2ZZk1L1W7WUU#y4TyaYXk?Oy|$+fn*J`|MW=#G1cJ9XGBto(PN>1cr$NMI
zJ#~DA`f|fKw96<^K~z}6H+T?&$~4eU+>rS8fTIgCYdI3$t5M1V%Qq`UamiaUxc*ev
zpVAfxdoYn+$hH0!0IDuR&5AQ*!y$?eYdd@<nEqR}I$B-IW)%`y<JxSolC6j$i^N@#
zRHeD(+?a;He_!Agxvea;3;zUR*QWOK{&Jw`0XD7OgsgpZt?69TP;`};A&VlfRW$6b
zp;fJH>Zqgs!QxEdAid3Qu_PEPlm-#c9WpM_;spSeKbQxLw(R7rE=@7~z;2_{r9T)n
z8{8`L?@No5z=umHgG<svuZ73PRZ)l2m8@nTR3H2>J=4HWmcsgTO~K_MU1yp(DD*(o
zMY2|(YC-Bkpj9kUCPn(EiwcNOy7%73MpxSxPc4$Sv6mZRJX)<Y!H@3(U7e;kZznqx
zc>Vz*m&OPH0Eh(ufT)`Q@Z}tG)51Q4x}bTqBOSKWX@9gk)O4`oWgm7xJ<7dD0RZ3%
z5deVa5IUNLUR(M)6%ZV-Harp*B-^v%Y##RZch1@YLw6*ndMHA(p#`5`R%ntNuZE9T
z^>~~5_g$IyVIzCM%S)hk56!H^Yw`#IqBVCyf~TlF0H8{xr!Pg9s)XlPu%x2>#fhRw
zWY8L@#O)f(g%Eo!l@#Mz<D}WlFskrQQ>Xkj;1)))*H!PK4#wI(_p4+vH~p|;Y%As`
zX%o>b!hO{CR&dmG9RTRXh$?v{XH9ZFk_VD9Gry%ReX322BOn>_ca+he@~pq_70BxC
zOS~rei4)eRoG~dkdh({HR9HO3c-o-}p6Ep^pM_Do5u+a6o)%NT^_d8NkJ?7zKx4ZS
z{6w<)$&DDFr0X?X;Sf3iH2z&D4u02!8iI>ugW47c_4RRUN*q=GP@7sZ(0y-x<EV<`
z4b#d}Pj2$Wx>W2&20XiFAasa@GpD2ZL^VU}pd4(YX<*<(@ic^!FJIx!xT$%hx4_5u
zJ*nI}o!T^~TkKAAHdTX3qa&sme4|6fpI2pXMPEoV>NhC8*80@N6k@PFTkuJHF<B$Y
zo`GbZ;aS*GiOak?R27_E0!Q^*on&GGqBbeWO)}L<@_aS#ugN>5;s#!`eo<9Z+j}zM
z1n%4296US>6R$)(BI^#sORp0Hh`@7*m)cm#LE9Z>mGjVAKTGKSTNbaZjS#`GrH*@@
z-tZ67Nya0BdtJ?v-|v+tcqR(wWPZDc(9USD;iZZ%sh|S&GHwD_i0l(d10heTrG1qZ
z;SZ;3=)qP3P=8|%6PLv|*#|veU3+Ck={>0vOLwNaHup%Ywxp#1GeJF>R#UaF)gKz#
z0*QL9GQcg&Ui&!~AHR=tE0GRnu-J;d#MRzKi3o=i0BBsAWZ+sMx__laZK;3`<&Vf_
z%`gy_8zIF)f#(p`FpB3h&$duA!NLYJt{xlZf@J8?I;vbw+3q}9P1t7g;%^omRznxD
z{6YbAN$SN5z;R%_g*gELY*5)V005vOJOiH9U5-mO<gfO;GCA5}@$7<4xu(@qaX%8P
zgHZ^%|K4sezl~SbfhSc5*1*=HSxn#AuwqvOo=e()P^>X*ygV~9T05R4dKOhW8-Upq
zouN45-$Jc)(*sCLr>?2hSE^;2kAF*=(6o)GNZ3EUk15Hv^q>6fcDo`H3^(O(?o}Er
z=L&i9H{b|N()9>?rx9j|b3D1m!>#;G1%%fFm3a9Zf%t+)71z$O>S27JA*yhy=db-R
zuFx4`d;-e-2tiihzol6tA3foG6Eo6p6`Izk;i)|tu1v8>YCGW19O{3qi=2i^hW`z^
zu2#MP;tLoZItn~zj4}DD7i=li5`lA3y$eDw-#=7TZt*GOz&BOmREoC~(C*QP&jP8a
zUmXGoZo%%&7%{Wfk6apSo`s)U>+(5Ijt?qYGSAd7c)0gk@5)N%gZV^@fAK8DGPy_9
zYZ{vEW4W1K+sjuXNRwukQcCU!DLnhuZe$s*s7^6AESHYC<_b^vV9cJe?>h}iN)gWT
z^94w2Qhjza%x0tnPA^(S7dT)R_00~_Vt;Co<;_E6VW14%<L6n5mp&v}gw~iY#swKn
zIljK=%3{+TE0UJ@lZn7}uwY#8;As}s{66yUCc-={V$&=T@pb~b#d~4(`Cmt-K(p!#
znHCq$cm)|@@S7GAGvW<6<6rs#)+Ym9)V>ar&*WMbH55HRH<UQo@tA^Rifrh<^{il;
zT;{`hvxm(mUjJ*qYIk9H{fh4TO}5Z&b#jcUa+twN$5%{O(f-m_JN{~OsmMxLR_?1)
z-^L@VtSkCpsTF~^v>u<)*y|VV<9Br2o2y;Q9(Di7O?g@r^=!7%ZMk|y-ilP#dBw^0
z0i1vRvr+G#-<MrCtChkFWbTz4bQDpQtf#abLJUdob;oTk^px4AIdVE#cO@Hvx(E8j
z=a;-N_ojBZ_qRL3q>|3g?=r36hy6M35AeiT2x&I1d!RPNG^}T9@gEu6Z67G&V!f*U
zNoK~Y9;o$>^qT8FOro0D=Me2G9d~r+zLRgxx5SH&e))Y{_LY~xS+_dM2hTZpH~eik
zLqj?X*0rpT28V0FST#GlSa5m^csuov#UK+_B6(wck;R{G{6&OYy{@~ouK9I%7331}
zcS*}s$F1f&SzD5$T7eI4rM7a9UNt05if;a`tSnV?i1Xm!+<_jYZ1WBepg<xXs2<{~
zekO-t*VWa0|J&$4--@rMJn*J27q#`~`lMw=ajDu7n9UTD-*B05wiN}Sk|(#Kyx}{9
zFS3nh{Pn(q-$p^X-!;N!e^<??RnYTNwzN7o9}S5S2g`_co5;m@r#xaxHdQ_fW}f)x
zGTai=ye%CT(hbMzVpvxvEAJZWgLik^bj&`O%*B9g`<T6w@(=T`hY<q7U#+impyJt}
zWET!z_B*$c)F@bh<DiiO(||k}`x?TKycXxqdloMl1v3PzaAIbng}%6RK?&;W=c=5o
zWhHb1cA7$YtzuwxOGZ4DE&OOdM?HqEQ(tk6Z_nzi-(#;~L!}e0rbb?uCNsmtrjq-u
zUYaSE?L{=d#?E=e>+$DMH5H`cb4b`yPYoHzAxW&bw3H`S*Ycz&_en=_+t_w`F7)o%
zO7j7~_l3?{b=F?3$g2HEwVY68GatL8RS$FVxU=vf$s7mFq-u0|tk<u>vEanXi=t&+
z-tgtvgGR6Zl{cO0Y~=g0`nB@I!sB-^`jfC(`STX57L4VrzMBndJJ;TeNmqq(F6d<R
z!2DW2yZ9}fDbOb^sd`Aoi&D#?d0q-p)!sI_U47(LZL=G4_nTgnN+$yGVr1R52vPis
z=m0A|8wGQ=vEctD<^PJY2wDBZ%{OpMwp=%0KUXVPt!nZ_WnBvPN%NN9^-Mh<9H%)S
zlCa@6;s1=&%6)3+SzRLO;Zwe{6>Uk}aEX@6pPHyZ7k_lWJoyW;%2=S5v^wr(85L01
z!*N07+MwB!SUGUWX=47*X+ctN`~AEcm6s)J7Uro}L(hD-E6J($>aX8?!X0b7@z76M
z=~wmG?3s2cu9FjVsG2*izXq(v_M?OGTW-orA-tzmDV7hOu+%$t{|L!-ogJuYH7wf@
z<gJ1%+#c82W?HDIZ@;I~orZd^Dc`9y&tBr$sViNqPC;9JNiLsY8Cwj=3FVpeXiU3*
zmI(mLn~q@?4Uz#@hz;GHggFt8bw?$&EQtk^^%DRaSt%6$c&Gi7!&|PLWGRDzumeh;
zkA_t!Vv)j(_Sf(+{Js2BsJgBn*Ws&OSsA`6VPERql#rYik9)_ZTD1D9m+$A?Sn9kY
z75A7ibM=V^9RR{}q7<mIiBt92DRU<ZQeB#V2b<2YMxTCG-*069EI;`C-8l2L^2&`%
z@NBOednRaK`IXfy$ilYlN)Cj<of80}V6P!58dXwbE9*CXofi@jFN)cr)~g5TkIWf5
z-6w&fwgeGkPnf!Wk&-^~zQQ;9_PAigVy?#${Ur@`8=Vc17Q%{N4%XxR49d3<z&`<f
zeOGvHMvquLbJHLqBjG#%pyH_*{jUa0BlV`ZmUnyE-nFZhF{;fio%JiNW!&;C$W78{
zlZj;4oVmFBbv2_!_pK}Du=`G6m3FoRUnkX~`)Z1I5kCw>C~sG~mVD<D(LV-gRgb?1
zG5NZyWHpCni2H!dtj?Zf$FzYQlLy*Yto|1|YLgyBFxhU&8ig;7`Ah(sP=8XMqM5=*
zkU^!rGMj%ouh%E9IA%k3C~ymN2|=trN@^wyH2HbN3`|k#XYG1DZm(;Re5NhV=_5h-
zw3^Z9kOhQmkuASWBS&BGs1-)bkPk%<fD!p%5@p4VFTCU;xhp7$e?l~(q1$JY{Bq($
zG>HScfUW-g$^cC2D-R?QSLgi^e@KM!7xBBFK^~C}RR3y7q#Hc|L~ZJV&|>C03#Pm>
zoa4eC3U)E7cXM$Rzqx&jnkM0059Vsw8LV$mz9|33gZzUxafg;Y(C!*Ld!>aOm9n3P
zP58=Psp6<@%x6djkM+UdMJ0M5YSa74k0o4Y0Cl4st45~UJz;2#Jpo)Hsy<BD-o6&r
z7@-#?I})X27Rxlcf#m|e`~j1qCtdgNkVa~X-!m;N59%xh&g4$YTdlDYd!i+X8xQme
zFNRq)m9(w<F`i=~kFAV=FNyU30$Tv;*a{LSB9TEe-wj;V#E#Dwbu>c}VZn&*{*wRz
z#)eH%MmcC@D;xB<ctv^slnn`3OU*w`+lc}}@O<?)ih4-1938E?H9YQ;r_cMJ=d(ir
z;JG@jral1x;B@HiW1RP2#CL3Mvwq$lW5fO&&y00{T&NSzlaSy^4y|Lg5fEY>MHrXy
zU!DjnANG8k4nsx<<_@LPhQy3Omth!P`t#PUvrlw$ab>1sJV6Q`qmqXz7s<Z}R?1}#
zdmyymmGQ0_J+V_ek&bvs9IQ4DvS90iXRQpHVgMt0!79oUqL%Lr;75`|&B@Za(>*P(
zAy%J<3lV-+yQlcgk+_%q+HVJUK8sf?{C>TbM7>y6we}G~eM`>>fU)@x`up8;-xcKA
zr|foh3|Zkfm*^la?fd7yNu|#{i+6fo?-vEze&JckCR!m><eWNj->0&BeQ6U!y<^~N
z**N!D+?GT9aTl(nL*~Huu1kOYn814ytI&QqX+CMsuDYiP)SJ_>DeE-EzXhTEUR3aN
zrq*ez7VJ_D<S=j8k~Y4+8VQ^e%esu@^(x47S$Z_zmtLliQ*0`PWJtRubDG;RGQRnE
z?m1-J0z<7W(LCSka#ItiZpv$Wn0@k+AQ5|wHzU_kzmKQdSIbakQ~?Q0J;&lY1c?QC
z!mSIB%a?Rq0zK%na&&JtJXbhtw6`!#aLceb3>uIvTZRqd9PXVQT+z=XW-L@1n6=eQ
zWV)jLu^kp=zS+zL2j}OcJ4^7dP27_&S=#m^<Z@!p9-(88Cc4#n3nR7;b{TJB*vYml
zVVFJ3MJW-_$;2+jm{=#cII;Uu`~IU`TZ{DPTt&@Y52`=mWKAs(6ps2Se~i@x#q}&M
zK<md+_|1Rg&QBEi2Ug$Y@-O<$;VkUX&5}s*ZPyJ$o5E$VYHjQ$-QDpzjqwWhHnY9f
z$yenL7=!BhtVi`^-Grv@d+l2dxgP{SF&jSx#-@O5l>{apr7Y1Y#jfkstmu?!W17J+
z9lU84LBhn6^^W^yE4WQ-F7k95g15kPYQpjR5GqS->vpjO(L)`o`hBHU(!9Uz@9Oxu
zXJ_M8L2(dPFlMDpk26PmtJC%}8)uW-1t%Nrj7=-Tc%#o{w3U|QQ@eJMM?^!XhiZ!k
z#R$_JIpEU&d;o`av*Ubh5UQ$L(qB>z$><|f{WFZkf_$!RJH<f740`-!kz3N@-^SgO
zuWyuYl+ug;+%jK{CEv`c6ItUhs*=ifj@m4((n0c}iVdWCMBc@K(c&K(h+t}9dr3pY
zN2>p24$3#m^$Teh6%gzC1=y7iJd<=Ad&fSJrO<8u0>AkvjtOT`v|yG)-&_tk8-i4M
zl9)_?B~ZsqJH4P#FCx)GhVc!t{Dsu+RDwEo=3x;#$K2jL`nK+^1y1=}nA#g}TPgO~
z96@bWzL(V_kX!b0<w&M(|BVi^P-9D9M5DEG*VTu%@<ARFC+H3w9LvDi-!GpAJ$p$J
zmMee>MvN>DxK4A`vyFM$xnxJh+b_qo{Ngv&j*v@l$~on1plPysg=k%(yz9R``3ha=
z%-HyyT?ne&X&7>JPR8ugr$<P<>t>H@ASZwP<!6E|bqm6RZI{4FIW2}|nJ?Bk_Ir=s
za9qJzxVINkaTY!&57)BhOc_CF&6G1jPyU?BXuQ*)Ah`%|{2LAY8y7I!VCbAqh_{Hr
zMw@E$$CEOu9?Zp2Zo1PVa|Rpv-beScsy>GFP4n)C3(7NwyfDSMOkZwVzGFd-4QfBE
zfrQ!N*&-3ztYc${g@*vZje-15tx3M_RcHDgXCSU;D&|$&%-NYHanQV1ESgrllluM3
zEy9a?>%kH%@Ay&lz%9&B_%Ei`AfkMw!96gk^K^B`>jaEwJaR<x(aAm*k;iB5r(fi0
zb$ufQ0HAS0RH?1Yb*y~tdxL9L0rtU1#hzenX#0uB6F#(18!1K1Zr*$6I+>9E8fF5D
z6Jenh?aE^w;7S%M=fzd=a}OO~%nlI7Wkj-RVH{<bsD}KlsqhDE?SJ`fx8$<KME>DV
zJHPvH>T%V&T4h$agm@=fLM-inbjDn(w|GUGyO~V_0Kf>KSS?M*2vge>U{7ejzbl_|
zmgd(x3!;H$9btHJX*1F2O_htQ?iJ?qVj*8?RKRi0_=hB=S<gd}RYNKbb#=87X5y~-
z*`aL`bEg0xs_Hs%{@s-kCXQMzZNoCvWrg?MLo%xBX$6Poc3k=9zHe#EW`V(9tsjvP
zuuW*}#@=O^Z*pd1r_J988Knz-YKSe$P4_S)p~76V=m7w1bsh@miH@t)>7)^L!$Bxd
zxotm@r|Pssd2oSjuBYz*(+EF)3IKpjV~ll4_Z#W*)LNM`h47omyEJM~G6oiIcDYbX
zC5xfqGo)4z0Dvz>T8Q5pkvCp2(&jw|oX3RTF%S5^t?j#*0kx?a84ftz@d_I5uJ!NT
zSE1nym^5L$i<ybG7ys$2_%zMc$LKgylNwZ4ZnqQ?X_seoj+w%$e;VN5{mTVF-Oj?a
z4sw#$|2G5qkEJR_tTY+u>DqLpedZ>nETLsvKq7#)2zU;%1?xFl_6Gi&_hFrK001ny
ztWv5NcsP;(0QmL)&kG!IK=V$Y27pDsRnPyE^tq!TlbNxs()`xl1MK+rxArdni1EUO
z^bm54X}g3JB`!^d<(O5R$2b)#j*zL#o6dPR>+E*;HStY_5PN~R#NT!T1)Yq#0*aiZ
zB8JGWRC)lo%L$!}COvvz-}a0+dI!_VKmW30w}2_;=G`^`aQFa1e=1gH>fFNU9d!OQ
zP2+pHrDe4uT5M|1cS*Vz8bq9c&a^~aB?7>WhbV)0#@-Ln3Q!YSzMW05m5Sr^MRyj3
z+Hen|PvLYwD*%*lfcUtI%~u+ec{JC0-UvLsSFS&axZKw+F8iv7DFXm*IH2NVIW71u
zo;USXsazbUGO<5ZgB}Nf$xQIp&iZI<4$dwlv>~ve$h1$Gh4%X7d*La?QSdEs#VE9>
zyN25ci@P<01=PF$su^wBm<=(4`Aj1>;!Ivc=zuQ{LGV?Tjt$qV(#IQuvH#^s;0sAh
z<-y!gnSE2>#{9}??dk+R=;-i3u|QIWnQ()7H1pqzmeaokEi_(DGeAk@Z}8{%euFGj
z6L*B;vE&f`;1RsHbNa|lh3Frwa}GosHcSuRt!>R&JzO@-h1m0p^O&o6#K55cNT2I$
zH2s92AVnNuzl{og7J4I{w{&xQpK|@m!tg!t?$h*rRo&D%L&vq97bJrtxM|_v>ELAk
zyz802Dxsf6rhe_`3KDk=*`6{J${UeY>*XdHc4_%{FtrlI`e|Of>ht7C28PE=**2MT
z44>j`noY=P<%F)`G$btV$7>(j=VV+UYlg0)QBInFL+~Oc-^Sw&oUExBU+o>A^fOx{
zE?0^1dl`pi(W1jWJ>O1iXVXN`mPDzLQV|9Q!$0qXq=@m2$w%%h>iyYXlZnY;FCDof
zsFoN$!*p-BG?=uRDTKP{G!${;aa?~gWI?rIHI?SV5((nYU-6(XNuF=`>unp@$&$#b
zbLPMQ)?6d%iBzEV$|y<-s+yV`U=?`vvAkRoeKRr5f#&{yMC^Yx|IxB(&B}`dP0P~+
VF}DIK82|tP9W4WJ=^clc{{!#gquu}j

diff --git a/docs/src/tutorial/readings.rst b/docs/src/tutorial/readings.rst
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9zcmMvdHV0b3JpYWwvcmVhZGluZ3MucnN0..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9zcmMvdHV0b3JpYWwvcmVhZGluZ3MucnN0 100644
--- a/docs/src/tutorial/readings.rst
+++ b/docs/src/tutorial/readings.rst
@@ -16,7 +16,7 @@
 Finally, don't hesitate to ask questions (or post reports on
 successes!) on the Cython users mailing list [UserList]_.  The Cython
 developer mailing list, [DevList]_, is also open to everybody, but
-focusses on core development issues.  Feel free to use it to report a
+focuses on core development issues.  Feel free to use it to report a
 clear bug, to ask for guidance if you have time to spare to develop
 Cython, or if you have suggestions for future development.
 
diff --git a/docs/src/tutorial/related_work.rst b/docs/src/tutorial/related_work.rst
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9zcmMvdHV0b3JpYWwvcmVsYXRlZF93b3JrLnJzdA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9zcmMvdHV0b3JpYWwvcmVsYXRlZF93b3JrLnJzdA== 100644
--- a/docs/src/tutorial/related_work.rst
+++ b/docs/src/tutorial/related_work.rst
@@ -41,8 +41,9 @@
 
 .. [ctypes] https://docs.python.org/library/ctypes.html.
 .. there's also the original ctypes home page: http://python.net/crew/theller/ctypes/
-.. [Pyrex] G. Ewing, Pyrex: C-Extensions for Python,
-   http://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/
+..
+   [Pyrex] G. Ewing, Pyrex: C-Extensions for Python,
+   https://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/
 .. [ShedSkin] M. Dufour, J. Coughlan, ShedSkin,
    https://github.com/shedskin/shedskin
 .. [SWIG] David M. Beazley et al.,
diff --git a/docs/src/tutorial/strings.rst b/docs/src/tutorial/strings.rst
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9zcmMvdHV0b3JpYWwvc3RyaW5ncy5yc3Q=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9zcmMvdHV0b3JpYWwvc3RyaW5ncy5yc3Q= 100644
--- a/docs/src/tutorial/strings.rst
+++ b/docs/src/tutorial/strings.rst
@@ -441,7 +441,7 @@
 encodes efficiently.  This makes it a very good choice for source code
 files which usually consist mostly of ASCII characters.
 
-.. _`UTF-8`: http://en.wikipedia.org/wiki/UTF-8
+.. _`UTF-8`: https://en.wikipedia.org/wiki/UTF-8
 
 As an example, putting the following line into a UTF-8 encoded source
 file will print ``5``, as UTF-8 encodes the letter ``'ö'`` in the two
@@ -554,7 +554,7 @@
 For more information on this topic, it is worth reading the `Wikipedia
 article about the UTF-16 encoding`_.
 
-.. _`Wikipedia article about the UTF-16 encoding`: http://en.wikipedia.org/wiki/UTF-16/UCS-2
+.. _`Wikipedia article about the UTF-16 encoding`: https://en.wikipedia.org/wiki/UTF-16/UCS-2
 
 The same properties apply to Cython code that gets compiled for a
 narrow CPython runtime environment.  In most cases, e.g. when
diff --git a/docs/src/userguide/compute_typed_html.jpg b/docs/src/userguide/compute_typed_html.jpg
index f8607bdd80d73130a61af43ec3b87a4b9a9cf530..a1e0065734100b194bec5ffe9d12e5620fc11d48
GIT binary patch
literal 116673
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

diff --git a/docs/src/userguide/debugging.rst b/docs/src/userguide/debugging.rst
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9zcmMvdXNlcmd1aWRlL2RlYnVnZ2luZy5yc3Q=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9zcmMvdXNlcmd1aWRlL2RlYnVnZ2luZy5yc3Q= 100644
--- a/docs/src/userguide/debugging.rst
+++ b/docs/src/userguide/debugging.rst
@@ -25,11 +25,10 @@
 This can be achieved from within the setup script by passing ``gdb_debug=True``
 to ``cythonize()``::
 
-    from distutils.core import setup
-    from distutils.extension import Extension
+    from setuptools import Extension, setup
 
     extensions = [Extension('source', ['source.pyx'])]
 
     setup(..., ext_modules=cythonize(extensions, gdb_debug=True))
 
 For development it's often helpful to pass the ``--inplace`` flag to
@@ -30,10 +29,10 @@
 
     extensions = [Extension('source', ['source.pyx'])]
 
     setup(..., ext_modules=cythonize(extensions, gdb_debug=True))
 
 For development it's often helpful to pass the ``--inplace`` flag to
-the ``setup.py`` script, which makes distutils build your project
+the ``setup.py`` script, which makes setuptools build your project
 "in place", i.e., not in a separate `build` directory.
 
 When invoking Cython from the command line directly you can have it write
diff --git a/docs/src/userguide/extension_types.rst b/docs/src/userguide/extension_types.rst
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9zcmMvdXNlcmd1aWRlL2V4dGVuc2lvbl90eXBlcy5yc3Q=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9zcmMvdXNlcmd1aWRlL2V4dGVuc2lvbl90eXBlcy5yc3Q= 100644
--- a/docs/src/userguide/extension_types.rst
+++ b/docs/src/userguide/extension_types.rst
@@ -327,7 +327,8 @@
 Subclassing
 =============
 
-An extension type may inherit from a built-in type or another extension type::
+If an extension type inherits from other types, the first base class must be
+a built-in type or another extension type::
 
     cdef class Parrot:
         ...
@@ -342,7 +343,9 @@
 must either be declared as an extern extension type or imported using the
 :keyword:`cimport` statement.
 
-An extension type can only have one base class (no multiple inheritance).
+Multiple inheritance is supported, however the second and subsequent base 
+classes must be an ordinary Python class (not an extension type or a built-in
+type).
 
 Cython extension types can also be subclassed in Python. A Python class can
 inherit from multiple extension types provided that the usual Python rules for
@@ -504,7 +507,7 @@
 (pointer to a) data structure, often as returned by external C/C++ functions.
 
 As extension classes can only accept Python objects as arguments in their
-contructors, this necessitates the use of factory functions. For example, ::
+constructors, this necessitates the use of factory functions. For example, ::
 
     from libc.stdlib cimport malloc, free
 
@@ -611,6 +614,39 @@
         cdef object __weakref__
 
 
-Controlling cyclic garbage collection in CPython
-================================================
+Controlling deallocation and garbage collection in CPython
+==========================================================
+
+.. NOTE::
+
+    This section only applies to the usual CPython implementation
+    of Python. Other implementations like PyPy work differently.
+
+.. _dealloc_intro:
+
+Introduction
+------------
+
+First of all, it is good to understand that there are two ways to
+trigger deallocation of Python objects in CPython:
+CPython uses reference counting for all objects and any object with a
+reference count of zero is immediately deallocated. This is the most
+common way of deallocating an object. For example, consider ::
+
+    >>> x = "foo"
+    >>> x = "bar"
+
+After executing the second line, the string ``"foo"`` is no longer referenced,
+so it is deallocated. This is done using the ``tp_dealloc`` slot, which can be
+customized in Cython by implementing ``__dealloc__``.
+
+The second mechanism is the cyclic garbage collector.
+This is meant to resolve cyclic reference cycles such as ::
+
+    >>> class Object:
+    ...     pass
+    >>> def make_cycle():
+    ...     x = Object()
+    ...     y = [x]
+    ...     x.attr = y
 
@@ -616,5 +652,57 @@
 
-By default each extension type will support the cyclic garbage collector of
+When calling ``make_cycle``, a reference cycle is created since ``x``
+references ``y`` and vice versa. Even though neither ``x`` or ``y``
+are accessible after ``make_cycle`` returns, both have a reference count
+of 1, so they are not immediately deallocated. At regular times, the garbage
+collector runs, which will notice the reference cycle
+(using the ``tp_traverse`` slot) and break it.
+Breaking a reference cycle means taking an object in the cycle
+and removing all references from it to other Python objects (we call this
+*clearing* an object). Clearing is almost the same as deallocating, except
+that the actual object is not yet freed. For ``x`` in the example above,
+the attributes of ``x`` would be removed from ``x``.
+
+Note that it suffices to clear just one object in the reference cycle,
+since there is no longer a cycle after clearing one object. Once the cycle
+is broken, the usual refcount-based deallocation will actually remove the
+objects from memory. Clearing is implemented in the ``tp_clear`` slot.
+As we just explained, it is sufficient that one object in the cycle
+implements ``tp_clear``.
+
+Enabling the deallocation trashcan
+----------------------------------
+
+In CPython, it is possible to create deeply recursive objects. For example::
+
+    >>> L = None
+    >>> for i in range(2**20):
+    ...     L = [L]
+
+Now imagine that we delete the final ``L``. Then ``L`` deallocates
+``L[0]``, which deallocates ``L[0][0]`` and so on until we reach a
+recursion depth of ``2**20``. This deallocation is done in C and such
+a deep recursion will likely overflow the C call stack, crashing Python.
+
+CPython invented a mechanism for this called the *trashcan*. It limits the
+recursion depth of deallocations by delaying some deallocations.
+
+By default, Cython extension types do not use the trashcan but it can be
+enabled by setting the ``trashcan`` directive to ``True``. For example::
+
+    cimport cython
+    @cython.trashcan(True)
+    cdef class Object:
+        cdef dict __dict__
+
+Trashcan usage is inherited by subclasses
+(unless explicitly disabled by ``@cython.trashcan(False)``).
+Some builtin types like ``list`` use the trashcan, so subclasses of it
+use the trashcan by default.
+
+Disabling cycle breaking (``tp_clear``)
+---------------------------------------
+
+By default, each extension type will support the cyclic garbage collector of
 CPython. If any Python objects can be referenced, Cython will automatically
 generate the ``tp_traverse`` and ``tp_clear`` slots. This is usually what you
 want.
@@ -622,6 +710,6 @@
 There is at least one reason why this might not be what you want: If you need
 to cleanup some external resources in the ``__dealloc__`` special function and
 your object happened to be in a reference cycle, the garbage collector may
-have triggered a call to ``tp_clear`` to drop references. This is the way that
-reference cycles are broken so that the garbage can actually be reclaimed.
+have triggered a call to ``tp_clear`` to clear the object
+(see :ref:`dealloc_intro`).
 
@@ -627,8 +715,8 @@
 
-In that case any object references have vanished by the time when
-``__dealloc__`` is called. Now your cleanup code lost access to the objects it
-has to clean up. In that case you can disable the cycle breaker ``tp_clear``
-by using the ``no_gc_clear`` decorator ::
+In that case, any object references have vanished when ``__dealloc__``
+is called. Now your cleanup code lost access to the objects it has to clean up.
+To fix this, you can disable clearing instances of a specific class by using
+the ``no_gc_clear`` directive::
 
     @cython.no_gc_clear
     cdef class DBCursor:
@@ -641,6 +729,6 @@
 This example tries to close a cursor via a database connection when the Python
 object is destroyed. The ``DBConnection`` object is kept alive by the reference
 from ``DBCursor``. But if a cursor happens to be in a reference cycle, the
-garbage collector may effectively "steal" the database connection reference,
+garbage collector may delete the database connection reference,
 which makes it impossible to clean up the cursor.
 
@@ -645,9 +733,13 @@
 which makes it impossible to clean up the cursor.
 
-Using the ``no_gc_clear`` decorator this can not happen anymore because the
-references of a cursor object will not be cleared anymore.
+If you use ``no_gc_clear``, it is important that any given reference cycle
+contains at least one object *without* ``no_gc_clear``. Otherwise, the cycle
+cannot be broken, which is a memory leak.
+
+Disabling cyclic garbage collection
+-----------------------------------
 
 In rare cases, extension types can be guaranteed not to participate in cycles,
 but the compiler won't be able to prove this. This would be the case if
 the class can never reference itself, even indirectly.
 In that case, you can manually disable cycle collection by using the
@@ -649,9 +741,9 @@
 
 In rare cases, extension types can be guaranteed not to participate in cycles,
 but the compiler won't be able to prove this. This would be the case if
 the class can never reference itself, even indirectly.
 In that case, you can manually disable cycle collection by using the
-``no_gc`` decorator, but beware that doing so when in fact the extension type
+``no_gc`` directive, but beware that doing so when in fact the extension type
 can participate in cycles could cause memory leaks ::
 
     @cython.no_gc
@@ -850,6 +942,7 @@
 
 instead of the desired C equivalent of ``return f->f0 + f->f1 + f->f2``. We can
 alias the fields by using::
+
     cdef extern from "foo_nominal.h":
 
         ctypedef class foo_extension.Foo [object FooStructNominal]:
diff --git a/docs/src/userguide/external_C_code.rst b/docs/src/userguide/external_C_code.rst
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9zcmMvdXNlcmd1aWRlL2V4dGVybmFsX0NfY29kZS5yc3Q=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9zcmMvdXNlcmd1aWRlL2V4dGVybmFsX0NfY29kZS5yc3Q= 100644
--- a/docs/src/userguide/external_C_code.rst
+++ b/docs/src/userguide/external_C_code.rst
@@ -17,7 +17,7 @@
 Cython module can be used as a bridge to allow Python code to call C code, it
 can also be used to allow C code to call Python code.
 
-.. _embedding Python: http://www.freenet.org.nz/python/embeddingpyrex/
+.. _embedding Python: https://web.archive.org/web/20120225082358/http://www.freenet.org.nz:80/python/embeddingpyrex/
 
 External declarations
 =======================
@@ -524,7 +524,7 @@
 ---------------------------------
 
 Cython provides facilities for acquiring and releasing the
-`Global Interpreter Lock (GIL) <http://docs.python.org/dev/glossary.html#term-global-interpreter-lock>`_.
+`Global Interpreter Lock (GIL) <https://docs.python.org/dev/glossary.html#term-global-interpreter-lock>`_.
 This may be useful when calling from multi-threaded code into
 (external C) code that may block, or when wanting to use Python
 from a (native) C thread callback.  Releasing the GIL should
@@ -549,11 +549,10 @@
     with nogil:
         <code to be executed with the GIL released>
 
-Code in the body of the with-statement must not raise exceptions or
-manipulate Python objects in any way, and must not call anything that
-manipulates Python objects without first re-acquiring the GIL.  Cython
-validates these operations at compile time, but cannot look into
-external C functions, for example.  They must be correctly declared
-as requiring or not requiring the GIL (see below) in order to make
+Code in the body of the with-statement must not manipulate Python objects
+in any way, and must not call anything that manipulates Python objects without
+first re-acquiring the GIL.  Cython validates these operations at compile time,
+but cannot look into external C functions, for example.  They must be correctly
+declared as requiring or not requiring the GIL (see below) in order to make
 Cython's checks effective.
 
@@ -558,5 +557,10 @@
 Cython's checks effective.
 
+Since Cython 3.0, some simple Python statements can be used inside of ``nogil``
+sections: ``raise``, ``assert`` and ``print`` (the Py2 statement, not the function).
+Since they tend to be lone Python statements, Cython will automatically acquire
+and release the GIL around them for convenience.
+
 .. _gil:
 
 Acquiring the GIL
@@ -580,6 +584,26 @@
     with gil:
         <execute this block with the GIL acquired>
 
+.. _gil_conditional:
+
+Conditional Acquiring / Releasing the GIL
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Sometimes it is helpful to use a condition to decide whether to run a
+certain piece of code with or without the GIL. This code would run anyway,
+the difference is whether the GIL will be held or released.
+The condition must be constant (at compile time).
+
+This could be useful for profiling, debugging, performance testing, and
+for fused types (see :ref:`fused_gil_conditional`).::
+
+    DEF FREE_GIL = True
+
+    with nogil(FREE_GIL):
+        <code to be executed with the GIL released>
+
+        with gil(False):
+           <GIL is still released>
+
 Declaring a function as callable without the GIL
 --------------------------------------------------
 
diff --git a/docs/src/userguide/fusedtypes.rst b/docs/src/userguide/fusedtypes.rst
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9zcmMvdXNlcmd1aWRlL2Z1c2VkdHlwZXMucnN0..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9zcmMvdXNlcmd1aWRlL2Z1c2VkdHlwZXMucnN0 100644
--- a/docs/src/userguide/fusedtypes.rst
+++ b/docs/src/userguide/fusedtypes.rst
@@ -249,6 +249,34 @@
         if bunch_of_types in string_t:
             print("s is a string!")
 
+.. _fused_gil_conditional:
+
+Conditional GIL Acquiring / Releasing
+=====================================
+
+Acquiring and releasing the GIL can be controlled by a condition
+which is known at compile time (see :ref:`gil_conditional`).
+
+This is most useful when combined with fused types.
+A fused type function may have to handle both cython native types
+(e.g. cython.int or cython.double) and python types (e.g. object or bytes).
+Conditional Acquiring / Releasing the GIL provides a method for running
+the same piece of code either with the GIL released (for cython native types)
+and with the GIL held (for python types).::
+
+    cimport cython
+
+    ctypedef fused double_or_object:
+        cython.double
+        object
+
+    def increment(double_or_object x):
+        with nogil(double_or_object is cython.double):
+            # Same code handles both cython.double (GIL is released)
+            # and python object (GIL is not released).
+            x = x + 1
+        return x
+
 __signatures__
 ==============
 
diff --git a/docs/src/userguide/index.rst b/docs/src/userguide/index.rst
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9zcmMvdXNlcmd1aWRlL2luZGV4LnJzdA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9zcmMvdXNlcmd1aWRlL2luZGV4LnJzdA== 100644
--- a/docs/src/userguide/index.rst
+++ b/docs/src/userguide/index.rst
@@ -16,6 +16,7 @@
    wrapping_CPlusPlus
    fusedtypes
    pypy
+   migrating_to_cy30
    limitations
    pyrex_differences
    memoryviews
diff --git a/docs/src/userguide/language_basics.rst b/docs/src/userguide/language_basics.rst
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9zcmMvdXNlcmd1aWRlL2xhbmd1YWdlX2Jhc2ljcy5yc3Q=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9zcmMvdXNlcmd1aWRlL2xhbmd1YWdlX2Jhc2ljcy5yc3Q= 100644
--- a/docs/src/userguide/language_basics.rst
+++ b/docs/src/userguide/language_basics.rst
@@ -288,6 +288,17 @@
 about object parameters in C functions.
 
 
+To create a borrowed reference, specify the parameter type as ``PyObject*``.
+Cython won't perform automatic ``Py_INCREF``, or ``Py_DECREF``, e.g.:
+
+.. literalinclude:: ../../examples/userguide/language_basics/parameter_refcount.pyx
+
+will display::
+
+    Initial refcount: 2
+    Inside owned_reference: 3
+    Inside borrowed_reference: 2
+
 .. _optional_arguments:
 
 Optional Arguments
@@ -579,6 +590,10 @@
 
 The precedence of ``<...>`` is such that ``<type>a.b.c`` is interpreted as ``<type>(a.b.c)``.
 
+Casting to ``<object>`` creates an owned reference. Cython will automatically
+perform a ``Py_INCREF`` and ``Py_DECREF`` operation. Casting to
+``<PyObject *>`` creates a borrowed reference, leaving the refcount unchanged.
+
 .. _checked_type_casts:
 
 Checked Type Casts
diff --git a/docs/src/userguide/limitations.rst b/docs/src/userguide/limitations.rst
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9zcmMvdXNlcmd1aWRlL2xpbWl0YXRpb25zLnJzdA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9zcmMvdXNlcmd1aWRlL2xpbWl0YXRpb25zLnJzdA== 100644
--- a/docs/src/userguide/limitations.rst
+++ b/docs/src/userguide/limitations.rst
@@ -8,9 +8,12 @@
 
 This page used to list bugs in Cython that made the semantics of
 compiled code differ from that in Python.  Most of the missing
-features have been fixed in Cython 0.15. Note that a
-future version 1.0 of Cython is planned to provide full Python
-language compatibility.
+features have been fixed in Cython 0.15.  A future version of
+Cython is planned to provide full Python language compatibility.
+For now, the issue tracker can provide an overview of deviations
+that we are aware of and would like to see fixed.
+
+https://github.com/cython/cython/labels/Python%20Semantics
 
 Below is a list of differences that we will probably not be addressing.
 Most of these things that fall more into the implementation details rather
diff --git a/docs/src/userguide/memoryviews.rst b/docs/src/userguide/memoryviews.rst
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9zcmMvdXNlcmd1aWRlL21lbW9yeXZpZXdzLnJzdA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9zcmMvdXNlcmd1aWRlL21lbW9yeXZpZXdzLnJzdA== 100644
--- a/docs/src/userguide/memoryviews.rst
+++ b/docs/src/userguide/memoryviews.rst
@@ -20,6 +20,9 @@
 class attribute, etc) and can be obtained from nearly any object that
 exposes writable buffer through the `PEP 3118`_ buffer interface.
 
+.. _`PEP 3118`: https://www.python.org/dev/peps/pep-3118/
+
+
 .. _view_quickstart:
 
 Quickstart
@@ -56,12 +59,7 @@
 
     cdef int[:,:,:] view3D = exporting_object
 
-A 2D view that restricts the first dimension of a buffer to 100 rows
-starting at the second (index 1) and then skips every second (odd) row::
-
-    cdef int[1:102:2,:] partial_view = exporting_object
-
-This also works conveniently as function arguments:
+They also work conveniently as function arguments:
 
 .. code-block:: cython
 
@@ -65,7 +63,7 @@
 
 .. code-block:: cython
 
-    def process_3d_buffer(int[1:102:2,:] view not None):
+    def process_3d_buffer(int[:,:,:] view not None):
         ...
 
 The ``not None`` declaration for the argument automatically rejects
@@ -234,6 +232,8 @@
 data array to themselves be pointers; Cython memoryviews do not yet support
 this.
 
+.. _`new style buffers`: https://docs.python.org/3/c-api/buffer.html
+
 .. _view_memory_layout:
 
 Memory layout
@@ -660,6 +660,6 @@
 call functions in C files, see :ref:`using_c_libraries`.
 
 
-.. _GIL: http://docs.python.org/dev/glossary.html#term-global-interpreter-lock
+.. _GIL: https://docs.python.org/dev/glossary.html#term-global-interpreter-lock
 .. _NumPy: https://docs.scipy.org/doc/numpy/reference/arrays.ndarray.html#memory-layout
 .. _example: https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html
diff --git a/docs/src/userguide/migrating_to_cy30.rst b/docs/src/userguide/migrating_to_cy30.rst
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9zcmMvdXNlcmd1aWRlL21pZ3JhdGluZ190b19jeTMwLnJzdA==
--- /dev/null
+++ b/docs/src/userguide/migrating_to_cy30.rst
@@ -0,0 +1,159 @@
+.. highlight:: cython
+
+.. _cython30:
+
+*********************************
+Migrating from Cython 0.29 to 3.0
+*********************************
+
+Cython 3.0 is a major revision of the compiler and the language
+that comes with some backwards incompatible changes.
+This document lists the important ones and explains how to deal with
+them in existing code.
+
+
+Python 3 syntax/semantics
+=========================
+
+Cython 3.0 now uses Python 3 syntax and semantics by default, which previously
+required setting the ``language_level`` `directive <compiler-directives>` to
+either ``3`` or ``3str``.
+The new default setting is now ``language_level=3str``, which means Python 3
+semantics, but unprefixed strings are ``str`` objects, i.e. unicode text strings
+under Python 3 and byte strings under Python 2.7.
+
+You can revert your code to the previous (Python 2.x) semantics by setting
+``language_level=2``.
+
+Further semantic changes due to the language level include:
+
+* ``/``-division uses the true (float) division operator, unless ``cdivision`` is enabled.
+* ``print`` is a function, not a statement.
+* Python classes that are defined without bases (``class C: ...``) are "new-style"
+  classes also in Py2.x (if you never heard about "old-style classes", you're probably
+  happy without them).
+* Annotations (type hints) are now stored as strings.
+  (`PEP 563 <https://github.com/cython/cython/issues/2863>`_)
+* ``StopIteration`` handling in generators has been changed according to
+  `PEP 479 <https://www.python.org/dev/peps/pep-0479/>`_.
+
+
+Python semantics
+================
+
+Some Python compatibility bugs were fixed, e.g.
+
+* Subscripting (``x[1]``) now tries the mapping protocol before the sequence protocol.
+  (https://github.com/cython/cython/issues/1807)
+* Exponentiation of integer literals now follows Python semantics and not C semantics.
+  (https://github.com/cython/cython/issues/2133)
+
+
+Binding functions
+=================
+
+The :ref:`binding directive <compiler-directives>` is now enabled by default.
+This makes Cython compiled Python (``def``) functions mostly compatible
+with normal (non-compiled) Python functions, regarding signature introspection,
+annotations, etc.
+
+It also makes them bind as methods in Python classes on attribute assignments,
+thus the name.
+If this is not intended, i.e. if a function is really meant to be a function
+and never a method, you can disable the binding (and all other Python function
+features) by setting ``binding=False`` or selectively adding a decorator
+``@cython.binding(False)``.
+In pure Python mode, the decorator was not available in Cython 0.29.16 yet,
+but compiled code does not suffer from this.
+
+We recommend, however, to keep the new function features and instead deal
+with the binding issue using the standard Python ``staticmethod()`` builtin.
+
+::
+
+    def func(self, b): ...
+
+    class MyClass(object):
+        binding_method = func
+
+        no_method = staticmethod(func)
+
+
+Namespace packages
+==================
+
+Cython now has support for loading pxd files also from namespace packages
+according to `PEP-420 <https://www.python.org/dev/peps/pep-0420/>`_.
+This might have an impact on the import path.
+
+
+NumPy C-API
+===========
+
+Cython used to generate code that depended on the deprecated pre-NumPy-1.7 C-API.
+This is no longer the case with Cython 3.0.
+
+You can now define the macro ``NPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION``
+to get rid of the long-standing build warnings that the compiled C module
+uses a deprecated API.  Either per file::
+
+    # distutils: define_macros=NPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION
+
+or by setting it in your Extensions in ``setup.py``::
+
+    Extension(...
+        define_macros=[("NPY_NO_DEPRECATED_API", "NPY_1_7_API_VERSION")]
+    )
+
+One side-effect of the different C-API usage is that your code may now
+require a call to the `NumPy C-API initialisation function
+<https://docs.scipy.org/doc/numpy-1.17.0/reference/c-api.array.html#importing-the-api>`_
+where it previously got away without doing so.
+
+In order to reduce the user impact here, Cython 3.0 will now call it
+automatically when it sees ``numpy`` being cimported, but the function
+not being used.
+In the (hopefully rare) cases where this gets in the way, the internal
+C-API initialisation can be disabled by faking the use of the function
+without actually calling it, e.g.
+
+::
+
+    # Explicitly disable the automatic initialisation of NumPy's C-API.
+    <void>import_array
+
+Class-private name mangling
+===========================
+
+Cython has been updated to follow the `Python rules for class-private names
+<https://docs.python.org/3/tutorial/classes.html#private-variables>`_
+more closely. Essentially any name that starts with and doesn't end with 
+``__`` within a class is mangled with the class name. Most user code
+should be unaffected -- unlike in Python unmangled global names will
+still be matched to ensure it is possible to access C names
+beginning with ``__``::
+
+     cdef extern void __foo()
+     
+     class C: # or "cdef class"
+        def call_foo(self):
+            return __foo() # still calls the global name
+            
+What will no-longer work is overriding methods starting with ``__`` in
+a ``cdef class``::
+
+    cdef class Base:
+        cdef __bar(self):
+            return 1
+
+        def call_bar(self):
+            return self.__bar()
+
+    cdef class Derived(Base):
+        cdef __bar(self):
+            return 2
+
+Here ``Base.__bar`` is mangled to ``_Base__bar`` and ``Derived.__bar``
+to ``_Derived__bar``. Therefore ``call_bar`` will always call 
+``_Base__bar``. This matches established Python behaviour and applies
+for ``def``, ``cdef`` and ``cpdef`` methods and attributes.
diff --git a/docs/src/userguide/numpy_pythran.rst b/docs/src/userguide/numpy_pythran.rst
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9zcmMvdXNlcmd1aWRlL251bXB5X3B5dGhyYW4ucnN0..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9zcmMvdXNlcmd1aWRlL251bXB5X3B5dGhyYW4ucnN0 100644
--- a/docs/src/userguide/numpy_pythran.rst
+++ b/docs/src/userguide/numpy_pythran.rst
@@ -16,7 +16,7 @@
 
 Please note that this feature is experimental.
 
-Usage example with distutils
-----------------------------
+Usage example with setuptools
+-----------------------------
 
 You first need to install Pythran. See its `documentation
@@ -21,7 +21,7 @@
 
 You first need to install Pythran. See its `documentation
-<http://pythran.readthedocs.io/en/latest/>`_ for more information.
+<https://pythran.readthedocs.io/>`_ for more information.
 
 Then, simply add a ``cython: np_pythran=True`` directive at the top of the
 Python files that needs to be compiled using Pythran numpy support.
 
@@ -24,8 +24,8 @@
 
 Then, simply add a ``cython: np_pythran=True`` directive at the top of the
 Python files that needs to be compiled using Pythran numpy support.
 
-Here is an example of a simple ``setup.py`` file using distutils:
+Here is an example of a simple ``setup.py`` file using setuptools:
 
 .. code::
 
@@ -29,5 +29,5 @@
 
 .. code::
 
-  from distutils.core import setup
+  from setuptools import setup
   from Cython.Build import cythonize
@@ -33,5 +33,5 @@
   from Cython.Build import cythonize
-  
+
   setup(
       name = "My hello app",
       ext_modules = cythonize('hello_pythran.pyx')
diff --git a/docs/src/userguide/numpy_tutorial.rst b/docs/src/userguide/numpy_tutorial.rst
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9zcmMvdXNlcmd1aWRlL251bXB5X3R1dG9yaWFsLnJzdA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9zcmMvdXNlcmd1aWRlL251bXB5X3R1dG9yaWFsLnJzdA== 100644
--- a/docs/src/userguide/numpy_tutorial.rst
+++ b/docs/src/userguide/numpy_tutorial.rst
@@ -65,7 +65,7 @@
    excellent support for using Cython and NumPy from an interactive command
    line or through a notebook interface (like
    Maple/Mathematica). See `this documentation
-   <http://doc.sagemath.org/html/en/developer/coding_in_cython.html>`_.
+   <https://doc.sagemath.org/html/en/developer/coding_in_cython.html>`_.
 2. Cython can be used as an extension within a Jupyter notebook,
    making it easy to compile and use Cython code with just a ``%%cython``
    at the top of a cell. For more information see
@@ -73,7 +73,7 @@
 3. A version of pyximport is shipped with Cython,
    so that you can import pyx-files dynamically into Python and
    have them compiled automatically (See :ref:`pyximport`).
-4. Cython supports distutils so that you can very easily create build scripts
+4. Cython supports setuptools so that you can very easily create build scripts
    which automate the process, this is the preferred method for
    Cython implemented libraries and packages.
    See :ref:`Basic setup.py <basic_setup.py>`.
@@ -487,8 +487,8 @@
 Where to go from here?
 ======================
 
-* If you want to learn how to make use of `BLAS <http://www.netlib.org/blas/>`_
-  or `LAPACK <http://www.netlib.org/lapack/>`_ with Cython, you can watch
+* If you want to learn how to make use of `BLAS <https://www.netlib.org/blas/>`_
+  or `LAPACK <https://www.netlib.org/lapack/>`_ with Cython, you can watch
   `the presentation of Ian Henriksen at SciPy 2015
   <https://www.youtube.com/watch?v=R4yB-8tB0J0&t=693s&ab_channel=Enthought>`_.
 * If you want to learn how to use Pythran as backend in Cython, you
diff --git a/docs/src/userguide/pypy.rst b/docs/src/userguide/pypy.rst
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9zcmMvdXNlcmd1aWRlL3B5cHkucnN0..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9zcmMvdXNlcmd1aWRlL3B5cHkucnN0 100644
--- a/docs/src/userguide/pypy.rst
+++ b/docs/src/userguide/pypy.rst
@@ -2,7 +2,7 @@
 ===========================
 
 Cython has basic support for cpyext, the layer in
-`PyPy <http://pypy.org/>`_ that emulates CPython's C-API.  This is
+`PyPy <https://pypy.org/>`_ that emulates CPython's C-API.  This is
 achieved by making the generated C code adapt at C compile time, so
 the generated code will compile in both CPython and PyPy unchanged.
 
diff --git a/docs/src/userguide/pyrex_differences.rst b/docs/src/userguide/pyrex_differences.rst
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9zcmMvdXNlcmd1aWRlL3B5cmV4X2RpZmZlcmVuY2VzLnJzdA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9zcmMvdXNlcmd1aWRlL3B5cmV4X2RpZmZlcmVuY2VzLnJzdA== 100644
--- a/docs/src/userguide/pyrex_differences.rst
+++ b/docs/src/userguide/pyrex_differences.rst
@@ -310,7 +310,7 @@
 
 Rather than introducing a new keyword ``typecheck`` as explained in the
 `Pyrex docs
-<http://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/version/Doc/Manual/special_methods.html>`_,
+<https://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/version/Doc/Manual/special_methods.html>`_,
 Cython emits a (non-spoofable and faster) typecheck whenever
 :func:`isinstance` is used with an extension type as the second parameter.
 
diff --git a/docs/src/userguide/source_files_and_compilation.rst b/docs/src/userguide/source_files_and_compilation.rst
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9zcmMvdXNlcmd1aWRlL3NvdXJjZV9maWxlc19hbmRfY29tcGlsYXRpb24ucnN0..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9zcmMvdXNlcmd1aWRlL3NvdXJjZV9maWxlc19hbmRfY29tcGlsYXRpb24ucnN0 100644
--- a/docs/src/userguide/source_files_and_compilation.rst
+++ b/docs/src/userguide/source_files_and_compilation.rst
@@ -53,7 +53,7 @@
 platform for generating an extension module. For these options look at the
 official Python documentation.
 
-The other, and probably better, way is to use the :mod:`distutils` extension
+The other, and probably better, way is to use the :mod:`setuptools` extension
 provided with Cython. The benefit of this method is that it will give the
 platform specific compilation options, acting like a stripped down autotools.
 
@@ -93,7 +93,7 @@
 After compilation, a ``yourmod.so`` (:file:`yourmod.pyd` for Windows)
 file is written into the target directory
 and your module, ``yourmod``, is available for you to import as with any other
-Python module.  Note that if you are not relying on ``cythonize`` or distutils,
+Python module.  Note that if you are not relying on ``cythonize`` or setuptools,
 you will not automatically benefit from the platform specific file extension
 that CPython generates for disambiguation, such as
 ``yourmod.cpython-35m-x86_64-linux-gnu.so`` on a regular 64bit Linux installation
@@ -103,10 +103,10 @@
 
 Basic setup.py
 ===============
-The distutils extension provided with Cython allows you to pass ``.pyx`` files
+The setuptools extension provided with Cython allows you to pass ``.pyx`` files
 directly to the ``Extension`` constructor in your setup file.
 
 If you have a single Cython file that you want to turn into a compiled
 extension, say with filename :file:`example.pyx` the associated :file:`setup.py`
 would be::
 
@@ -107,13 +107,13 @@
 directly to the ``Extension`` constructor in your setup file.
 
 If you have a single Cython file that you want to turn into a compiled
 extension, say with filename :file:`example.pyx` the associated :file:`setup.py`
 would be::
 
-    from distutils.core import setup
+    from setuptools import setup
     from Cython.Build import cythonize
 
     setup(
         ext_modules = cythonize("example.pyx")
     )
 
@@ -114,12 +114,20 @@
     from Cython.Build import cythonize
 
     setup(
         ext_modules = cythonize("example.pyx")
     )
 
-To understand the :file:`setup.py` more fully look at the official
-:mod:`distutils` documentation. To compile the extension for use in the
-current directory use:
+If your build depends directly on Cython in this way,
+then you may also want to inform pip that :mod:`Cython` is required for
+:file:`setup.py` to execute, following `PEP 518
+<https://www.python.org/dev/peps/pep-0518/>`, creating a :file:`pyproject.toml`
+file containing, at least::
+
+    [build-system]
+    requires = ["setuptools", "wheel", "Cython"]
+
+To understand the :file:`setup.py` more fully look at the official `setuptools
+documentation`_. To compile the extension for use in the current directory use:
 
 .. sourcecode:: text
 
@@ -131,7 +139,7 @@
 If you have include files in non-standard places you can pass an
 ``include_path`` parameter to ``cythonize``::
 
-    from distutils.core import setup
+    from setuptools import setup
     from Cython.Build import cythonize
 
     setup(
@@ -150,8 +158,8 @@
     you have to add the path to NumPy include files. You need to add this path only
     if you use ``cimport numpy``.
 
-Despite this, you will still get warnings like the
-following from the compiler, because Cython is using a deprecated Numpy API::
+Despite this, you may still get warnings like the following from the compiler,
+because Cython is not disabling the usage of the old deprecated Numpy API::
 
    .../include/numpy/npy_1_7_deprecated_api.h:15:2: warning: #warning "Using deprecated NumPy API, disable it by " "#defining NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION" [-Wcpp]
 
@@ -155,10 +163,29 @@
 
    .../include/numpy/npy_1_7_deprecated_api.h:15:2: warning: #warning "Using deprecated NumPy API, disable it by " "#defining NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION" [-Wcpp]
 
-For the time being, it is just a warning that you can ignore.
+In Cython 3.0, you can get rid of this warning by defining the C macro
+``NPY_NO_DEPRECATED_API`` as ``NPY_1_7_API_VERSION``
+in your build, e.g.::
+
+    # distutils: define_macros=NPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION
+
+or (see below)::
+
+    Extension(
+        ...,
+        define_macros=[("NPY_NO_DEPRECATED_API", "NPY_1_7_API_VERSION")],
+    )
+
+With older Cython releases, setting this macro will fail the C compilation,
+because Cython generates code that uses this deprecated C-API.  However, the
+warning has no negative effects even in recent NumPy versions including 1.18.x.
+You can ignore it until you (or your library's users) switch to a newer NumPy
+version that removes this long deprecated API, in which case you also need to
+use Cython 3.0 or later.  Thus, the earlier you switch to Cython 3.0, the
+better for your users.
 
 If you need to specify compiler options, libraries to link with or other
 linker options you will need to create ``Extension`` instances manually
 (note that glob syntax can still be used to specify multiple extensions
 in one line)::
 
@@ -159,11 +186,10 @@
 
 If you need to specify compiler options, libraries to link with or other
 linker options you will need to create ``Extension`` instances manually
 (note that glob syntax can still be used to specify multiple extensions
 in one line)::
 
-    from distutils.core import setup
-    from distutils.extension import Extension
+    from setuptools import Extension, setup
     from Cython.Build import cythonize
 
     extensions = [
@@ -182,7 +208,6 @@
         ext_modules=cythonize(extensions),
     )
 
-Note that when using setuptools, you should import it before Cython as
-setuptools may replace the ``Extension`` class in distutils.  Otherwise,
+Note that when using setuptools, you should import it before Cython, otherwise,
 both might disagree about the class to use here.
 
@@ -187,6 +212,6 @@
 both might disagree about the class to use here.
 
-Note also that if you use setuptools instead of distutils, the default
+Note also that if you use setuptools instead of :mod:`distutils`, the default
 action when running ``python setup.py install`` is to create a zipped
 ``egg`` file which will not work with ``cimport`` for ``pxd`` files
 when you try to use them from a dependent package.
@@ -204,7 +229,7 @@
 with other options, like ``include_dirs`` above).
 
 If you have some C files that have been wrapped with Cython and you want to
-compile them into your extension, you can define the distutils ``sources``
+compile them into your extension, you can define the setuptools ``sources``
 parameter::
 
     # distutils: sources = helper.c, another_helper.c
@@ -213,5 +238,5 @@
 extension module.  Spelling this out in the :file:`setup.py` file looks
 as follows::
 
-    from distutils.core import setup
+    from setuptools import Extension, setup
     from Cython.Build import cythonize
@@ -217,5 +242,4 @@
     from Cython.Build import cythonize
-    from distutils.extension import Extension
 
     sourcefiles = ['example.pyx', 'helper.c', 'another_helper.c']
 
@@ -226,7 +250,7 @@
     )
 
 The :class:`Extension` class takes many options, and a fuller explanation can
-be found in the `distutils documentation`_. Some useful options to know about
+be found in the `setuptools documentation`_. Some useful options to know about
 are ``include_dirs``, ``libraries``, and ``library_dirs`` which specify where
 to find the ``.h`` and library files when linking to external libraries.
 
@@ -230,6 +254,6 @@
 are ``include_dirs``, ``libraries``, and ``library_dirs`` which specify where
 to find the ``.h`` and library files when linking to external libraries.
 
-.. _distutils documentation: https://docs.python.org/extending/building.html
+.. _setuptools documentation: https://setuptools.readthedocs.io/
 
 Sometimes this is not enough and you need finer customization of the
@@ -234,6 +258,6 @@
 
 Sometimes this is not enough and you need finer customization of the
-distutils :class:`Extension`.
+setuptools :class:`Extension`.
 To do this, you can provide a custom function ``create_extension``
 to create the final :class:`Extension` object after Cython has processed
 the sources, dependencies and ``# distutils`` directives but before the
@@ -329,6 +353,6 @@
 may not be the same one you used, and may not compile your sources correctly.
 
 This simply means that the :file:`setup.py` file that you ship with will just
-be a normal distutils file on the generated `.c` files, for the basic example
+be a normal setuptools file on the generated `.c` files, for the basic example
 we would have instead::
 
@@ -333,7 +357,6 @@
 we would have instead::
 
-    from distutils.core import setup
-    from distutils.extension import Extension
+    from setuptools import Extension, setup
 
     setup(
         ext_modules = [Extension("example", ["example.c"])]
@@ -342,8 +365,7 @@
 This is easy to combine with :func:`cythonize` by changing the file extension
 of the extension module sources::
 
-    from distutils.core import setup
-    from distutils.extension import Extension
+    from setuptools import Extension, setup
 
     USE_CYTHON = ...   # command line option, try-import, ...
 
@@ -385,7 +407,4 @@
 Cython's build_ext module which runs ``cythonize`` as part of the build process::
 
     setup(
-        setup_requires=[
-            'cython>=0.x',
-        ],
         extensions = [Extension("*", ["*.pyx"])],
@@ -391,5 +410,5 @@
         extensions = [Extension("*", ["*.pyx"])],
-        cmdclass={'build_ext': Cython.Build.build_ext},
+        cmdclass={'build_ext': Cython.Build.new_build_ext},
         ...
     )
 
@@ -393,6 +412,12 @@
         ...
     )
 
+This depends on pip knowing that :mod:`Cython` is a setup dependency, by having
+a :file:`pyproject.toml` file::
+
+    [build-system]
+    requires = ["setuptools", "wheel", "Cython"]
+
 If you want to expose the C-level interface of your library for other
 libraries to cimport from, use package_data to install the ``.pxd`` files,
 e.g.::
@@ -522,7 +547,7 @@
 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
+something more sophisticated like informing setuptools of the dependencies
 directly.
 
 
@@ -538,7 +563,7 @@
 you wanted to write your program in half-C, half-Cython and build them
 into a single library.
 
-Pyximport does not hide the Distutils/GCC warnings and errors generated
+Pyximport does not hide the setuptools/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 feeling that pyximport really did rebuild your module as it
@@ -582,7 +607,7 @@
 code simply by typing ``%cython`` at the top of a cell and evaluate
 it. Variables and functions defined in a Cython cell are imported into the
 running session.  Please check `Sage documentation
-<http://www.sagemath.org/doc/>`_ for details.
+<https://www.sagemath.org/doc/>`_ for details.
 
 You can tailor the behavior of the Cython compiler by specifying the
 directives below.
@@ -623,6 +648,8 @@
 
 -a, --annotate                                Produce a colorized HTML version of the source.
 
+--annotate-fullc                              Produce a colorized HTML version of the source which includes entire generated C/C++-code.
+
 -+, --cplus                                   Output a C++ rather than C file.
 
 -f, --force                                   Force the compilation of a new module, even if the source has been previously compiled.
@@ -648,6 +675,7 @@
 --pgo                                         Enable profile guided optimisation in the C compiler. Compiles the cell twice and executes it in between to generate a runtime profile.
 
 --verbose                                     Print debug information like generated .c/.cpp file location and exact gcc/g++ command invoked.
+
 ============================================  =======================================================================================================================================
 
 
@@ -659,7 +687,7 @@
 Compiler options can be set in the :file:`setup.py`, before calling :func:`cythonize`,
 like this::
 
-    from distutils.core import setup
+    from setuptools import setup
 
     from Cython.Build import cythonize
     from Cython.Compiler import Options
@@ -675,7 +703,6 @@
 
 .. autodata:: Cython.Compiler.Options.docstrings
 .. autodata:: Cython.Compiler.Options.embed_pos_in_docstring
-.. autodata:: Cython.Compiler.Options.emit_code_comments
 .. pre_import
 .. autodata:: Cython.Compiler.Options.generate_cleanup_code
 .. autodata:: Cython.Compiler.Options.clear_to_none
@@ -711,7 +738,11 @@
     class attribute (hence the name) and will emulate the attributes
     of Python functions, including introspections like argument names and
     annotations.
-    Default is False.
+
+    Default is True.
+
+    .. versionchanged:: 3.0.0
+        Default changed from False to True 
 
 ``boundscheck``  (True / False)
     If set to False, Cython is free to assume that indexing operations
@@ -803,7 +834,7 @@
     into the compiled C code.  This also enables profiling.  Default is
     False.  Note that the generated module will not actually use line
     tracing, unless you additionally pass the C macro definition
-    ``CYTHON_TRACE=1`` to the C compiler (e.g. using the distutils option
+    ``CYTHON_TRACE=1`` to the C compiler (e.g. using the setuptools option
     ``define_macros``).  Define ``CYTHON_TRACE_NOGIL=1`` to also include
     ``nogil`` functions and sections.
 
@@ -856,4 +887,10 @@
     asyncio before Python 3.5.  This directive can be applied in modules or
     selectively as decorator on an async-def coroutine to make the affected
     coroutine(s) iterable and thus directly interoperable with yield-from.
+  
+``annotation_typing`` (True / False)
+    Uses function argument annotations to determine the type of variables. Default
+    is True, but can be disabled. Since Python does not enforce types given in
+    annotations, setting to False gives greater compatibility with Python code.
+    Must be set globally.
 
@@ -859,4 +896,8 @@
 
+``emit_code_comments`` (True / False)
+    Copy the original source code line by line into C code comments in the generated
+    code file to help with understanding the output.
+    This is also required for coverage analysis.
 
 .. _configurable_optimisations:
 
@@ -964,7 +1005,7 @@
 Compiler directives can also be set in the :file:`setup.py` file by passing a keyword
 argument to ``cythonize``::
 
-    from distutils.core import setup
+    from setuptools import setup
     from Cython.Build import cythonize
 
     setup(
diff --git a/docs/src/userguide/special_methods.rst b/docs/src/userguide/special_methods.rst
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9zcmMvdXNlcmd1aWRlL3NwZWNpYWxfbWV0aG9kcy5yc3Q=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9zcmMvdXNlcmd1aWRlL3NwZWNpYWxfbWV0aG9kcy5yc3Q= 100644
--- a/docs/src/userguide/special_methods.rst
+++ b/docs/src/userguide/special_methods.rst
@@ -43,5 +43,5 @@
 The :meth:`__cinit__` method is where you should perform basic C-level
 initialisation of the object, including allocation of any C data structures
 that your object will own. You need to be careful what you do in the
-:meth:`__cinit__` method, because the object may not yet be fully valid Python
+:meth:`__cinit__` method, because the object may not yet be a fully valid Python
 object when it is called. Therefore, you should be careful invoking any Python
@@ -47,5 +47,7 @@
 object when it is called. Therefore, you should be careful invoking any Python
-operations which might touch the object; in particular, its methods.
+operations which might touch the object; in particular, its methods and anything
+that could be overridden by subtypes (and thus depend on their subtype state being
+initialised already).
 
 By the time your :meth:`__cinit__` method is called, memory has been allocated for the
 object and any C attributes it has have been initialised to 0 or null. (Any
@@ -53,12 +55,13 @@
 shouldn't rely on that.) Your :meth:`__cinit__` method is guaranteed to be called
 exactly once.
 
-If your extension type has a base type, the :meth:`__cinit__` method of the base type
-is automatically called before your :meth:`__cinit__` method is called; you cannot
-explicitly call the inherited :meth:`__cinit__` method. If you need to pass a modified
-argument list to the base type, you will have to do the relevant part of the
-initialisation in the :meth:`__init__` method instead (where the normal rules for
-calling inherited methods apply).
+If your extension type has a base type, any existing :meth:`__cinit__` methods in
+the base type hierarchy are automatically called before your :meth:`__cinit__`
+method.  You cannot explicitly call the inherited :meth:`__cinit__` methods, and the
+base types are free to choose whether they implement :meth:`__cinit__` at all.
+If you need to pass a modified argument list to the base type, you will have to do
+the relevant part of the initialisation in the :meth:`__init__` method instead, where
+the normal rules for calling inherited methods apply.
 
 Any initialisation which cannot safely be done in the :meth:`__cinit__` method should
 be done in the :meth:`__init__` method. By the time :meth:`__init__` is called, the object is
@@ -212,9 +215,9 @@
 +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
 | __dealloc__           |self 	                                |             | Basic deallocation (no direct Python equivalent)    |
 +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
-| __cmp__               |x, y 	                                | int         | 3-way comparison                                    |
+| __cmp__               |x, y 	                                | int         | 3-way comparison (Python 2 only)                    |
 +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
 | __str__               |self 	                                | object      | str(self)                                           |
 +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
 | __repr__              |self 	                                | object      | repr(self)                                          |
 +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
@@ -216,9 +219,9 @@
 +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
 | __str__               |self 	                                | object      | str(self)                                           |
 +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
 | __repr__              |self 	                                | object      | repr(self)                                          |
 +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
-| __hash__              |self 	                                | int         | Hash function                                       |
+| __hash__              |self 	                                | Py_hash_t   | Hash function (returns 32/64 bit integer)           |
 +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
 | __call__              |self, ...                              | object      | self(...)                                           |
 +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
@@ -372,7 +375,7 @@
 +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
 | Name 	                | Parameters                            | Return type | 	Description                                 |
 +=======================+=======================================+=============+=====================================================+
-| __len__ 	        | self 	int 	                        |             | len(self)                                           |
+| __len__               | self                                  | Py_ssize_t  | len(self)                                           |
 +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
 | __getitem__ 	        | self, x 	                        | object      | self[x]                                             |
 +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
diff --git a/docs/src/userguide/wrapping_CPlusPlus.rst b/docs/src/userguide/wrapping_CPlusPlus.rst
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_ZG9jcy9zcmMvdXNlcmd1aWRlL3dyYXBwaW5nX0NQbHVzUGx1cy5yc3Q=..162972e7c0335748b70e02edc37e5e3bbb4858ae_ZG9jcy9zcmMvdXNlcmd1aWRlL3dyYXBwaW5nX0NQbHVzUGx1cy5yc3Q= 100644
--- a/docs/src/userguide/wrapping_CPlusPlus.rst
+++ b/docs/src/userguide/wrapping_CPlusPlus.rst
@@ -97,7 +97,7 @@
         pass
 
 to include the C++ code from :file:`Rectangle.cpp`. It is also possible to specify to
-distutils that :file:`Rectangle.cpp` is a source. To do that, you can add this directive at the
+setuptools that :file:`Rectangle.cpp` is a source. To do that, you can add this directive at the
 top of the ``.pyx`` (not ``.pxd``) file::
 
     # distutils: sources = Rectangle.cpp
@@ -527,7 +527,7 @@
 Instead of specifying the language and the sources in the source files, it is
 possible to declare them in the :file:`setup.py` file::
 
-   from distutils.core import setup
+   from setuptools import setup
    from Cython.Build import cythonize
 
    setup(ext_modules = cythonize(
@@ -553,7 +553,7 @@
 option to an :class:`Extension` that describes your extension and that
 is then handled by ``cythonize()`` as follows::
 
-   from distutils.core import setup, Extension
+   from setuptools import Extension, setup
    from Cython.Build import cythonize
 
    setup(ext_modules = cythonize(Extension(
@@ -568,7 +568,7 @@
 version 0.17, Cython also allows passing external source files into the
 ``cythonize()`` command this way.  Here is a simplified setup.py file::
 
-   from distutils.core import setup
+   from setuptools import setup
    from Cython.Build import cythonize
 
    setup(
@@ -586,8 +586,8 @@
 .. note::
 
      When using distutils directives, the paths are relative to the working
-     directory of the distutils run (which is usually the
-     project root where the :file:`setup.py` resides).
+     directory of the setuptools run (which is usually the project root where
+     the :file:`setup.py` resides).
 
 To compile manually (e.g. using ``make``), the ``cython`` command-line
 utility can be used to generate a C++ ``.cpp`` file, and then compile it
diff --git a/pyximport/pyxbuild.py b/pyximport/pyxbuild.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_cHl4aW1wb3J0L3B5eGJ1aWxkLnB5..162972e7c0335748b70e02edc37e5e3bbb4858ae_cHl4aW1wb3J0L3B5eGJ1aWxkLnB5 100644
--- a/pyximport/pyxbuild.py
+++ b/pyximport/pyxbuild.py
@@ -103,7 +103,7 @@
         so_path = obj_build_ext.get_outputs()[0]
         if obj_build_ext.inplace:
             # Python distutils get_outputs()[ returns a wrong so_path
-            # when --inplace ; see http://bugs.python.org/issue5977
+            # when --inplace ; see https://bugs.python.org/issue5977
             # workaround:
             so_path = os.path.join(os.path.dirname(filename),
                                    os.path.basename(so_path))
diff --git a/pyximport/pyximport.py b/pyximport/pyximport.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_cHl4aW1wb3J0L3B5eGltcG9ydC5weQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_cHl4aW1wb3J0L3B5eGltcG9ydC5weQ== 100644
--- a/pyximport/pyximport.py
+++ b/pyximport/pyximport.py
@@ -350,7 +350,7 @@
                             language_level=language_level)
         self.uncompilable_modules = {}
         self.blocked_modules = ['Cython', 'pyxbuild', 'pyximport.pyxbuild',
-                                'distutils.extension', 'distutils.sysconfig']
+                                'distutils']
 
     def find_module(self, fullname, package_path=None):
         if fullname in sys.modules:
diff --git a/pyximport/test/test_pyximport.py b/pyximport/test/test_pyximport.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_cHl4aW1wb3J0L3Rlc3QvdGVzdF9weXhpbXBvcnQucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_cHl4aW1wb3J0L3Rlc3QvdGVzdF9weXhpbXBvcnQucHk= 100644
--- a/pyximport/test/test_pyximport.py
+++ b/pyximport/test/test_pyximport.py
@@ -68,7 +68,7 @@
 
     time.sleep(1) # sleep a second to get safer mtimes
     open(os.path.join(tempdir, "abc.txt"), "w").write(" ")
-    print("Here goes the reolad")
+    print("Here goes the reload")
     reload(dummy)
     assert len(pyximport._test_files) == 1, pyximport._test_files
 
diff --git a/runtests.py b/runtests.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_cnVudGVzdHMucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_cnVudGVzdHMucHk= 100755
--- a/runtests.py
+++ b/runtests.py
@@ -3,6 +3,7 @@
 from __future__ import print_function
 
 import atexit
+import base64
 import os
 import sys
 import re
@@ -21,6 +22,7 @@
 import zlib
 import glob
 from contextlib import contextmanager
+from collections import defaultdict
 
 try:
     import platform
@@ -29,6 +31,7 @@
 except (ImportError, AttributeError):
     IS_CPYTHON = True
     IS_PYPY = False
+IS_PY2 = sys.version_info[0] < 3
 
 from io import open as io_open
 try:
@@ -47,26 +50,6 @@
     threading = None
 
 try:
-    from collections import defaultdict
-except ImportError:
-    class defaultdict(object):
-        def __init__(self, default_factory=lambda : None):
-            self._dict = {}
-            self.default_factory = default_factory
-        def __getitem__(self, key):
-            if key not in self._dict:
-                self._dict[key] = self.default_factory()
-            return self._dict[key]
-        def __setitem__(self, key, value):
-            self._dict[key] = value
-        def __contains__(self, key):
-            return key in self._dict
-        def __repr__(self):
-            return repr(self._dict)
-        def __nonzero__(self):
-            return bool(self._dict)
-
-try:
     from unittest import SkipTest
 except ImportError:
     class SkipTest(Exception):  # don't raise, only provided to allow except-ing it!
@@ -87,7 +70,6 @@
 
 from distutils.command.build_ext import build_ext as _build_ext
 from distutils import sysconfig
-from distutils import ccompiler
 _to_clean = []
 
 @atexit.register
@@ -115,7 +97,7 @@
     distutils_distro = Distribution()
 
     if sys.platform == 'win32':
-        # TODO: Figure out why this hackery (see http://thread.gmane.org/gmane.comp.python.cython.devel/8280/).
+        # TODO: Figure out why this hackery (see https://thread.gmane.org/gmane.comp.python.cython.devel/8280/).
         config_files = distutils_distro.find_config_files()
         try:
             config_files.remove('setup.cfg')
@@ -135,7 +117,6 @@
 
 EXT_DEP_MODULES = {
     'tag:numpy':     'numpy',
-    'tag:numpy_old': 'numpy',
     'tag:pythran':  'pythran',
     'tag:setuptools':  'setuptools.sandbox',
     'tag:asyncio':  'asyncio',
@@ -255,10 +236,6 @@
     return ext
 
 
-def update_old_numpy_extension(ext):
-    update_numpy_extension(ext, set_api17_macro=False)
-
-
 def update_numpy_extension(ext, set_api17_macro=True):
     import numpy
     from numpy.distutils.misc_util import get_info
@@ -329,7 +306,8 @@
     else:
         cc = sysconfig.get_config_var('CC')
     if not cc:
-       cc = ccompiler.get_default_compiler()
+        from distutils import ccompiler
+        cc = ccompiler.get_default_compiler()
 
     if not cc:
         return ''
@@ -399,9 +377,8 @@
 
 EXT_EXTRAS = {
     'tag:numpy' : update_numpy_extension,
-    'tag:numpy_old' : update_old_numpy_extension,
     'tag:openmp': update_openmp_extension,
     'tag:cpp11': update_cpp11_extension,
     'tag:trace' : update_linetrace_extension,
     'tag:bytesformat':  exclude_extension_in_pyver((3, 3), (3, 4)),  # no %-bytes formatting
     'tag:no-macos':  exclude_extension_on_platform('darwin'),
@@ -403,8 +380,9 @@
     'tag:openmp': update_openmp_extension,
     'tag:cpp11': update_cpp11_extension,
     'tag:trace' : update_linetrace_extension,
     'tag:bytesformat':  exclude_extension_in_pyver((3, 3), (3, 4)),  # no %-bytes formatting
     'tag:no-macos':  exclude_extension_on_platform('darwin'),
+    'tag:py3only':  exclude_extension_in_pyver((2, 7)),
 }
 
 
@@ -412,15 +390,10 @@
 VER_DEP_MODULES = {
     # tests are excluded if 'CurrentPythonVersion OP VersionTuple', i.e.
     # (2,4) : (operator.lt, ...) excludes ... when PyVer < 2.4.x
-    (2,7) : (operator.lt, lambda x: x in ['run.withstat_py27', # multi context with statement
-                                          'run.yield_inside_lambda',
-                                          'run.test_dictviews',
-                                          'run.pyclass_special_methods',
-                                          'run.set_literals',
-                                          ]),
+
     # The next line should start (3,); but this is a dictionary, so
     # we can only have one (3,) key.  Since 2.7 is supposed to be the
     # last 2.x release, things would have to change drastically for this
     # to be unsafe...
     (2,999): (operator.lt, lambda x: x in ['run.special_methods_T561_py3',
                                            'run.test_raisefrom',
@@ -421,10 +394,13 @@
     # The next line should start (3,); but this is a dictionary, so
     # we can only have one (3,) key.  Since 2.7 is supposed to be the
     # last 2.x release, things would have to change drastically for this
     # to be unsafe...
     (2,999): (operator.lt, lambda x: x in ['run.special_methods_T561_py3',
                                            'run.test_raisefrom',
+                                           'run.different_package_names',
+                                           'run.unicode_imports',  # encoding problems on appveyor in Py2
+                                           'run.reimport_failure',  # reimports don't do anything in Py2
                                            ]),
     (3,): (operator.ge, lambda x: x in ['run.non_future_division',
                                         'compile.extsetslice',
                                         'compile.extdelslice',
@@ -427,7 +403,7 @@
                                            ]),
     (3,): (operator.ge, lambda x: x in ['run.non_future_division',
                                         'compile.extsetslice',
                                         'compile.extdelslice',
-                                        'run.special_methods_T561_py2'
+                                        'run.special_methods_T561_py2',
                                         ]),
     (3,3) : (operator.lt, lambda x: x in ['build.package_compilation',
@@ -432,4 +408,5 @@
                                         ]),
     (3,3) : (operator.lt, lambda x: x in ['build.package_compilation',
+                                          'build.cythonize_pep420_namespace',
                                           'run.yield_from_py33',
                                           'pyximport.pyximport_namespace',
@@ -434,5 +411,6 @@
                                           'run.yield_from_py33',
                                           'pyximport.pyximport_namespace',
+                                          'run.qualname',
                                           ]),
     (3,4): (operator.lt, lambda x: x in ['run.py34_signature',
                                          'run.test_unicode',  # taken from Py3.7, difficult to backport
@@ -500,7 +478,7 @@
     return tags
 
 
-list_unchanging_dir = memoize(lambda x: os.listdir(x))
+list_unchanging_dir = memoize(lambda x: os.listdir(x))  # needs lambda to set function attribute
 
 
 @memoize
@@ -546,5 +524,5 @@
 class ErrorWriter(object):
     match_error = re.compile(r'(warning:)?(?:.*:)?\s*([-0-9]+)\s*:\s*([-0-9]+)\s*:\s*(.*)').match
 
-    def __init__(self):
+    def __init__(self, encoding=None):
         self.output = []
@@ -550,5 +528,10 @@
         self.output = []
-        self.write = self.output.append
+        self.encoding = encoding
+
+    def write(self, value):
+        if self.encoding:
+            value = value.encode('ISO-8859-1').decode(self.encoding)
+        self.output.append(value)
 
     def _collect(self):
         s = ''.join(self.output)
@@ -645,8 +628,9 @@
         self.default_mode = default_mode
         self.stats = stats
         self.add_embedded_test = add_embedded_test
+        self.capture = options.capture
 
     def build_suite(self):
         suite = unittest.TestSuite()
         filenames = os.listdir(self.rootdir)
         filenames.sort()
@@ -648,8 +632,9 @@
 
     def build_suite(self):
         suite = unittest.TestSuite()
         filenames = os.listdir(self.rootdir)
         filenames.sort()
+        # TODO: parallelise I/O with a thread pool for the different directories once we drop Py2 support
         for filename in filenames:
             path = os.path.join(self.rootdir, filename)
             if os.path.isdir(path) and filename != TEST_SUPPORT_DIR:
@@ -702,7 +687,9 @@
 
             if ext == '.srctree':
                 if 'cpp' not in tags['tag'] or 'cpp' in self.languages:
-                    suite.addTest(EndToEndTest(filepath, workdir, self.cleanup_workdir, stats=self.stats))
+                    suite.addTest(EndToEndTest(filepath, workdir,
+                             self.cleanup_workdir, stats=self.stats,
+                             capture=self.capture))
                 continue
 
             # Choose the test suite.
@@ -754,6 +741,7 @@
         elif 'no-cpp' in tags['tag'] and 'cpp' in self.languages:
             languages = list(languages)
             languages.remove('cpp')
+        language_levels = [2, 3] if 'all_language_levels' in tags['tag'] else [None]
 
         pythran_dir = self.pythran_dir
         if 'pythran' in tags['tag'] and not pythran_dir and 'cpp' in languages:
@@ -765,7 +753,7 @@
             pythran_dir = pythran_ext['include_dirs'][0]
 
         preparse_list = tags.get('preparse', ['id'])
-        tests = [ self.build_test(test_class, path, workdir, module, tags, language,
+        tests = [ self.build_test(test_class, path, workdir, module, tags, language, language_level,
                                   expect_errors, expect_warnings, warning_errors, preparse,
                                   pythran_dir if language == "cpp" else None)
                   for language in languages
@@ -769,6 +757,8 @@
                                   expect_errors, expect_warnings, warning_errors, preparse,
                                   pythran_dir if language == "cpp" else None)
                   for language in languages
-                  for preparse in preparse_list ]
+                  for preparse in preparse_list
+                  for language_level in language_levels
+        ]
         return tests
 
@@ -773,9 +763,9 @@
         return tests
 
-    def build_test(self, test_class, path, workdir, module, tags, language,
+    def build_test(self, test_class, path, workdir, module, tags, language, language_level,
                    expect_errors, expect_warnings, warning_errors, preparse, pythran_dir):
         language_workdir = os.path.join(workdir, language)
         if not os.path.exists(language_workdir):
             os.makedirs(language_workdir)
         workdir = os.path.join(language_workdir, module)
         if preparse != 'id':
@@ -776,10 +766,12 @@
                    expect_errors, expect_warnings, warning_errors, preparse, pythran_dir):
         language_workdir = os.path.join(workdir, language)
         if not os.path.exists(language_workdir):
             os.makedirs(language_workdir)
         workdir = os.path.join(language_workdir, module)
         if preparse != 'id':
-            workdir += '_%s' % str(preparse)
+            workdir += '_%s' % (preparse,)
+        if language_level:
+            workdir += '_cy%d' % (language_level,)
         return test_class(path, workdir, module, tags,
                           language=language,
                           preparse=preparse,
@@ -791,7 +783,7 @@
                           cleanup_failures=self.cleanup_failures,
                           cython_only=self.cython_only,
                           fork=self.fork,
-                          language_level=self.language_level,
+                          language_level=language_level or self.language_level,
                           warning_errors=warning_errors,
                           test_determinism=self.test_determinism,
                           common_utility_dir=self.common_utility_dir,
@@ -858,9 +850,17 @@
         unittest.TestCase.__init__(self)
 
     def shortDescription(self):
-        return "compiling (%s%s) %s" % (self.language, "/pythran" if self.pythran_dir is not None else "", self.name)
+        return "compiling (%s%s%s) %s" % (
+            self.language,
+            "/cy2" if self.language_level == 2 else "/cy3" if self.language_level == 3 else "",
+            "/pythran" if self.pythran_dir is not None else "",
+            self.description_name()
+        )
+
+    def description_name(self):
+        return self.name
 
     def setUp(self):
         from Cython.Compiler import Options
         self._saved_options = [
             (name, getattr(Options, name))
@@ -862,9 +862,15 @@
 
     def setUp(self):
         from Cython.Compiler import Options
         self._saved_options = [
             (name, getattr(Options, name))
-            for name in ('warning_errors', 'clear_to_none', 'error_on_unknown_names', 'error_on_uninitialized')
+            for name in (
+                'warning_errors',
+                'clear_to_none',
+                'error_on_unknown_names',
+                'error_on_uninitialized',
+                # 'cache_builtins',  # not currently supported due to incorrect global caching
+            )
         ]
         self._saved_default_directives = list(Options.get_directive_defaults().items())
         Options.warning_errors = self.warning_errors
@@ -901,4 +907,5 @@
                 shutil.rmtree(self.workdir, ignore_errors=True)
             else:
                 for rmfile in os.listdir(self.workdir):
+                    ext = os.path.splitext(rmfile)[1]
                     if not cleanup_c_files:
@@ -904,6 +911,9 @@
                     if not cleanup_c_files:
-                        if (rmfile[-2:] in (".c", ".h") or
-                                rmfile[-4:] == ".cpp" or
-                                rmfile.endswith(".html") and rmfile.startswith(self.module)):
+                        # Keep C, C++ files, header files, preprocessed sources
+                        # and assembly sources (typically the .i and .s files
+                        # are intentionally generated when -save-temps is given)
+                        if ext in (".c", ".cpp", ".h", ".i", ".ii", ".s"):
+                            continue
+                        if ext == ".html" and rmfile.startswith(self.module):
                             continue
 
@@ -908,6 +918,6 @@
                             continue
 
-                    is_shared_obj = rmfile.endswith(".so") or rmfile.endswith(".dll")
+                    is_shared_obj = ext in (".so", ".dll")
 
                     if not cleanup_lib_files and is_shared_obj:
                         continue
@@ -983,6 +993,13 @@
 
     def split_source_and_output(self, test_directory, module, workdir):
         source_file = self.find_module_source_file(os.path.join(test_directory, module) + '.pyx')
+
+        from Cython.Utils import detect_opened_file_encoding
+        with io_open(source_file, 'rb') as f:
+            # encoding is passed to ErrorWriter but not used on the source
+            # since it is sometimes deliberately wrong
+            encoding = detect_opened_file_encoding(f, default=None)
+
         with io_open(source_file, 'r', encoding='ISO-8859-1') as source_and_output:
             error_writer = warnings_writer = None
             out = io_open(os.path.join(workdir, module + os.path.splitext(source_file)[1]),
@@ -991,6 +1008,6 @@
                 for line in source_and_output:
                     if line.startswith("_ERRORS"):
                         out.close()
-                        out = error_writer = ErrorWriter()
+                        out = error_writer = ErrorWriter(encoding=encoding)
                     elif line.startswith("_WARNINGS"):
                         out.close()
@@ -995,6 +1012,6 @@
                     elif line.startswith("_WARNINGS"):
                         out.close()
-                        out = warnings_writer = ErrorWriter()
+                        out = warnings_writer = ErrorWriter(encoding=encoding)
                     else:
                         out.write(line)
             finally:
@@ -1027,5 +1044,5 @@
         try:
             CompilationOptions
         except NameError:
-            from Cython.Compiler.Main import CompilationOptions
+            from Cython.Compiler.Options import CompilationOptions
             from Cython.Compiler.Main import compile as cython_compile
@@ -1031,5 +1048,5 @@
             from Cython.Compiler.Main import compile as cython_compile
-            from Cython.Compiler.Main import default_options
+            from Cython.Compiler.Options import default_options
         common_utility_include_dir = self.common_utility_dir
 
         options = CompilationOptions(
@@ -1095,6 +1112,11 @@
                 from Cython.Build.Dependencies import update_pythran_extension
                 update_pythran_extension(extension)
 
+            # Compile with -DCYTHON_CLINE_IN_TRACEBACK=1 unless we have
+            # the "traceback" tag
+            if 'traceback' not in self.tags['tag']:
+                extension.define_macros.append(("CYTHON_CLINE_IN_TRACEBACK", 1))
+
             for matcher, fixer in list(EXT_EXTRAS.items()):
                 if isinstance(matcher, str):
                     # lazy init
@@ -1109,6 +1131,8 @@
                     extension = newext or extension
             if self.language == 'cpp':
                 extension.language = 'c++'
+            if IS_PY2:
+                workdir = str(workdir)  # work around type check in distutils that disallows unicode strings
             build_extension.extensions = [extension]
             build_extension.build_temp = workdir
             build_extension.build_lib  = workdir
@@ -1205,7 +1229,11 @@
             finally:
                 if show_output:
                     stdout = get_stdout and get_stdout().strip()
+                    stderr = get_stderr and filter_stderr(get_stderr()).strip()
+                    if so_path and not stderr:
+                        # normal success case => ignore non-error compiler output
+                        stdout = None
                     if stdout:
                         print_bytes(
                             stdout, header_text="\n=== C/C++ compiler output: =========\n",
                             end=None, file=sys.__stderr__)
@@ -1208,8 +1236,7 @@
                     if stdout:
                         print_bytes(
                             stdout, header_text="\n=== C/C++ compiler output: =========\n",
                             end=None, file=sys.__stderr__)
-                    stderr = get_stderr and filter_stderr(get_stderr()).strip()
                     if stderr:
                         print_bytes(
                             stderr, header_text="\n=== C/C++ compiler error output: ===\n",
@@ -1243,11 +1270,8 @@
         from Cython.Compiler import Options
         Options.clear_to_none = False
 
-    def shortDescription(self):
-        if self.cython_only:
-            return CythonCompileTestCase.shortDescription(self)
-        else:
-            return "compiling (%s%s) and running %s" % (self.language, "/pythran" if self.pythran_dir is not None else "", self.name)
+    def description_name(self):
+        return self.name if self.cython_only else "and running %s" % self.name
 
     def run(self, result=None):
         if result is None:
@@ -1258,8 +1282,7 @@
             try:
                 self.success = False
                 ext_so_path = self.runCompileTest()
-                # Py2.6 lacks "_TextTestResult.skipped"
-                failures, errors, skipped = len(result.failures), len(result.errors), len(getattr(result, 'skipped', []))
+                failures, errors, skipped = len(result.failures), len(result.errors), len(result.skipped)
                 if not self.cython_only and ext_so_path is not None:
                     self.run_tests(result, ext_so_path)
                 if failures == len(result.failures) and errors == len(result.errors):
@@ -1442,10 +1465,6 @@
         _TextTestResult.__init__(
             self, self._StringIO(), True,
             base_result.dots + base_result.showAll*2)
-        try:
-            self.skipped
-        except AttributeError:
-            self.skipped = []  # Py2.6
 
     def strip_error_results(self, results):
         for test_case, error in results:
@@ -1470,10 +1489,7 @@
         if output:
             result.stream.write(output)
         result.errors.extend(errors)
-        try:
-            result.skipped.extend(skipped)
-        except AttributeError:
-            pass  # Py2.6
+        result.skipped.extend(skipped)
         result.failures.extend(failures)
         result.testsRun += tests_run
 
@@ -1486,7 +1502,7 @@
 
 class CythonUnitTestCase(CythonRunTestCase):
     def shortDescription(self):
-        return "compiling (%s) tests in %s" % (self.language, self.name)
+        return "compiling (%s) tests in %s" % (self.language, self.description_name())
 
     def run_tests(self, result, ext_so_path):
         with self.stats.time(self.name, self.language, 'import'):
@@ -1579,5 +1595,5 @@
 
     def runTest(self):
         import pycodestyle
-        config_file = os.path.join(self.cython_dir, "tox.ini")
+        config_file = os.path.join(self.cython_dir, "setup.cfg")
         if not os.path.exists(config_file):
@@ -1583,6 +1599,8 @@
         if not os.path.exists(config_file):
-            config_file=os.path.join(os.path.dirname(__file__), "tox.ini")
-        paths = glob.glob(os.path.join(self.cython_dir, "**/*.py"), recursive=True)
+            config_file=os.path.join(os.path.dirname(__file__), "setup.cfg")
+        paths = []
+        for codedir in ['Cython', 'Demos', 'docs', 'pyximport', 'tests']:
+            paths += glob.glob(os.path.join(self.cython_dir, codedir + "/**/*.py"), recursive=True)
         style = pycodestyle.StyleGuide(config_file=config_file)
         print("")  # Fix the first line of the report.
         result = style.check_files(paths)
@@ -1682,9 +1700,10 @@
     """
     cython_root = os.path.dirname(os.path.abspath(__file__))
 
-    def __init__(self, treefile, workdir, cleanup_workdir=True, stats=None):
+    def __init__(self, treefile, workdir, cleanup_workdir=True, stats=None,
+                 capture=True):
         self.name = os.path.splitext(os.path.basename(treefile))[0]
         self.treefile = treefile
         self.workdir = os.path.join(workdir, self.name)
         self.cleanup_workdir = cleanup_workdir
         self.stats = stats
@@ -1686,8 +1705,9 @@
         self.name = os.path.splitext(os.path.basename(treefile))[0]
         self.treefile = treefile
         self.workdir = os.path.join(workdir, self.name)
         self.cleanup_workdir = cleanup_workdir
         self.stats = stats
+        self.capture = capture
         cython_syspath = [self.cython_root]
         for path in sys.path:
             if path.startswith(self.cython_root) and path not in cython_syspath:
@@ -1703,6 +1723,6 @@
 
     def setUp(self):
         from Cython.TestUtils import unpack_source_tree
-        _, self.commands = unpack_source_tree(self.treefile, self.workdir)
+        _, self.commands = unpack_source_tree(self.treefile, self.workdir, self.cython_root)
         self.old_dir = os.getcwd()
         os.chdir(self.workdir)
@@ -1707,7 +1727,5 @@
         self.old_dir = os.getcwd()
         os.chdir(self.workdir)
-        if self.workdir not in sys.path:
-            sys.path.insert(0, self.workdir)
 
     def tearDown(self):
         if self.cleanup_workdir:
@@ -1728,10 +1746,7 @@
 
     def runTest(self):
         self.success = False
-        commands = (self.commands
-            .replace("CYTHON", "PYTHON %s" % os.path.join(self.cython_root, 'cython.py'))
-            .replace("PYTHON", sys.executable))
         old_path = os.environ.get('PYTHONPATH')
         env = dict(os.environ)
         new_path = self.cython_syspath
         if old_path:
@@ -1734,6 +1749,6 @@
         old_path = os.environ.get('PYTHONPATH')
         env = dict(os.environ)
         new_path = self.cython_syspath
         if old_path:
-            new_path = new_path + os.pathsep + old_path
+            new_path = new_path + os.pathsep + self.workdir + os.pathsep + old_path
         env['PYTHONPATH'] = new_path
@@ -1739,4 +1754,6 @@
         env['PYTHONPATH'] = new_path
+        if not env.get("PYTHONIOENCODING"):
+            env["PYTHONIOENCODING"] = sys.stdout.encoding or sys.getdefaultencoding()
         cmd = []
         out = []
         err = []
@@ -1740,5 +1757,5 @@
         cmd = []
         out = []
         err = []
-        for command_no, command in enumerate(filter(None, commands.splitlines()), 1):
+        for command_no, command in enumerate(self.commands, 1):
             with self.stats.time('%s(%d)' % (self.name, command_no), 'c',
@@ -1744,11 +1761,13 @@
             with self.stats.time('%s(%d)' % (self.name, command_no), 'c',
-                                 'etoe-build' if ' setup.py ' in command else 'etoe-run'):
-                p = subprocess.Popen(command,
-                                     stderr=subprocess.PIPE,
-                                     stdout=subprocess.PIPE,
-                                     shell=True,
-                                     env=env)
-                _out, _err = p.communicate()
+                                 'etoe-build' if 'setup.py' in command else 'etoe-run'):
+                if self.capture:
+                    p = subprocess.Popen(command, stderr=subprocess.PIPE, stdout=subprocess.PIPE, env=env)
+                    _out, _err = p.communicate()
+                    res = p.returncode
+                else:
+                    p = subprocess.call(command, env=env)
+                    _out, _err = b'', b''
+                    res = p
                 cmd.append(command)
                 out.append(_out)
                 err.append(_err)
@@ -1752,7 +1771,6 @@
                 cmd.append(command)
                 out.append(_out)
                 err.append(_err)
-            res = p.returncode
             if res != 0:
                 for c, o, e in zip(cmd, out, err):
                     sys.stderr.write("%s\n%s\n%s\n\n" % (
@@ -1796,6 +1814,5 @@
         if sys.version_info[0] >=3 and CY3_DIR:
             cython = os.path.join(CY3_DIR, cython)
         cython = os.path.abspath(os.path.join('..', '..', cython))
-        self.assertEqual(0, os.system(
-            "make PYTHON='%s' CYTHON='%s' LIBDIR1='%s' test > make.output" % (sys.executable, cython, libdir)))
+
         try:
@@ -1801,6 +1818,14 @@
         try:
-            os.remove('make.output')
-        except OSError:
-            pass
+            subprocess.check_output([
+                "make",
+                "PYTHON='%s'" % sys.executable,
+                "CYTHON='%s'" % cython,
+                "LIBDIR1='%s'" % libdir,
+                "paths", "test",
+            ])
+        except subprocess.CalledProcessError as err:
+            print(err.output.decode())
+            raise
+        self.assertTrue(True)  # :)
 
 
@@ -1805,5 +1830,10 @@
 
 
+def load_listfile(filename):
+    # just re-use the FileListExclude implementation
+    fle = FileListExcluder(filename)
+    return list(fle.excludes)
+
 class MissingDependencyExcluder(object):
     def __init__(self, deps):
         # deps: { matcher func : module name }
@@ -1851,8 +1881,7 @@
                     self.excludes[line.split()[0]] = True
 
     def __call__(self, testname, tags=None):
-        exclude = (testname in self.excludes
-                   or testname.split('.')[-1] in self.excludes)
+        exclude = any(string_selector(ex)(testname) for ex in self.excludes)
         if exclude and self.verbose:
             print("Excluding %s because it's listed in %s"
                   % (testname, self._list_file))
@@ -1894,7 +1923,11 @@
     # This is an exclude selector so it can override the (include) selectors.
     # It may not provide uniform distribution (in time or count), but is a
     # determanistic partition of the tests which is important.
+
+    # Random seed to improve the hash distribution.
+    _seed = base64.b64decode(b'2ged1EtsGz/GkisJr22UcLeP6n9XIaA5Vby2wM49Wvg=')
+
     def __init__(self, shard_num, shard_count):
         self.shard_num = shard_num
         self.shard_count = shard_count
 
@@ -1897,7 +1930,7 @@
     def __init__(self, shard_num, shard_count):
         self.shard_num = shard_num
         self.shard_count = shard_count
 
-    def __call__(self, testname, tags=None, _hash=zlib.crc32, _is_py2=sys.version_info[0] < 3):
+    def __call__(self, testname, tags=None, _hash=zlib.crc32, _is_py2=IS_PY2):
         # Cannot use simple hash() here as shard processes might use different hash seeds.
         # CRC32 is fast and simple, but might return negative values in Py2.
@@ -1902,6 +1935,6 @@
         # Cannot use simple hash() here as shard processes might use different hash seeds.
         # CRC32 is fast and simple, but might return negative values in Py2.
-        hashval = _hash(testname) & 0x7fffffff if _is_py2 else _hash(testname.encode())
+        hashval = _hash(self._seed + testname) & 0x7fffffff if _is_py2 else _hash(self._seed + testname.encode())
         return hashval % self.shard_count != self.shard_num
 
 
@@ -1973,6 +2006,10 @@
 def main():
 
     global DISTDIR, WITH_CYTHON
+
+    # Set an environment variable to the top directory
+    os.environ['CYTHON_PROJECT_DIR'] = os.path.abspath(os.path.dirname(__file__))
+
     DISTDIR = os.path.join(os.getcwd(), os.path.dirname(sys.argv[0]))
 
     from Cython.Compiler import DebugFlags
@@ -2041,6 +2078,9 @@
     parser.add_option("-x", "--exclude", dest="exclude",
                       action="append", metavar="PATTERN",
                       help="exclude tests matching the PATTERN")
+    parser.add_option("--listfile", dest="listfile",
+                      action="append",
+                      help="specify a file containing a list of tests to run")
     parser.add_option("-j", "--shard_count", dest="shard_count", metavar="N",
                       type=int, default=1,
                       help="shard this run into several parallel runs")
@@ -2104,6 +2144,10 @@
                       help="test whether Cython's output is deterministic")
     parser.add_option("--pythran-dir", dest="pythran_dir", default=None,
                       help="specify Pythran include directory. This will run the C++ tests using Pythran backend for Numpy")
+    parser.add_option("--no-capture", dest="capture", default=True, action="store_false",
+                      help="do not capture stdout, stderr in srctree tests. Makes pdb.set_trace interactive")
+    parser.add_option("--limited-api", dest="limited_api", default=False, action="store_true",
+                      help="Compiles Cython using CPython's LIMITED_API")
 
     options, cmd_args = parser.parse_args(args)
 
@@ -2130,4 +2174,12 @@
     if options.xml_output_dir:
         shutil.rmtree(options.xml_output_dir, ignore_errors=True)
 
+    if options.listfile:
+        for listfile in options.listfile:
+            cmd_args.extend(load_listfile(listfile))
+
+    if options.capture:
+        keep_alive_interval = 10
+    else:
+        keep_alive_interval = None
     if options.shard_count > 1 and options.shard_num == -1:
@@ -2133,4 +2185,7 @@
     if options.shard_count > 1 and options.shard_num == -1:
+        if "PYTHONIOENCODING" not in os.environ:
+            # Make sure subprocesses can print() Unicode text.
+            os.environ["PYTHONIOENCODING"] = sys.stdout.encoding or sys.getdefaultencoding()
         import multiprocessing
         pool = multiprocessing.Pool(options.shard_count)
         tasks = [(options, cmd_args, shard_num) for shard_num in range(options.shard_count)]
@@ -2138,7 +2193,7 @@
         # NOTE: create process pool before time stamper thread to avoid forking issues.
         total_time = time.time()
         stats = Stats()
-        with time_stamper_thread():
+        with time_stamper_thread(interval=keep_alive_interval):
             for shard_num, shard_stats, return_code in pool.imap_unordered(runtests_callback, tasks):
                 if return_code != 0:
                     errors.append(shard_num)
@@ -2155,7 +2210,7 @@
         else:
             return_code = 0
     else:
-        with time_stamper_thread():
+        with time_stamper_thread(interval=keep_alive_interval):
             _, stats, return_code = runtests(options, cmd_args, coverage)
 
     if coverage:
@@ -2185,9 +2240,14 @@
     Print regular time stamps into the build logs to find slow tests.
     @param interval: time interval in seconds
     """
+    if not interval or interval < 0:
+        # Do nothing
+        yield
+        return
+
     try:
         _xrange = xrange
     except NameError:
         _xrange = range
 
     import threading
@@ -2188,10 +2248,10 @@
     try:
         _xrange = xrange
     except NameError:
         _xrange = range
 
     import threading
-    from datetime import datetime
+    import datetime
     from time import sleep
 
     interval = _xrange(interval * 4)
@@ -2195,7 +2255,6 @@
     from time import sleep
 
     interval = _xrange(interval * 4)
-    now = datetime.now
-    write = sys.__stderr__.write
+    now = datetime.datetime.now
     stop = False
 
@@ -2200,5 +2259,11 @@
     stop = False
 
+    # We capture stderr in some places.
+    # => make sure we write to the real (original) stderr of the test runner.
+    stderr = os.dup(2)
+    def write(s):
+        os.write(stderr, s if type(s) is bytes else s.encode('ascii'))
+
     def time_stamper():
         while True:
             for _ in interval:
@@ -2208,10 +2273,10 @@
             write('\n#### %s\n' % now())
 
     thread = threading.Thread(target=time_stamper, name='time_stamper')
-    thread.setDaemon(True)  # Py2.6 ...
+    thread.setDaemon(True)  # Py2 ...
     thread.start()
     try:
         yield
     finally:
         stop = True
         thread.join()
@@ -2212,10 +2277,11 @@
     thread.start()
     try:
         yield
     finally:
         stop = True
         thread.join()
+        os.close(stderr)
 
 
 def configure_cython(options):
     global CompilationOptions, pyrex_default_options, cython_compile
@@ -2218,8 +2284,8 @@
 
 
 def configure_cython(options):
     global CompilationOptions, pyrex_default_options, cython_compile
-    from Cython.Compiler.Main import \
+    from Cython.Compiler.Options import \
         CompilationOptions, \
         default_options as pyrex_default_options
     from Cython.Compiler.Options import _directive_defaults as directive_defaults
@@ -2253,6 +2319,24 @@
 
 
 def runtests(options, cmd_args, coverage=None):
+    # faulthandler should be able to provide a limited traceback
+    # in the event of a segmentation fault. Hopefully better than Travis
+    # just keeping running until timeout. Only available on Python 3.3+
+    try:
+        import faulthandler
+    except ImportError:
+        pass  # OK - not essential
+    else:
+        faulthandler.enable()
+
+    if sys.platform == "win32" and sys.version_info < (3, 6):
+        # enable Unicode console output, if possible
+        try:
+            import win_unicode_console
+        except ImportError:
+            pass
+        else:
+            win_unicode_console.enable()
 
     WITH_CYTHON = options.with_cython
     ROOTDIR = os.path.abspath(options.root_dir)
@@ -2291,7 +2375,7 @@
         options.cleanup_sharedlibs = False
         options.fork = False
         if WITH_CYTHON and include_debugger:
-            from Cython.Compiler.Main import default_options as compiler_default_options
+            from Cython.Compiler.Options import default_options as compiler_default_options
             compiler_default_options['gdb_debug'] = True
             compiler_default_options['output_dir'] = os.getcwd()
 
@@ -2308,6 +2392,10 @@
         sys.path.insert(0, os.path.split(libpath)[0])
         CFLAGS.append("-DCYTHON_REFNANNY=1")
 
+    if options.limited_api:
+        CFLAGS.append("-DCYTHON_LIMITED_API=1")
+        CFLAGS.append('-Wno-unused-function')
+
     if xml_output_dir and options.fork:
         # doesn't currently work together
         sys.stderr.write("Disabling forked testing to support XML test output\n")
@@ -2366,6 +2454,10 @@
         bug_files = [
             ('bugs.txt', True),
             ('pypy_bugs.txt', IS_PYPY),
+            ('pypy2_bugs.txt', IS_PYPY and IS_PY2),
+            ('pypy_crash_bugs.txt', IS_PYPY),
+            ('pypy_implementation_detail_bugs.txt', IS_PYPY),
+            ('limited_api_bugs.txt', options.limited_api),
             ('windows_bugs.txt', sys.platform == 'win32'),
             ('cygwin_bugs.txt', sys.platform == 'cygwin')
         ]
@@ -2470,10 +2562,7 @@
     else:
         text_runner_options = {}
         if options.failfast:
-            if sys.version_info < (2, 7):
-                sys.stderr.write("--failfast not supported with Python < 2.7\n")
-            else:
-                text_runner_options['failfast'] = True
+            text_runner_options['failfast'] = True
         test_runner = unittest.TextTestRunner(verbosity=options.verbosity, **text_runner_options)
 
     if options.pyximport_py:
diff --git a/setup.cfg b/setup.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_c2V0dXAuY2Zn
--- /dev/null
+++ b/setup.cfg
@@ -0,0 +1,28 @@
+[flake8]
+max-complexity = 10
+
+[pycodestyle]
+exclude = .git,build,__pycache__,venv*,TEST*
+max-line-length = 150
+format = pylint
+select = E711, E714, E501, W291
+#ignore = W, E
+ignore =
+    W504,
+    # W504 line break after binary operator
+    S001,
+    # S001 found module formatter
+    E226,
+    # E226 missing whitespace around operator[run]
+
+[coverage:run]
+branch = True
+parallel = True
+concurrency = multiprocessing,thread
+include = Cython/*
+source = Cython
+omit = Test*
+
+[bdist_wheel]
+universal = 1
+
diff --git a/setup.py b/setup.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_c2V0dXAucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_c2V0dXAucHk= 100755
--- a/setup.py
+++ b/setup.py
@@ -14,7 +14,7 @@
 
 # this specifies which versions of python we support, pip >= 9 knows to skip
 # versions of packages which are not compatible with the running python
-PYTHON_REQUIRES = '>=2.6, !=3.0.*, !=3.1.*, !=3.2.*'
+PYTHON_REQUIRES = '>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*'
 
 if sys.platform == "darwin":
     # Don't create resource files on OS X tar.
@@ -42,8 +42,7 @@
     directory for directory, dirs, files
     in os.walk(os.path.join('Cython', 'Includes'))
     if '__init__.pyx' in files or '__init__.pxd' in files
-    or directory == os.path.join('Cython', 'Includes')
-    or directory == os.path.join('Cython', 'Includes', 'Deprecated')]
+    or directory == os.path.join('Cython', 'Includes')]
 
 pxd_include_patterns = [
     p+'/*.pxd' for p in pxd_include_dirs ] + [
@@ -189,8 +188,5 @@
 except ValueError:
     compile_cython_itself = True
 
-if compile_cython_itself and (is_cpython or cython_compile_more):
-    compile_cython_modules(cython_profile, cython_compile_more, cython_with_refnanny)
-
 setup_args.update(setuptools_extra_args)
 
@@ -195,4 +191,3 @@
 setup_args.update(setuptools_extra_args)
 
-from Cython import __version__ as version
 
@@ -198,6 +193,5 @@
 
-
-def dev_status():
+def dev_status(version):
     if 'b' in version or 'c' in version:
         # 1b1, 1beta1, 2rc1, ...
         return 'Development Status :: 4 - Beta'
@@ -225,15 +219,4 @@
     'pyximport',
 ]
 
-setup(
-    name='Cython',
-    version=version,
-    url='http://cython.org/',
-    author='Robert Bradshaw, Stefan Behnel, Dag Seljebotn, Greg Ewing, et al.',
-    author_email='cython-devel@python.org',
-    description="The Cython compiler for writing C extensions for the Python language.",
-    long_description=textwrap.dedent("""\
-    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.
 
@@ -239,17 +222,5 @@
 
-    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, 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"
+def run_build():
+    if compile_cython_itself and (is_cpython or cython_compile_more):
+        compile_cython_modules(cython_profile, cython_compile_more, cython_with_refnanny)
 
@@ -255,28 +226,57 @@
 
-    .. _Pyrex: http://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/
-    """),
-    license='Apache',
-    classifiers=[
-        dev_status(),
-        "Intended Audience :: Developers",
-        "License :: OSI Approved :: Apache Software License",
-        "Operating System :: OS Independent",
-        "Programming Language :: Python",
-        "Programming Language :: Python :: 2",
-        "Programming Language :: Python :: 2.6",
-        "Programming Language :: Python :: 2.7",
-        "Programming Language :: Python :: 3",
-        "Programming Language :: Python :: 3.4",
-        "Programming Language :: Python :: 3.5",
-        "Programming Language :: Python :: 3.6",
-        "Programming Language :: Python :: 3.7",
-        "Programming Language :: Python :: 3.8",
-        "Programming Language :: Python :: Implementation :: CPython",
-        "Programming Language :: Python :: Implementation :: PyPy",
-        "Programming Language :: C",
-        "Programming Language :: Cython",
-        "Topic :: Software Development :: Code Generators",
-        "Topic :: Software Development :: Compilers",
-        "Topic :: Software Development :: Libraries :: Python Modules"
-    ],
+    from Cython import __version__ as version
+    setup(
+        name='Cython',
+        version=version,
+        url='https://cython.org/',
+        author='Robert Bradshaw, Stefan Behnel, Dag Seljebotn, Greg Ewing, et al.',
+        author_email='cython-devel@python.org',
+        description="The Cython compiler for writing C extensions for the Python language.",
+        long_description=textwrap.dedent("""\
+        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: https://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/
+        """),
+        license='Apache',
+        classifiers=[
+            dev_status(version),
+            "Intended Audience :: Developers",
+            "License :: OSI Approved :: Apache Software License",
+            "Operating System :: OS Independent",
+            "Programming Language :: Python",
+            "Programming Language :: Python :: 2",
+            "Programming Language :: Python :: 2.7",
+            "Programming Language :: Python :: 3",
+            "Programming Language :: Python :: 3.4",
+            "Programming Language :: Python :: 3.5",
+            "Programming Language :: Python :: 3.6",
+            "Programming Language :: Python :: 3.7",
+            "Programming Language :: Python :: 3.8",
+            "Programming Language :: Python :: Implementation :: CPython",
+            "Programming Language :: Python :: Implementation :: PyPy",
+            "Programming Language :: C",
+            "Programming Language :: Cython",
+            "Topic :: Software Development :: Code Generators",
+            "Topic :: Software Development :: Compilers",
+            "Topic :: Software Development :: Libraries :: Python Modules"
+        ],
 
@@ -282,6 +282,10 @@
 
-    scripts=scripts,
-    packages=packages,
-    py_modules=["cython"],
-    **setup_args
-)
+        scripts=scripts,
+        packages=packages,
+        py_modules=["cython"],
+        **setup_args
+    )
+
+
+if __name__ == '__main__':
+    run_build()
diff --git a/tests/broken/cdefemptysue.pyx b/tests/broken/cdefemptysue.pyx
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvYnJva2VuL2NkZWZlbXB0eXN1ZS5weXg=..0000000000000000000000000000000000000000
--- a/tests/broken/cdefemptysue.pyx
+++ /dev/null
@@ -1,14 +0,0 @@
-cdef extern from "cdefemptysue.h":
-
-    cdef struct spam:
-        pass
-
-    ctypedef union eggs:
-        pass
-
-    cdef enum ham:
-        pass
-
-cdef extern spam s
-cdef extern eggs e
-cdef extern ham h
diff --git a/tests/broken/cdefexternblock.pyx b/tests/broken/cdefexternblock.pyx
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvYnJva2VuL2NkZWZleHRlcm5ibG9jay5weXg=..0000000000000000000000000000000000000000
--- a/tests/broken/cdefexternblock.pyx
+++ /dev/null
@@ -1,19 +0,0 @@
-cdef extern from "cheese.h":
-
-    ctypedef int camembert
-
-    struct roquefort:
-        int x
-
-    char *swiss
-
-    void cheddar()
-
-    class external.runny [object runny_obj]:
-        cdef int a
-        def __init__(self):
-            pass
-
-cdef runny r
-r = x
-r.a = 42
diff --git a/tests/buffers/bufaccess.pyx b/tests/buffers/bufaccess.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvYnVmZmVycy9idWZhY2Nlc3MucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvYnVmZmVycy9idWZhY2Nlc3MucHl4 100644
--- a/tests/buffers/bufaccess.pyx
+++ b/tests/buffers/bufaccess.pyx
@@ -959,6 +959,7 @@
 def decref(*args):
     for item in args: Py_DECREF(item)
 
+@cython.binding(False)
 def get_refcount(x):
     return (<PyObject*>x).ob_refcnt
 
@@ -991,7 +992,8 @@
     See comments on printbuf_object above.
 
     >>> a, b = [1, 2, 3], [4, 5, 6]
-    >>> get_refcount(a), get_refcount(b)
-    (2, 2)
+    >>> rca1, rcb1 = get_refcount(a), get_refcount(b)
+    >>> rca1 == rcb1
+    True
     >>> addref(a)
     >>> A = ObjectMockBuffer(None, [1, a]) # 1, ...,otherwise it thinks nested lists...
@@ -996,5 +998,5 @@
     >>> addref(a)
     >>> A = ObjectMockBuffer(None, [1, a]) # 1, ...,otherwise it thinks nested lists...
-    >>> get_refcount(a), get_refcount(b)
-    (3, 2)
+    >>> get_refcount(a) == rca1+1, get_refcount(b) == rcb1
+    (True, True)
     >>> assign_to_object(A, 1, b)
@@ -1000,6 +1002,6 @@
     >>> assign_to_object(A, 1, b)
-    >>> get_refcount(a), get_refcount(b)
-    (2, 3)
+    >>> get_refcount(a) == rca1, get_refcount(b) == rcb1+1
+    (True, True)
     >>> decref(b)
     """
     buf[idx] = obj
@@ -1010,7 +1012,6 @@
     See comments on printbuf_object above.
 
     >>> a, b = [1, 2, 3], {4:23}
-    >>> get_refcount(a)
-    2
+    >>> rc1 = get_refcount(a)
     >>> addref(a)
     >>> A = ObjectMockBuffer(None, [b, a])
@@ -1015,5 +1016,5 @@
     >>> addref(a)
     >>> A = ObjectMockBuffer(None, [b, a])
-    >>> get_refcount(a)
-    3
+    >>> get_refcount(a) == rc1+1
+    True
     >>> assign_temporary_to_object(A)
@@ -1019,6 +1020,6 @@
     >>> assign_temporary_to_object(A)
-    >>> get_refcount(a)
-    2
+    >>> get_refcount(a) == rc1
+    True
 
     >>> printbuf_object(A, (2,))
     {4: 23} 2
diff --git a/tests/buffers/buffmt.pyx b/tests/buffers/buffmt.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvYnVmZmVycy9idWZmbXQucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvYnVmZmVycy9idWZmbXQucHl4 100644
--- a/tests/buffers/buffmt.pyx
+++ b/tests/buffers/buffmt.pyx
@@ -165,7 +165,7 @@
     >>> char3int("c3xiii")
     >>> char3int("cxxxiii")
 
-    Standard alignment (assming int size is 4)
+    Standard alignment (assuming int size is 4)
     >>> char3int("=c3xiii")
     >>> char3int("=ciii")
     Traceback (most recent call last):
@@ -406,6 +406,59 @@
         fmt, sizeof(PackedStructWithCharArrays))
 
 
+ctypedef struct PackedStructWithArrays:
+    double a[16]
+    double b[16]
+    double c
+
+ctypedef struct UnpackedStructWithArrays:
+    int a
+    float b[8]
+    float c
+    unsigned long long d
+    int e[5]
+    int f
+    int g
+    double h[4]
+    int i
+
+ctypedef struct PackedStructWithNDArrays:
+    double a
+    double b[2][2]
+    float c
+    float d
+
+
+@testcase
+def packed_struct_with_arrays(fmt):
+    """
+    >>> packed_struct_with_arrays("T{(16)d:a:(16)d:b:d:c:}")
+    """
+
+    cdef object[PackedStructWithArrays] buf = MockBuffer(
+        fmt, sizeof(PackedStructWithArrays))
+
+
+@testcase
+def unpacked_struct_with_arrays(fmt):
+    """
+    >>> unpacked_struct_with_arrays("T{i:a:(8)f:b:f:c:Q:d:(5)i:e:i:f:i:g:xxxx(4)d:h:i:i:}")
+    """
+
+    cdef object[UnpackedStructWithArrays] buf = MockBuffer(
+        fmt, sizeof(UnpackedStructWithArrays))
+
+
+@testcase
+def packed_struct_with_ndarrays(fmt):
+    """
+    >>> packed_struct_with_ndarrays("T{d:a:(2,2)d:b:f:c:f:d:}")
+    """
+
+    cdef object[PackedStructWithNDArrays] buf = MockBuffer(
+        fmt, sizeof(PackedStructWithNDArrays))
+
+
 # TODO: empty struct
 # TODO: Incomplete structs
 # TODO: mixed structs
diff --git a/tests/buffers/mockbuffers.pxi b/tests/buffers/mockbuffers.pxi
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvYnVmZmVycy9tb2NrYnVmZmVycy5weGk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvYnVmZmVycy9tb2NrYnVmZmVycy5weGk= 100644
--- a/tests/buffers/mockbuffers.pxi
+++ b/tests/buffers/mockbuffers.pxi
@@ -1,5 +1,4 @@
 from libc cimport stdlib
-from libc cimport stdio
 cimport cpython.buffer
 
 import sys
@@ -34,7 +33,7 @@
         cdef Py_ssize_t x, s, cumprod, itemsize
         self.label = label
         self.release_ok = True
-        self.log = ""
+        self.log = u""
         self.offset = offset
         self.itemsize = itemsize = self.get_itemsize()
         self.writable = writable
@@ -43,9 +42,7 @@
         if strides is None:
             strides = []
             cumprod = 1
-            rshape = list(shape)
-            rshape.reverse()
-            for s in rshape:
+            for s in shape[::-1]:
                 strides.append(cumprod)
                 cumprod *= s
             strides.reverse()
@@ -140,7 +137,7 @@
                 self.received_flags.append(name)
 
         if flags & cpython.buffer.PyBUF_WRITABLE and not self.writable:
-            raise BufferError("Writable buffer requested from read-only mock: %s" % ' | '.join(self.received_flags))
+            raise BufferError(f"Writable buffer requested from read-only mock: {' | '.join(self.received_flags)}")
 
         buffer.buf = <void*>(<char*>self.buffer + (<int>self.offset * self.itemsize))
         buffer.obj = self
@@ -154,11 +151,11 @@
         buffer.itemsize = self.itemsize
         buffer.internal = NULL
         if self.label:
-            msg = "acquired %s" % self.label
-            print msg
-            self.log += msg + "\n"
+            msg = f"acquired {self.label}"
+            print(msg)
+            self.log += msg + u"\n"
 
     def __releasebuffer__(MockBuffer self, Py_buffer* buffer):
         if buffer.suboffsets != self.suboffsets:
             self.release_ok = False
         if self.label:
@@ -160,10 +157,10 @@
 
     def __releasebuffer__(MockBuffer self, Py_buffer* buffer):
         if buffer.suboffsets != self.suboffsets:
             self.release_ok = False
         if self.label:
-            msg = "released %s" % self.label
-            print msg
-            self.log += msg + "\n"
+            msg = f"released {self.label}"
+            print(msg)
+            self.log += msg + u"\n"
 
     def printlog(self):
@@ -168,5 +165,5 @@
 
     def printlog(self):
-        print self.log[:-1]
+        print(self.log[:-1])
 
     def resetlog(self):
@@ -171,6 +168,6 @@
 
     def resetlog(self):
-        self.log = ""
+        self.log = u""
 
     cdef int write(self, char* buf, object value) except -1: raise Exception()
     cdef get_itemsize(self):
@@ -174,5 +171,5 @@
 
     cdef int write(self, char* buf, object value) except -1: raise Exception()
     cdef get_itemsize(self):
-        print "ERROR, not subclassed", self.__class__
+        print(f"ERROR, not subclassed: {self.__class__}")
     cdef get_default_format(self):
@@ -178,5 +175,5 @@
     cdef get_default_format(self):
-        print "ERROR, not subclassed", self.__class__
+        print(f"ERROR, not subclassed {self.__class__}")
 
 cdef class CharMockBuffer(MockBuffer):
     cdef int write(self, char* buf, object value) except -1:
@@ -248,6 +245,6 @@
         self.label = label
 
     def __getbuffer__(ErrorBuffer self, Py_buffer* buffer, int flags):
-        raise Exception("acquiring %s" % self.label)
+        raise Exception(f"acquiring {self.label}")
 
     def __releasebuffer__(ErrorBuffer self, Py_buffer* buffer):
@@ -252,6 +249,6 @@
 
     def __releasebuffer__(ErrorBuffer self, Py_buffer* buffer):
-        raise Exception("releasing %s" % self.label)
+        raise Exception(f"releasing {self.label}")
 
 #
 # Structs
@@ -338,10 +335,8 @@
 
 
 def print_offsets(*args, size, newline=True):
-    sys.stdout.write(' '.join([str(item // size) for item in args]))
-    if newline:
-        sys.stdout.write('\n')
+    sys.stdout.write(' '.join([str(item // size) for item in args]) + ('\n' if newline else ''))
 
 def print_int_offsets(*args, newline=True):
     print_offsets(*args, size=sizeof(int), newline=newline)
 
@@ -344,7 +339,8 @@
 
 def print_int_offsets(*args, newline=True):
     print_offsets(*args, size=sizeof(int), newline=newline)
 
+
 shape_5_3_4_list = [[list(range(k * 12 + j * 4, k * 12 + j * 4 + 4))
                         for j in range(3)]
                             for k in range(5)]
diff --git a/tests/buffers/userbuffer.pyx b/tests/buffers/userbuffer.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvYnVmZmVycy91c2VyYnVmZmVyLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvYnVmZmVycy91c2VyYnVmZmVyLnB5eA== 100644
--- a/tests/buffers/userbuffer.pyx
+++ b/tests/buffers/userbuffer.pyx
@@ -1,2 +1,1 @@
-import sys
 
@@ -2,14 +1,7 @@
 
-__doc__ = u""
-
-if sys.version_info[:2] == (2, 6):
-    __doc__ += u"""
->>> memoryview = _memoryview
-"""
-
-__doc__ += u"""
+__doc__ = u"""
 >>> b1 = UserBuffer1()
 >>> m1 = memoryview(b1)
 >>> m1.tolist()
 [0, 1, 2, 3, 4]
 >>> del m1, b1
@@ -11,7 +3,6 @@
 >>> b1 = UserBuffer1()
 >>> m1 = memoryview(b1)
 >>> m1.tolist()
 [0, 1, 2, 3, 4]
 >>> del m1, b1
-"""
 
@@ -17,5 +8,4 @@
 
-__doc__ += u"""
 >>> b2 = UserBuffer2()
 >>> m2 = memoryview(b2)
 UserBuffer2: getbuffer
diff --git a/tests/build/cythonize_pep420_namespace.srctree b/tests/build/cythonize_pep420_namespace.srctree
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvYnVpbGQvY3l0aG9uaXplX3BlcDQyMF9uYW1lc3BhY2Uuc3JjdHJlZQ==
--- /dev/null
+++ b/tests/build/cythonize_pep420_namespace.srctree
@@ -0,0 +1,44 @@
+PYTHON setup.py build_ext --inplace
+PYTHON -c "import runner"
+
+######## setup.py ########
+
+from Cython.Build.Dependencies import cythonize
+
+from distutils.core import setup, Extension
+
+setup(
+  ext_modules=cythonize([
+    Extension("nsp.m1.a", ["nsp/m1/a.pyx"]),
+    Extension("nsp.m2.b", ["nsp/m2/b.pyx"])
+  ]),
+)
+
+######## nsp/m1/__init__.py ########
+
+######## nsp/m1/a.pyx ########
+
+cdef class A:
+    pass
+
+######## nsp/m1/a.pxd ########
+
+cdef class A:
+    pass
+
+######## nsp/m2/__init__.py ########
+
+######## nsp/m2/b.pyx ########
+
+from nsp.m1.a cimport A
+
+cdef class B(A):
+    pass
+
+######## runner.py ########
+
+from nsp.m1.a import A
+from nsp.m2.b import B
+
+a = A()
+b = B()
diff --git a/tests/build/cythonize_with_annotate.srctree b/tests/build/cythonize_with_annotate.srctree
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvYnVpbGQvY3l0aG9uaXplX3dpdGhfYW5ub3RhdGUuc3JjdHJlZQ==
--- /dev/null
+++ b/tests/build/cythonize_with_annotate.srctree
@@ -0,0 +1,45 @@
+PYTHON setup.py build_ext --inplace
+PYTHON -c "import not_annotated; not_annotated.check()"
+PYTHON -c "import default_annotated; default_annotated.check()"
+PYTHON -c "import fullc_annotated; fullc_annotated.check()"
+######## setup.py ########
+
+from Cython.Build.Dependencies import cythonize
+
+from distutils.core import setup
+
+setup(
+  ext_modules = cythonize(["not_annotated.pyx"], language_level=3) +
+                cythonize(["default_annotated.pyx"], annotate=True, language_level=3) + 
+                cythonize(["fullc_annotated.pyx"], annotate='fullc', language_level=3)
+)
+######## not_annotated.pyx ########
+# check that html-file doesn't exist:
+def check():
+    import os.path as os_path
+    assert not os_path.isfile(__name__+'.html')
+
+
+
+######## default_annotated.pyx ########
+# load html-site and check that the marker isn't there:
+def check():
+    from codecs import open
+    with open(__name__+'.html', 'r', 'utf8') as html_file:
+        html = html_file.read()
+
+    from Cython.Compiler.Annotate import AnnotationCCodeWriter
+    assert (AnnotationCCodeWriter.COMPLETE_CODE_TITLE not in html) # per default no complete c code
+
+
+
+######## fullc_annotated.pyx ########
+# load html-site and check that the marker is there:
+def check():
+    from codecs import open
+    with open(__name__+'.html', 'r', 'utf8') as html_file:
+        html = html_file.read()
+
+    from Cython.Compiler.Annotate import AnnotationCCodeWriter
+    assert (AnnotationCCodeWriter.COMPLETE_CODE_TITLE in html)
+
diff --git a/tests/build/cythonize_with_annotate_via_Options.srctree b/tests/build/cythonize_with_annotate_via_Options.srctree
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvYnVpbGQvY3l0aG9uaXplX3dpdGhfYW5ub3RhdGVfdmlhX09wdGlvbnMuc3JjdHJlZQ==
--- /dev/null
+++ b/tests/build/cythonize_with_annotate_via_Options.srctree
@@ -0,0 +1,27 @@
+PYTHON setup.py build_ext --inplace
+PYTHON -c "import fullc_annotated; fullc_annotated.check()"
+
+######## setup.py ########
+
+from Cython.Build.Dependencies import cythonize
+from Cython.Compiler import Options
+
+Options.annotate = 'fullc'
+
+from distutils.core import setup
+
+setup(
+  ext_modules = cythonize(["fullc_annotated.pyx"], language_level=3)
+)
+
+######## fullc_annotated.pyx ########
+# load html-site and check that the marker is there:
+
+def check():
+    from codecs import open
+    with open(__name__+'.html', 'r', 'utf8') as html_file:
+        html = html_file.read()
+
+    from Cython.Compiler.Annotate import AnnotationCCodeWriter
+    assert (AnnotationCCodeWriter.COMPLETE_CODE_TITLE in html)
+
diff --git a/tests/build/cythonize_with_annotate_via_cli.srctree b/tests/build/cythonize_with_annotate_via_cli.srctree
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvYnVpbGQvY3l0aG9uaXplX3dpdGhfYW5ub3RhdGVfdmlhX2NsaS5zcmN0cmVl
--- /dev/null
+++ b/tests/build/cythonize_with_annotate_via_cli.srctree
@@ -0,0 +1,36 @@
+CYTHONIZE -i -3 not_annotated.pyx
+PYTHON -c "import not_annotated; not_annotated.check()"
+CYTHONIZE -i -3 --annotate default_annotated.pyx
+PYTHON -c "import default_annotated; default_annotated.check()"
+CYTHONIZE -i -3 --annotate-fullc fullc_annotated.pyx
+PYTHON -c "import fullc_annotated; fullc_annotated.check()"
+
+######## not_annotated.pyx ########
+# check that html-file doesn't exist:
+def check():
+    import os.path as os_path
+    assert not os_path.isfile(__name__+'.html')
+
+
+
+######## default_annotated.pyx ########
+# load html-site and check that the marker isn't there:
+def check():
+    from codecs import open
+    with open(__name__+'.html', 'r', 'utf8') as html_file:
+        html = html_file.read()
+
+    from Cython.Compiler.Annotate import AnnotationCCodeWriter
+    assert (AnnotationCCodeWriter.COMPLETE_CODE_TITLE not in html) # per default no complete c code
+
+
+
+######## fullc_annotated.pyx ########
+# load html-site and check that the marker is there:
+def check():
+    from codecs import open
+    with open(__name__+'.html', 'r', 'utf8') as html_file:
+        html = html_file.read()
+
+    from Cython.Compiler.Annotate import AnnotationCCodeWriter
+    assert (AnnotationCCodeWriter.COMPLETE_CODE_TITLE in html)
diff --git a/tests/build/dotted.filename.modules.pxd b/tests/build/dotted.filename.modules.pxd
new file mode 100644
diff --git a/tests/build/dotted.filename.modules.pyx b/tests/build/dotted.filename.modules.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvYnVpbGQvZG90dGVkLmZpbGVuYW1lLm1vZHVsZXMucHl4
--- /dev/null
+++ b/tests/build/dotted.filename.modules.pyx
@@ -0,0 +1,7 @@
+# mode: compile
+# tag: warnings
+
+_WARNINGS="""
+1:0: Dotted filenames ('dotted.filename.modules.pxd') are deprecated. Please use the normal Python package directory layout.
+1:0: Dotted filenames ('dotted.filename.modules.pyx') are deprecated. Please use the normal Python package directory layout.
+"""
diff --git a/tests/build/inline_distutils.srctree b/tests/build/inline_distutils.srctree
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvYnVpbGQvaW5saW5lX2Rpc3R1dGlscy5zcmN0cmVl..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvYnVpbGQvaW5saW5lX2Rpc3R1dGlscy5zcmN0cmVl 100644
--- a/tests/build/inline_distutils.srctree
+++ b/tests/build/inline_distutils.srctree
@@ -38,4 +38,4 @@
 
 from my_lib cimport x
 
-print x
+print(x)
diff --git a/tests/compile/branch_hints.pyx b/tests/compile/branch_hints.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvY29tcGlsZS9icmFuY2hfaGludHMucHl4
--- /dev/null
+++ b/tests/compile/branch_hints.pyx
@@ -0,0 +1,91 @@
+# mode: compile
+# tag: if, unlikely
+
+cimport cython
+
+
+@cython.test_assert_path_exists(
+    "//IfClauseNode",
+    "//IfClauseNode[not(@branch_hint)]",
+)
+def if_simple(x):
+    if x:
+        x = 2
+
+
+@cython.test_assert_path_exists(
+    "//IfClauseNode",
+    "//IfClauseNode[not(@branch_hint)]",
+)
+def if_return(x):
+    if x:
+        return 1
+    raise TypeError()
+
+
+@cython.test_assert_path_exists(
+    "//IfClauseNode",
+    "//IfClauseNode[@branch_hint = 'unlikely']",
+)
+def if_raise_else(x):
+    if x:
+        raise TypeError()
+    else:
+        return 1
+
+
+@cython.test_assert_path_exists(
+    "//IfClauseNode",
+    "//IfClauseNode[@branch_hint = 'likely']",
+)
+def if_else_raise(x):
+    if x:
+        return 1
+    else:
+        raise TypeError()
+
+
+@cython.test_assert_path_exists(
+    "//IfClauseNode",
+    "//IfClauseNode[@branch_hint = 'unlikely']",
+)
+def if_raise_else_raise(x):
+    if x:
+        raise ValueError()
+    else:
+        raise TypeError()
+
+
+@cython.test_assert_path_exists(
+    "//IfClauseNode",
+    "//IfClauseNode[@branch_hint = 'unlikely']",
+)
+@cython.test_fail_if_path_exists(
+    "//IfClauseNode[@branch_hint = 'likely']",
+    "//IfClauseNode[not(@branch_hint)]",
+)
+def if_elif_raise_else_raise(x):
+    if x:
+        raise ValueError()
+    elif not x:
+        raise AttributeError()
+    else:
+        raise TypeError()
+
+
+@cython.test_assert_path_exists(
+    "//IfClauseNode",
+    "//IfClauseNode[@branch_hint = 'unlikely']",
+    "//IfClauseNode[@branch_hint = 'unlikely']//GILStatNode",
+)
+@cython.test_fail_if_path_exists(
+    "//IfClauseNode[@branch_hint = 'likely']",
+    "//IfClauseNode[not(@branch_hint)]",
+)
+cpdef int nogil_if_raise(int x) nogil except -1:
+    if x:
+        raise TypeError()
+    elif not x:
+        raise ValueError()
+    else:
+        x = 2
diff --git a/tests/compile/buildenv.pyx b/tests/compile/buildenv.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvY29tcGlsZS9idWlsZGVudi5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvY29tcGlsZS9idWlsZGVudi5weXg= 100644
--- a/tests/compile/buildenv.pyx
+++ b/tests/compile/buildenv.pyx
@@ -107,6 +107,15 @@
 SIZEOF_UINTPTR_T  {SIZEOF_UINTPTR_T}  ({sizeof(unsigned int *)})
 SIZEOF_OFF_T  {SIZEOF_OFF_T}
 
+Paths:
+sys.executable = {sys.executable}
+sys.exec_prefix = {sys.exec_prefix}
+sys.base_exec_prefix = {getattr(sys, 'base_exec_prefix', "")}
+sys.prefix = {sys.prefix}
+sys.path = {sys.path}
+PYTHONPATH (env) = {get_env('PYTHONPATH', '')}
+PYTHONHOME (env) = {get_env('PYTHONHOME', '')}
+
 Distutils:
 INCDIR = {sysconfig.get_python_inc()}
 LIBS = {config_var('LIBS')}
@@ -121,4 +130,11 @@
 CFLAGS (env) = {get_env('CFLAGS', '')}
 LINKCC (distutils) = {config_var('LINKCC')}
 LINKCC (env) = {get_env('LINKCC', '')}
+
+Encodings:
+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()}
 """)
diff --git a/tests/compile/cascmp.pyx b/tests/compile/cascmp.pyx
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvY29tcGlsZS9jYXNjbXAucHl4..0000000000000000000000000000000000000000
--- a/tests/compile/cascmp.pyx
+++ /dev/null
@@ -1,17 +0,0 @@
-# mode: compile
-
-cdef void foo():
-    cdef int bool, int1=0, int2=0, int3=0, int4=0
-    cdef object obj1, obj2, obj3, obj4
-    obj1 = 1
-    obj2 = 2
-    obj3 = 3
-    obj4 = 4
-    bool = int1 < int2 < int3
-    bool = obj1 < obj2 < obj3
-    bool = int1 < int2 < obj3
-    bool = obj1 < 2 < 3
-    bool = obj1 < 2 < 3 < 4
-    bool = int1 < (int2 == int3) < int4
-
-foo()
diff --git a/tests/compile/cdefemptysue.pyx b/tests/compile/cdefemptysue.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvY29tcGlsZS9jZGVmZW1wdHlzdWUucHl4
--- /dev/null
+++ b/tests/compile/cdefemptysue.pyx
@@ -0,0 +1,43 @@
+# mode: compile
+# tag: struct, union, enum, cdefextern
+
+cdef extern from *:
+    """
+    struct spam { int a; };
+    struct flat_spam { int a; };
+    typedef struct { int a; } flat_spam_type;
+
+    typedef union { int a; long b; } eggs;
+    typedef union { int a; long b; } flat_eggs;
+
+    enum ham { TOAST };
+    enum flat_ham { FLAT_TOAST };
+    """
+
+    cdef struct spam:
+        pass
+
+    cdef struct flat_spam: pass
+
+    ctypedef struct flat_spam_type: pass
+
+    ctypedef union eggs:
+        pass
+
+    ctypedef union flat_eggs: pass
+
+    cdef enum ham:
+        pass
+
+    cdef enum flat_ham: pass
+
+
+cdef extern spam s
+cdef extern flat_spam fs
+cdef extern flat_spam_type fst
+
+cdef extern eggs e
+cdef extern flat_eggs fe
+
+cdef extern ham h
+cdef extern flat_ham fh
diff --git a/tests/compile/cdefexternblock.pyx b/tests/compile/cdefexternblock.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvY29tcGlsZS9jZGVmZXh0ZXJuYmxvY2sucHl4
--- /dev/null
+++ b/tests/compile/cdefexternblock.pyx
@@ -0,0 +1,23 @@
+# mode: compile
+# tag: struct, union, enum, cdefextern
+
+cdef extern from "cheese.h":
+
+    ctypedef int camembert
+
+    struct roquefort:
+        int x
+
+    char *swiss
+
+    void cheddar()
+
+    # FIXME: find a real declaration here.
+    #class external.runny [object runny_obj]:
+    #    cdef int a
+    #    def __init__(self):
+    #        pass
+
+
+#cdef runny r = runny()
+#r.a = 42
diff --git a/tests/compile/cpp_enums.h b/tests/compile/cpp_enums.h
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvY29tcGlsZS9jcHBfZW51bXMuaA==..0000000000000000000000000000000000000000
--- a/tests/compile/cpp_enums.h
+++ /dev/null
@@ -1,11 +0,0 @@
-enum Enum1 {
-  Item1,
-  Item2
-};
-
-namespace Namespace1 {
-  enum Enum2 {
-    Item3,
-    Item4
-  };
-}
diff --git a/tests/compile/cpp_enums.pyx b/tests/compile/cpp_enums.pyx
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvY29tcGlsZS9jcHBfZW51bXMucHl4..0000000000000000000000000000000000000000
--- a/tests/compile/cpp_enums.pyx
+++ /dev/null
@@ -1,27 +0,0 @@
-# tag: cpp
-# mode: compile
-
-cdef extern from "cpp_enums.h":
-    cdef enum Enum1:
-        Item1
-        Item2
-
-a = Item1
-b = Item2
-
-cdef Enum1 x, y
-x = Item1
-y = Item2
-
-cdef extern from "cpp_enums.h" namespace "Namespace1":
-    cdef enum Enum2:
-        Item3
-        Item4
-
-c = Item3
-d = Item4
-
-cdef Enum2 z, w
-z = Item3
-w = Item4
-
diff --git a/tests/compile/cpp_temp_assignment.pyx b/tests/compile/cpp_temp_assignment.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvY29tcGlsZS9jcHBfdGVtcF9hc3NpZ25tZW50LnB5eA==
--- /dev/null
+++ b/tests/compile/cpp_temp_assignment.pyx
@@ -0,0 +1,65 @@
+# tag: cpp
+# mode: compile
+
+cdef extern from *:
+    """
+    #if __cplusplus >= 201103L
+    class NoAssign {
+        public:
+            NoAssign() {}
+            NoAssign(NoAssign&) = delete;
+            NoAssign(NoAssign&&) {}
+            NoAssign& operator=(NoAssign&) = delete;
+            NoAssign& operator=(NoAssign&&) { return *this; }
+            void func() {}
+    };
+    #else
+    // the test becomes meaningless
+    // (but just declare something to ensure it passes)
+    class NoAssign {
+        public:
+            void func() {}
+    };
+    #endif
+
+    NoAssign get_NoAssign_Py() {
+        return NoAssign();
+    }
+    NoAssign get_NoAssign_Cpp() {
+        return NoAssign();
+    }
+    """
+    cdef cppclass NoAssign:
+        void func()
+
+    # might raise Python exception (thus needs a temp)
+    NoAssign get_NoAssign_Py() except *
+    # might raise C++ exception (thus needs a temp)
+    NoAssign get_NoAssign_Cpp() except +
+
+cdef internal_cpp_func(NoAssign arg):
+    pass
+
+def test_call_to_function():
+    # will fail to compile if move constructors aren't used
+    internal_cpp_func(get_NoAssign_Py())
+    internal_cpp_func(get_NoAssign_Cpp())
+
+def test_assignment_to_name():
+    # will fail if move constructors aren't used
+    cdef NoAssign value
+    value = get_NoAssign_Py()
+    value = get_NoAssign_Cpp()
+
+def test_assignment_to_scope():
+    cdef NoAssign value
+    value = get_NoAssign_Py()
+    value = get_NoAssign_Cpp()
+    def inner():
+        value.func()
+
+cdef class AssignToClassAttr:
+    cdef NoAssign attr
+    def __init__(self):
+        self.attr = get_NoAssign_Py()
+        self.attr = get_NoAssign_Cpp()
diff --git a/tests/compile/crunchytype.h b/tests/compile/crunchytype.h
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvY29tcGlsZS9jcnVuY2h5dHlwZS5o..0000000000000000000000000000000000000000
--- a/tests/compile/crunchytype.h
+++ /dev/null
@@ -1,5 +0,0 @@
-
-struct CrunchyType {
-  int number;
-  PyObject* string;
-};
diff --git a/tests/compile/crunchytype.pxd b/tests/compile/crunchytype.pxd
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvY29tcGlsZS9jcnVuY2h5dHlwZS5weGQ=..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvY29tcGlsZS9jcnVuY2h5dHlwZS5weGQ= 100644
--- a/tests/compile/crunchytype.pxd
+++ b/tests/compile/crunchytype.pxd
@@ -1,4 +1,10 @@
-cdef extern from "crunchytype.h":
+cdef extern from *:
+    """
+    struct CrunchyType {
+        int number;
+        PyObject* string;
+    };
+    """
     cdef class crunchytype.Crunchy [ object CrunchyType ]:
         cdef int number
         cdef object string
diff --git a/tests/compile/ctuple_unused_T3543.pyx b/tests/compile/ctuple_unused_T3543.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvY29tcGlsZS9jdHVwbGVfdW51c2VkX1QzNTQzLnB5eA==
--- /dev/null
+++ b/tests/compile/ctuple_unused_T3543.pyx
@@ -0,0 +1,9 @@
+# ticket: 3543
+# mode: compile
+
+# Views define unused ctuples, including (long,)
+from cython cimport view
+
+# Implicitly generate a ctuple (long,)
+obj = None
+obj or (1,)
diff --git a/tests/compile/cython_compiled_folding.pxd b/tests/compile/cython_compiled_folding.pxd
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvY29tcGlsZS9jeXRob25fY29tcGlsZWRfZm9sZGluZy5weGQ=
--- /dev/null
+++ b/tests/compile/cython_compiled_folding.pxd
@@ -0,0 +1,1 @@
+from libc.math cimport sin, cos, sqrt, tan, log
diff --git a/tests/compile/cython_compiled_folding.py b/tests/compile/cython_compiled_folding.py
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvY29tcGlsZS9jeXRob25fY29tcGlsZWRfZm9sZGluZy5weQ==
--- /dev/null
+++ b/tests/compile/cython_compiled_folding.py
@@ -0,0 +1,39 @@
+# mode: compile
+
+# libc sin, cos and sqrt cimported in the pxd file
+
+import cython
+from cython import compiled
+
+if not cython.compiled:
+    from math import sin
+
+if cython.compiled:
+    pass
+else:
+    from math import cos
+
+if "aa" == "bb":
+    pass
+elif cython.compiled:
+    pass
+elif True:
+    from math import sqrt
+
+if "aa" == "bb":
+    pass
+elif compiled:
+    pass
+else:
+    from math import tan
+
+# log10 isn't defined in the pxd file
+from math import log10
+
+@cython.test_fail_if_path_exists("//FromImportStatNode//ImportNode")
+@cython.test_assert_path_exists("//AddNode")
+def import_log(x, y):
+    if compiled:
+        return x+y
+    else:
+        from math import log
diff --git a/tests/compile/find_pxd.srctree b/tests/compile/find_pxd.srctree
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvY29tcGlsZS9maW5kX3B4ZC5zcmN0cmVl..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvY29tcGlsZS9maW5kX3B4ZC5zcmN0cmVl 100644
--- a/tests/compile/find_pxd.srctree
+++ b/tests/compile/find_pxd.srctree
@@ -41,7 +41,7 @@
 
 ######## path/numpy/__init__.pxd ########
 
-# gh-2905: This should be found before Cython/Inlude/numpy/__init__.pxd
+# gh-2905: This should be found before Cython/Includes/numpy/__init__.pxd
 
 ctypedef int my_type
 
diff --git a/tests/compile/fused_redeclare_T3111.pyx b/tests/compile/fused_redeclare_T3111.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvY29tcGlsZS9mdXNlZF9yZWRlY2xhcmVfVDMxMTEucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvY29tcGlsZS9mdXNlZF9yZWRlY2xhcmVfVDMxMTEucHl4 100644
--- a/tests/compile/fused_redeclare_T3111.pyx
+++ b/tests/compile/fused_redeclare_T3111.pyx
@@ -22,10 +22,14 @@
 # "__pyxutil:16:4: '___pyx_npy_uint8' redeclared".  The remaining warnings are
 # unrelated to this test.
 _WARNINGS = """
-20:10: 'cpdef_method' redeclared
-31:10: 'cpdef_cname_method' redeclared
-446:72: Argument evaluation order in C function call is undefined and may not be as expected
-446:72: Argument evaluation order in C function call is undefined and may not be as expected
-749:34: Argument evaluation order in C function call is undefined and may not be as expected
-749:34: Argument evaluation order in C function call is undefined and may not be as expected
+# cpdef redeclaration bug
+22:10: 'cpdef_method' redeclared
+33:10: 'cpdef_cname_method' redeclared
+# from MemoryView.pyx
+981:29: Ambiguous exception value, same as default return value: 0
+981:29: Ambiguous exception value, same as default return value: 0
+1008:46: Ambiguous exception value, same as default return value: 0
+1008:46: Ambiguous exception value, same as default return value: 0
+1098:29: Ambiguous exception value, same as default return value: 0
+1098:29: Ambiguous exception value, same as default return value: 0
 """
diff --git a/tests/compile/fused_wraparound.pyx b/tests/compile/fused_wraparound.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvY29tcGlsZS9mdXNlZF93cmFwYXJvdW5kLnB5eA==
--- /dev/null
+++ b/tests/compile/fused_wraparound.pyx
@@ -0,0 +1,22 @@
+# mode: compile
+# tag: fused, werror
+
+"""
+Very short test for https://github.com/cython/cython/issues/3492
+(Needs its own file since werror fails on the main fused-test files)
+wraparound and boundscheck directives shouldn't break the fused
+dispatcher function
+"""
+
+cimport cython
+
+ctypedef fused fused_t:
+    str
+    int
+    long
+    complex
+
+@cython.wraparound(False)
+@cython.boundscheck(False)
+def func(fused_t a, cython.floating b):
+    return a, b
diff --git a/tests/compile/volatile.pyx b/tests/compile/volatile.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvY29tcGlsZS92b2xhdGlsZS5weXg=
--- /dev/null
+++ b/tests/compile/volatile.pyx
@@ -0,0 +1,17 @@
+# mode: compile
+
+cdef volatile int x = 1
+
+cdef const volatile char* greeting1 = "hello world"
+cdef volatile const char* greeting2 = "goodbye"
+
+
+cdef extern from "stdlib.h":
+    volatile void* malloc(size_t)
+
+cdef volatile long* test(volatile size_t s):
+    cdef volatile long* arr = <long*><volatile long*>malloc(s)
+    return arr
+
+
+test(64)
diff --git a/tests/errors/cdefkwargs.pyx b/tests/errors/cdefkwargs.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvZXJyb3JzL2NkZWZrd2FyZ3MucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvZXJyb3JzL2NkZWZrd2FyZ3MucHl4 100644
--- a/tests/errors/cdefkwargs.pyx
+++ b/tests/errors/cdefkwargs.pyx
@@ -6,10 +6,6 @@
     >>> call4()
 """
 
-import sys, re
-if sys.version_info >= (2,6):
-    __doc__ = re.sub(u"Error: (.*)exactly(.*)", u"Error: \\1at most\\2", __doc__)
-
 # the calls:
 
 def call2():
diff --git a/tests/errors/cfunc_directive_in_pyclass.pyx b/tests/errors/cfunc_directive_in_pyclass.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvZXJyb3JzL2NmdW5jX2RpcmVjdGl2ZV9pbl9weWNsYXNzLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvZXJyb3JzL2NmdW5jX2RpcmVjdGl2ZV9pbl9weWNsYXNzLnB5eA== 100644
--- a/tests/errors/cfunc_directive_in_pyclass.pyx
+++ b/tests/errors/cfunc_directive_in_pyclass.pyx
@@ -7,5 +7,5 @@
         pass
 
 _ERRORS = """
- 6:4: cfunc directive is not allowed here
+ 5:4: cfunc directive is not allowed here
 """
diff --git a/tests/errors/cimport_attributes.pyx b/tests/errors/cimport_attributes.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvZXJyb3JzL2NpbXBvcnRfYXR0cmlidXRlcy5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvZXJyb3JzL2NpbXBvcnRfYXR0cmlidXRlcy5weXg= 100644
--- a/tests/errors/cimport_attributes.pyx
+++ b/tests/errors/cimport_attributes.pyx
@@ -1,4 +1,5 @@
 # mode: error
+# tag: cpp
 
 
 cimport libcpp
@@ -24,8 +25,8 @@
 
 
 _ERRORS = u"""
-5:12: cimported module has no attribute 'no_such_attribute'
-8:16: cimported module has no attribute 'no_such_attribute'
-11:12: cimported module has no attribute 'no_such_attribute'
-14:15: cimported module has no attribute 'no_such_attribute'
+6:12: cimported module has no attribute 'no_such_attribute'
+9:16: cimported module has no attribute 'no_such_attribute'
+12:12: cimported module has no attribute 'no_such_attribute'
+15:15: cimported module has no attribute 'no_such_attribute'
 """
diff --git a/tests/errors/const_decl_errors.pyx b/tests/errors/const_decl_errors.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvZXJyb3JzL2NvbnN0X2RlY2xfZXJyb3JzLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvZXJyb3JzL2NvbnN0X2RlY2xfZXJyb3JzLnB5eA== 100644
--- a/tests/errors/const_decl_errors.pyx
+++ b/tests/errors/const_decl_errors.pyx
@@ -19,5 +19,7 @@
     d = NULL
     t = &s
 
+cdef volatile object v
+
 
 _ERRORS = """
@@ -22,6 +24,6 @@
 
 _ERRORS = """
-3:5: Const base type cannot be a Python object
+3:5: Const/volatile base type cannot be a Python object
 8:5: Assignment to const 'x'
 15:4: Assignment to const 'a'
 16:4: Assignment to const 'c'
@@ -29,4 +31,5 @@
 18:5: Assignment to const attribute 'member'
 19:4: Assignment to const 'd'
 20:4: Assignment to const 't'
+22:5: Const/volatile base type cannot be a Python object
 """
diff --git a/tests/errors/cpp_object_template.pyx b/tests/errors/cpp_object_template.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvZXJyb3JzL2NwcF9vYmplY3RfdGVtcGxhdGUucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvZXJyb3JzL2NwcF9vYmplY3RfdGVtcGxhdGUucHl4 100644
--- a/tests/errors/cpp_object_template.pyx
+++ b/tests/errors/cpp_object_template.pyx
@@ -1,4 +1,5 @@
 # mode: error
+# tag: cpp
 
 from libcpp.vector cimport vector
 
@@ -12,6 +13,6 @@
     va.push_back(A())
 
 _ERRORS = u"""
-9:16: Python object type 'Python object' cannot be used as a template argument
-11:16: Python object type 'A' cannot be used as a template argument
+10:16: Python object type 'Python object' cannot be used as a template argument
+12:16: Python object type 'A' cannot be used as a template argument
 """
diff --git a/tests/errors/duplicate_const.pyx b/tests/errors/duplicate_const.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvZXJyb3JzL2R1cGxpY2F0ZV9jb25zdC5weXg=
--- /dev/null
+++ b/tests/errors/duplicate_const.pyx
@@ -0,0 +1,13 @@
+# mode: error
+
+cdef extern from *:
+    cdef const const int a
+    cdef const volatile int b
+    cdef volatile const int c
+    cdef volatile volatile int d
+
+
+_ERRORS = """
+4:9: Duplicate 'const'
+7:9: Duplicate 'volatile'
+"""
diff --git a/tests/errors/e_assert.pyx b/tests/errors/e_assert.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvZXJyb3JzL2VfYXNzZXJ0LnB5eA==
--- /dev/null
+++ b/tests/errors/e_assert.pyx
@@ -0,0 +1,25 @@
+# mode: error
+# tag: assert
+
+def nontrivial_assert_in_nogil(int a, obj):
+    with nogil:
+        # NOK
+        assert obj
+        assert a*obj
+        assert obj, "abc"
+
+        # OK
+        assert a
+        assert a*a
+        assert a, "abc"
+        assert a, u"abc"
+        assert a, f"123{a}xyz"
+
+
+_ERRORS = """
+7:15: Truth-testing Python object not allowed without gil
+8:15: Converting to Python object not allowed without gil
+8:16: Operation not allowed without gil
+8:16: Truth-testing Python object not allowed without gil
+9:15: Truth-testing Python object not allowed without gil
+"""
diff --git a/tests/errors/e_autotestdict.pyx b/tests/errors/e_autotestdict.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvZXJyb3JzL2VfYXV0b3Rlc3RkaWN0LnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvZXJyb3JzL2VfYXV0b3Rlc3RkaWN0LnB5eA== 100644
--- a/tests/errors/e_autotestdict.pyx
+++ b/tests/errors/e_autotestdict.pyx
@@ -7,5 +7,5 @@
     pass
 
 _ERRORS = u"""
-6:0: The autotestdict compiler directive is not allowed in function scope
+5:0: The autotestdict compiler directive is not allowed in function scope
 """
diff --git a/tests/errors/e_cdefemptysue.pyx b/tests/errors/e_cdefemptysue.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvZXJyb3JzL2VfY2RlZmVtcHR5c3VlLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvZXJyb3JzL2VfY2RlZmVtcHR5c3VlLnB5eA== 100644
--- a/tests/errors/e_cdefemptysue.pyx
+++ b/tests/errors/e_cdefemptysue.pyx
@@ -8,7 +8,16 @@
 
 cdef enum ham:
 	pass
+
+
+cdef struct flat_spam: pass
+
+ctypedef union flat_eggs: pass
+
+cdef enum flat_ham: pass
+
+
 _ERRORS = u"""
 3:5: Empty struct or union definition not allowed outside a 'cdef extern from' block
 6:0: Empty struct or union definition not allowed outside a 'cdef extern from' block
 9:5: Empty enum definition not allowed outside a 'cdef extern from' block
@@ -11,5 +20,9 @@
 _ERRORS = u"""
 3:5: Empty struct or union definition not allowed outside a 'cdef extern from' block
 6:0: Empty struct or union definition not allowed outside a 'cdef extern from' block
 9:5: Empty enum definition not allowed outside a 'cdef extern from' block
+
+13:5: Empty struct or union definition not allowed outside a 'cdef extern from' block
+15:0: Empty struct or union definition not allowed outside a 'cdef extern from' block
+17:5: Empty enum definition not allowed outside a 'cdef extern from' block
 """
diff --git a/tests/errors/fused_types.pyx b/tests/errors/fused_types.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvZXJyb3JzL2Z1c2VkX3R5cGVzLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvZXJyb3JzL2Z1c2VkX3R5cGVzLnB5eA== 100644
--- a/tests/errors/fused_types.pyx
+++ b/tests/errors/fused_types.pyx
@@ -1,4 +1,5 @@
 # mode: error
+# ticket: 1772
 
 cimport cython
 from cython import fused_type
@@ -64,4 +65,15 @@
 func(x, y)
 
 
+cdef fused mix_const_t:
+    int
+    const int
+
+cdef cdef_func_with_mix_const_type(mix_const_t val):
+    print(val)
+
+# Mixing const and non-const type makes fused type ambiguous
+cdef_func_with_mix_const_type(1)
+
+
 _ERRORS = u"""
@@ -67,7 +79,5 @@
 _ERRORS = u"""
-10:15: fused_type does not take keyword arguments
-15:33: Type specified multiple times
-26:0: Invalid use of fused types, type cannot be specialized
-26:4: Not enough types specified to specialize the function, int2_t is still fused
+11:15: fused_type does not take keyword arguments
+16:33: Type specified multiple times
 27:0: Invalid use of fused types, type cannot be specialized
 27:4: Not enough types specified to specialize the function, int2_t is still fused
@@ -72,9 +82,13 @@
 27:0: Invalid use of fused types, type cannot be specialized
 27:4: Not enough types specified to specialize the function, int2_t is still fused
-28:16: Call with wrong number of arguments (expected 2, got 1)
-29:16: Call with wrong number of arguments (expected 2, got 3)
-36:6: Invalid base type for memoryview slice: int *
-39:0: Fused lambdas not allowed
-42:5: Fused types not allowed here
-45:9: Fused types not allowed here
+28:0: Invalid use of fused types, type cannot be specialized
+28:4: Not enough types specified to specialize the function, int2_t is still fused
+29:16: Call with wrong number of arguments (expected 2, got 1)
+30:16: Call with wrong number of arguments (expected 2, got 3)
+37:6: Invalid base type for memoryview slice: int *
+40:0: Fused lambdas not allowed
+43:5: Fused types not allowed here
+46:9: Fused types not allowed here
+76:0: Invalid use of fused types, type cannot be specialized
+76:29: ambiguous overloaded method
 """
diff --git a/tests/errors/nogil.pyx b/tests/errors/nogil.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvZXJyb3JzL25vZ2lsLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvZXJyb3JzL25vZ2lsLnB5eA== 100644
--- a/tests/errors/nogil.pyx
+++ b/tests/errors/nogil.pyx
@@ -52,7 +52,7 @@
         x, y = y, x
         obj[i] = x
         obj.fred = x
-        print obj
+        print obj  # allowed!
         del fred
         return obj
         raise obj  # allowed!
@@ -105,5 +105,4 @@
 31:16: Constructing complex number not allowed without gil
 33:8: Assignment of Python object not allowed without gil
 33:14: Backquote expression not allowed without gil
-33:15: Operation not allowed without gil
 34:15: Assignment of Python object not allowed without gil
@@ -109,3 +108,2 @@
 34:15: Assignment of Python object not allowed without gil
-34:15: Operation not allowed without gil
 34:15: Python import not allowed without gil
@@ -111,4 +109,3 @@
 34:15: Python import not allowed without gil
-35:8: Operation not allowed without gil
 35:13: Python import not allowed without gil
 35:25: Constructing Python list not allowed without gil
@@ -113,6 +110,5 @@
 35:13: Python import not allowed without gil
 35:25: Constructing Python list not allowed without gil
-35:25: Operation not allowed without gil
 36:17: Iterating over Python object not allowed without gil
 38:11: Discarding owned Python object not allowed without gil
 38:11: Indexing Python object not allowed without gil
@@ -151,7 +147,6 @@
 53:11: Indexing Python object not allowed without gil
 54:11: Accessing Python attribute not allowed without gil
 54:11: Assignment of Python object not allowed without gil
-55:8: Constructing Python tuple not allowed without gil
-55:8: Python print statement not allowed without gil
+
 56:8: Deleting Python object not allowed without gil
 57:8: Returning Python object not allowed without gil
@@ -156,5 +151,6 @@
 56:8: Deleting Python object not allowed without gil
 57:8: Returning Python object not allowed without gil
+
 59:11: Truth-testing Python object not allowed without gil
 61:14: Truth-testing Python object not allowed without gil
 63:8: For-loop using object bounds or target not allowed without gil
diff --git a/tests/errors/nogil_conditional.pyx b/tests/errors/nogil_conditional.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvZXJyb3JzL25vZ2lsX2NvbmRpdGlvbmFsLnB5eA==
--- /dev/null
+++ b/tests/errors/nogil_conditional.pyx
@@ -0,0 +1,81 @@
+# cython: remove_unreachable=False
+# mode: error
+
+cdef int f_nogil(int x) nogil:
+    cdef int y
+    y = x + 10
+    return y
+
+
+def f_gil(x):
+    y = 0
+    y = x + 100
+    return y
+
+
+def illegal_gil_usage():
+    cdef int res = 0
+    with nogil(True):
+        res = f_gil(res)
+
+        with nogil(True):
+            res = f_gil(res)
+
+        with gil(False):
+            res = f_gil(res)
+
+    with nogil(False):
+        res = f_nogil(res)
+
+
+def foo(a):
+    return a < 10
+
+
+def non_constant_condition(int x) -> int:
+    cdef int res = x
+    with nogil(x < 10):
+        res = f_nogil(res)
+
+    with gil(foo(x)):
+         res = f_gil(res)
+
+
+ctypedef fused number_or_object:
+    float
+    object
+
+
+def fused_type(number_or_object x):
+    with nogil(number_or_object is object):
+        res = x + 1
+
+    # This should be fine
+    with nogil(number_or_object is float):
+        res = x + 1
+
+    return res
+
+
+_ERRORS = u"""
+19:14: Accessing Python global or builtin not allowed without gil
+19:19: Calling gil-requiring function not allowed without gil
+19:19: Coercion from Python not allowed without the GIL
+19:19: Constructing Python tuple not allowed without gil
+19:20: Converting to Python object not allowed without gil
+21:13: Trying to release the GIL while it was previously released.
+22:18: Accessing Python global or builtin not allowed without gil
+22:23: Calling gil-requiring function not allowed without gil
+22:23: Coercion from Python not allowed without the GIL
+22:23: Constructing Python tuple not allowed without gil
+22:24: Converting to Python object not allowed without gil
+25:18: Accessing Python global or builtin not allowed without gil
+25:23: Calling gil-requiring function not allowed without gil
+25:23: Coercion from Python not allowed without the GIL
+25:23: Constructing Python tuple not allowed without gil
+25:24: Converting to Python object not allowed without gil
+37:17: Non-constant condition in a `with nogil(<condition>)` statement
+40:16: Non-constant condition in a `with gil(<condition>)` statement
+51:8: Assignment of Python object not allowed without gil
+51:16: Calling gil-requiring function not allowed without gil
+"""
diff --git a/tests/errors/nonconst_excval.pyx b/tests/errors/nonconst_excval.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvZXJyb3JzL25vbmNvbnN0X2V4Y3ZhbC5weXg=
--- /dev/null
+++ b/tests/errors/nonconst_excval.pyx
@@ -0,0 +1,12 @@
+# mode: error
+
+import math
+
+cdef double cfunc(double x) except math.nan:
+    return x
+
+
+_ERRORS = """
+5:39: Exception value must be constant
+5:39: Not allowed in a constant expression
+"""
diff --git a/tests/errors/pep492_badsyntax_async2.pyx b/tests/errors/pep492_badsyntax_async2.pyx
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvZXJyb3JzL3BlcDQ5Ml9iYWRzeW50YXhfYXN5bmMyLnB5eA==..0000000000000000000000000000000000000000
--- a/tests/errors/pep492_badsyntax_async2.pyx
+++ /dev/null
@@ -1,11 +0,0 @@
-# mode: error
-# tag: pep492, async
-
-async def foo():
-    def foo(a:await list()):
-        pass
-
-_ERRORS = """
-5:14: 'await' not supported here
-5:14: 'await' not supported here
-"""
diff --git a/tests/errors/posonly.pyx b/tests/errors/posonly.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvZXJyb3JzL3Bvc29ubHkucHl4
--- /dev/null
+++ b/tests/errors/posonly.pyx
@@ -0,0 +1,102 @@
+# mode: error
+# tag: posonly
+
+def f(a, b = 5, /, c):
+    pass
+
+def f(a = 5, b, /, c):
+    pass
+
+def f(a = 5, b, /):
+    pass
+
+def f(a, /, a):
+    pass
+
+def f(a, /, *, a):
+    pass
+
+#def f(a, b/2, c): #D
+#    pass
+
+#def f(*args, /): #D
+#    pass
+
+#def f(*args, a, /):
+#    pass
+
+#def f(**kwargs, /):
+#    pass
+
+#def f(/, a = 1): # D
+#    pass
+
+#def f(/, a):
+#    pass
+
+#def f(/):
+#    pass
+
+#def f(*, a, /):
+#    pass
+
+#def f(*, /, a):
+#    pass
+
+#def f(a, /, c, /):
+#    pass
+
+#def f(a, /, c, /, d):
+#    pass
+
+#def f(a, /, c, /, d, *, e):
+#    pass
+
+#def f(a, *, c, /, d, e):
+#    pass
+
+def test_invalid_syntax_lambda(self):
+    lambda a, b = 5, /, c: None
+    lambda a = 5, b, /, c: None
+    lambda a = 5, b, /: None
+    lambda a, /, a: None
+    lambda a, /, *, a: None
+#    lambda *args, /: None
+#    lambda *args, a, /: None
+#    lambda **kwargs, /: None
+#    lambda /, a = 1: None
+#    lambda /, a: None
+#    lambda /: None
+#    lambda *, a, /: None
+#    lambda *, /, a: None
+
+async def f(a, b = 5, /, c):
+    pass
+
+#def test_multiple_seps(a,/,b,/):
+#    pass
+
+_ERRORS = u"""
+4:19: Non-default argument following default argument
+7:13: Non-default argument following default argument
+7:19: Non-default argument following default argument
+10:13: Non-default argument following default argument
+13:6: Previous declaration is here
+13:12: 'a' redeclared
+16:6: Previous declaration is here
+16:15: 'a' redeclared
+59:24: Non-default argument following default argument
+60:18: Non-default argument following default argument
+60:24: Non-default argument following default argument
+61:18: Non-default argument following default argument
+62:11: Previous declaration is here
+62:17: 'a' redeclared
+63:11: Previous declaration is here
+63:20: 'a' redeclared
+73:25: Non-default argument following default argument
+"""
+
+
+
+
+
diff --git a/tests/errors/posonly2.pyx b/tests/errors/posonly2.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvZXJyb3JzL3Bvc29ubHkyLnB5eA==
--- /dev/null
+++ b/tests/errors/posonly2.pyx
@@ -0,0 +1,9 @@
+# mode: error
+# tag: posonly
+
+def f(a, b/2, c):
+    pass
+
+_ERRORS = u"""
+4:11: Syntax error in Python function argument list
+"""
diff --git a/tests/errors/posonly3.pyx b/tests/errors/posonly3.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvZXJyb3JzL3Bvc29ubHkzLnB5eA==
--- /dev/null
+++ b/tests/errors/posonly3.pyx
@@ -0,0 +1,13 @@
+# mode: error
+# tag: posonly
+
+def f(*args, /):
+    pass
+
+def f(*args, a, /):
+    pass
+
+
+_ERRORS = u"""
+4:13: Expected ')', found '/'
+"""
diff --git a/tests/errors/posonly4.pyx b/tests/errors/posonly4.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvZXJyb3JzL3Bvc29ubHk0LnB5eA==
--- /dev/null
+++ b/tests/errors/posonly4.pyx
@@ -0,0 +1,9 @@
+# mode: error
+# tag: posonly
+
+def f(/, a = 1):
+    pass
+
+_ERRORS = u"""
+4:6: Got zero positional-only arguments despite presence of positional-only specifier '/'
+"""
diff --git a/tests/errors/posonly5.pyx b/tests/errors/posonly5.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvZXJyb3JzL3Bvc29ubHk1LnB5eA==
--- /dev/null
+++ b/tests/errors/posonly5.pyx
@@ -0,0 +1,11 @@
+# mode: error
+# tag: posonly
+
+def test_multiple_seps(a,/,b,/):
+    pass
+
+_ERRORS = u"""
+4:29: Expected ')', found '/'
+"""
+
+
diff --git a/tests/errors/pure_errors.py b/tests/errors/pure_errors.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvZXJyb3JzL3B1cmVfZXJyb3JzLnB5..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvZXJyb3JzL3B1cmVfZXJyb3JzLnB5 100644
--- a/tests/errors/pure_errors.py
+++ b/tests/errors/pure_errors.py
@@ -53,5 +53,5 @@
 _ERRORS = """
 44:22: Calling gil-requiring function not allowed without gil
 45:24: Calling gil-requiring function not allowed without gil
-49:0: Python functions cannot be declared 'nogil'
+48:0: Python functions cannot be declared 'nogil'
 """
diff --git a/tests/errors/tree_assert.pyx b/tests/errors/tree_assert.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvZXJyb3JzL3RyZWVfYXNzZXJ0LnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvZXJyb3JzL3RyZWVfYXNzZXJ0LnB5eA== 100644
--- a/tests/errors/tree_assert.pyx
+++ b/tests/errors/tree_assert.pyx
@@ -11,8 +11,8 @@
 
 
 _ERRORS = u"""
-9:0: Expected path '//ComprehensionNode' not found in result tree
-9:0: Expected path '//ComprehensionNode//FuncDefNode' not found in result tree
-9:0: Unexpected path '//NameNode' found in result tree
-9:0: Unexpected path '//SimpleCallNode' found in result tree
+5:0: Expected path '//ComprehensionNode' not found in result tree
+5:0: Expected path '//ComprehensionNode//FuncDefNode' not found in result tree
+5:0: Unexpected path '//NameNode' found in result tree
+5:0: Unexpected path '//SimpleCallNode' found in result tree
 """
diff --git a/tests/errors/unicode_identifiers_e1.pyx b/tests/errors/unicode_identifiers_e1.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvZXJyb3JzL3VuaWNvZGVfaWRlbnRpZmllcnNfZTEucHl4
--- /dev/null
+++ b/tests/errors/unicode_identifiers_e1.pyx
@@ -0,0 +1,8 @@
+# -*- coding: utf-8 -*-
+# mode: error
+
+★1 = 5 # invalid start symbol
+
+_ERRORS = u"""
+4:0: Unrecognized character
+"""
diff --git a/tests/errors/unicode_identifiers_e2.pyx b/tests/errors/unicode_identifiers_e2.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvZXJyb3JzL3VuaWNvZGVfaWRlbnRpZmllcnNfZTIucHl4
--- /dev/null
+++ b/tests/errors/unicode_identifiers_e2.pyx
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+# mode: error
+
+class MyClass₡: # invalid continue symbol
+    pass
+
+_ERRORS = u"""
+4:13: Unrecognized character
+"""
diff --git a/tests/errors/unicode_identifiers_e3.pyx b/tests/errors/unicode_identifiers_e3.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvZXJyb3JzL3VuaWNvZGVfaWRlbnRpZmllcnNfZTMucHl4
--- /dev/null
+++ b/tests/errors/unicode_identifiers_e3.pyx
@@ -0,0 +1,11 @@
+# -*- coding: utf-8 -*-
+# mode: error
+
+def f():
+    a = 1
+    ́b = 2 # looks like an indentation error but is actually a combining accent as the first letter of column 4
+    c = 3
+
+_ERRORS = u"""
+6:4: Unrecognized character
+"""
diff --git a/tests/errors/unicode_identifiers_e4.pyx b/tests/errors/unicode_identifiers_e4.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvZXJyb3JzL3VuaWNvZGVfaWRlbnRpZmllcnNfZTQucHl4
--- /dev/null
+++ b/tests/errors/unicode_identifiers_e4.pyx
@@ -0,0 +1,13 @@
+# -*- coding: utf-8 -*-
+# mode: error
+
+cdef class C:
+    # these two symbols "\u1e69" and "\u1e9b\u0323" normalize to the same thing
+    # so the two attributes can't coexist
+    cdef int ṩomething
+    cdef double ẛ̣omething
+
+_ERRORS = u"""
+7:13: Previous declaration is here
+8:16: 'ṩomething' redeclared
+"""
diff --git a/tests/errors/w_numpy_arr_as_cppvec_ref.pyx b/tests/errors/w_numpy_arr_as_cppvec_ref.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvZXJyb3JzL3dfbnVtcHlfYXJyX2FzX2NwcHZlY19yZWYucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvZXJyb3JzL3dfbnVtcHlfYXJyX2FzX2NwcHZlY19yZWYucHl4 100644
--- a/tests/errors/w_numpy_arr_as_cppvec_ref.pyx
+++ b/tests/errors/w_numpy_arr_as_cppvec_ref.pyx
@@ -5,6 +5,8 @@
 cimport numpy as np
 from libcpp.vector cimport vector
 
+np.import_array()
+
 cdef extern from *:
     void cpp_function_vector1(vector[int])
     void cpp_function_vector2(vector[int] &)
@@ -24,8 +26,8 @@
 
 
 _ERRORS = """
-17:25: Cannot pass Python object as C++ data structure reference (vector[int] &), will pass by copy.
-18:25: Cannot pass Python object as C++ data structure reference (vector[int] &), will pass by copy.
-19:28: Cannot pass Python object as C++ data structure reference (vector[int] &), will pass by copy.
-19:33: Cannot pass Python object as C++ data structure reference (vector[int] &), will pass by copy.
+19:25: Cannot pass Python object as C++ data structure reference (vector[int] &), will pass by copy.
+20:25: Cannot pass Python object as C++ data structure reference (vector[int] &), will pass by copy.
+21:28: Cannot pass Python object as C++ data structure reference (vector[int] &), will pass by copy.
+21:33: Cannot pass Python object as C++ data structure reference (vector[int] &), will pass by copy.
 """
diff --git a/tests/limited_api_bugs.txt b/tests/limited_api_bugs.txt
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvbGltaXRlZF9hcGlfYnVncy50eHQ=
--- /dev/null
+++ b/tests/limited_api_bugs.txt
@@ -0,0 +1,8 @@
+# This file contains tests corresponding to unresolved bugs using CPython's
+# Limited API which will be skipped in the normal testing run.
+
+convolve2
+dict_animal
+not_none
+queue3
+test_queue
diff --git a/tests/memoryview/cythonarray.pyx b/tests/memoryview/cythonarray.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvbWVtb3J5dmlldy9jeXRob25hcnJheS5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvbWVtb3J5dmlldy9jeXRob25hcnJheS5weXg= 100644
--- a/tests/memoryview/cythonarray.pyx
+++ b/tests/memoryview/cythonarray.pyx
@@ -209,3 +209,11 @@
 
     mslice = a
     print mslice[0, 0], mslice[1, 0], mslice[2, 5]
+
+class InheritFrom(v.array):
+    """
+    Test is just to confirm it works, not to do anything meaningful with it
+    (Be aware that itemsize isn't necessarily right)
+    >>> inst = InheritFrom(shape=(3, 3, 3), itemsize=4, format="i")
+    """
+    pass
diff --git a/tests/memoryview/memoryview.pyx b/tests/memoryview/memoryview.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvbWVtb3J5dmlldy9tZW1vcnl2aWV3LnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvbWVtb3J5dmlldy9tZW1vcnl2aWV3LnB5eA== 100644
--- a/tests/memoryview/memoryview.pyx
+++ b/tests/memoryview/memoryview.pyx
@@ -626,6 +626,7 @@
 def decref(*args):
     for item in args: Py_DECREF(item)
 
+@cython.binding(False)
 def get_refcount(x):
     return (<PyObject*>x).ob_refcnt
 
@@ -1099,7 +1100,7 @@
 
 
 def test_assign_from_byteslike(byteslike):
-    # Once http://python3statement.org is accepted, should be just
+    # Once https://python3statement.org/ is accepted, should be just
     # >>> test_assign_from_byteslike(bytes(b'hello'))
     # b'hello'
     # ...
diff --git a/tests/memoryview/memoryview_cache_builtins.srctree b/tests/memoryview/memoryview_cache_builtins.srctree
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvbWVtb3J5dmlldy9tZW1vcnl2aWV3X2NhY2hlX2J1aWx0aW5zLnNyY3RyZWU=
--- /dev/null
+++ b/tests/memoryview/memoryview_cache_builtins.srctree
@@ -0,0 +1,21 @@
+PYTHON setup.py build_ext --inplace
+
+################ setup.py #####################
+
+from distutils.core import setup
+from Cython.Build import cythonize
+from Cython.Compiler import Options
+
+Options.cache_builtins = False
+
+setup(
+    ext_modules = cythonize("mview.pyx")
+)
+
+############### mview.pyx ################
+
+# https://github.com/cython/cython/issues/3406
+# Failure was at Cython compilation stage
+
+def f(double [::1] x):
+    pass
diff --git a/tests/memoryview/memoryview_pep484_typing.pyx b/tests/memoryview/memoryview_pep484_typing.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvbWVtb3J5dmlldy9tZW1vcnl2aWV3X3BlcDQ4NF90eXBpbmcucHl4
--- /dev/null
+++ b/tests/memoryview/memoryview_pep484_typing.pyx
@@ -0,0 +1,96 @@
+# mode: run
+# tag: pep484, memoryview
+
+cimport cython
+
+include "../buffers/mockbuffers.pxi"
+
+
+def get_int_2d(mslice: cython.int[:, :], i: cython.int, j: cython.int) -> cython.int:
+    """
+    >>> C = IntMockBuffer("C", range(6), (2,3))
+    >>> get_int_2d(C, 1, 1)
+    acquired C
+    released C
+    4
+
+    Check negative indexing:
+    >>> get_int_2d(C, -1, 0)
+    acquired C
+    released C
+    3
+    >>> get_int_2d(C, -1, -2)
+    acquired C
+    released C
+    4
+    >>> get_int_2d(C, -2, -3)
+    acquired C
+    released C
+    0
+
+    Out-of-bounds errors:
+    >>> get_int_2d(C, 2, 0)
+    Traceback (most recent call last):
+        ...
+    IndexError: Out of bounds on buffer access (axis 0)
+    >>> get_int_2d(C, 0, -4)
+    Traceback (most recent call last):
+        ...
+    IndexError: Out of bounds on buffer access (axis 1)
+    """
+    buf = mslice
+    return buf[i, j]
+
+
+def set_int_2d(mslice: cython.int[:, :], i: cython.int, j: cython.int, value: cython.int) -> cython.int:
+    """
+    Uses get_int_2d to read back the value afterwards. For pure
+    unit test, one should support reading in MockBuffer instead.
+
+    >>> C = IntMockBuffer("C", range(6), (2,3))
+    >>> set_int_2d(C, 1, 1, 10)
+    acquired C
+    released C
+    >>> get_int_2d(C, 1, 1)
+    acquired C
+    released C
+    10
+
+    Check negative indexing:
+    >>> set_int_2d(C, -1, 0, 3)
+    acquired C
+    released C
+    >>> get_int_2d(C, -1, 0)
+    acquired C
+    released C
+    3
+
+    >>> set_int_2d(C, -1, -2, 8)
+    acquired C
+    released C
+    >>> get_int_2d(C, -1, -2)
+    acquired C
+    released C
+    8
+
+    >>> set_int_2d(C, -2, -3, 9)
+    acquired C
+    released C
+    >>> get_int_2d(C, -2, -3)
+    acquired C
+    released C
+    9
+
+    Out-of-bounds errors:
+    >>> set_int_2d(C, 2, 0, 19)
+    Traceback (most recent call last):
+        ...
+    IndexError: Out of bounds on buffer access (axis 0)
+    >>> set_int_2d(C, 0, -4, 19)
+    Traceback (most recent call last):
+        ...
+    IndexError: Out of bounds on buffer access (axis 1)
+
+    """
+    buf = mslice
+    buf[i, j] = value
diff --git a/tests/memoryview/memoryview_pep489_typing.pyx b/tests/memoryview/memoryview_pep489_typing.pyx
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvbWVtb3J5dmlldy9tZW1vcnl2aWV3X3BlcDQ4OV90eXBpbmcucHl4..0000000000000000000000000000000000000000
--- a/tests/memoryview/memoryview_pep489_typing.pyx
+++ /dev/null
@@ -1,96 +0,0 @@
-# mode: run
-# tag: pep489, memoryview
-
-cimport cython
-
-include "../buffers/mockbuffers.pxi"
-
-
-def get_int_2d(mslice: cython.int[:, :], i: cython.int, j: cython.int) -> cython.int:
-    """
-    >>> C = IntMockBuffer("C", range(6), (2,3))
-    >>> get_int_2d(C, 1, 1)
-    acquired C
-    released C
-    4
-
-    Check negative indexing:
-    >>> get_int_2d(C, -1, 0)
-    acquired C
-    released C
-    3
-    >>> get_int_2d(C, -1, -2)
-    acquired C
-    released C
-    4
-    >>> get_int_2d(C, -2, -3)
-    acquired C
-    released C
-    0
-
-    Out-of-bounds errors:
-    >>> get_int_2d(C, 2, 0)
-    Traceback (most recent call last):
-        ...
-    IndexError: Out of bounds on buffer access (axis 0)
-    >>> get_int_2d(C, 0, -4)
-    Traceback (most recent call last):
-        ...
-    IndexError: Out of bounds on buffer access (axis 1)
-    """
-    buf = mslice
-    return buf[i, j]
-
-
-def set_int_2d(mslice: cython.int[:, :], i: cython.int, j: cython.int, value: cython.int) -> cython.int:
-    """
-    Uses get_int_2d to read back the value afterwards. For pure
-    unit test, one should support reading in MockBuffer instead.
-
-    >>> C = IntMockBuffer("C", range(6), (2,3))
-    >>> set_int_2d(C, 1, 1, 10)
-    acquired C
-    released C
-    >>> get_int_2d(C, 1, 1)
-    acquired C
-    released C
-    10
-
-    Check negative indexing:
-    >>> set_int_2d(C, -1, 0, 3)
-    acquired C
-    released C
-    >>> get_int_2d(C, -1, 0)
-    acquired C
-    released C
-    3
-
-    >>> set_int_2d(C, -1, -2, 8)
-    acquired C
-    released C
-    >>> get_int_2d(C, -1, -2)
-    acquired C
-    released C
-    8
-
-    >>> set_int_2d(C, -2, -3, 9)
-    acquired C
-    released C
-    >>> get_int_2d(C, -2, -3)
-    acquired C
-    released C
-    9
-
-    Out-of-bounds errors:
-    >>> set_int_2d(C, 2, 0, 19)
-    Traceback (most recent call last):
-        ...
-    IndexError: Out of bounds on buffer access (axis 0)
-    >>> set_int_2d(C, 0, -4, 19)
-    Traceback (most recent call last):
-        ...
-    IndexError: Out of bounds on buffer access (axis 1)
-
-    """
-    buf = mslice
-    buf[i, j] = value
diff --git a/tests/memoryview/memslice.pyx b/tests/memoryview/memslice.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvbWVtb3J5dmlldy9tZW1zbGljZS5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvbWVtb3J5dmlldy9tZW1zbGljZS5weXg= 100644
--- a/tests/memoryview/memslice.pyx
+++ b/tests/memoryview/memslice.pyx
@@ -1058,6 +1058,7 @@
 def decref(*args):
     for item in args: Py_DECREF(item)
 
+@cython.binding(False)
 def get_refcount(x):
     return (<PyObject*>x).ob_refcnt
 
@@ -1853,11 +1854,7 @@
     """
     cdef TestAttrs[10] array
     cdef TestAttrs[:] struct_memview = array
-
-    if sys.version_info[:2] >= (2, 7):
-        print builtins.memoryview(struct_memview).format
-    else:
-        print "T{i:int_attrib:c:char_attrib:}"
+    print builtins.memoryview(struct_memview).format
 
 
 # Test padding at the end of structs in the buffer support
@@ -2145,7 +2142,7 @@
     7
     8
     9
-    2 5
+    5
     1 5
     """
     cdef int i
@@ -2166,6 +2163,7 @@
         print m2[i]
 
     obj = m2[5]
-    print get_refcount(obj), obj
+    refcount1 = get_refcount(obj)
+    print obj
 
     del m2
@@ -2170,6 +2168,7 @@
 
     del m2
-    print get_refcount(obj), obj
+    refcount2 = get_refcount(obj)
+    print refcount1 - refcount2, obj
 
     assert unique_refcount == get_refcount(unique), (unique_refcount, get_refcount(unique))
 
@@ -2256,4 +2255,5 @@
     """
     >>> test_contig_scalar_to_slice_assignment()
     14 14 14 14
+    30 14 30 14
     20 20 20 20
@@ -2259,4 +2259,5 @@
     20 20 20 20
+    30 30 20 20
     """
     cdef int[5][10] a
     cdef int[:, ::1] m = a
@@ -2264,6 +2265,9 @@
     m[...] = 14
     print m[0, 0], m[-1, -1], m[3, 2], m[4, 9]
 
+    m[:, :1] = 30
+    print m[0, 0], m[0, 1], m[1, 0], m[1, 1]
+
     m[:, :] = 20
     print m[0, 0], m[-1, -1], m[3, 2], m[4, 9]
 
@@ -2267,6 +2271,9 @@
     m[:, :] = 20
     print m[0, 0], m[-1, -1], m[3, 2], m[4, 9]
 
+    m[:1, :] = 30
+    print m[0, 0], m[0, 1], m[1, 0], m[1, 1]
+
 @testcase
 def test_dtype_object_scalar_assignment():
     """
diff --git a/tests/memoryview/numpy_memoryview.pyx b/tests/memoryview/numpy_memoryview.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvbWVtb3J5dmlldy9udW1weV9tZW1vcnl2aWV3LnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvbWVtb3J5dmlldy9udW1weV9tZW1vcnl2aWV3LnB5eA== 100644
--- a/tests/memoryview/numpy_memoryview.pyx
+++ b/tests/memoryview/numpy_memoryview.pyx
@@ -718,3 +718,42 @@
         x[i]
         x[i, ...]
         x[i, :]
+
+
+ctypedef struct SameTypeAfterArraysStructSimple:
+    double a[16]
+    double b[16]
+    double c
+
+@testcase
+def same_type_after_arrays_simple():
+    """
+    >>> same_type_after_arrays_simple()
+    """
+
+    cdef SameTypeAfterArraysStructSimple element
+    arr = np.ones(2, np.asarray(<SameTypeAfterArraysStructSimple[:1]>&element).dtype)
+    cdef SameTypeAfterArraysStructSimple[:] memview = arr
+
+
+ctypedef struct SameTypeAfterArraysStructComposite:
+    int a
+    float b[8]
+    float c
+    unsigned long d
+    int e[5]
+    int f
+    int g
+    double h[4]
+    int i
+
+@testcase
+def same_type_after_arrays_composite():
+    """
+    >>> same_type_after_arrays_composite() if sys.version_info[:2] >= (3, 5) else None
+    >>> same_type_after_arrays_composite() if sys.version_info[:2] == (2, 7) else None
+    """
+
+    cdef SameTypeAfterArraysStructComposite element
+    arr = np.ones(2, np.asarray(<SameTypeAfterArraysStructComposite[:1]>&element).dtype)
+    cdef SameTypeAfterArraysStructComposite[:] memview = arr
diff --git a/tests/memoryview/numpy_memoryview_readonly.pyx b/tests/memoryview/numpy_memoryview_readonly.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvbWVtb3J5dmlldy9udW1weV9tZW1vcnl2aWV3X3JlYWRvbmx5LnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvbWVtb3J5dmlldy9udW1weV9tZW1vcnl2aWV3X3JlYWRvbmx5LnB5eA== 100644
--- a/tests/memoryview/numpy_memoryview_readonly.pyx
+++ b/tests/memoryview/numpy_memoryview_readonly.pyx
@@ -1,4 +1,5 @@
 # mode: run
 # tag: readonly, const, numpy
+# ticket: 1772
 
 import numpy as np
@@ -3,3 +4,4 @@
 
 import numpy as np
+cimport cython
 
@@ -5,6 +7,8 @@
 
-def new_array():
-    return np.arange(10).astype('float')
+def new_array(dtype='float', writeable=True):
+    array = np.arange(10, dtype=dtype)
+    array.setflags(write=writeable)
+    return array
 
 ARRAY = new_array()
 
@@ -124,3 +128,45 @@
     rw[1] = 2
     rw2[2] = 2
     return rw[0], rw[1], rw[2], rw2[0], rw2[1], rw2[2]
+
+
+cdef getmax_floating(const cython.floating[:] x):
+    """Function with fused type, should work with both ro and rw memoryviews"""
+    cdef cython.floating max_val = - float('inf')
+    for val in x:
+        if val > max_val:
+            max_val = val
+    return max_val
+
+
+def test_mmview_const_fused_cdef():
+    """Test cdef function with const fused type memory view as argument.
+
+    >>> test_mmview_const_fused_cdef()
+    """
+    cdef float[:] data_rw = new_array(dtype='float32')
+    assert getmax_floating(data_rw) == 9
+
+    cdef const float[:] data_ro = new_array(dtype='float32', writeable=False)
+    assert getmax_floating(data_ro) == 9
+
+
+def test_mmview_const_fused_def(const cython.floating[:] x):
+    """Test def function with const fused type memory view as argument.
+
+    With read-write numpy array:
+
+    >>> test_mmview_const_fused_def(new_array('float32', writeable=True))
+    0.0
+    >>> test_mmview_const_fused_def(new_array('float64', writeable=True))
+    0.0
+
+    With read-only numpy array:
+
+    >>> test_mmview_const_fused_def(new_array('float32', writeable=False))
+    0.0
+    >>> test_mmview_const_fused_def(new_array('float64', writeable=False))
+    0.0
+    """
+    cdef cython.floating result = x[0]
+    return result
diff --git a/tests/memoryview/relaxed_strides.pyx b/tests/memoryview/relaxed_strides.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvbWVtb3J5dmlldy9yZWxheGVkX3N0cmlkZXMucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvbWVtb3J5dmlldy9yZWxheGVkX3N0cmlkZXMucHl4 100644
--- a/tests/memoryview/relaxed_strides.pyx
+++ b/tests/memoryview/relaxed_strides.pyx
@@ -10,8 +10,8 @@
 See also:
 
     Mailing list threads:
-      http://thread.gmane.org/gmane.comp.python.cython.devel/14762
-      http://thread.gmane.org/gmane.comp.python.cython.devel/14634
+      https://thread.gmane.org/gmane.comp.python.cython.devel/14762
+      https://thread.gmane.org/gmane.comp.python.cython.devel/14634
 
     Detailed discussion of the difference between numpy/cython's current
     definition of "contiguity", and the correct definition:
@@ -15,7 +15,7 @@
 
     Detailed discussion of the difference between numpy/cython's current
     definition of "contiguity", and the correct definition:
-      http://thread.gmane.org/gmane.comp.python.cython.devel/14634/focus=14640
+      https://thread.gmane.org/gmane.comp.python.cython.devel/14634/focus=14640
 
     The PR implementing NPY_RELAXED_STRIDES_CHECKING:
       https://github.com/numpy/numpy/pull/3162
diff --git a/tests/memoryview/view_return_errors.pyx b/tests/memoryview/view_return_errors.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvbWVtb3J5dmlldy92aWV3X3JldHVybl9lcnJvcnMucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvbWVtb3J5dmlldy92aWV3X3JldHVybl9lcnJvcnMucHl4 100644
--- a/tests/memoryview/view_return_errors.pyx
+++ b/tests/memoryview/view_return_errors.pyx
@@ -13,7 +13,18 @@
         raise TypeError('dummy')
 
 
-def propagate(i):
+cdef double[:] foo_nogil(int i) nogil:
+    if i == 1:
+        raise AttributeError('dummy')
+    if i == 2:
+        raise RuntimeError('dummy')
+    if i == 3:
+        raise ValueError('dummy')
+    if i == 4:
+        raise TypeError('dummy')
+
+
+def propagate(i, bint nogil=False):
     """
     >>> propagate(0)
     TypeError('Memoryview return value is not initialized')
@@ -25,5 +36,16 @@
     ValueError('dummy')
     >>> propagate(4)
     TypeError('dummy')
+
+    >>> propagate(0, nogil=True)
+    TypeError('Memoryview return value is not initialized')
+    >>> propagate(1, nogil=True)
+    AttributeError('dummy')
+    >>> propagate(2, nogil=True)
+    RuntimeError('dummy')
+    >>> propagate(3, nogil=True)
+    ValueError('dummy')
+    >>> propagate(4, nogil=True)
+    TypeError('dummy')
     """
     try:
@@ -28,6 +50,6 @@
     """
     try:
-        foo(i)
+        foo_nogil(i) if nogil else foo(i)
     except Exception as e:
         print '%s(%r)' % (e.__class__.__name__, e.args[0])
     else:
diff --git a/tests/pypy2_bugs.txt b/tests/pypy2_bugs.txt
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcHlweTJfYnVncy50eHQ=
--- /dev/null
+++ b/tests/pypy2_bugs.txt
@@ -0,0 +1,29 @@
+# Specific bugs that only apply to pypy2
+
+build.cythonize_script
+build.cythonize_script_package
+run.initial_file_path
+run.reduce_pickle
+run.final_in_pxd
+run.cdef_multiple_inheritance
+run.cdef_multiple_inheritance_nodict
+run.extstarargs
+run.cpython_capi
+run.isnot
+
+# pypy 2 seems to be preferring .py files to .so files
+# https://foss.heptapod.net/pypy/pypy/issues/3185
+run.language_level
+run.pure_pxd
+
+# Silly error with doctest matching slightly different string outputs rather than 
+# an actual bug but one I can't easily resolve
+run.with_gil
+
+
+# looks like a "when does the GC run?" issue - slightly surprised it's OK on pypy3
+memoryview.numpy_memoryview
+
+# type features that are disabled in PyPy2:
+#run.test_genericclass
+run.test_subclassinit
diff --git a/tests/pypy_bugs.txt b/tests/pypy_bugs.txt
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcHlweV9idWdzLnR4dA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcHlweV9idWdzLnR4dA== 100644
--- a/tests/pypy_bugs.txt
+++ b/tests/pypy_bugs.txt
@@ -4,10 +4,9 @@
 
 broken_exception
 bufaccess
-memoryview
-memslice
+memoryview.memoryview$
 sequential_parallel
 
 yield_from_pep380
 memoryview_inplace_division
 
@@ -9,6 +8,53 @@
 sequential_parallel
 
 yield_from_pep380
 memoryview_inplace_division
 
+run.unicodemethods
+run.unicode_imports
+run.test_genericclass
+run.tp_new
+run.test_fstring
+run.test_exceptions
+run.test_dictviews
+run.str_subclass_kwargs
+run.special_method_docstrings
+run.slice_ptr
+compile.min_async
+run.cython_includes
+run.pyarray
+run.test_unicode
+run.__getattribute__
+run.__getattribute_subclasses__
+run.__debug__
+run.array_cimport
+run.builtin_abs
+run.builtincomplex
+run.cdef_multiple_inheritance_errors
+run.cdivision_CEP_516
+run.cyfunction
+run.final_cdef_class
+run.index
+run.pyclass_special_methods
+run.reimport_from_package
+run.reimport_from_subinterpreter
+run.reimport_failure
+pkg.cimportfrom
+embedded
+TestCyCache
+run.ext_auto_richcmp
+run.coverage_cmd
+run.coverage_cmd_src_layout
+run.coverage_installed_pkg
+run.coverage_api
+run.coverage_nogil
+
+# very little coroutine-related seems to work
+run.test_asyncgen
+run.test_coroutines_pep492
+run.async_iter_pep492
+run.embedsignatures
+run.py35_asyncio_async_def
+run.asyncio_generators
+
 # gc issue?
@@ -14,5 +60,4 @@
 # gc issue?
-memoryview_in_subclasses
 external_ref_reassignment
 run.exttype_dealloc
 
@@ -20,20 +65,13 @@
 run.special_methods_T561
 run.special_methods_T561_py2
 
-# tests for things that don't exist in cpyext
-compile.pylong
-run.datetime_pxd
-run.datetime_cimport
-run.datetime_members
-run.extern_builtins_T258
-run.line_trace
-run.line_profile_test
-run.pstats_profile_test
-run.longintrepr
-
-# refcounting-specific tests
-double_dealloc_T796
-run.exceptionrefcount
-run.capiimpl
-run.refcount_in_meth
-
+# looks to be fixed in PyPy 7.3.0
+# TODO - remove when Travis updates
+run.py_unicode_strings
+run.unicodeliterals
+run.unicode_identifiers
+run.unicode_identifiers_import
+errors.unicode_identifiers_e4
+run.tracebacks
+run.fstring
+run.unicode_identifiers_normalization
diff --git a/tests/pypy_crash_bugs.txt b/tests/pypy_crash_bugs.txt
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcHlweV9jcmFzaF9idWdzLnR4dA==
--- /dev/null
+++ b/tests/pypy_crash_bugs.txt
@@ -0,0 +1,13 @@
+# Bugs that causes hard crashes that we certainly don't 
+# want to run because it will break the testsuite
+
+# segfault
+run.fastcall
+memslice
+
+# """Fatal RPython error: NotImplementedError
+# Aborted (core dumped)"""
+run.py35_pep492_interop
+
+# gc issue?
+memoryview_in_subclasses
diff --git a/tests/pypy_implementation_detail_bugs.txt b/tests/pypy_implementation_detail_bugs.txt
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcHlweV9pbXBsZW1lbnRhdGlvbl9kZXRhaWxfYnVncy50eHQ=
--- /dev/null
+++ b/tests/pypy_implementation_detail_bugs.txt
@@ -0,0 +1,45 @@
+# PyPy "bugs" that are probably implementation differences from
+# CPython rather than actual bugs. Therefore they aren't targets
+# to be fixed (but there *may* be other details in the testfile
+# that should be tested on PyPy?)
+
+run.starargs
+
+# refcounting-specific tests
+double_dealloc_T796
+run.exceptionrefcount
+run.capiimpl
+run.refcount_in_meth
+# Ideally just disable the reference-counting tests on PyPy?
+run.fused_types
+run.generator_frame_cycle
+run.generators_in_refcycles
+run.generators_py
+run.parallel
+
+# "sys.getsizeof(object, default) will always return default on PyPy, and
+# raise a TypeError if default is not provided."
+buildenv
+
+# tests for things that don't exist in cpyext
+compile.pylong
+run.datetime_pxd
+run.datetime_cimport
+run.datetime_members
+run.extern_builtins_T258
+run.line_trace
+run.line_profile_test
+run.pstats_profile_test
+run.longintrepr
+
+# tests probably rely on immediate GC (although maybe the tests could be tweaked so
+# only these bits don't run in PyPy?)
+buffers.buffer
+buffers.userbuffer
+memoryview.cythonarray
+memoryview.memoryview_pep484_typing
+run.cpp_classes
+run.cpp_classes_def
+
+# missing pypy feature?
+matrix_multiplier
diff --git a/tests/pyximport/pyximport_pyimport.srctree b/tests/pyximport/pyximport_pyimport.srctree
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcHl4aW1wb3J0L3B5eGltcG9ydF9weWltcG9ydC5zcmN0cmVl..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcHl4aW1wb3J0L3B5eGltcG9ydF9weWltcG9ydC5zcmN0cmVl 100644
--- a/tests/pyximport/pyximport_pyimport.srctree
+++ b/tests/pyximport/pyximport_pyimport.srctree
@@ -8,7 +8,6 @@
 
 # blacklist for speed
 import pyximport.pyxbuild, Cython.Compiler.Pipeline
-import distutils.core, distutils.ccompiler, distutils.command.build
 
 pyximport.install(pyximport=False, pyimport=True,
                   build_dir=os.path.join(os.path.dirname(__file__), "TEST_TMP"))
diff --git a/tests/run/addop.pyx b/tests/run/addop.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2FkZG9wLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2FkZG9wLnB5eA== 100644
--- a/tests/run/addop.pyx
+++ b/tests/run/addop.pyx
@@ -166,3 +166,20 @@
     ... except TypeError: pass
     """
     return 2**30 + x
+
+
+def add0(x):
+    """
+    >>> add0(0)
+    (0, 0)
+    >>> add0(1)
+    (1, 1)
+    >>> add0(-1)
+    (-1, -1)
+    >>> a, b = add0(2**32)
+    >>> bigint(a)
+    4294967296
+    >>> bigint(b)
+    4294967296
+    """
+    return x + 0, 0 + x
diff --git a/tests/run/always_allow_keywords_T295.pyx b/tests/run/always_allow_keywords_T295.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2Fsd2F5c19hbGxvd19rZXl3b3Jkc19UMjk1LnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2Fsd2F5c19hbGxvd19rZXl3b3Jkc19UMjk1LnB5eA== 100644
--- a/tests/run/always_allow_keywords_T295.pyx
+++ b/tests/run/always_allow_keywords_T295.pyx
@@ -2,8 +2,19 @@
 
 cimport cython
 
+def assert_typeerror_no_keywords(func, *args, **kwds):
+    # Python 3.9 produces an slightly different error message
+    # to previous versions, so doctest isn't matching the
+    # traceback
+    try:
+        func(*args, **kwds)
+    except TypeError as e:
+        assert e.args[0].endswith(" takes no keyword arguments"), e.args[0]
+    else:
+        assert False, "call did not raise TypeError"
+
 
 def func1(arg):
     """
     >>> func1(None)
     >>> func1(*[None])
@@ -5,12 +16,9 @@
 
 def func1(arg):
     """
     >>> func1(None)
     >>> func1(*[None])
-    >>> func1(arg=None)
-    Traceback (most recent call last):
-    ...
-    TypeError: func1() takes no keyword arguments
+    >>> assert_typeerror_no_keywords(func1, arg=None)
     """
     pass
 
@@ -19,10 +27,7 @@
     """
     >>> func2(None)
     >>> func2(*[None])
-    >>> func2(arg=None)
-    Traceback (most recent call last):
-    ...
-    TypeError: func2() takes no keyword arguments
+    >>> assert_typeerror_no_keywords(func2, arg=None)
     """
     pass
 
@@ -39,9 +44,6 @@
     """
     >>> A().meth1(None)
     >>> A().meth1(*[None])
-    >>> A().meth1(arg=None)
-    Traceback (most recent call last):
-    ...
-    TypeError: meth1() takes no keyword arguments
+    >>> assert_typeerror_no_keywords(A().meth1, arg=None)
     >>> A().meth2(None)
     >>> A().meth2(*[None])
@@ -46,9 +48,6 @@
     >>> A().meth2(None)
     >>> A().meth2(*[None])
-    >>> A().meth2(arg=None)
-    Traceback (most recent call last):
-    ...
-    TypeError: meth2() takes no keyword arguments
+    >>> assert_typeerror_no_keywords(A().meth2, arg=None)
     >>> A().meth3(None)
     >>> A().meth3(*[None])
     >>> A().meth3(arg=None)
diff --git a/tests/run/annotate_html.pyx b/tests/run/annotate_html.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2Fubm90YXRlX2h0bWwucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2Fubm90YXRlX2h0bWwucHl4 100644
--- a/tests/run/annotate_html.pyx
+++ b/tests/run/annotate_html.pyx
@@ -11,6 +11,8 @@
 
 >>> import re
 >>> assert re.search('<pre .*def.* .*mixed_test.*</pre>', html)
+>>> from Cython.Compiler.Annotate import AnnotationCCodeWriter
+>>> assert (AnnotationCCodeWriter.COMPLETE_CODE_TITLE not in html) # per default no complete c code
 """
 
 
diff --git a/tests/run/annotation_typing.pyx b/tests/run/annotation_typing.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2Fubm90YXRpb25fdHlwaW5nLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2Fubm90YXRpb25fdHlwaW5nLnB5eA== 100644
--- a/tests/run/annotation_typing.pyx
+++ b/tests/run/annotation_typing.pyx
@@ -242,7 +242,7 @@
 218:29: Ambiguous types in annotation, ignoring
 # BUG:
 46:6: 'pytypes_cpdef' redeclared
-121:0: 'struct_io' redeclared
-156:0: 'struct_convert' redeclared
-175:0: 'exception_default' redeclared
+120:0: 'struct_io' redeclared
+149:0: 'struct_convert' redeclared
+168:0: 'exception_default' redeclared
 """
diff --git a/tests/run/array_cimport.srctree b/tests/run/array_cimport.srctree
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2FycmF5X2NpbXBvcnQuc3JjdHJlZQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2FycmF5X2NpbXBvcnQuc3JjdHJlZQ== 100644
--- a/tests/run/array_cimport.srctree
+++ b/tests/run/array_cimport.srctree
@@ -32,5 +32,5 @@
 
 cdef array a = array('i', [1,2,3])
 cdef Foo x
-print a.data.as_ints[0]
+print(a.data.as_ints[0])
 x = Foo(a)
@@ -36,2 +36,2 @@
 x = Foo(a)
-print x.obj.data.as_ints[0]
+print(x.obj.data.as_ints[0])
diff --git a/tests/run/assert.pyx b/tests/run/assert.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2Fzc2VydC5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2Fzc2VydC5weXg= 100644
--- a/tests/run/assert.pyx
+++ b/tests/run/assert.pyx
@@ -2,6 +2,10 @@
 
 cimport cython
 
+@cython.test_assert_path_exists(
+    '//AssertStatNode',
+    '//AssertStatNode//RaiseStatNode',
+)
 def f(a, b, int i):
     """
     >>> f(1, 2, 1)
@@ -22,7 +26,9 @@
 
 @cython.test_assert_path_exists(
     '//AssertStatNode',
-    '//AssertStatNode//TupleNode')
+    '//AssertStatNode//RaiseStatNode',
+    '//AssertStatNode//RaiseStatNode//TupleNode',
+)
 def g(a, b):
     """
     >>> g(1, "works")
@@ -38,7 +44,9 @@
 
 @cython.test_assert_path_exists(
     '//AssertStatNode',
-    '//AssertStatNode//TupleNode')
+    '//AssertStatNode//RaiseStatNode',
+    '//AssertStatNode//RaiseStatNode//TupleNode',
+)
 def g(a, b):
     """
     >>> g(1, "works")
@@ -54,8 +62,9 @@
 
 @cython.test_assert_path_exists(
     '//AssertStatNode',
-    '//AssertStatNode//TupleNode',
-    '//AssertStatNode//TupleNode//TupleNode')
+    '//AssertStatNode//RaiseStatNode',
+    '//AssertStatNode//RaiseStatNode//TupleNode',
+    '//AssertStatNode//RaiseStatNode//TupleNode//TupleNode',)
 def assert_with_tuple_arg(a):
     """
     >>> assert_with_tuple_arg(True)
@@ -67,5 +76,7 @@
 
 
 @cython.test_assert_path_exists(
-    '//AssertStatNode')
+    '//AssertStatNode',
+    '//AssertStatNode//RaiseStatNode',
+)
 @cython.test_fail_if_path_exists(
@@ -71,5 +82,6 @@
 @cython.test_fail_if_path_exists(
-    '//AssertStatNode//TupleNode')
+    '//AssertStatNode//TupleNode',
+)
 def assert_with_str_arg(a):
     """
     >>> assert_with_str_arg(True)
diff --git a/tests/run/builtin_abs.pyx b/tests/run/builtin_abs.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2J1aWx0aW5fYWJzLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2J1aWx0aW5fYWJzLnB5eA== 100644
--- a/tests/run/builtin_abs.pyx
+++ b/tests/run/builtin_abs.pyx
@@ -59,6 +59,27 @@
     """
     return abs(a)
 
+@cython.overflowcheck(True)
+@cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']",
+                                "//ReturnStatNode//NameNode[@entry.cname = 'abs']")
+cdef int c_int_abs(int a) nogil except *:
+    return abs(a)
+
+def test_c_int_abs(int a):
+    """
+    >>> test_c_int_abs(-5) == 5
+    True
+    >>> test_c_int_abs(-5.1) == 5
+    True
+    >>> test_c_int_abs(-max_int-1)     #doctest: +ELLIPSIS
+    Traceback (most recent call last):
+        ...
+    OverflowError: ...
+    >>> test_c_int_abs(max_int) == abs(max_int)  or (max_int, test_c_int_abs(max_int), abs(max_int))
+    True
+    """
+    return c_int_abs(a)
+
 @cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']")
 @cython.test_fail_if_path_exists("//ReturnStatNode//NameNode[@entry.cname = 'abs']",
                                  "//ReturnStatNode//NameNode[@entry.cname = 'labs']")
@@ -69,6 +90,19 @@
     """
     return abs(a)
 
+@cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']")
+@cython.test_fail_if_path_exists("//ReturnStatNode//NameNode[@entry.cname = 'abs']",
+                                 "//ReturnStatNode//NameNode[@entry.cname = 'labs']")
+cdef unsigned int c_uint_abs(unsigned int a) nogil:
+    return abs(a)
+
+def test_c_uint_abs(unsigned int a):
+    """
+    >>> test_c_uint_abs(max_int) == abs(max_int)  or (max_int, test_c_uint_abs(max_int), abs(max_int))
+    True
+    """
+    return c_uint_abs(a)
+
 @cython.overflowcheck(True)
 @cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']",
                                 "//ReturnStatNode//NameNode[@entry.cname = 'labs']")
@@ -87,6 +121,27 @@
     """
     return abs(a)
 
+@cython.overflowcheck(True)
+@cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']",
+                                "//ReturnStatNode//NameNode[@entry.cname = 'labs']")
+cdef long c_long_abs(long a) nogil except *:
+    return abs(a)
+
+def test_c_long_abs(long a):
+    """
+    >>> test_c_long_abs(-5) == 5
+    True
+    >>> test_c_long_abs(-5.1) == 5
+    True
+    >>> test_c_long_abs(-max_long-1)     #doctest: +ELLIPSIS
+    Traceback (most recent call last):
+        ...
+    OverflowError: ...
+    >>> test_c_long_abs(max_long) == abs(max_long)  or (max_long, test_c_long_abs(max_long), abs(max_long))
+    True
+    """
+    return c_long_abs(a)
+
 @cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']")
 @cython.test_fail_if_path_exists("//ReturnStatNode//NameNode[@entry.cname = 'abs']",
                                  "//ReturnStatNode//NameNode[@entry.cname = 'labs']")
@@ -99,6 +154,21 @@
     """
     return abs(a)
 
+@cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']")
+@cython.test_fail_if_path_exists("//ReturnStatNode//NameNode[@entry.cname = 'abs']",
+                                 "//ReturnStatNode//NameNode[@entry.cname = 'labs']")
+cdef unsigned long c_ulong_abs(unsigned long a) nogil:
+    return abs(a)
+
+def test_c_ulong_abs(unsigned long a):
+    """
+    >>> test_c_ulong_abs(max_long) == abs(max_long)  or (max_int, test_c_ulong_abs(max_long), abs(max_long))
+    True
+    >>> test_c_ulong_abs(max_long + 5) == abs(max_long + 5)  or (max_long + 5, test_c_ulong_abs(max_long + 5), abs(max_long + 5))
+    True
+    """
+    return c_ulong_abs(a)
+
 @cython.overflowcheck(True)
 @cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']",
                                 "//ReturnStatNode//NameNode[@entry.cname = '__Pyx_abs_longlong']")
@@ -115,6 +185,25 @@
     """
     return abs(a)
 
+@cython.overflowcheck(True)
+@cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']",
+                                "//ReturnStatNode//NameNode[@entry.cname = '__Pyx_abs_longlong']")
+cdef long long c_long_long_abs(long long a) nogil except *:
+    return abs(a)
+
+def test_c_long_long_abs(long long a):
+    """
+    >>> test_c_long_long_abs(-(2**33)) == 2**33
+    True
+    >>> test_c_long_long_abs(-max_long_long-1)     #doctest: +ELLIPSIS
+    Traceback (most recent call last):
+        ...
+    OverflowError: ...
+    >>> test_c_long_long_abs(max_long_long) == abs(max_long_long) or (max_long_long, test_c_long_long_abs(max_long_long), abs(max_long_long))
+    True
+    """
+    return c_long_long_abs(a)
+
 @cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']",
                                 "//ReturnStatNode//NameNode[@entry.cname = 'fabs']")
 def double_abs(double a):
@@ -127,6 +216,20 @@
     return abs(a)
 
 @cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']",
+                                "//ReturnStatNode//NameNode[@entry.cname = 'fabs']")
+cdef double c_double_abs(double a) nogil:
+    return abs(a)
+
+def test_c_double_abs(double a):
+    """
+    >>> test_c_double_abs(-5)
+    5.0
+    >>> test_c_double_abs(-5.5)
+    5.5
+    """
+    return c_double_abs(a)
+
+@cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']",
                                 "//ReturnStatNode//NameNode[@entry.cname = 'fabsf']")
 def float_abs(float a):
     """
@@ -138,6 +241,20 @@
     return abs(a)
 
 @cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']",
+                                "//ReturnStatNode//NameNode[@entry.cname = 'fabsf']")
+cdef float c_float_abs(float a) nogil:
+    return abs(a)
+
+def test_c_float_abs(float a):
+    """
+    >>> test_c_float_abs(-5)
+    5.0
+    >>> test_c_float_abs(-5.5)
+    5.5
+    """
+    return c_float_abs(a)
+
+@cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']",
                                 "//ReturnStatNode//NameNode[@entry.cname = '__Pyx_c_abs_double']")
 def complex_abs(complex a):
     """
@@ -147,3 +264,17 @@
     5.5
     """
     return abs(a)
+
+@cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']",
+                                "//ReturnStatNode//NameNode[@entry.cname = '__Pyx_c_abs_double']")
+cdef double c_complex_abs(complex a) nogil:
+    return abs(a)
+
+def test_c_complex_abs(complex a):
+    """
+    >>> test_c_complex_abs(-5j)
+    5.0
+    >>> test_c_complex_abs(-5.5j)
+    5.5
+    """
+    return c_complex_abs(a)
diff --git a/tests/run/builtin_float.py b/tests/run/builtin_float.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2J1aWx0aW5fZmxvYXQucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2J1aWx0aW5fZmxvYXQucHk= 100644
--- a/tests/run/builtin_float.py
+++ b/tests/run/builtin_float.py
@@ -1,5 +1,3 @@
-
-import sys
 
 def empty_float():
     """
@@ -11,8 +9,9 @@
     x = float()
     return x
 
+
 def float_conjugate():
     """
     >>> float_call_conjugate()
     1.5
     """
@@ -14,11 +13,8 @@
 def float_conjugate():
     """
     >>> float_call_conjugate()
     1.5
     """
-    if sys.version_info >= (2,6):
-        x = 1.5 .conjugate()
-    else:
-        x = 1.5
+    x = 1.5 .conjugate()
     return x
 
@@ -23,7 +19,8 @@
     return x
 
+
 def float_call_conjugate():
     """
     >>> float_call_conjugate()
     1.5
     """
@@ -25,10 +22,7 @@
 def float_call_conjugate():
     """
     >>> float_call_conjugate()
     1.5
     """
-    if sys.version_info >= (2,6):
-        x = float(1.5).conjugate()
-    else:
-        x = 1.5
+    x = float(1.5).conjugate()
     return x
diff --git a/tests/run/bytesmethods.pyx b/tests/run/bytesmethods.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2J5dGVzbWV0aG9kcy5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2J5dGVzbWV0aG9kcy5weXg= 100644
--- a/tests/run/bytesmethods.pyx
+++ b/tests/run/bytesmethods.pyx
@@ -1,5 +1,13 @@
 cimport cython
 
+cdef extern from *:
+    cdef Py_ssize_t PY_SSIZE_T_MIN
+    cdef Py_ssize_t PY_SSIZE_T_MAX
+
+SSIZE_T_MAX = PY_SSIZE_T_MAX
+SSIZE_T_MIN = PY_SSIZE_T_MIN
+
+
 b_a = b'a'
 b_b = b'b'
 
@@ -114,6 +122,14 @@
     <BLANKLINE>
     >>> print(bytes_decode(s, -300, -500))
     <BLANKLINE>
+    >>> print(bytes_decode(s, SSIZE_T_MIN, SSIZE_T_MIN))
+    <BLANKLINE>
+    >>> print(bytes_decode(s, SSIZE_T_MIN, SSIZE_T_MAX))
+    abaab
+    >>> print(bytes_decode(s, SSIZE_T_MAX, SSIZE_T_MIN))
+    <BLANKLINE>
+    >>> print(bytes_decode(s, SSIZE_T_MAX, SSIZE_T_MAX))
+    <BLANKLINE>
 
     >>> s[:'test']                       # doctest: +ELLIPSIS
     Traceback (most recent call last):
diff --git a/tests/run/c_int_types_T255.pyx b/tests/run/c_int_types_T255.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2NfaW50X3R5cGVzX1QyNTUucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2NfaW50X3R5cGVzX1QyNTUucHl4 100644
--- a/tests/run/c_int_types_T255.pyx
+++ b/tests/run/c_int_types_T255.pyx
@@ -685,6 +685,9 @@
 
 def test_convert_pyint(x):
    u"""
-   >>> test_convert_pyint(None)
+   >>> test_convert_pyint(None)  # doctest: +ELLIPSIS
+   Traceback (most recent call last):
+   TypeError:... int...
+   >>> test_convert_pyint("123")  # doctest: +ELLIPSIS
    Traceback (most recent call last):
        ...
@@ -689,10 +692,6 @@
    Traceback (most recent call last):
        ...
-   TypeError: an integer is required
-   >>> test_convert_pyint("123")
-   Traceback (most recent call last):
-       ...
-   TypeError: an integer is required
+   TypeError:... int...
    >>> test_convert_pyint(MyBadInt(0)) #doctest: +ELLIPSIS
    Traceback (most recent call last):
        ...
@@ -733,6 +732,6 @@
 
 def test_convert_pylong(x):
    u"""
-   >>> test_convert_pylong(None)
+   >>> test_convert_pylong(None)  # doctest: +ELLIPSIS
    Traceback (most recent call last):
        ...
@@ -737,6 +736,6 @@
    Traceback (most recent call last):
        ...
-   TypeError: an integer is required
-   >>> test_convert_pylong("123")
+   TypeError:... int...
+   >>> test_convert_pylong("123")  # doctest: +ELLIPSIS
    Traceback (most recent call last):
        ...
@@ -741,6 +740,6 @@
    Traceback (most recent call last):
        ...
-   TypeError: an integer is required
+   TypeError:... int...
    >>> test_convert_pylong(MyBadLong(0)) #doctest: +ELLIPSIS
    Traceback (most recent call last):
        ...
diff --git a/tests/run/c_type_methods_T236.pyx b/tests/run/c_type_methods_T236.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2NfdHlwZV9tZXRob2RzX1QyMzYucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2NfdHlwZV9tZXRob2RzX1QyMzYucHl4 100644
--- a/tests/run/c_type_methods_T236.pyx
+++ b/tests/run/c_type_methods_T236.pyx
@@ -1,4 +1,4 @@
 # ticket: 236
 
-__doc__ = ''
+import sys
 
@@ -4,7 +4,5 @@
 
-import sys
-if sys.version_info >= (2,6):
-    __doc__ += '''
+__doc__ = '''
 >>> float_is_integer(1.0)
 True
 >>> float_is_integer(1.1)
@@ -19,7 +17,6 @@
 '''
 
 def float_is_integer(float f):
-    # requires Python 2.6+
     return f.is_integer()
 
 def int_bit_length(int i):
diff --git a/tests/run/callargs.pyx b/tests/run/callargs.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2NhbGxhcmdzLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2NhbGxhcmdzLnB5eA== 100644
--- a/tests/run/callargs.pyx
+++ b/tests/run/callargs.pyx
@@ -168,6 +168,6 @@
     """
     >>> test_int_kwargs(e)     # doctest: +ELLIPSIS
     Traceback (most recent call last):
-    TypeError: ...keywords must be strings
+    TypeError: ...keywords must be strings...
     >>> test_int_kwargs(f)     # doctest: +ELLIPSIS
     Traceback (most recent call last):
@@ -172,5 +172,5 @@
     >>> test_int_kwargs(f)     # doctest: +ELLIPSIS
     Traceback (most recent call last):
-    TypeError: ...keywords must be strings
+    TypeError: ...keywords must be strings...
     >>> test_int_kwargs(g)     # doctest: +ELLIPSIS
     Traceback (most recent call last):
@@ -175,5 +175,5 @@
     >>> test_int_kwargs(g)     # doctest: +ELLIPSIS
     Traceback (most recent call last):
-    TypeError: ...keywords must be strings
+    TypeError: ...keywords must be strings...
     >>> test_int_kwargs(h)     # doctest: +ELLIPSIS
     Traceback (most recent call last):
@@ -178,5 +178,5 @@
     >>> test_int_kwargs(h)     # doctest: +ELLIPSIS
     Traceback (most recent call last):
-    TypeError: ...keywords must be strings
+    TypeError: ...keywords must be strings...
     """
     f(a=1,b=2,c=3, **{10:20,30:40})
diff --git a/tests/run/cascadedassignment.pyx b/tests/run/cascadedassignment.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2Nhc2NhZGVkYXNzaWdubWVudC5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2Nhc2NhZGVkYXNzaWdubWVudC5weXg= 100644
--- a/tests/run/cascadedassignment.pyx
+++ b/tests/run/cascadedassignment.pyx
@@ -56,3 +56,15 @@
     """
     a = b = c = float(expr())
     return a, b, c
+
+
+def test_overwrite():
+    """
+    >>> test_overwrite()
+    {0: {1: {2: {}}}}
+    """
+    x = a = {}
+    for i in range(3):
+        a[i] = a = {}
+    assert a == {}
+    return x
diff --git a/tests/run/cascmp.pyx b/tests/run/cascmp.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2Nhc2NtcC5weXg=
--- /dev/null
+++ b/tests/run/cascmp.pyx
@@ -0,0 +1,38 @@
+# mode: run
+# tag: cascade, compare
+
+def ints_and_objects():
+    """
+    >>> ints_and_objects()
+    (0, 1, 0, 1, 1, 0)
+    """
+    cdef int int1=0, int2=0, int3=0, int4=0
+    cdef int r1, r2, r3, r4, r5, r6
+    cdef object obj1, obj2, obj3, obj4
+    obj1 = 1
+    obj2 = 2
+    obj3 = 3
+    obj4 = 4
+    r1 = int1 < int2 < int3
+    r2 = obj1 < obj2 < obj3
+    r3 = int1 < int2 < obj3
+    r4 = obj1 < 2 < 3
+    r5 = obj1 < 2 < 3 < 4
+    r6 = int1 < (int2 == int3) < int4
+    return r1, r2, r3, r4, r5, r6
+
+
+def const_cascade(x):
+    """
+    >>> const_cascade(2)
+    (True, False, True, False, False, True, False)
+    """
+    return (
+        0 <= 1,
+        1 <= 0,
+        1 <= 1 <= 2,
+        1 <= 0 < 1,
+        1 <= 1 <= 0,
+        1 <= 1 <= x <= 2 <= 3 > x <= 2 <= 2,
+        1 <= 1 <= x <= 1 <= 1 <= x <= 2,
+    )
diff --git a/tests/run/cclass_assign_attr_GH3100.pyx b/tests/run/cclass_assign_attr_GH3100.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2NjbGFzc19hc3NpZ25fYXR0cl9HSDMxMDAucHl4
--- /dev/null
+++ b/tests/run/cclass_assign_attr_GH3100.pyx
@@ -0,0 +1,19 @@
+cdef class Foo:
+    """
+    >>> D = Foo.__dict__
+    >>> D["meth"] is D["meth2"]
+    True
+    >>> D["classmeth"] is D["classmeth2"]
+    True
+    >>> D["staticmeth"] is D["staticmeth2"]
+    True
+    """
+    def meth(self): pass
+    @classmethod
+    def classmeth(cls): pass
+    @staticmethod
+    def staticmeth(): pass
+
+    meth2 = meth
+    classmeth2 = classmeth
+    staticmeth2 = staticmeth
diff --git a/tests/run/cdef_multiple_inheritance.pyx b/tests/run/cdef_multiple_inheritance.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2NkZWZfbXVsdGlwbGVfaW5oZXJpdGFuY2UucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2NkZWZfbXVsdGlwbGVfaW5oZXJpdGFuY2UucHl4 100644
--- a/tests/run/cdef_multiple_inheritance.pyx
+++ b/tests/run/cdef_multiple_inheritance.pyx
@@ -1,3 +1,5 @@
+cimport cython
+
 cdef class CBase(object):
     cdef int a
     cdef c_method(self):
@@ -9,7 +11,8 @@
     def py_method(self):
         return "PyBase"
 
-cdef class Both(CBase, PyBase):
+@cython.binding(True)
+cdef class BothBound(CBase, PyBase):
     cdef dict __dict__
     """
     >>> b = Both()
@@ -32,7 +35,7 @@
     def call_c_method(self):
         return self.c_method()
 
-cdef class BothSub(Both):
+cdef class BothSub(BothBound):
     """
     >>> b = BothSub()
     >>> b.py_method()
@@ -43,3 +46,27 @@
     'Both'
     """
     pass
+
+@cython.binding(False)
+cdef class BothUnbound(CBase, PyBase):
+    cdef dict __dict__
+    """
+    >>> b = Both()
+    >>> b.py_method()
+    'PyBase'
+    >>> b.cp_method()
+    'Both'
+    >>> b.call_c_method()
+    'Both'
+
+    >>> isinstance(b, CBase)
+    True
+    >>> isinstance(b, PyBase)
+    True
+    """
+    cdef c_method(self):
+        return "Both"
+    cpdef cp_method(self):
+        return "Both"
+    def call_c_method(self):
+        return self.c_method()
diff --git a/tests/run/cdef_multiple_inheritance_errors.srctree b/tests/run/cdef_multiple_inheritance_errors.srctree
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2NkZWZfbXVsdGlwbGVfaW5oZXJpdGFuY2VfZXJyb3JzLnNyY3RyZWU=..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2NkZWZfbXVsdGlwbGVfaW5oZXJpdGFuY2VfZXJyb3JzLnNyY3RyZWU= 100644
--- a/tests/run/cdef_multiple_inheritance_errors.srctree
+++ b/tests/run/cdef_multiple_inheritance_errors.srctree
@@ -48,6 +48,7 @@
     pass
 
 ######## oldstyle.pyx ########
+# cython: language_level=2
 
 cdef class Base:
     cdef dict __dict__
diff --git a/tests/run/cdivision_CEP_516.pyx b/tests/run/cdivision_CEP_516.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2NkaXZpc2lvbl9DRVBfNTE2LnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2NkaXZpc2lvbl9DRVBfNTE2LnB5eA== 100644
--- a/tests/run/cdivision_CEP_516.pyx
+++ b/tests/run/cdivision_CEP_516.pyx
@@ -27,6 +27,9 @@
 >>> [test_cdiv_cmod(a, b) for a, b in v]
 [(1, 7), (-1, -7), (1, -7), (-1, 7)]
 
+>>> [test_cdiv_cmod(a, b) for a, b in [(4, -4), (4, -2), (4, -1)]]
+[(-1, 0), (-2, 0), (-4, 0)]
+
 >>> all([mod_int_py(a,b) == a % b for a in range(-10, 10) for b in range(-10, 10) if b != 0])
 True
 >>> all([div_int_py(a,b) == a // b for a in range(-10, 10) for b in range(-10, 10) if b != 0])
diff --git a/tests/run/cfunc_convert.pyx b/tests/run/cfunc_convert.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2NmdW5jX2NvbnZlcnQucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2NmdW5jX2NvbnZlcnQucHl4 100644
--- a/tests/run/cfunc_convert.pyx
+++ b/tests/run/cfunc_convert.pyx
@@ -82,7 +82,7 @@
 
 cdef long long rad(long long x):
     cdef long long rad = 1
-    for p in range(2, <long long>sqrt(x) + 1):
+    for p in range(2, <long long>sqrt(<double>x) + 1):  # MSVC++ fails without the input cast
         if x % p == 0:
             rad *= p
             while x % p == 0:
diff --git a/tests/run/charptr_decode.pyx b/tests/run/charptr_decode.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2NoYXJwdHJfZGVjb2RlLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2NoYXJwdHJfZGVjb2RlLnB5eA== 100644
--- a/tests/run/charptr_decode.pyx
+++ b/tests/run/charptr_decode.pyx
@@ -1,6 +1,11 @@
 
 cimport cython
 
+cdef extern from *:
+    cdef Py_ssize_t PY_SSIZE_T_MIN
+    cdef Py_ssize_t PY_SSIZE_T_MAX
+
+
 ############################################################
 # tests for char* slicing
 
@@ -118,6 +123,19 @@
             (cstring+1)[:].decode('UTF-8'),
             (cstring+1)[return1():return5()].decode('UTF-8'))
 
+@cython.test_assert_path_exists("//PythonCapiCallNode")
+@cython.test_fail_if_path_exists("//AttributeNode")
+def slice_charptr_decode_large_bounds():
+    """
+    >>> print(str(slice_charptr_decode_large_bounds()).replace("u'", "'"))
+    ('abcABCqtp', '', '', '')
+    """
+    return (cstring[PY_SSIZE_T_MIN:9].decode('UTF-8'),
+            cstring[PY_SSIZE_T_MAX:PY_SSIZE_T_MIN].decode('UTF-8'),
+            cstring[PY_SSIZE_T_MIN:PY_SSIZE_T_MIN].decode('UTF-8'),
+            cstring[PY_SSIZE_T_MAX:PY_SSIZE_T_MAX].decode('UTF-8'))
+
+
 cdef return1(): return 1
 cdef return3(): return 3
 cdef return4(): return 4
diff --git a/tests/run/cimport.srctree b/tests/run/cimport.srctree
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2NpbXBvcnQuc3JjdHJlZQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2NpbXBvcnQuc3JjdHJlZQ== 100644
--- a/tests/run/cimport.srctree
+++ b/tests/run/cimport.srctree
@@ -45,6 +45,6 @@
     A,
     foo,
 )
-print A, foo(10)
+print(A, foo(10))
 
 cimport other
@@ -49,7 +49,7 @@
 
 cimport other
-print other.A, other.foo(10)
+print(other.A, other.foo(10))
 
 from pkg cimport sub
 cdef sub.my_int a = 100
 
@@ -52,5 +52,5 @@
 
 from pkg cimport sub
 cdef sub.my_int a = 100
 
-from pkg.subpkg cimport submod
\ No newline at end of file
+from pkg.subpkg cimport submod
diff --git a/tests/run/cimport_from_sys_path.srctree b/tests/run/cimport_from_sys_path.srctree
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2NpbXBvcnRfZnJvbV9zeXNfcGF0aC5zcmN0cmVl..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2NpbXBvcnRfZnJvbV9zeXNfcGF0aC5zcmN0cmVl 100644
--- a/tests/run/cimport_from_sys_path.srctree
+++ b/tests/run/cimport_from_sys_path.srctree
@@ -32,6 +32,6 @@
 ######## a.pyx ########
 
 from b.other cimport foo
-print foo(10)
+print(foo(10))
 
 cimport b.other
@@ -36,3 +36,3 @@
 
 cimport b.other
-print b.other.foo(10)
+print(b.other.foo(10))
diff --git a/tests/run/clear_to_null.pyx b/tests/run/clear_to_null.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2NsZWFyX3RvX251bGwucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2NsZWFyX3RvX251bGwucHl4 100644
--- a/tests/run/clear_to_null.pyx
+++ b/tests/run/clear_to_null.pyx
@@ -2,7 +2,7 @@
 Check that Cython generates a tp_clear function that actually clears object
 references to NULL instead of None.
 
-Discussed here: http://article.gmane.org/gmane.comp.python.cython.devel/14833
+Discussed here: https://article.gmane.org/gmane.comp.python.cython.devel/14833
 """
 
 from cpython.ref cimport PyObject, Py_TYPE
diff --git a/tests/run/complex_int_T446.pyx b/tests/run/complex_int_T446.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2NvbXBsZXhfaW50X1Q0NDYucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2NvbXBsZXhfaW50X1Q0NDYucHl4 100644
--- a/tests/run/complex_int_T446.pyx
+++ b/tests/run/complex_int_T446.pyx
@@ -2,8 +2,13 @@
 
 import cython
 
-cdef extern from "complex_int_T446_fix.h":
-    pass
+cdef extern from *:
+    """
+    #if defined _MSC_VER && defined __cplusplus
+    #define CYTHON_CCOMPLEX 0
+    #endif
+    """
+
 
 def test_arith(int complex a, int complex b):
     """
diff --git a/tests/run/complex_int_T446_fix.h b/tests/run/complex_int_T446_fix.h
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2NvbXBsZXhfaW50X1Q0NDZfZml4Lmg=..0000000000000000000000000000000000000000
--- a/tests/run/complex_int_T446_fix.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#if defined _MSC_VER && defined __cplusplus
-#define CYTHON_CCOMPLEX 0
-#endif
diff --git a/tests/run/complex_numbers_cmath_T2891.pyx b/tests/run/complex_numbers_cmath_T2891.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2NvbXBsZXhfbnVtYmVyc19jbWF0aF9UMjg5MS5weXg=
--- /dev/null
+++ b/tests/run/complex_numbers_cmath_T2891.pyx
@@ -0,0 +1,15 @@
+# ticket: 2891
+# tag: c, no-cpp
+
+cdef extern from "complex_numbers_c99_T398.h": pass
+
+from libc.complex cimport cimag, creal, cabs, carg
+
+
+def test_decomposing(double complex z):
+    """
+    >>> test_decomposing(3+4j)
+    (3.0, 4.0, 5.0, 0.9272952180016122)
+    """
+
+    return (creal(z), cimag(z), cabs(z), carg(z))
diff --git a/tests/run/constant_folding.py b/tests/run/constant_folding.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2NvbnN0YW50X2ZvbGRpbmcucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2NvbnN0YW50X2ZvbGRpbmcucHk= 100644
--- a/tests/run/constant_folding.py
+++ b/tests/run/constant_folding.py
@@ -136,6 +136,17 @@
     return (mul_int, mul_large_int, pow_int, pow_large_int)
 
 
+def binop_pow_negative():
+    """
+    >>> print_big_ints(binop_pow_negative())
+    (4.018775720164609e-06, 8.020807320287816e-38, 0.1)
+    """
+    pow_int = 12 ** -5
+    pow_large_int = 1234 ** -12
+    pow_expression_int = 10 ** (1-2)
+    return (pow_int, pow_large_int, pow_expression_int)
+
+
 @cython.test_fail_if_path_exists(
     "//SliceIndexNode",
 )
diff --git a/tests/run/consts.pyx b/tests/run/consts.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2NvbnN0cy5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2NvbnN0cy5weXg= 100644
--- a/tests/run/consts.pyx
+++ b/tests/run/consts.pyx
@@ -156,4 +156,14 @@
     """
     return x * [1,2,3]
 
+
+@cython.test_fail_if_path_exists("//MulNode")
+def multiplied_nonconst_list_const_int(x):
+    """
+    >>> multiplied_nonconst_list_const_int(2)
+    [1, 2, 3, 1, 2, 3]
+    """
+    return [1,x,3] * 2
+
+
 @cython.test_fail_if_path_exists("//MulNode//ListNode")
@@ -159,5 +169,4 @@
 @cython.test_fail_if_path_exists("//MulNode//ListNode")
-@cython.test_assert_path_exists("//MulNode")
 def multiplied_lists_nonconst_expression(x):
     """
     >>> multiplied_lists_nonconst_expression(5) == [1,2,3] * (5 * 2)
diff --git a/tests/run/coroutines.py b/tests/run/coroutines.py
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2Nvcm91dGluZXMucHk=
--- /dev/null
+++ b/tests/run/coroutines.py
@@ -0,0 +1,60 @@
+# cython: language_level=3
+# mode: run
+# tag: pep492, pure3.5, gh1462, async, await
+
+
+async def test_coroutine_frame(awaitable):
+    """
+    >>> class Awaitable(object):
+    ...     def __await__(self):
+    ...         return iter([2])
+
+    >>> coro = test_coroutine_frame(Awaitable())
+    >>> import types
+    >>> isinstance(coro.cr_frame, types.FrameType) or coro.cr_frame
+    True
+    >>> coro.cr_frame is coro.cr_frame  # assert that it's cached
+    True
+    >>> coro.cr_frame.f_code is not None
+    True
+    >>> code_obj = coro.cr_frame.f_code
+    >>> code_obj.co_argcount
+    1
+    >>> code_obj.co_varnames
+    ('awaitable', 'b')
+
+    >>> next(coro.__await__())  # avoid "not awaited" warning
+    2
+    """
+    b = await awaitable
+    return b
+
+
+# gh1462: Using decorators on coroutines.
+
+def pass_through(func):
+    return func
+
+
+@pass_through
+async def test_pass_through():
+    """
+    >>> t = test_pass_through()
+    >>> try: t.send(None)
+    ... except StopIteration as ex:
+    ...     print(ex.args[0] if ex.args else None)
+    ... else: print("NOT STOPPED!")
+    None
+    """
+
+
+@pass_through(pass_through)
+async def test_pass_through_with_args():
+    """
+    >>> t = test_pass_through_with_args()
+    >>> try: t.send(None)
+    ... except StopIteration as ex:
+    ...     print(ex.args[0] if ex.args else None)
+    ... else: print("NOT STOPPED!")
+    None
+    """
diff --git a/tests/run/coverage_nogil.srctree b/tests/run/coverage_nogil.srctree
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2NvdmVyYWdlX25vZ2lsLnNyY3RyZWU=..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2NvdmVyYWdlX25vZ2lsLnNyY3RyZWU= 100644
--- a/tests/run/coverage_nogil.srctree
+++ b/tests/run/coverage_nogil.srctree
@@ -1,5 +1,5 @@
 # mode: run
-# tag: coverage,trace,nogil
+# tag: coverage,trace,nogil,fastgil
 
 """
 PYTHON setup.py build_ext -i
@@ -21,6 +21,6 @@
 plugins = Cython.Coverage
 
 
-######## coverage_test_nogil.pyx ########
-# cython: linetrace=True
+######## coverage_test_nogil_fastgil.pyx ########
+# cython: linetrace=True,fast_gil=True
 # distutils: define_macros=CYTHON_TRACE=1 CYTHON_TRACE_NOGIL=1
@@ -26,2 +26,3 @@
 # distutils: define_macros=CYTHON_TRACE=1 CYTHON_TRACE_NOGIL=1
+include "_coverage_test_nogil.pxi"
 
@@ -27,7 +28,18 @@
 
+
+######## coverage_test_nogil_nofastgil.pyx ########
+# cython: linetrace=True,fast_gil=False
+# distutils: define_macros=CYTHON_TRACE=1 CYTHON_TRACE_NOGIL=1
+include "_coverage_test_nogil.pxi"
+
+
+######## _coverage_test_nogil.pxi ########
+#  1
+#  2
+#  3
 cdef int func1(int a, int b) nogil:  #  4
     cdef int x                       #  5
     with gil:                        #  6
         x = 1                        #  7
     cdef int c = func2(a) + b        #  8
     return x + c                     #  9
@@ -28,10 +40,10 @@
 cdef int func1(int a, int b) nogil:  #  4
     cdef int x                       #  5
     with gil:                        #  6
         x = 1                        #  7
     cdef int c = func2(a) + b        #  8
     return x + c                     #  9
-
-
+# 10
+# 11
 cdef int func2(int a) with gil:  # 12
     return a * 2                 # 13
@@ -36,7 +48,7 @@
 cdef int func2(int a) with gil:  # 12
     return a * 2                 # 13
-
-
+# 14
+# 15
 def call(int a, int b):          # 16
     a, b = b, a                  # 17
     with nogil:                  # 18
@@ -56,7 +68,8 @@
 from coverage import coverage
 
 
-def run_coverage():
+def run_coverage(module_name):
+    print("Testing module %s" % module_name)
     cov = coverage()
     cov.start()
 
@@ -60,7 +73,7 @@
     cov = coverage()
     cov.start()
 
-    import coverage_test_nogil as module
+    module = __import__(module_name)
     module_name = module.__name__
     module_path = module_name + '.pyx'
     assert not any(module.__file__.endswith(ext)
@@ -69,7 +82,6 @@
     assert module.call(1, 2) == (1 * 2) + 2 + 1
 
     cov.stop()
-
     out = StringIO()
     cov.report(file=out)
     #cov.report([module], file=out)
@@ -77,7 +89,8 @@
     assert any(module_path in line for line in lines), \
         "'%s' not found in coverage report:\n\n%s" % (module_path, out.getvalue())
 
-    mod_file, exec_lines, excl_lines, missing_lines, _ = cov.analysis2(os.path.abspath(module_path))
-    assert module_path in mod_file
+    module_pxi = "_coverage_test_nogil.pxi"
+    mod_file, exec_lines, excl_lines, missing_lines, _ = cov.analysis2(os.path.abspath(module_pxi))
+    assert module_pxi in mod_file
 
     executed = set(exec_lines) - set(missing_lines)
@@ -82,5 +95,5 @@
 
     executed = set(exec_lines) - set(missing_lines)
-    # check that everything that runs with the gil owned was executed
-    assert all(line in executed for line in [12, 13, 16, 17, 18, 20]), '%s / %s' % (exec_lines, missing_lines)
+    # check that everything that runs with the gil owned was executed (missing due to pxi: 4, 12, 16)
+    assert all(line in executed for line in [13, 17, 18, 20]), '%s / %s' % (exec_lines, missing_lines)
     # check that everything that runs in nogil sections was executed
@@ -86,5 +99,5 @@
     # check that everything that runs in nogil sections was executed
-    assert all(line in executed for line in [4, 6, 7, 8, 9]), '%s / %s' % (exec_lines, missing_lines)
+    assert all(line in executed for line in [6, 7, 8, 9]), '%s / %s' % (exec_lines, missing_lines)
 
 
 if __name__ == '__main__':
@@ -88,4 +101,5 @@
 
 
 if __name__ == '__main__':
-    run_coverage()
+    for module_name in ["coverage_test_nogil_fastgil", "coverage_test_nogil_nofastgil"]:
+        run_coverage(module_name)
diff --git a/tests/run/cpdef_enums.pyx b/tests/run/cpdef_enums.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2NwZGVmX2VudW1zLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2NwZGVmX2VudW1zLnB5eA== 100644
--- a/tests/run/cpdef_enums.pyx
+++ b/tests/run/cpdef_enums.pyx
@@ -70,14 +70,8 @@
     """
     >>> test_as_variable_from_cython()
     """
-    import sys
-    if sys.version_info >= (2, 7):
-        assert list(PyxEnum) == [TWO, THREE, FIVE], list(PyxEnum)
-        assert list(PxdEnum) == [RANK_0, RANK_1, RANK_2], list(PxdEnum)
-    else:
-        # No OrderedDict.
-        assert set(PyxEnum) == {TWO, THREE, FIVE}, list(PyxEnum)
-        assert set(PxdEnum) == {RANK_0, RANK_1, RANK_2}, list(PxdEnum)
+    assert list(PyxEnum) == [TWO, THREE, FIVE], list(PyxEnum)
+    assert list(PxdEnum) == [RANK_0, RANK_1, RANK_2], list(PxdEnum)
 
 cdef int verify_pure_c() nogil:
     cdef int x = TWO
diff --git a/tests/run/cpdef_nogil.pyx b/tests/run/cpdef_nogil.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2NwZGVmX25vZ2lsLnB5eA==
--- /dev/null
+++ b/tests/run/cpdef_nogil.pyx
@@ -0,0 +1,19 @@
+# cython: binding=True
+# mode: run
+# tag: cyfunction
+
+cpdef int simple() nogil:
+    """
+    >>> simple()
+    1
+    """
+    return 1
+
+
+cpdef int call_nogil():
+    """
+    >>> call_nogil()
+    1
+    """
+    with nogil:
+        return simple()
diff --git a/tests/run/cpp_class_attrib.srctree b/tests/run/cpp_class_attrib.srctree
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2NwcF9jbGFzc19hdHRyaWIuc3JjdHJlZQ==
--- /dev/null
+++ b/tests/run/cpp_class_attrib.srctree
@@ -0,0 +1,26 @@
+# tag: cpp
+
+PYTHON setup.py build_ext --inplace
+PYTHON -c "import runner"
+
+######## setup.py ########
+
+from Cython.Build.Dependencies import cythonize
+from distutils.core import setup
+import os
+
+example_dir = os.path.abspath(os.path.join(os.environ['CYTHON_PROJECT_DIR'],
+                              'docs/examples/userguide/wrapping_CPlusPlus'))
+
+ext_modules= cythonize(os.path.join(example_dir, "rect_with_attributes.pyx"),
+                       include_path=[example_dir])
+setup(ext_modules=ext_modules)
+
+######## runner.py ########
+
+import rect_with_attributes
+
+x0, y0, x1, y1 = 1, 2, 3, 4
+rect_obj = rect_with_attributes.PyRectangle(x0, y0, x1, y1)
+
+assert rect_obj.x0 == x0
diff --git a/tests/run/cpp_enums.pyx b/tests/run/cpp_enums.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2NwcF9lbnVtcy5weXg=
--- /dev/null
+++ b/tests/run/cpp_enums.pyx
@@ -0,0 +1,58 @@
+# tag: cpp
+# mode: run
+
+cdef extern from *:
+    """
+    enum Enum1 {
+        Item1,
+        Item2
+    };
+
+    """
+    cdef enum Enum1:
+        Item1
+        Item2
+
+a = Item1
+b = Item2
+
+cdef Enum1 x, y
+x = Item1
+y = Item2
+
+
+def compare_enums():
+    """
+    >>> compare_enums()
+    (True, True, True, True)
+    """
+    return x == a, a == Item1, b == y, y == Item2
+
+
+cdef extern from * namespace "Namespace1":
+    """
+    namespace Namespace1 {
+        enum Enum2 {
+            Item3,
+            Item4
+        };
+    }
+    """
+    cdef enum Enum2:
+        Item3
+        Item4
+
+c = Item3
+d = Item4
+
+cdef Enum2 z, w
+z = Item3
+w = Item4
+
+
+def compare_namespace_enums():
+    """
+    >>> compare_namespace_enums()
+    (True, True, True, True)
+    """
+    return z == c, c == Item3, d == w, d == Item4
diff --git a/tests/run/cpp_iterators.pyx b/tests/run/cpp_iterators.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2NwcF9pdGVyYXRvcnMucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2NwcF9pdGVyYXRvcnMucHl4 100644
--- a/tests/run/cpp_iterators.pyx
+++ b/tests/run/cpp_iterators.pyx
@@ -25,7 +25,7 @@
 
 def test_deque_iterator_subtraction(py_v):
     """
-    >>> test_deque_iterator_subtraction([1, 2, 3])
+    >>> print(test_deque_iterator_subtraction([1, 2, 3]))
     3
     """
     cdef deque[int] dint
@@ -38,7 +38,7 @@
 
 def test_vector_iterator_subtraction(py_v):
     """
-    >>> test_vector_iterator_subtraction([1, 2, 3])
+    >>> print(test_vector_iterator_subtraction([1, 2, 3]))
     3
     """
     cdef vector[int] vint = py_v
diff --git a/tests/run/cpp_move.pyx b/tests/run/cpp_move.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2NwcF9tb3ZlLnB5eA==
--- /dev/null
+++ b/tests/run/cpp_move.pyx
@@ -0,0 +1,34 @@
+# mode: run
+# tag: cpp, werror, cpp11
+
+from libcpp cimport nullptr
+from libcpp.memory cimport shared_ptr, make_shared
+from libcpp.utility cimport move
+from cython.operator cimport dereference
+
+cdef extern from *:
+    """
+    #include <string>
+
+    template<typename T> const char* move_helper(T&) { return "lvalue-ref"; }
+    template<typename T> const char* move_helper(T&&) { return "rvalue-ref"; }
+    """
+    const char* move_helper[T](T)
+
+def test_move_assignment():
+    """
+    >>> test_move_assignment()
+    """
+    cdef shared_ptr[int] p1, p2
+    p1 = make_shared[int](1337)
+    p2 = move(p1)
+    assert p1 == nullptr
+    assert dereference(p2) == 1337
+
+def test_move_func_call():
+    """
+    >>> test_move_func_call()
+    """
+    cdef shared_ptr[int] p
+    assert move_helper(p) == b'lvalue-ref'
+    assert move_helper(move(p)) == b'rvalue-ref'
diff --git a/tests/run/cpp_operators_helper.h b/tests/run/cpp_operators_helper.h
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2NwcF9vcGVyYXRvcnNfaGVscGVyLmg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2NwcF9vcGVyYXRvcnNfaGVscGVyLmg= 100644
--- a/tests/run/cpp_operators_helper.h
+++ b/tests/run/cpp_operators_helper.h
@@ -84,7 +84,7 @@
 #define REF_BIN_OP(op) int& operator op (int x) { x++; return value; }
 
 class RefTestOps {
-    int value = 0;
+    int value;
 
 public:
 
@@ -88,6 +88,8 @@
 
 public:
 
+    RefTestOps() { value = 0; }
+
     REF_UN_OP(-);
     REF_UN_OP(+);
     REF_UN_OP(*);
diff --git a/tests/run/cpp_stl_algo_modifying_sequence_ops.pyx b/tests/run/cpp_stl_algo_modifying_sequence_ops.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2NwcF9zdGxfYWxnb19tb2RpZnlpbmdfc2VxdWVuY2Vfb3BzLnB5eA==
--- /dev/null
+++ b/tests/run/cpp_stl_algo_modifying_sequence_ops.pyx
@@ -0,0 +1,434 @@
+# mode: run
+# tag: cpp, werror, cpp11
+
+from __future__ import print_function
+
+from cython.operator cimport dereference as deref
+from cython.operator cimport preincrement, postincrement
+from libcpp cimport bool
+from libcpp.algorithm cimport copy, copy_if, copy_n, copy_backward, move, move_backward, fill, fill_n, transform
+from libcpp.algorithm cimport generate, generate_n, remove, remove_if, remove_copy, remove_copy_if, replace, replace_if
+from libcpp.algorithm cimport replace_copy, replace_copy_if, swap, swap_ranges, iter_swap, reverse, reverse_copy
+from libcpp.algorithm cimport rotate, rotate_copy, unique, unique_copy
+from libcpp.algorithm cimport sort, upper_bound, min_element
+from libcpp.iterator cimport back_inserter
+from libcpp.string cimport string
+from libcpp.vector cimport vector
+
+
+def copy_int(vector[int] values):
+    """
+    Test copy.
+
+    >>> copy_int(range(5))
+    [0, 1, 2, 3, 4]
+    """
+    cdef vector[int] out
+    copy(values.begin(), values.end(), back_inserter(out))
+    return out
+
+
+cdef bool is_odd(int i):
+    return i % 2
+
+
+def copy_int_if_odd(vector[int] values):
+    """
+    Test copy_if.
+
+    >>> copy_int_if_odd(range(5))
+    [1, 3]
+    """
+    cdef vector[int] out
+    copy_if(values.begin(), values.end(), back_inserter(out), is_odd)
+    return out
+
+
+def copy_int_n(vector[int] values, int count):
+    """
+    Test copy_n.
+
+    >>> copy_int_n(range(5), 2)
+    [0, 1]
+    """
+    cdef vector[int] out
+    copy_n(values.begin(), count, back_inserter(out))
+    return out
+
+
+def copy_int_backward(vector[int] values):
+    """
+    Test copy_backward.
+
+    >>> copy_int_backward(range(5))
+    [0, 0, 0, 0, 1, 2, 3, 4]
+    """
+    out = vector[int](values.size() + 3)
+    copy_backward(values.begin(), values.end(), out.end())
+    return out
+
+
+def move_int(vector[int] values):
+    """
+    Test move.
+
+    >>> move_int(range(5))
+    [0, 1, 2, 3, 4]
+    """
+    cdef vector[int] out
+    move(values.begin(), values.end(), back_inserter(out))
+    return out
+
+
+def move_int_backward(vector[int] values):
+    """
+    Test move_backward.
+
+    >>> move_int_backward(range(5))
+    [0, 0, 0, 0, 1, 2, 3, 4]
+    """
+    out = vector[int](values.size() + 3)
+    move_backward(values.begin(), values.end(), out.end())
+    return out
+
+
+def fill_int(vector[int] array, int value):
+    """
+    Test fill.
+
+    >>> fill_int(range(5), -1)
+    [-1, -1, -1, -1, -1]
+    """
+    fill(array.begin(), array.end(), value)
+    return array
+
+
+def fill_int_n(vector[int] array, int count, int value):
+    """
+    Test fill_n.
+
+    >>> fill_int_n(range(5), 3, -1)
+    [-1, -1, -1, 3, 4]
+    """
+    fill_n(array.begin(), count, value)
+    return array
+
+
+cdef int to_ord(unsigned char c):
+    return c
+
+
+def string_to_ord(string s):
+    """
+    Test transform (unary version).
+
+    >> string_to_ord(b"HELLO")
+    [72, 69, 76, 76, 79]
+    """
+    cdef vector[int] ordinals
+    transform(s.begin(), s.end(), back_inserter(ordinals), to_ord)
+    return ordinals
+
+
+cdef int add_ints(int lhs, int rhs):
+    return lhs + rhs
+
+
+def add_int_vectors(vector[int] lhs, vector[int] rhs):
+    """
+    Test transform (binary version).
+
+    >>> add_int_vectors([1, 2, 3], [4, 5, 6])
+    [5, 7, 9]
+    """
+    transform(lhs.begin(), lhs.end(), rhs.begin(), lhs.begin(), add_ints)
+    return lhs
+
+
+cdef int i = 0
+cdef int generator():
+    return postincrement(i)
+
+
+def generate_ints(int count):
+    """
+    Test generate.
+
+    >> generate_ints(5)
+    [0, 1, 2, 3, 4]
+    """
+    out = vector[int](count)
+    generate(out.begin(), out.end(), generator)
+    return out
+
+
+cdef int j = 0
+cdef int generator2():
+    return postincrement(j)
+
+
+def generate_n_ints(int count):
+    """
+    Test generate_n.
+
+    >> generate_n_ints(5)
+    [0, 1, 2, 3, 4, 0, 0, 0]
+    """
+    out = vector[int](count + 3)
+    generate_n(out.begin(), count, generator2)
+    return out
+
+
+def remove_spaces(string s):
+    """
+    Test remove.
+
+    >>> print(remove_spaces(b"Text with some   spaces").decode("ascii"))
+    Textwithsomespaces
+    """
+    s.erase(remove(s.begin(), s.end(), ord(" ")), s.end())
+    return s
+
+
+cdef bool is_whitespace(unsigned char c) except -1:
+    # std::isspace from <cctype>
+    return chr(c) in " \f\n\r\t\v"
+
+
+def remove_whitespace(string s):
+    r"""
+    Test remove_if.
+
+    >>> print(remove_whitespace(b"Text\n with\tsome \t  whitespaces\n\n").decode("ascii"))
+    Textwithsomewhitespaces
+    """
+    s.erase(remove_if(s.begin(), s.end(), &is_whitespace), s.end())
+    return s
+
+
+def remove_spaces2(string s):
+    """
+    Test remove_copy.
+
+    >>> print(remove_spaces2(b"Text with some   spaces").decode("ascii"))
+    Textwithsomespaces
+    """
+    cdef string out
+    remove_copy(s.begin(), s.end(), back_inserter(out), ord(" "))
+    return out
+
+
+def remove_whitespace2(string s):
+    r"""
+    Test remove_copy_if.
+
+    >>> print(remove_whitespace2(b"Text\n with\tsome \t  whitespaces\n\n").decode("ascii"))
+    Textwithsomewhitespaces
+    """
+    cdef string out
+    remove_copy_if(s.begin(), s.end(), back_inserter(out), &is_whitespace)
+    return out
+
+
+def replace_ints(vector[int] values, int old, int new):
+    """
+    Test replace.
+
+    >>> replace_ints([5, 7, 4, 2, 8, 6, 1, 9, 0, 3], 8, 88)
+    [5, 7, 4, 2, 88, 6, 1, 9, 0, 3]
+    """
+    replace(values.begin(), values.end(), old, new)
+    return values
+
+
+cdef bool less_than_five(int i):
+    return i < 5
+
+
+def replace_ints_less_than_five(vector[int] values, int new):
+    """
+    Test replace_if (using cppreference example that doesn't translate well).
+
+    >>> replace_ints_less_than_five([5, 7, 4, 2, 88, 6, 1, 9, 0, 3], 55)
+    [5, 7, 55, 55, 88, 6, 55, 9, 55, 55]
+    """
+    replace_if(values.begin(), values.end(), less_than_five, new)
+    return values
+
+
+def replace_ints2(vector[int] values, int old, int new):
+    """
+    Test replace_copy.
+
+    >>> replace_ints2([5, 7, 4, 2, 8, 6, 1, 9, 0, 3], 8, 88)
+    [5, 7, 4, 2, 88, 6, 1, 9, 0, 3]
+    """
+    cdef vector[int] out
+    replace_copy(values.begin(), values.end(), back_inserter(out), old, new)
+    return out
+
+
+def replace_ints_less_than_five2(vector[int] values, int new):
+    """
+    Test replace_copy_if (using cppreference example that doesn't translate well).
+
+    >>> replace_ints_less_than_five2([5, 7, 4, 2, 88, 6, 1, 9, 0, 3], 55)
+    [5, 7, 55, 55, 88, 6, 55, 9, 55, 55]
+    """
+    cdef vector[int] out
+    replace_copy_if(values.begin(), values.end(), back_inserter(out), less_than_five, new)
+    return out
+
+
+def test_swap_ints():
+    """
+    >>> test_swap_ints()
+    5 3
+    3 5
+    """
+    cdef int a = 5, b = 3
+    print(a, b)
+    swap(a, b)
+    print(a, b)
+
+
+def test_swap_vectors():
+    """
+    >>> test_swap_vectors()
+    [1, 2, 3] [4, 5, 6]
+    [4, 5, 6] [1, 2, 3]
+    """
+    cdef vector[int] a = [1, 2, 3], b = [4, 5, 6]
+    print(a, b)
+    swap(a, b)
+    print(a, b)
+
+
+def test_swap_ranges():
+    """
+    >>> test_swap_ranges()
+    [1, 2, 3] [4, 5, 6]
+    [4, 5, 6] [1, 2, 3]
+    """
+    cdef vector[int] a = [1, 2, 3], b = [4, 5, 6]
+    print(a, b)
+    swap_ranges(a.begin(), a.end(), b.begin())
+    print(a, b)
+
+
+def selection_sort(vector[int] values):
+    """
+    Test iter_swap using cppreference example.
+
+    >>> selection_sort([-7, 6, 2, 4, -1, 6, -9, -1, 2, -5, 10, -9, -5, -3, -5, -3, 6, 6, 1, 8])
+    [-9, -9, -7, -5, -5, -5, -3, -3, -1, -1, 1, 2, 2, 4, 6, 6, 6, 6, 8, 10]
+    """
+    i = values.begin()
+    end = values.end()
+    while i < end:
+        iter_swap(i, min_element(i, end))
+        preincrement(i)
+    return values
+
+
+def reverse_ints(vector[int] values):
+    """
+    Test reverse.
+
+    >>> reverse_ints([1, 2, 3])
+    [3, 2, 1]
+    """
+    reverse(values.begin(), values.end())
+    return values
+
+
+def reverse_ints2(vector[int] values):
+    """
+    Test reverse_copy.
+
+    >>> reverse_ints2([1, 2, 3])
+    [3, 2, 1]
+    """
+    cdef vector[int] out
+    reverse_copy(values.begin(), values.end(), back_inserter(out))
+    return out
+
+
+def insertion_sort(vector[int] values):
+    """
+    Test rotate using cppreference example.
+
+    >>> insertion_sort([2, 4, 2, 0, 5, 10, 7, 3, 7, 1])
+    [0, 1, 2, 2, 3, 4, 5, 7, 7, 10]
+    """
+    i = values.begin()
+    while i < values.end():
+        rotate(upper_bound(values.begin(), i, deref(i)), i, i + 1)
+        preincrement(i)
+    return values
+
+
+def rotate_ints_about_middle(vector[int] values):
+    """
+    Test rotate_copy.
+
+    >>> rotate_ints_about_middle([1, 2, 3, 4, 5])
+    [3, 4, 5, 1, 2]
+    """
+    cdef vector[int] out
+    cdef vector[int].iterator pivot = values.begin() + values.size()/2
+    rotate_copy(values.begin(), pivot, values.end(), back_inserter(out))
+    return out
+
+
+def unique_ints(vector[int] values):
+    """
+    Test unique.
+
+    >>> unique_ints([1, 2, 3, 1, 2, 3, 3, 4, 5, 4, 5, 6, 7])
+    [1, 2, 3, 4, 5, 6, 7]
+    """
+    sort(values.begin(), values.end())
+    values.erase(unique(values.begin(), values.end()), values.end())
+    return values
+
+
+cdef bool both_space(unsigned char lhs, unsigned char rhs):
+    return lhs == rhs == ord(' ')
+
+
+def collapse_spaces(string text):
+    """
+    Test unique (predicate version) using cppreference example for unique_copy.
+
+    >>> print(collapse_spaces(b"The      string    with many       spaces!").decode("ascii"))
+    The string with many spaces!
+    """
+    last = unique(text.begin(), text.end(), &both_space)
+    text.erase(last, text.end())
+    return text
+
+
+def unique_ints2(vector[int] values):
+    """
+    Test unique_copy.
+
+    >>> unique_ints2([1, 2, 3, 1, 2, 3, 3, 4, 5, 4, 5, 6, 7])
+    [1, 2, 3, 4, 5, 6, 7]
+    """
+    cdef vector[int] out
+    sort(values.begin(), values.end())
+    unique_copy(values.begin(), values.end(), back_inserter(out))
+    return out
+
+
+def collapse_spaces2(string text):
+    """
+    Test unique_copy (predicate version) using cppreference example.
+
+    >>> print(collapse_spaces2(b"The      string    with many       spaces!").decode("ascii"))
+    The string with many spaces!
+    """
+    cdef string out
+    unique_copy(text.begin(), text.end(), back_inserter(out), &both_space)
+    return out
diff --git a/tests/run/cpp_stl_algo_nonmodifying_sequence_ops.pyx b/tests/run/cpp_stl_algo_nonmodifying_sequence_ops.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2NwcF9zdGxfYWxnb19ub25tb2RpZnlpbmdfc2VxdWVuY2Vfb3BzLnB5eA==
--- /dev/null
+++ b/tests/run/cpp_stl_algo_nonmodifying_sequence_ops.pyx
@@ -0,0 +1,307 @@
+# mode: run
+# tag: cpp, werror, cpp11
+
+from cython.operator cimport dereference as deref
+
+from libcpp cimport bool
+from libcpp.algorithm cimport all_of, any_of, none_of, for_each, count, count_if, mismatch, find, find_if, find_if_not
+from libcpp.algorithm cimport find_end, find_first_of, adjacent_find, search, search_n
+from libcpp.iterator cimport distance
+from libcpp.string cimport string
+from libcpp.vector cimport vector
+
+
+cdef bool is_odd(int i):
+    return i % 2
+
+
+def all_odd(vector[int] values):
+    """
+    Test all_of with is_odd predicate.
+
+    >>> all_odd([3, 5, 7, 11, 13, 17, 19, 23])
+    True
+    >>> all_odd([3, 4])
+    False
+    """
+    return all_of(values.begin(), values.end(), is_odd)
+
+
+def any_odd(vector[int] values):
+    """
+    Test any_of with is_odd predicate.
+
+    >>> any_odd([1, 2, 3, 4])
+    True
+    >>> any_odd([2, 4, 6, 8])
+    False
+    """
+    return any_of(values.begin(), values.end(), is_odd)
+
+
+def none_odd(vector[int] values):
+    """
+    Test none_of with is_odd predicate.
+
+    >>> none_odd([2, 4, 6, 8])
+    True
+    >>> none_odd([1, 2, 3, 4])
+    False
+    """
+    return none_of(values.begin(), values.end(), is_odd)
+
+
+def count_ones(vector[int] values):
+    """
+    Test count.
+
+    >>> count_ones([1, 2, 1, 2])
+    2
+    """
+    return count(values.begin(), values.end(), 1)
+
+
+cdef void add_one(int &i):
+    # https://github.com/cython/cython/issues/1863
+    (&i)[0] += 1
+
+
+def increment_ints(vector[int] values):
+    """
+    Test for_each.
+
+    >>> increment_ints([3, 4, 2, 8, 15, 267])
+    [4, 5, 3, 9, 16, 268]
+    """
+    for_each(values.begin(), values.end(), &add_one)
+    return values
+
+
+def count_odd(vector[int] values):
+    """
+    Test count_if with is_odd predicate.
+
+    >>> count_odd([1, 2, 3, 4])
+    2
+    >>> count_odd([2, 4, 6, 8])
+    0
+    """
+    return count_if(values.begin(), values.end(), is_odd)
+
+
+def mirror_ends(string data):
+    """
+    Test mismatch using cppreference example.
+
+    This program determines the longest substring that is simultaneously found at the very beginning of the given string
+    and at the very end of it, in reverse order (possibly overlapping).
+
+    >>> print(mirror_ends(b'abXYZba').decode('ascii'))
+    ab
+    >>> print(mirror_ends(b'abca').decode('ascii'))
+    a
+    >>> print(mirror_ends(b'aba').decode('ascii'))
+    aba
+    """
+    return string(data.begin(), mismatch(data.begin(), data.end(), data.rbegin()).first)
+
+
+def mismatch_ints(vector[int] values1, vector[int] values2):
+    """
+    Test mismatch(first1, last1, first2).
+
+    >>> mismatch_ints([1, 2, 3], [1, 2, 3])
+    >>> mismatch_ints([1, 2], [1, 2, 3])
+    >>> mismatch_ints([1, 3], [1, 2, 3])
+    (3, 2)
+    """
+    result = mismatch(values1.begin(), values1.end(), values2.begin())
+    if result.first == values1.end():
+        return
+    return deref(result.first), deref(result.second)
+
+
+def is_int_in(vector[int] values, int target):
+    """
+    Test find.
+
+    >>> is_int_in(range(5), 3)
+    True
+    >>> is_int_in(range(5), 10)
+    False
+    """
+    return find(values.begin(), values.end(), target) != values.end()
+
+
+def find_odd(vector[int] values):
+    """
+    Test find_if using is_odd predicate.
+
+    >>> find_odd([2, 3, 4])
+    3
+    >>> find_odd([2, 4, 6])
+    """
+    result = find_if(values.begin(), values.end(), is_odd)
+    if result != values.end():
+        return deref(result)
+    else:
+        return None
+
+
+def find_even(vector[int] values):
+    """
+    Test find_if_not using is_odd predicate.
+
+    >>> find_even([3, 4, 5])
+    4
+    >>> find_even([1, 3, 5])
+    """
+    result = find_if_not(values.begin(), values.end(), is_odd)
+    if result != values.end():
+        return deref(result)
+    else:
+        return None
+
+
+def find_last_int_sequence(vector[int] values, vector[int] target):
+    """
+    Test find_end.
+
+    >>> find_last_int_sequence([1, 2, 3, 1, 2, 3], [2, 3])
+    4
+    >>> find_last_int_sequence([1, 2, 3], [4, 5])
+    """
+    result = find_end(values.begin(), values.end(), target.begin(), target.end())
+    if result != values.end():
+        return distance(values.begin(), result)
+    else:
+        return None
+
+
+cdef bool is_equal(int lhs, int rhs):
+    return lhs == rhs
+
+
+def find_last_int_sequence2(vector[int] values, vector[int] target):
+    """
+    Test find_end (using is_equal predicate).
+
+    >>> find_last_int_sequence2([1, 2, 3, 1, 2, 3], [2, 3])
+    4
+    >>> find_last_int_sequence2([1, 2, 3], [4, 5])
+    """
+    result = find_end(values.begin(), values.end(), target.begin(), target.end(), &is_equal)
+    if result != values.end():
+        return distance(values.begin(), result)
+    else:
+        return None
+
+
+def find_first_int_in_set(values, target):
+    """
+    Test find_first_of.
+
+    >>> find_first_int_in_set([1, 2, 3, 4, 5], [3, 5])
+    2
+    >>> find_first_int_in_set([1, 2, 3], [4, 5])
+    """
+    cdef vector[int] v = values
+    cdef vector[int] t = target
+    result = find_first_of(v.begin(), v.end(), t.begin(), t.end())
+    if result != v.end():
+        return distance(v.begin(), result)
+    else:
+        return None
+
+
+def find_first_int_in_set2(vector[int] values, vector[int] target):
+    """
+    Test find_first_of with is_equal predicate.
+
+    >>> find_first_int_in_set2([1, 2, 3, 4, 5], [3, 5])
+    2
+    >>> find_first_int_in_set2([1, 2, 3], [4, 5])
+    """
+    result = find_first_of(values.begin(), values.end(), target.begin(), target.end(), is_equal)
+    if result != values.end():
+        return distance(values.begin(), result)
+    else:
+        return None
+
+
+def find_adjacent_int(vector[int] values):
+    """
+    Test adjacent_find.
+
+    >>> find_adjacent_int([0, 1, 2, 3, 40, 40, 41, 41, 5])
+    4
+    >>> find_adjacent_int(range(5))
+    """
+    result = adjacent_find(values.begin(), values.end())
+    if result != values.end():
+        return distance(values.begin(), result)
+    else:
+        return None
+
+
+def find_adjacent_int2(vector[int] values):
+    """
+    Test find_adjacent with is_equal predicate.
+
+    >>> find_adjacent_int2([0, 1, 2, 3, 40, 40, 41, 41, 5])
+    4
+    >>> find_adjacent_int2(range(5))
+    """
+    result = adjacent_find(values.begin(), values.end(), is_equal)
+    if result != values.end():
+        return distance(values.begin(), result)
+    else:
+        return None
+
+
+def in_quote(string quote, string word):
+    """
+    Test search using cppreference example.
+
+    >>> in_quote(b"why waste time learning, when ignorance is instantaneous?", b"learning")
+    True
+    >>> in_quote(b"why waste time learning, when ignorance is instantaneous?", b"lemming")
+    False
+    """
+    return search(quote.begin(), quote.end(), word.begin(), word.end()) != quote.end()
+
+
+def in_quote2(string quote, string word):
+    """
+    Test search using cppreference example (with is_equal predicate).
+
+    >>> in_quote2(b"why waste time learning, when ignorance is instantaneous?", b"learning")
+    True
+    >>> in_quote2(b"why waste time learning, when ignorance is instantaneous?", b"lemming")
+    False
+    """
+    return search(quote.begin(), quote.end(), word.begin(), word.end(), &is_equal) != quote.end()
+
+
+def consecutive_values(string c, int count, char v):
+    """
+    Test search_n using cppreference example (without std::begin and std::end).
+
+    >>> consecutive_values(b"1001010100010101001010101", 4, ord("0"))
+    False
+    >>> consecutive_values(b"1001010100010101001010101", 3, ord("0"))
+    True
+    """
+    return search_n(c.begin(), c.end(), count, v) != c.end()
+
+
+def consecutive_values2(string c, int count, char v):
+    """
+    Test search_n using cppreference example (with is_equal predicate).
+
+    >>> consecutive_values2(b"1001010100010101001010101", 4, ord("0"))
+    False
+    >>> consecutive_values2(b"1001010100010101001010101", 3, ord("0"))
+    True
+    """
+    return search_n(c.begin(), c.end(), count, v, &is_equal) != c.end()
diff --git a/tests/run/cpp_stl_algo_partitioning_ops.pyx b/tests/run/cpp_stl_algo_partitioning_ops.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2NwcF9zdGxfYWxnb19wYXJ0aXRpb25pbmdfb3BzLnB5eA==
--- /dev/null
+++ b/tests/run/cpp_stl_algo_partitioning_ops.pyx
@@ -0,0 +1,90 @@
+# mode: run
+# tag: cpp, werror, cpp11
+
+from __future__ import print_function
+
+from libcpp cimport bool
+from libcpp.algorithm cimport is_partitioned, partition, partition_copy, stable_partition, partition_point
+from libcpp.algorithm cimport for_each, copy, reverse
+from libcpp.iterator cimport back_inserter
+from libcpp.vector cimport vector
+
+
+cdef bool is_even(int i):
+    return i % 2 == 0
+
+
+def test_is_partitioned():
+    """
+    >>> test_is_partitioned()
+    False
+    True
+    False
+    """
+    cdef vector[int] values = range(10)
+    print(is_partitioned(values.begin(), values.end(), is_even))
+
+    partition(values.begin(), values.end(), &is_even)
+    print(is_partitioned(values.begin(), values.end(), is_even))
+
+    reverse(values.begin(), values.end())
+    print(is_partitioned(values.begin(), values.end(), is_even))
+
+
+cdef int print_int(int v) except -1:
+    print(v, end=" ")
+
+
+def print_partition(vector[int] values):
+    """
+    Test partition.
+
+    >> print_partition(range(10))
+    0 8 2 6 4  *  5 3 7 1 9
+    """
+    it = partition(values.begin(), values.end(), &is_even)
+    for_each(values.begin(), it, &print_int)
+    print("*", end=" ")
+    for_each(it, values.end(), &print_int)
+    print()
+
+
+def partition_ints_even(vector[int] values):
+    """
+    Test partition_copy.
+
+    >>> partition_ints_even(range(10))
+    ([0, 2, 4, 6, 8], [1, 3, 5, 7, 9])
+    """
+    cdef vector[int] even_values, odd_values
+    partition_copy(values.begin(), values.end(), back_inserter(even_values), back_inserter(odd_values), &is_even)
+    return even_values, odd_values
+
+
+cdef bool is_positive(int v):
+    return v > 0
+
+
+def partition_ints_positive(vector[int] values):
+    """
+    Test stable_partition.
+
+    >>> partition_ints_positive([0, 0, 3, 0, 2, 4, 5, 0, 7])
+    [3, 2, 4, 5, 7, 0, 0, 0, 0]
+    """
+    stable_partition(values.begin(), values.end(), &is_positive)
+    return values
+
+
+def partition_point_ints_even(vector[int] values):
+    """
+    Test partition_point.
+
+    >>> partition_point_ints_even([0, 8, 2, 6, 4, 5, 3, 7, 1, 9])
+    ([0, 8, 2, 6, 4], [5, 3, 7, 1, 9])
+    """
+    it = partition_point(values.begin(), values.end(), is_even)
+    cdef vector[int] even_values, odd_values
+    copy(values.begin(), it, back_inserter(even_values))
+    copy(it, values.end(), back_inserter(odd_values))
+    return even_values, odd_values
diff --git a/tests/run/cpp_stl_algo_sorting_ops.pyx b/tests/run/cpp_stl_algo_sorting_ops.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2NwcF9zdGxfYWxnb19zb3J0aW5nX29wcy5weXg=
--- /dev/null
+++ b/tests/run/cpp_stl_algo_sorting_ops.pyx
@@ -0,0 +1,187 @@
+# mode: run
+# tag: cpp, werror, cpp11
+
+from __future__ import print_function
+
+from libcpp cimport bool
+from libcpp.algorithm cimport is_sorted, is_sorted_until, sort, partial_sort, partial_sort_copy, stable_sort
+from libcpp.algorithm cimport nth_element
+from libcpp.functional cimport greater
+from libcpp.iterator cimport distance
+from libcpp.string cimport string
+from libcpp.vector cimport vector
+
+
+def is_sorted_ints(vector[int] values):
+    """
+    Test is_sorted.
+
+    >>> is_sorted_ints([3, 1, 4, 1, 5])
+    False
+    >>> is_sorted_ints([1, 1, 3, 4, 5])
+    True
+    """
+    return is_sorted(values.begin(), values.end())
+
+
+def initial_sorted_elements(vector[int] values):
+    """
+    Test is_sorted_until.
+
+    >>> initial_sorted_elements([4, 1, 9, 5, 1, 3])
+    1
+    >>> initial_sorted_elements([4, 5, 9, 3, 1, 1])
+    3
+    >>> initial_sorted_elements([9, 3, 1, 4, 5, 1])
+    1
+    >>> initial_sorted_elements([1, 3, 5, 4, 1, 9])
+    3
+    >>> initial_sorted_elements([5, 9, 1, 1, 3, 4])
+    2
+    >>> initial_sorted_elements([4, 9, 1, 5, 1, 3])
+    2
+    >>> initial_sorted_elements([1, 1, 4, 9, 5, 3])
+    4
+    """
+    sorted_end = is_sorted_until(values.begin(), values.end())
+    return distance(values.begin(), sorted_end)
+
+
+def sort_ints(vector[int] values):
+    """Test sort using the default operator<.
+
+    >>> sort_ints([5, 7, 4, 2, 8, 6, 1, 9, 0, 3])
+    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+    """
+    sort(values.begin(), values.end())
+    return values
+
+
+def sort_ints_reverse(vector[int] values):
+    """Test sort using a standard library comparison function object.
+
+    >>> sort_ints_reverse([5, 7, 4, 2, 8, 6, 1, 9, 0, 3])
+    [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
+    """
+    sort(values.begin(), values.end(), greater[int]())
+    return values
+
+
+def partial_sort_ints(vector[int] values, int k):
+    """
+    Test partial_sort using the default operator<.
+
+    >>> partial_sort_ints([4, 2, 3, 1, 5], 2)[:2]
+    [1, 2]
+    """
+    partial_sort(values.begin(), values.begin() + k, values.end())
+    return values
+
+
+def partial_sort_ints_reverse(vector[int] values, int k):
+    """
+    Test partial_sort using a standard library comparison function object.
+
+    >>> partial_sort_ints_reverse([4, 2, 3, 1, 5], 2)[:2]
+    [5, 4]
+    """
+    partial_sort(values.begin(), values.begin() + k, values.end(), greater[int]())
+    return values
+
+
+def partial_sort_ints2(vector[int] values, int k):
+    """
+    Test partial_sort_copy using the default operator<.
+
+    >>> partial_sort_ints2([4, 2, 3, 1, 5], 2)
+    [1, 2]
+    """
+    output = vector[int](2)
+    partial_sort_copy(values.begin(), values.end(), output.begin(), output.end())
+    return output
+
+
+def partial_sort_ints_reverse2(vector[int] values, int k):
+    """
+    Test partial_sort_copy using a standard library comparison function object.
+
+    >>> partial_sort_ints_reverse2([4, 2, 3, 1, 5], 2)
+    [5, 4]
+    """
+    output = vector[int](2)
+    partial_sort_copy(values.begin(), values.end(), output.begin(), output.end(), greater[int]())
+    return output
+
+
+cdef extern from *:
+    """
+    struct Employee
+    {
+        Employee() = default;
+        Employee(int age, std::string name): age(age), name(name) {}
+        int age;
+        std::string name;  // Does not participate in comparisons
+    };
+
+    bool operator<(const Employee& lhs, const Employee& rhs)
+    {
+        return lhs.age < rhs.age;
+    }
+    """
+    cppclass Employee:
+        Employee()
+        Employee(int, string)
+        int age
+        string name
+
+cdef bool Employee_greater(const Employee& lhs, const Employee& rhs):
+    return lhs.age > rhs.age
+
+def test_stable_sort():
+    """
+    Test stable_sort using cppreference example.
+
+    >>> test_stable_sort()
+    32, Arthur
+    108, Zaphod
+    108, Ford
+    108, Zaphod
+    108, Ford
+    32, Arthur
+    """
+    cdef vector[Employee] employees
+    employees.push_back(Employee(108, <string>b"Zaphod"))
+    employees.push_back(Employee(32, <string>b"Arthur"))
+    employees.push_back(Employee(108, <string>b"Ford"))
+
+    stable_sort(employees.begin(), employees.end())
+
+    for e in employees:
+        print("%s, %s" % (e.age, <str>(e.name).decode("ascii")))
+
+    stable_sort(employees.begin(), employees.end(), &Employee_greater)
+
+    for e in employees:
+        print("%s, %s" % (e.age, <str>(e.name).decode("ascii")))
+
+
+def second_smallest(vector[int] values):
+    """
+    Test nth_element using the default operator<.
+
+    >>> second_smallest([5, 6, 4, 3, 2, 6, 7, 9, 3])
+    3
+    """
+    nth_element(values.begin(), values.begin() + 1, values.end())
+    return values[1]
+
+
+def second_largest(vector[int] values):
+    """
+    Test nth_element using a standard library comparison function object.
+
+    >>> second_largest([5, 6, 4, 3, 2, 6, 7, 9, 3])
+    7
+    """
+    nth_element(values.begin(), values.begin() + 1, values.end(), greater[int]())
+    return values[1]
diff --git a/tests/run/cpp_stl_atomic.pyx b/tests/run/cpp_stl_atomic.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2NwcF9zdGxfYXRvbWljLnB5eA==
--- /dev/null
+++ b/tests/run/cpp_stl_atomic.pyx
@@ -0,0 +1,85 @@
+# mode: run
+# tag: cpp, cpp11, werror
+
+from cython.operator cimport preincrement as incr, dereference as deref
+from libc.stdint cimport *
+
+from libcpp.atomic cimport atomic
+
+def int_test(int x):
+    """
+    >>> int_test(55)
+    3
+    >>> int_test(42)
+    3
+    >>> int_test(100000)
+    3
+    """
+    atom = new atomic[int](x)
+    try:
+        atom.store(0)
+        incr(deref(atom))
+        incr(deref(atom))
+        incr(deref(atom))
+        return atom.load()
+    finally:
+        del atom
+
+ctypedef atomic[int32_t] atomint32_t
+
+def typedef_test(int x):
+    """
+    >>> typedef_test(55)
+    3
+    >>> typedef_test(42)
+    3
+    >>> typedef_test(100000)
+    3
+    """
+    atom = new atomint32_t(x)
+    try:
+        atom.store(0)
+        incr(deref(atom))
+        incr(deref(atom))
+        incr(deref(atom))
+        return atom.load()
+    finally:
+        del atom
+
+def stack_allocation_test(int x):
+    """
+    >>> stack_allocation_test(55)
+    3
+    >>> stack_allocation_test(42)
+    3
+    >>> stack_allocation_test(100000)
+    3
+    """
+    cdef atomint32_t atom
+    atom.store(x)
+    try:
+        atom.store(0)
+        incr(atom)
+        incr(atom)
+        incr(atom)
+        return atom.load()
+    finally:
+        pass
+
+def nogil_int_test(int x):
+    """
+    >>> nogil_int_test(55)
+    55
+    >>> nogil_int_test(42)
+    42
+    >>> nogil_int_test(100000)
+    100000
+    """
+    with nogil:
+        atom = new atomic[int](0)
+    try:
+        with nogil:
+            atom.store(x)
+        return atom.load()
+    finally:
+        del atom
diff --git a/tests/run/cpp_stl_conversion.pyx b/tests/run/cpp_stl_conversion.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2NwcF9zdGxfY29udmVyc2lvbi5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2NwcF9zdGxfY29udmVyc2lvbi5weXg= 100644
--- a/tests/run/cpp_stl_conversion.pyx
+++ b/tests/run/cpp_stl_conversion.pyx
@@ -143,6 +143,8 @@
     Traceback (most recent call last):
     ...
     OverflowError: ...
+
+    "TypeError: an integer is required" on CPython
     >>> test_typedef_vector([1, 2, None])       #doctest: +ELLIPSIS
     Traceback (most recent call last):
     ...
@@ -146,7 +148,7 @@
     >>> test_typedef_vector([1, 2, None])       #doctest: +ELLIPSIS
     Traceback (most recent call last):
     ...
-    TypeError: an integer is required
+    TypeError: ...int...
     """
     cdef vector[my_int] v = o
     return v
diff --git a/tests/run/cpp_stl_numeric_ops.pyx b/tests/run/cpp_stl_numeric_ops.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2NwcF9zdGxfbnVtZXJpY19vcHMucHl4
--- /dev/null
+++ b/tests/run/cpp_stl_numeric_ops.pyx
@@ -0,0 +1,147 @@
+# mode: run
+# tag: cpp, werror, cpp11
+
+from libcpp.numeric cimport inner_product, iota, accumulate, adjacent_difference, partial_sum
+from libcpp.vector cimport vector
+from libcpp cimport bool
+
+# Subtracts two integers.
+cdef int subtract_integers(int lhs, int rhs):
+    return lhs - rhs
+
+# Adds two integers.
+cdef int add_integers(int lhs, int rhs):
+    return lhs + rhs
+
+# Multiplies two integers.
+cdef int multiply_integers(int lhs, int rhs):
+    return lhs * rhs
+
+# Determines equality for two integers.
+# If lhs == rhs, returns true. Returns false otherwise.
+cdef bool is_equal(int lhs, int rhs):
+    return lhs == rhs
+
+def test_inner_product(vector[int] v1, vector[int] v2, int init):
+    """
+    Test inner_product with integer values.
+    >>> test_inner_product([1, 2, 3], [1, 2, 3], 1)
+    15
+    """
+    return inner_product(v1.begin(), v1.end(), v2.begin(), init)
+
+
+def test_inner_product_with_zero(vector[int] v1, vector[int] v2, int init):
+    """
+    Test inner_product with a zero value in the container.
+    >>> test_inner_product_with_zero([1, 2, 0], [1, 1, 1], 0)
+    3
+    """
+    return inner_product(v1.begin(), v1.end(), v2.begin(), init)
+
+def test_inner_product_with_bin_op(vector[int] v1, vector[int] v2, int init):
+    """
+    Test inner_product with two binary operations. In this case,
+    Looks at number of pairwise matches between v1 and v2.
+    [5, 1, 2, 3, 4]
+    [5, 4, 2, 3, 1]
+    There are 3 matches (5, 2, 3). So, 1 + 1 + 1 = 3.
+
+    >>> test_inner_product_with_bin_op([5, 1, 2, 3, 4], [5, 4, 2, 3, 1], 0)
+    3
+    """
+    return inner_product(v1.begin(), v1.end(), v2.begin(), init, add_integers, is_equal)
+
+def test_iota(vector[int] v, int value):
+    """
+    Test iota with beginning value of 0.
+    >>> test_iota(range(6), 0)
+    [0, 1, 2, 3, 4, 5]
+    """
+    iota(v.begin(), v.end(), value)
+    return v
+
+def test_iota_negative_init(vector[int] v, int value):
+    """
+    Test iota with a negative beginning value.
+    >>> test_iota_negative_init(range(7), -4)
+    [-4, -3, -2, -1, 0, 1, 2]
+    """
+    iota(v.begin(), v.end(), value)
+    return v
+
+def test_accumulate(vector[int] v, int init):
+    """
+    Test accumulate.
+     0 + 1 = 1
+     1 + 2 = 3
+     3 + 3 = 6
+    >>> test_accumulate([1, 2, 3], 0)
+    6
+    """
+    return accumulate(v.begin(), v.end(), init)
+
+def test_accumulate_with_subtraction(vector[int] v, int init):
+    """
+    Test accumulate with subtraction. Note that accumulate is a fold-left operation.
+     0 - 1 = -1
+    -1 - 2 = -3
+    -3 - 3 = -6
+    >>> test_accumulate_with_subtraction([1, 2, 3], 0)
+    -6
+    """
+    return accumulate(v.begin(), v.end(), init, subtract_integers)
+
+def test_adjacent_difference(vector[int] v):
+    """
+    Test adjacent_difference with integer values.
+    2 - 0,   -> 2
+    4 - 2,   -> 2
+    6 - 4,   -> 2
+    8 - 6,   -> 2
+    10 - 8,  -> 2
+    12 - 10  -> 2
+    >>> test_adjacent_difference([2, 4, 6, 8, 10, 12])
+    [2, 2, 2, 2, 2, 2]
+    """
+    adjacent_difference(v.begin(), v.end(), v.begin())
+    return v
+
+def test_adjacent_difference_with_bin_op(vector[int] v):
+    """
+    Test adjacent_difference with a binary operation.
+    0 + 1 -> 1
+    1 + 2 -> 3
+    2 + 4 -> 6
+    4 + 5 -> 9
+    5 + 6 -> 11
+    >>> test_adjacent_difference_with_bin_op([1, 2, 4, 5, 6])
+    [1, 3, 6, 9, 11]
+    """
+    adjacent_difference(v.begin(), v.end(), v.begin(), add_integers)
+    return v
+
+def test_partial_sum(vector[int] v):
+    """
+    Test partial_sum with integer values.
+    2 + 0   -> 2
+    2 + 2   -> 4
+    4 + 2   -> 6
+    6 + 2   -> 8
+    8 + 2   -> 10
+    10 + 2  -> 12
+    >>> test_partial_sum([2, 2, 2, 2, 2, 2])
+    [2, 4, 6, 8, 10, 12]
+    """
+    partial_sum(v.begin(), v.end(), v.begin())
+    return v
+
+def test_partial_sum_with_bin_op(vector[int] v):
+    """
+    Test partial_sum with a binary operation.
+    Using multiply_integers, partial_sum will calculate the first 5 powers of 2.
+    >>> test_partial_sum_with_bin_op([2, 2, 2, 2, 2])
+    [2, 4, 8, 16, 32]
+    """
+    partial_sum(v.begin(), v.end(), v.begin(), multiply_integers)
+    return v
diff --git a/tests/run/cpp_type_inference.pyx b/tests/run/cpp_type_inference.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2NwcF90eXBlX2luZmVyZW5jZS5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2NwcF90eXBlX2luZmVyZW5jZS5weXg= 100644
--- a/tests/run/cpp_type_inference.pyx
+++ b/tests/run/cpp_type_inference.pyx
@@ -12,6 +12,11 @@
     cdef cppclass Square(Shape):
         Square(int)
 
+    cdef cppclass Empty(Shape):
+        Empty()
+
+    cdef Empty make_Empty "shapes::Empty"()
+
 from cython cimport typeof
 
 from cython.operator cimport dereference as d
@@ -48,3 +53,35 @@
         ptr = new Square(size)
     print typeof(ptr)
     del ptr
+
+def test_stack_allocated(bint b=True):
+    """
+    >>> test_stack_allocated()
+    """
+    e1 = Empty()
+    e2 = Empty()
+    e = e1 if b else e2
+    assert typeof(e1) == "Empty", typeof(e1)
+    assert typeof(e2) == "Empty", typeof(e2)
+    assert typeof(e) == "Empty", typeof(e)
+
+cdef extern from *:
+    """
+    template <typename T>
+    struct MyTemplate {};
+    """
+    cdef cppclass MyTemplate[T]:
+        MyTemplate()
+
+def test_template_types():
+    """
+    >>> test_template_types()
+    """
+    t_stack = MyTemplate[int]()
+    assert typeof(t_stack) == "MyTemplate[int]", typeof(t_stack)
+
+    t_ptr = new MyTemplate[double]()
+    try:
+        assert typeof(t_ptr) == "MyTemplate[double] *", typeof(t_ptr)
+    finally:
+        del t_ptr
diff --git a/tests/run/cyfunction.pyx b/tests/run/cyfunction.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2N5ZnVuY3Rpb24ucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2N5ZnVuY3Rpb24ucHl4 100644
--- a/tests/run/cyfunction.pyx
+++ b/tests/run/cyfunction.pyx
@@ -271,9 +271,9 @@
     >>> isinstance(test_annotations.__annotations__, dict)
     True
     >>> sorted(test_annotations.__annotations__.items())
-    [('a', 'test'), ('b', 'other'), ('c', 123), ('return', 'ret')]
+    [('a', "'test'"), ('b', "'other'"), ('c', '123'), ('return', "'ret'")]
 
     >>> def func_b(): return 42
     >>> def func_c(): return 99
     >>> inner = test_annotations(1, func_b, func_c)
     >>> sorted(inner.__annotations__.items())
@@ -275,9 +275,9 @@
 
     >>> def func_b(): return 42
     >>> def func_c(): return 99
     >>> inner = test_annotations(1, func_b, func_c)
     >>> sorted(inner.__annotations__.items())
-    [('return', 99), ('x', 'banana'), ('y', 42)]
+    [('return', 'c()'), ('x', "'banana'"), ('y', 'b()')]
 
     >>> inner.__annotations__ = {234: 567}
     >>> inner.__annotations__
@@ -293,6 +293,6 @@
 
     >>> inner = test_annotations(1, func_b, func_c)
     >>> sorted(inner.__annotations__.items())
-    [('return', 99), ('x', 'banana'), ('y', 42)]
+    [('return', 'c()'), ('x', "'banana'"), ('y', 'b()')]
     >>> inner.__annotations__['abc'] = 66
     >>> sorted(inner.__annotations__.items())
@@ -297,6 +297,6 @@
     >>> inner.__annotations__['abc'] = 66
     >>> sorted(inner.__annotations__.items())
-    [('abc', 66), ('return', 99), ('x', 'banana'), ('y', 42)]
+    [('abc', 66), ('return', 'c()'), ('x', "'banana'"), ('y', 'b()')]
 
     >>> inner = test_annotations(1, func_b, func_c)
     >>> sorted(inner.__annotations__.items())
@@ -300,7 +300,7 @@
 
     >>> inner = test_annotations(1, func_b, func_c)
     >>> sorted(inner.__annotations__.items())
-    [('return', 99), ('x', 'banana'), ('y', 42)]
+    [('return', 'c()'), ('x', "'banana'"), ('y', 'b()')]
     """
     def inner(x: "banana", y: b()) -> c():
         return x,y
@@ -376,6 +376,18 @@
     def meth(self): pass
 
 
+class TestStaticmethod(object):
+    """
+    >>> x = TestStaticmethod()
+    >>> x.staticmeth(42)
+    42
+    >>> x.staticmeth.__get__(42)()
+    42
+    """
+    @staticmethod
+    def staticmeth(arg): return arg
+
+
 cdef class TestOptimisedBuiltinMethod:
     """
     >>> obj = TestOptimisedBuiltinMethod()
@@ -391,3 +403,22 @@
 
     def call(self, arg, obj=None):
         (obj or self).append(arg+1)  # optimistically optimised => uses fast fallback method call
+
+
+def do_nothing(f):
+    """Dummy decorator for `test_firstlineno_decorated_function`"""
+    return f
+
+
+@do_nothing
+@do_nothing
+def test_firstlineno_decorated_function():
+    """
+    check that `test_firstlineno_decorated_function` starts 5 lines below `do_nothing`
+
+    >>> test_firstlineno_decorated_function()
+    5
+    """
+    l1 = do_nothing.__code__.co_firstlineno
+    l2 = test_firstlineno_decorated_function.__code__.co_firstlineno
+    return l2 - l1
diff --git a/tests/run/cython3.pyx b/tests/run/cython3.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2N5dGhvbjMucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2N5dGhvbjMucHl4 100644
--- a/tests/run/cython3.pyx
+++ b/tests/run/cython3.pyx
@@ -1,2 +1,2 @@
-# cython: language_level=3, binding=True
+# cython: language_level=3, binding=True, annotation_typing=False
 # mode: run
@@ -2,5 +2,5 @@
 # mode: run
-# tag: generators, python3, exceptions
+# tag: generators, python3, exceptions, gh2230, gh2811
 
 print(end='')  # test that language_level 3 applies immediately at the module start, for the first token.
 
@@ -30,6 +30,18 @@
     return locals()
 
 
+### "new style" classes
+
+class T:
+    """
+    >>> t = T()
+    >>> isinstance(t, T)
+    True
+    >>> isinstance(T, type)  # not a Py2 old style class!
+    True
+    """
+
+
 ### true division
 
 def truediv(x):
@@ -578,5 +590,5 @@
     >>> len(annotation_syntax.__annotations__)
     5
     >>> print(annotation_syntax.__annotations__['a'])
-    test new test
+    u'test new test'
     >>> print(annotation_syntax.__annotations__['b'])
@@ -582,3 +594,3 @@
     >>> print(annotation_syntax.__annotations__['b'])
-    other
+    u'other'
     >>> print(annotation_syntax.__annotations__['args'])
@@ -584,3 +596,3 @@
     >>> print(annotation_syntax.__annotations__['args'])
-    ARGS
+    u'ARGS'
     >>> print(annotation_syntax.__annotations__['kwargs'])
@@ -586,3 +598,3 @@
     >>> print(annotation_syntax.__annotations__['kwargs'])
-    KWARGS
+    u'KWARGS'
     >>> print(annotation_syntax.__annotations__['return'])
@@ -588,8 +600,8 @@
     >>> print(annotation_syntax.__annotations__['return'])
-    ret
+    u'ret'
     """
     result : int = a + b
 
     return result
 
 
@@ -590,11 +602,23 @@
     """
     result : int = a + b
 
     return result
 
 
+def builtin_as_annotation(text: str):
+    # See https://github.com/cython/cython/issues/2811
+    """
+    >>> builtin_as_annotation("abc")
+    a
+    b
+    c
+    """
+    for c in text:
+        print(c)
+
+
 async def async_def_annotations(x: 'int') -> 'float':
     """
     >>> ret, arg = sorted(async_def_annotations.__annotations__.items())
     >>> print(ret[0]); print(ret[1])
     return
@@ -596,8 +620,8 @@
 async def async_def_annotations(x: 'int') -> 'float':
     """
     >>> ret, arg = sorted(async_def_annotations.__annotations__.items())
     >>> print(ret[0]); print(ret[1])
     return
-    float
+    u'float'
     >>> print(arg[0]); print(arg[1])
     x
@@ -602,5 +626,5 @@
     >>> print(arg[0]); print(arg[1])
     x
-    int
+    u'int'
     """
     return float(x)
diff --git a/tests/run/cython3_no_unicode_literals.pyx b/tests/run/cython3_no_unicode_literals.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2N5dGhvbjNfbm9fdW5pY29kZV9saXRlcmFscy5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2N5dGhvbjNfbm9fdW5pY29kZV9saXRlcmFscy5weXg= 100644
--- a/tests/run/cython3_no_unicode_literals.pyx
+++ b/tests/run/cython3_no_unicode_literals.pyx
@@ -140,6 +140,12 @@
     cdef str s = 'abc'
     return str, s
 
+def strip_wrapped_string(s):
+    # PEP 563 translates an annotation of "test new test" to '"test new test"'
+    # but choice of string delimiters is a bit arbitrary
+    #  this function handles that
+    assert s[0] == s[-1] # delimiters on either end are the same
+    return s[1:-1] # strip them
 
 def annotation_syntax(a: "test new test", b : "other" = 2, *args: "ARGS", **kwargs: "KWARGS") -> "ret":
     """
@@ -150,5 +156,5 @@
 
     >>> len(annotation_syntax.__annotations__)
     5
-    >>> annotation_syntax.__annotations__['a']
+    >>> strip_wrapped_string(annotation_syntax.__annotations__['a'])
     'test new test'
@@ -154,3 +160,3 @@
     'test new test'
-    >>> annotation_syntax.__annotations__['b']
+    >>> strip_wrapped_string(annotation_syntax.__annotations__['b'])
     'other'
@@ -156,3 +162,3 @@
     'other'
-    >>> annotation_syntax.__annotations__['args']
+    >>> strip_wrapped_string(annotation_syntax.__annotations__['args'])
     'ARGS'
@@ -158,3 +164,3 @@
     'ARGS'
-    >>> annotation_syntax.__annotations__['kwargs']
+    >>> strip_wrapped_string(annotation_syntax.__annotations__['kwargs'])
     'KWARGS'
@@ -160,5 +166,5 @@
     'KWARGS'
-    >>> annotation_syntax.__annotations__['return']
+    >>> strip_wrapped_string(annotation_syntax.__annotations__['return'])
     'ret'
     """
     result : int = a + b
diff --git a/tests/run/cython_includes.pyx b/tests/run/cython_includes.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2N5dGhvbl9pbmNsdWRlcy5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2N5dGhvbl9pbmNsdWRlcy5weXg= 100644
--- a/tests/run/cython_includes.pyx
+++ b/tests/run/cython_includes.pyx
@@ -28,6 +28,7 @@
 cimport cpython.long
 cimport cpython.longintrepr
 cimport cpython.mapping
+cimport cpython.marshal
 cimport cpython.mem
 cimport cpython.memoryview
 cimport cpython.method
diff --git a/tests/run/decorators_T593.pyx b/tests/run/decorators_T593.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2RlY29yYXRvcnNfVDU5My5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2RlY29yYXRvcnNfVDU5My5weXg= 100644
--- a/tests/run/decorators_T593.pyx
+++ b/tests/run/decorators_T593.pyx
@@ -110,8 +110,8 @@
 
 class Bar(metaclass=Base):
    """
-   >>> Bar._order
-   ['__module__', '__qualname__', '__doc__', 'bar']
+   >>> [n for n in Bar._order if n != "__qualname__"]
+   ['__module__', '__doc__', 'bar']
    """
    @property
    def bar(self):
diff --git a/tests/run/dict_getitem.pyx b/tests/run/dict_getitem.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2RpY3RfZ2V0aXRlbS5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2RpY3RfZ2V0aXRlbS5weXg= 100644
--- a/tests/run/dict_getitem.pyx
+++ b/tests/run/dict_getitem.pyx
@@ -146,3 +146,17 @@
     KeyError: (1, 2)
     """
     return d[key]
+
+
+def getitem_int_key(d, int key):
+    """
+    >>> d = {-1: 10}
+    >>> getitem_int_key(d, -1)  # dict
+    10
+    >>> class D(dict): pass
+    >>> d = D({-1: 10})
+    >>> getitem_int_key(d, -1)  # D
+    10
+    """
+    # Based on GH-1807: must check Mapping protocol first, even for integer "index" keys.
+    return d[key]
diff --git a/tests/run/different_package_names.srctree b/tests/run/different_package_names.srctree
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2RpZmZlcmVudF9wYWNrYWdlX25hbWVzLnNyY3RyZWU=
--- /dev/null
+++ b/tests/run/different_package_names.srctree
@@ -0,0 +1,43 @@
+# mode: run
+# tag: import,cimport,packages
+
+PYTHON setup.py build_ext --inplace
+PYTHON -c "import pkg_py"
+PYTHON -c "import pkg_py.pkg_pyx"
+PYTHON -c "import pkg_py.pkg_pyx.module as module; module.run_test()"
+
+######## setup.py ########
+
+from distutils.core import setup
+from Cython.Build import cythonize
+
+setup(
+    ext_modules=cythonize('**/*.pyx', language_level=3),
+)
+
+
+######## pkg_py/__init__.py ########
+
+TYPE = 'py'
+
+######## pkg_py/pkg_pyx/__init__.pyx ########
+
+TYPE = 'pyx'
+
+######## pkg_py/pkg_pyx/pkg_pxd/__init__.pxd ########
+
+# Not what Python would consider a package, but Cython can use it for cimports.
+from libc.math cimport fabs
+
+######## pkg_py/pkg_pyx/module.pyx ########
+
+from pkg_py.pkg_pyx.pkg_pxd cimport fabs
+
+def run_test():
+    import pkg_py
+    assert pkg_py.TYPE == 'py'
+
+    import pkg_py.pkg_pyx
+    assert pkg_py.pkg_pyx.TYPE == 'pyx'
+
+    assert fabs(-2.0) == 2.0
diff --git a/tests/run/embedsignatures.pyx b/tests/run/embedsignatures.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2VtYmVkc2lnbmF0dXJlcy5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2VtYmVkc2lnbmF0dXJlcy5weXg= 100644
--- a/tests/run/embedsignatures.pyx
+++ b/tests/run/embedsignatures.pyx
@@ -1,6 +1,12 @@
 #cython: embedsignature=True, annotation_typing=False
 
+# signatures here are a little fragile - when they are
+# generated during the build process gives slightly
+# different (but equivalent) forms - therefore tests
+# may need changing occasionally to reflect behaviour
+# and this isn't necessarily a bug
+
 import sys
 
 if sys.version_info >= (3, 4):
     def funcdoc(f):
@@ -3,8 +9,8 @@
 import sys
 
 if sys.version_info >= (3, 4):
     def funcdoc(f):
-        if not f.__text_signature__:
+        if not getattr(f, "__text_signature__", None):
             return f.__doc__
         doc = '%s%s' % (f.__name__, f.__text_signature__)
         if f.__doc__:
@@ -83,6 +89,9 @@
     >>> print (Ext.n.__doc__)
     Ext.n(self, a: int, b: float = 1.0, *args: tuple, **kwargs: dict) -> (None, True)
 
+    >>> print (Ext.o.__doc__)
+    Ext.o(self, a, b=1, /, c=5, *args, **kwargs)
+
     >>> print (Ext.get_int.__doc__)
     Ext.get_int(self) -> int
 
@@ -265,6 +274,9 @@
     def n(self, a: int, b: float = 1.0, *args: tuple, **kwargs: dict) -> (None, True):
         pass
 
+    def o(self, a, b=1, /, c=5, *args, **kwargs):
+        pass
+
     cpdef int get_int(self):
         return 0
 
@@ -441,6 +453,6 @@
 Foo.m02(self, a: True, b: False) -> bool
 
 >>> print(Foo.m03.__doc__)
-Foo.m03(self, a: 42, b: 42, c: -42) -> int
+Foo.m03(self, a: 42, b: +42, c: -42) -> int
 
 >>> print(Foo.m04.__doc__)
@@ -445,6 +457,6 @@
 
 >>> print(Foo.m04.__doc__)
-Foo.m04(self, a: 3.14, b: 3.14, c: -3.14) -> float
+Foo.m04(self, a: 3.14, b: +3.14, c: -3.14) -> float
 
 >>> print(Foo.m05.__doc__)
 Foo.m05(self, a: 1 + 2j, b: +2j, c: -2j) -> complex
@@ -459,7 +471,7 @@
 Foo.m08(self, a: (1, 2, 3), b: ()) -> tuple
 
 >>> print(Foo.m09.__doc__)
-Foo.m09(self, a: {1, 2, 3}, b: set()) -> set
+Foo.m09(self, a: {1, 2, 3}, b: {i for i in ()}) -> set
 
 >>> print(Foo.m10.__doc__)
 Foo.m10(self, a: {1: 1, 2: 2, 3: 3}, b: {}) -> dict
diff --git a/tests/run/ext_attr_getter.srctree b/tests/run/ext_attr_getter.srctree
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2V4dF9hdHRyX2dldHRlci5zcmN0cmVl..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2V4dF9hdHRyX2dldHRlci5zcmN0cmVl 100644
--- a/tests/run/ext_attr_getter.srctree
+++ b/tests/run/ext_attr_getter.srctree
@@ -4,6 +4,7 @@
 ######## setup.py ########
 
 from Cython.Build.Dependencies import cythonize
+from Cython.Compiler.Errors import CompileError
 from distutils.core import setup
 
 # force the build order
@@ -7,5 +8,6 @@
 from distutils.core import setup
 
 # force the build order
-setup(ext_modules= cythonize("foo_extension.pyx"))
+setup(ext_modules = cythonize("foo_extension.pyx", language_level=3))
+setup(ext_modules = cythonize("getter[0-9].pyx", language_level=3))
 
@@ -11,3 +13,8 @@
 
-setup(ext_modules = cythonize("getter*.pyx"))
+for name in ("getter_fail0.pyx", "getter_fail1.pyx"):
+    try:
+        cythonize(name, language_level=3)
+        assert False
+    except CompileError as e:
+        print("\nGot expected exception, continuing\n")
 
@@ -13,5 +20,5 @@
 
-######## foo_nominal.h ########
+######## foo.h ########
 
 #include <Python.h>
 
@@ -24,5 +31,6 @@
     int f0;
     int f1;
     int f2;
+    int v[10];
 } FooStructNominal;
 
@@ -27,5 +35,34 @@
 } FooStructNominal;
 
+typedef struct {
+    PyObject_HEAD
+} FooStructOpaque;
+
+
+#define PyFoo_GET0M(a) ((FooStructNominal*)a)->f0
+#define PyFoo_GET1M(a) ((FooStructNominal*)a)->f1
+#define PyFoo_GET2M(a) ((FooStructNominal*)a)->f2
+
+int PyFoo_Get0F(FooStructOpaque *f)
+{
+    return PyFoo_GET0M(f);
+}
+
+int PyFoo_Get1F(FooStructOpaque *f)
+{
+    return PyFoo_GET1M(f);
+}
+
+int PyFoo_Get2F(FooStructOpaque *f)
+{
+    return PyFoo_GET2M(f);
+}
+
+int *PyFoo_GetV(FooStructOpaque *f)
+{
+    return ((FooStructNominal*)f)->v;
+}
+
 #ifdef __cplusplus
 }
 #endif
@@ -33,5 +70,10 @@
 ######## foo_extension.pyx ########
 
 cdef class Foo:
-    cdef public int field0, field1, field2;
+    cdef public int _field0, _field1, _field2;
+    cdef public int _vector[10];
+
+    @property
+    def field0(self):
+        return self._field0
 
@@ -37,6 +79,9 @@
 
-    def __init__(self, f0, f1, f2):
-        self.field0 = f0
-        self.field1 = f1
-        self.field2 = f2
+    @property
+    def field1(self):
+        return self._field1
+
+    @property
+    def field2(self):
+        return self._field2
 
@@ -42,12 +87,20 @@
 
-cdef get_field0(Foo f):
-    return f.field0
-
-cdef get_field1(Foo f):
-    return f.field1
-
-cdef get_field2(Foo f):
-    return f.field2
+    def __init__(self, f0, f1, f2, vec=None):
+        if vec is None:
+            vec = ()
+        if not isinstance(vec, tuple):
+            raise ValueError("v must be None or a tuple")
+        self._field0 = f0
+        self._field1 = f1
+        self._field2 = f2
+        i = 0
+        for v in vec:
+            self._vector[i] = v
+            if i > 9:
+                break
+            i += 1
+        for j in range(i,10):
+            self._vector[j] = 0
 
 # A pure-python class that disallows direct access to fields
 class OpaqueFoo(Foo):
@@ -64,8 +117,7 @@
     def field2(self):
         raise AttributeError('no direct access to field2')
 
-
 ######## getter0.pyx ########
 
 # Access base Foo fields from C via aliased field names
 
@@ -68,8 +120,8 @@
 ######## getter0.pyx ########
 
 # Access base Foo fields from C via aliased field names
 
-cdef extern from "foo_nominal.h":
+cdef extern from "foo.h":
 
     ctypedef class foo_extension.Foo [object FooStructNominal]:
         cdef:
@@ -78,6 +130,7 @@
             int field2 "f2"
 
 def sum(Foo f):
-    # the f.__getattr__('field0') is replaced in c by f->f0
+    # Note - not a cdef function but compiling the f.__getattr__('field0')
+    # notices the alias and replaces the __getattr__ in c by f->f0 anyway
     return f.field0 + f.field1 + f.field2
 
@@ -82,4 +135,85 @@
     return f.field0 + f.field1 + f.field2
 
+def check_pyobj(Foo f):
+    # compare the c code to the check_pyobj in getter2.pyx
+    return bool(f.field1)
+
+######## getter.pxd ########
+
+# Access base Foo fields from C via getter functions
+
+
+cdef extern from "foo.h":
+    ctypedef class foo_extension.Foo [object FooStructOpaque, check_size ignore]:
+        @property
+        cdef int fieldM0(self):
+            return PyFoo_GET0M(self)
+
+        @property
+        cdef int fieldF1(self):
+            return PyFoo_Get1F(self)
+
+        @property
+        cdef int fieldM2(self):
+            return PyFoo_GET2M(self)
+
+        @property
+        cdef int *vector(self):
+            return PyFoo_GetV(self)
+
+    int PyFoo_GET0M(Foo);  # this is actually a macro !
+    int PyFoo_Get1F(Foo);
+    int PyFoo_GET2M(Foo);  # this is actually a macro !
+    int *PyFoo_GetV(Foo);
+
+######## getter1.pyx ########
+
+cimport getter
+
+def sum(getter.Foo f):
+    # Note - not a cdef function but compiling the f.__getattr__('field0')
+    # notices the getter and replaces the __getattr__ in c by PyFoo_GET anyway
+    return f.fieldM0 + f.fieldF1 + f.fieldM2
+
+def check_10(getter.Foo f):
+    return f.fieldF1 != 10
+
+def vec0(getter.Foo f):
+    return f.vector[0]
+
+def check_binop(getter.Foo f):
+    return f.fieldF1 / 10
+
+######## getter2.pyx ########
+
+cimport getter
+
+def check_pyobj(getter.Foo f):
+    return bool(f.fieldF1)
+ 
+def check_unary(getter.Foo f):
+    return -f.fieldF1
+
+######## getter_fail0.pyx ########
+
+# Make sure not all decorators are accepted
+
+cdef extern from "foo.h":
+    ctypedef class foo_extension.Foo [object FooStructOpaque]:
+        @classmethod
+        cdef void field0():
+            print('in staticmethod of Foo')
+
+######## getter_fail1.pyx ########
+
+# Make sure not all decorators are accepted
+cimport cython
+
+cdef extern from "foo.h":
+    ctypedef class foo_extension.Foo [object FooStructOpaque]:
+        @prop.getter
+        cdef void field0(self):
+            pass
+
 ######## runner.py ########
 
@@ -84,4 +218,5 @@
 ######## runner.py ########
 
-import foo_extension, getter0
+import warnings
+import foo_extension, getter0, getter1, getter2
 
@@ -87,4 +222,9 @@
 
+def sum(f):
+    # pure python field access, but code is identical to cython cdef sum
+    return f.field0 + f.field1 + f.field2
+
+# Baseline test: if this fails something else is wrong
 foo = foo_extension.Foo(23, 123, 1023)
 
 assert foo.field0 == 23
@@ -92,7 +232,11 @@
 assert foo.field2 == 1023
 
 ret =  getter0.sum(foo)
-assert ret == foo.field0 + foo.field1 + foo.field2
+assert ret == sum(foo)
+
+# Aliasing test. Check 'cdef int field0 "f0" works as advertised:
+# - C can access the fields through the aliases
+# - Python cannot access the fields at all
 
 opaque_foo = foo_extension.OpaqueFoo(23, 123, 1023)
 
@@ -96,6 +240,5 @@
 
 opaque_foo = foo_extension.OpaqueFoo(23, 123, 1023)
 
-# C can access the fields through the aliases
 opaque_ret = getter0.sum(opaque_foo)
 assert opaque_ret == ret
@@ -100,3 +243,9 @@
 opaque_ret = getter0.sum(opaque_foo)
 assert opaque_ret == ret
+
+val = getter2.check_pyobj(opaque_foo)
+assert val is True
+val = getter2.check_unary(opaque_foo)
+assert val == -123
+
 try:
@@ -102,7 +251,6 @@
 try:
-    # Python cannot access the fields
     f0 = opaque_ret.field0
     assert False
 except AttributeError as e:
     pass
 
@@ -104,6 +252,9 @@
     f0 = opaque_ret.field0
     assert False
 except AttributeError as e:
     pass
 
+# Getter test. Check C-level getter works as advertised:
+# - C accesses the fields through getter calls (maybe macros)
+# - Python accesses the fields through attribute lookup
 
@@ -109,1 +260,6 @@
 
+opaque_foo = foo_extension.OpaqueFoo(23, 123, 1023, (1, 2, 3))
+
+opaque_ret = getter1.sum(opaque_foo)
+assert opaque_ret == ret
+
diff --git a/tests/run/extstarargs.pyx b/tests/run/extstarargs.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2V4dHN0YXJhcmdzLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2V4dHN0YXJhcmdzLnB5eA== 100644
--- a/tests/run/extstarargs.pyx
+++ b/tests/run/extstarargs.pyx
@@ -1,95 +1,3 @@
-__doc__ = u"""
-    >>> s = Silly(1,2,3, 'test')
-    >>> (spam,grail,swallow,creosote,onlyt,onlyk,tk) = (
-    ...     s.spam,s.grail,s.swallow,s.creosote,s.onlyt,s.onlyk,s.tk)
-
-    >>> spam(1,2,3)
-    (1, 2, 3)
-    >>> spam(1,2)
-    Traceback (most recent call last):
-    TypeError: spam() takes exactly 3 positional arguments (2 given)
-    >>> spam(1,2,3,4)
-    Traceback (most recent call last):
-    TypeError: spam() takes exactly 3 positional arguments (4 given)
-    >>> spam(1,2,3, a=1) #doctest: +ELLIPSIS
-    Traceback (most recent call last):
-    TypeError: spam() got an unexpected keyword argument 'a'
-
-    >>> grail(1,2,3)
-    (1, 2, 3, ())
-    >>> grail(1,2,3,4)
-    (1, 2, 3, (4,))
-    >>> grail(1,2,3,4,5,6,7,8,9)
-    (1, 2, 3, (4, 5, 6, 7, 8, 9))
-    >>> grail(1,2)
-    Traceback (most recent call last):
-    TypeError: grail() takes at least 3 positional arguments (2 given)
-    >>> grail(1,2,3, a=1) #doctest: +ELLIPSIS
-    Traceback (most recent call last):
-    TypeError: grail() got an unexpected keyword argument 'a'
-
-    >>> swallow(1,2,3)
-    (1, 2, 3, ())
-    >>> swallow(1,2,3,4)
-    Traceback (most recent call last):
-    TypeError: swallow() takes exactly 3 positional arguments (4 given)
-    >>> swallow(1,2,3, a=1, b=2)
-    (1, 2, 3, (('a', 1), ('b', 2)))
-    >>> swallow(1,2,3, x=1)
-    Traceback (most recent call last):
-    TypeError: swallow() got multiple values for keyword argument 'x'
-
-    >>> creosote(1,2,3)
-    (1, 2, 3, (), ())
-    >>> creosote(1,2,3,4)
-    (1, 2, 3, (4,), ())
-    >>> creosote(1,2,3, a=1)
-    (1, 2, 3, (), (('a', 1),))
-    >>> creosote(1,2,3,4, a=1, b=2)
-    (1, 2, 3, (4,), (('a', 1), ('b', 2)))
-    >>> creosote(1,2,3,4, x=1)
-    Traceback (most recent call last):
-    TypeError: creosote() got multiple values for keyword argument 'x'
-
-    >>> onlyt(1)
-    (1,)
-    >>> onlyt(1,2)
-    (1, 2)
-    >>> onlyt(a=1)
-    Traceback (most recent call last):
-    TypeError: onlyt() got an unexpected keyword argument 'a'
-    >>> onlyt(1, a=2)
-    Traceback (most recent call last):
-    TypeError: onlyt() got an unexpected keyword argument 'a'
-
-    >>> onlyk(a=1)
-    (('a', 1),)
-    >>> onlyk(a=1, b=2)
-    (('a', 1), ('b', 2))
-    >>> onlyk(1)
-    Traceback (most recent call last):
-    TypeError: onlyk() takes exactly 0 positional arguments (1 given)
-    >>> onlyk(1, 2)
-    Traceback (most recent call last):
-    TypeError: onlyk() takes exactly 0 positional arguments (2 given)
-    >>> onlyk(1, a=1, b=2)
-    Traceback (most recent call last):
-    TypeError: onlyk() takes exactly 0 positional arguments (1 given)
-
-    >>> tk(a=1)
-    (('a', 1),)
-    >>> tk(a=1, b=2)
-    (('a', 1), ('b', 2))
-    >>> tk(1)
-    (1,)
-    >>> tk(1, 2)
-    (1, 2)
-    >>> tk(1, a=1, b=2)
-    (1, ('a', 1), ('b', 2))
-"""
-
-import sys, re
-if sys.version_info >= (2,6):
-    __doc__ = re.sub(u"(ELLIPSIS[^>]*Error: )[^\n]*\n", u"\\1...\n", __doc__)
+cimport cython
 
 cdef sorteditems(d):
@@ -94,9 +2,8 @@
 
 cdef sorteditems(d):
-    l = list(d.items())
-    l.sort()
-    return tuple(l)
+    return tuple(sorted(d.items()))
+
 
 cdef class Silly:
 
     def __init__(self, *a):
@@ -99,7 +6,9 @@
 
 cdef class Silly:
 
     def __init__(self, *a):
-        pass
+        """
+        >>> s = Silly(1,2,3, 'test')
+        """
 
     def spam(self, x, y, z):
@@ -104,5 +13,19 @@
 
     def spam(self, x, y, z):
+        """
+        >>> s = Silly()
+        >>> s.spam(1,2,3)
+        (1, 2, 3)
+        >>> s.spam(1,2)
+        Traceback (most recent call last):
+        TypeError: spam() takes exactly 3 positional arguments (2 given)
+        >>> s.spam(1,2,3,4)
+        Traceback (most recent call last):
+        TypeError: spam() takes exactly 3 positional arguments (4 given)
+        >>> s.spam(1,2,3, a=1)
+        Traceback (most recent call last):
+        TypeError: spam() got an unexpected keyword argument 'a'
+        """
         return (x, y, z)
 
     def grail(self, x, y, z, *a):
@@ -106,6 +29,21 @@
         return (x, y, z)
 
     def grail(self, x, y, z, *a):
+        """
+        >>> s = Silly()
+        >>> s.grail(1,2,3)
+        (1, 2, 3, ())
+        >>> s.grail(1,2,3,4)
+        (1, 2, 3, (4,))
+        >>> s.grail(1,2,3,4,5,6,7,8,9)
+        (1, 2, 3, (4, 5, 6, 7, 8, 9))
+        >>> s.grail(1,2)
+        Traceback (most recent call last):
+        TypeError: grail() takes at least 3 positional arguments (2 given)
+        >>> s.grail(1,2,3, a=1)
+        Traceback (most recent call last):
+        TypeError: grail() got an unexpected keyword argument 'a'
+        """
         return (x, y, z, a)
 
     def swallow(self, x, y, z, **k):
@@ -109,6 +47,19 @@
         return (x, y, z, a)
 
     def swallow(self, x, y, z, **k):
+        """
+        >>> s = Silly()
+        >>> s.swallow(1,2,3)
+        (1, 2, 3, ())
+        >>> s.swallow(1,2,3,4)
+        Traceback (most recent call last):
+        TypeError: swallow() takes exactly 3 positional arguments (4 given)
+        >>> s.swallow(1,2,3, a=1, b=2)
+        (1, 2, 3, (('a', 1), ('b', 2)))
+        >>> s.swallow(1,2,3, x=1)
+        Traceback (most recent call last):
+        TypeError: swallow() got multiple values for keyword argument 'x'
+        """
         return (x, y, z, sorteditems(k))
 
     def creosote(self, x, y, z, *a, **k):
@@ -112,6 +63,20 @@
         return (x, y, z, sorteditems(k))
 
     def creosote(self, x, y, z, *a, **k):
+        """
+        >>> s = Silly()
+        >>> s.creosote(1,2,3)
+        (1, 2, 3, (), ())
+        >>> s.creosote(1,2,3,4)
+        (1, 2, 3, (4,), ())
+        >>> s.creosote(1,2,3, a=1)
+        (1, 2, 3, (), (('a', 1),))
+        >>> s.creosote(1,2,3,4, a=1, b=2)
+        (1, 2, 3, (4,), (('a', 1), ('b', 2)))
+        >>> s.creosote(1,2,3,4, x=1)
+        Traceback (most recent call last):
+        TypeError: creosote() got multiple values for keyword argument 'x'
+        """
         return (x, y, z, a, sorteditems(k))
 
     def onlyt(self, *a):
@@ -115,6 +80,38 @@
         return (x, y, z, a, sorteditems(k))
 
     def onlyt(self, *a):
+        """
+        >>> s = Silly()
+        >>> s.onlyt(1)
+        (1,)
+        >>> s.onlyt(1,2)
+        (1, 2)
+        >>> s.onlyt(a=1)
+        Traceback (most recent call last):
+        TypeError: onlyt() got an unexpected keyword argument 'a'
+        >>> s.onlyt(1, a=2)
+        Traceback (most recent call last):
+        TypeError: onlyt() got an unexpected keyword argument 'a'
+        """
+        return a
+
+    @cython.binding(False)  # passthrough of exact same tuple can't work with binding
+    def onlyt_nobinding(self, *a):
+        """
+        >>> s = Silly()
+        >>> s.onlyt_nobinding(1)
+        (1,)
+        >>> s.onlyt_nobinding(1,2)
+        (1, 2)
+        >>> s.onlyt_nobinding(a=1)
+        Traceback (most recent call last):
+        TypeError: onlyt_nobinding() got an unexpected keyword argument 'a'
+        >>> s.onlyt_nobinding(1, a=2)
+        Traceback (most recent call last):
+        TypeError: onlyt_nobinding() got an unexpected keyword argument 'a'
+        >>> test_no_copy_args(s.onlyt_nobinding)
+        True
+        """
         return a
 
     def onlyk(self, **k):
@@ -118,6 +115,22 @@
         return a
 
     def onlyk(self, **k):
+        """
+        >>> s = Silly()
+        >>> s.onlyk(a=1)
+        (('a', 1),)
+        >>> s.onlyk(a=1, b=2)
+        (('a', 1), ('b', 2))
+        >>> s.onlyk(1)
+        Traceback (most recent call last):
+        TypeError: onlyk() takes exactly 0 positional arguments (1 given)
+        >>> s.onlyk(1, 2)
+        Traceback (most recent call last):
+        TypeError: onlyk() takes exactly 0 positional arguments (2 given)
+        >>> s.onlyk(1, a=1, b=2)
+        Traceback (most recent call last):
+        TypeError: onlyk() takes exactly 0 positional arguments (1 given)
+        """
         return sorteditems(k)
 
     def tk(self, *a, **k):
@@ -121,4 +134,17 @@
         return sorteditems(k)
 
     def tk(self, *a, **k):
+        """
+        >>> s = Silly()
+        >>> s.tk(a=1)
+        (('a', 1),)
+        >>> s.tk(a=1, b=2)
+        (('a', 1), ('b', 2))
+        >>> s.tk(1)
+        (1,)
+        >>> s.tk(1, 2)
+        (1, 2)
+        >>> s.tk(1, a=1, b=2)
+        (1, ('a', 1), ('b', 2))
+        """
         return a + sorteditems(k)
@@ -124,1 +150,20 @@
         return a + sorteditems(k)
+
+    @cython.binding(False)  # passthrough of exact same tuple can't work with binding
+    def t_kwonly(self, *a, k):
+        """
+        >>> s = Silly()
+        >>> test_no_copy_args(s.t_kwonly, k=None)
+        True
+        """
+        return a
+
+
+def test_no_copy_args(func, **kw):
+    """
+    func is a function such that func(*args, **kw) returns args.
+    We test that no copy is made of the args tuple.
+    This tests both the caller side and the callee side.
+    """
+    args = (1, 2, 3)
+    return func(*args, **kw) is args
diff --git a/tests/run/exttype.pyx b/tests/run/exttype.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2V4dHR5cGUucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2V4dHR5cGUucHl4 100644
--- a/tests/run/exttype.pyx
+++ b/tests/run/exttype.pyx
@@ -1,2 +1,9 @@
+# mode: run
+# tag: exttype, tpnew
+
+from __future__ import print_function
+
+from cpython.object cimport PyTypeObject
+
 
 cdef gobble(a, b):
@@ -1,6 +8,45 @@
 
 cdef gobble(a, b):
-    print a, b
+    print(a, b)
+
+
+def tp_new_ptr(exttype):
+    assert isinstance(exttype, type)
+    tp = <PyTypeObject*> exttype
+    return <unsigned long long><void*>tp.tp_new
+
+
+cdef class Empty:
+    """
+    >>> n = Empty()
+    >>> isinstance(n, Empty)
+    True
+    >>> tp_new_ptr(Empty) != 0
+    True
+    """
+
+
+cdef class EmptySubclass(Empty):
+    """
+    >>> n = EmptySubclass()
+    >>> isinstance(n, EmptySubclass)
+    True
+    >>> tp_new_ptr(EmptySubclass) != 0
+    True
+    >>> tp_new_ptr(EmptySubclass) == tp_new_ptr(Empty)
+    True
+    """
+
+
+cdef class CInit:
+    """
+    >>> c = CInit()
+    >>> isinstance(c, CInit)
+    True
+    """
+    def __cinit__(self):
+        assert self is not None
+
 
 cdef class Spam:
     """
@@ -21,6 +67,7 @@
     def eat(self):
         gobble(self.eggs, self.ham)
 
+
 def f(Spam spam):
     """
     >>> s = Spam(12)
diff --git a/tests/run/fastcall.pyx b/tests/run/fastcall.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2Zhc3RjYWxsLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2Zhc3RjYWxsLnB5eA== 100644
--- a/tests/run/fastcall.pyx
+++ b/tests/run/fastcall.pyx
@@ -1,6 +1,8 @@
 # mode: run
 # tag: METH_FASTCALL
 
+cimport cython
+
 import sys
 import struct
 from collections import deque
@@ -63,3 +65,64 @@
     """
     def index_of_self(self, list orbit not None):
         return orbit.index(self)
+
+
+cdef extern from *:
+    int PyCFunction_GET_FLAGS(op)
+
+
+def has_fastcall(meth):
+    """
+    Given a builtin_function_or_method or cyfunction ``meth``,
+    return whether it uses ``METH_FASTCALL``.
+    """
+    # Hardcode METH_FASTCALL constant equal to 0x80 for simplicity
+    return bool(PyCFunction_GET_FLAGS(meth) & 0x80)
+
+
+def assert_fastcall(meth):
+    """
+    Assert that ``meth`` uses ``METH_FASTCALL`` if the Python
+    implementation supports it.
+    """
+    # getattr uses METH_FASTCALL on CPython >= 3.7
+    if has_fastcall(getattr) and not has_fastcall(meth):
+        raise AssertionError(f"{meth} does not use METH_FASTCALL")
+
+
+@cython.binding(False)
+def fastcall_function(**kw):
+    """
+    >>> assert_fastcall(fastcall_function)
+    """
+    return kw
+
+@cython.binding(True)
+def fastcall_cyfunction(**kw):
+    """
+    >>> assert_fastcall(fastcall_cyfunction)
+    """
+    return kw
+
+cdef class Dummy:
+    @cython.binding(False)
+    def fastcall_method(self, x, *args, **kw):
+        """
+        >>> assert_fastcall(Dummy().fastcall_method)
+        """
+        return tuple(args) + tuple(kw)
+
+cdef class CyDummy:
+    @cython.binding(True)
+    def fastcall_method(self, x, *args, **kw):
+        """
+        >>> assert_fastcall(CyDummy.fastcall_method)
+        """
+        return tuple(args) + tuple(kw)
+
+class PyDummy:
+    def fastcall_method(self, x, *args, **kw):
+        """
+        >>> assert_fastcall(PyDummy.fastcall_method)
+        """
+        return tuple(args) + tuple(kw)
diff --git a/tests/run/fstring.pyx b/tests/run/fstring.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2ZzdHJpbmcucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2ZzdHJpbmcucHl4 100644
--- a/tests/run/fstring.pyx
+++ b/tests/run/fstring.pyx
@@ -18,6 +18,65 @@
 
 
 @cython.test_fail_if_path_exists(
+    "//JoinedStrNode",
+)
+@cython.test_assert_path_exists(
+    "//AddNode",
+)
+def concat_strings(a, b):
+    """
+    >>> concat_strings("", "")
+    x
+    <BLANKLINE>
+    x
+    x
+    x
+    xx
+    >>> concat_strings("a", "")
+    ax
+    a
+    x
+    ax
+    ax
+    axx
+    >>> concat_strings("", "b")
+    x
+    b
+    xb
+    xb
+    xb
+    xxb
+    >>> concat_strings("a", "b")
+    ax
+    ab
+    xb
+    axb
+    axb
+    axxb
+    >>> concat_strings("".join(["a", "b"]), "")  # fresh temp string left
+    abx
+    ab
+    x
+    abx
+    abx
+    abxx
+    >>> concat_strings("", "".join(["a", "b"]))  # fresh temp string right
+    x
+    ab
+    xab
+    xab
+    xab
+    xxab
+    """
+    print(f"{a}x")
+    print(f"{a}{b}")
+    print(f"x{b}")
+    print(f"{a+'x'}{b}")      # fresh temp string left
+    print(f"{a}{'x'+b}")      # fresh temp string right
+    print(f"{a+'x'}{'x'+b}")  # fresh temp strings right and left
+
+
+@cython.test_fail_if_path_exists(
     "//FormattedValueNode",
     "//JoinedStrNode",
     "//AddNode",
diff --git a/tests/run/function_as_method_T494.pyx b/tests/run/function_as_method_T494.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2Z1bmN0aW9uX2FzX21ldGhvZF9UNDk0LnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2Z1bmN0aW9uX2FzX21ldGhvZF9UNDk0LnB5eA== 100644
--- a/tests/run/function_as_method_T494.pyx
+++ b/tests/run/function_as_method_T494.pyx
@@ -12,3 +12,39 @@
 
 def foo(self):
     return self is not None
+
+# assignment of functions used in a "static method" type way behaves differently
+# in Python2 and 3
+import sys
+if sys.version_info[0] == 2:
+    __doc__ = """>>> B.plus1(1) #doctest: +IGNORE_EXCEPTION_DETAIL
+Traceback (most recent call last):
+    ...
+TypeError: unbound
+"""
+else:
+    __doc__ = """>>> B.plus1(1)
+2
+"""
+
+# with binding==False assignment of functions always worked - doesn't match Python
+# behaviour but ensures Cython behaviour stays consistent
+__doc__ += """
+>>> B.plus1_nobind(1)
+2
+"""
+
+cimport cython
+
+def f_plus(a):
+    return a + 1
+
+@cython.binding(False)
+def f_plus_nobind(a):
+    return a+1
+
+cdef class B:
+    plus1 = f_plus
+    plus1_nobind = f_plus_nobind
+
+
diff --git a/tests/run/function_as_method_py_T494.py b/tests/run/function_as_method_py_T494.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2Z1bmN0aW9uX2FzX21ldGhvZF9weV9UNDk0LnB5..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2Z1bmN0aW9uX2FzX21ldGhvZF9weV9UNDk0LnB5 100644
--- a/tests/run/function_as_method_py_T494.py
+++ b/tests/run/function_as_method_py_T494.py
@@ -11,3 +11,35 @@
 
 def foo(self):
     return self is not None
+
+
+# assignment of functions used in a "static method" type way behaves differently
+# in Python2 and 3
+import sys
+if sys.version_info[0] == 2:
+    __doc__ = u"""
+>>> B.plus1(1) #doctest: +IGNORE_EXCEPTION_DETAIL
+Traceback (most recent call last):
+    ...
+TypeError: unbound
+>>> C.plus1(1) #doctest: +IGNORE_EXCEPTION_DETAIL
+Traceback (most recent call last):
+    ...
+TypeError: unbound
+"""
+else:
+    __doc__ = u"""
+>>> B.plus1(1)
+2
+>>> C.plus1(1)
+2
+"""
+
+def f_plus(a):
+    return a + 1
+
+class B:
+    plus1 = f_plus
+
+class C(object):
+    plus1 = f_plus
diff --git a/tests/run/fused_bound_functions.py b/tests/run/fused_bound_functions.py
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2Z1c2VkX2JvdW5kX2Z1bmN0aW9ucy5weQ==
--- /dev/null
+++ b/tests/run/fused_bound_functions.py
@@ -0,0 +1,151 @@
+# mode: run
+# tag: pure3.0
+# cython: binding=True
+
+"""
+Test that fused functions can be used in the same way as CyFunctions with respect to
+assigning them to class attributes. Previously they enforced extra type/argument checks
+beyond those which CyFunctions did.
+"""
+
+import cython
+
+MyFusedClass = cython.fused_type(
+    float,
+    'Cdef',
+    object)
+
+def fused_func(x: MyFusedClass):
+    return (type(x).__name__, cython.typeof(x))
+
+IntOrFloat = cython.fused_type(int, float)
+
+def fused_func_0(x: IntOrFloat = 0):
+    """
+    Fused functions can legitimately take 0 arguments
+    >>> fused_func_0()
+    ('int', 'int')
+
+    # subscripted in module __doc__ conditionally
+    """
+    return (type(x).__name__, cython.typeof(x))
+
+def regular_func(x):
+    return (type(x).__name__, cython.typeof(x))
+
+def regular_func_0():
+    return
+
+@cython.cclass
+class Cdef:
+    __doc__ = """
+    >>> c = Cdef()
+
+    # functions are callable with an instance of c
+    >>> c.fused_func()
+    ('Cdef', 'Cdef')
+    >>> c.regular_func()
+    ('Cdef', '{typeofCdef}')
+    >>> c.fused_in_class(1.5)
+    ('float', 'float')
+
+    # Fused functions are callable without an instance
+    # (This applies to everything in Py3 - see __doc__ below)
+    >>> Cdef.fused_func(1.5)
+    ('float', 'float')
+    >>> Cdef.fused_in_class(c, 1.5)
+    ('float', 'float')
+    >>> Cdef.fused_func_0()
+    ('int', 'int')
+
+    # Functions not expecting an argument don't work with an instance
+    >>> c.regular_func_0()  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    TypeError: regular_func_0() takes ... arguments ...1... given...
+    """.format(typeofCdef = 'Python object' if cython.compiled else 'Cdef')
+
+    if cython.compiled:
+        __doc__ += """
+
+    # fused_func_0 does not accept a "Cdef" instance
+    >>> c.fused_func_0()
+    Traceback (most recent call last):
+    TypeError: No matching signature found
+
+    # subscripting requires fused methods (so  not pure Python)
+    >>> Cdef.fused_func_0['float']()
+    ('float', 'float')
+    >>> c.fused_func_0['float']()  # doctest: +IGNORE_EXCEPTION_DETAIL
+    Traceback (most recent call last):
+    TypeError: (Exception looks quite different in Python2 and 3 so no way to match both)
+    """
+    fused_func = fused_func
+    fused_func_0 = fused_func_0
+    regular_func = regular_func
+    regular_func_0 = regular_func_0
+
+    def fused_in_class(self, x: MyFusedClass):
+        return (type(x).__name__, cython.typeof(x))
+
+    def regular_in_class(self):
+        return type(self).__name__
+
+class Regular(object):
+    __doc__ = """
+    >>> c = Regular()
+
+    # Functions are callable with an instance of C
+    >>> c.fused_func()
+    ('Regular', '{typeofRegular}')
+    >>> c.regular_func()
+    ('Regular', '{typeofRegular}')
+
+    # Fused functions are callable without an instance
+    # (This applies to everything in Py3 - see __doc__ below)
+    >>> Regular.fused_func(1.5)
+    ('float', 'float')
+    >>> Regular.fused_func_0()
+    ('int', 'int')
+
+    # Functions not expecting an argument don't work with an instance
+    >>> c.regular_func_0()  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    TypeError: regular_func_0() takes ... arguments ...1... given...
+    """.format(typeofRegular = "Python object" if cython.compiled else 'Regular')
+    if cython.compiled:
+        __doc__ += """
+    # fused_func_0 does not accept a "Regular" instance
+    >>> c.fused_func_0()
+    Traceback (most recent call last):
+    TypeError: No matching signature found
+
+    # subscripting requires fused methods (so  not pure Python)
+    >>> c.fused_func_0['float']()  # doctest: +IGNORE_EXCEPTION_DETAIL
+    Traceback (most recent call last):
+    TypeError: (Exception looks quite different in Python2 and 3 so no way to match both)
+    >>> Regular.fused_func_0['float']()
+    ('float', 'float')
+    """
+
+    fused_func = fused_func
+    fused_func_0 = fused_func_0
+    regular_func = regular_func
+    regular_func_0 = regular_func_0
+
+import sys
+if sys.version_info[0] > 2:
+    # extra Py3 only tests - shows that functions added to a class can be called
+    # with an type as the first argument
+    __doc__ = """
+    >>> Cdef.regular_func(1.5)
+    ('float', '{typeoffloat}')
+    >>> Regular.regular_func(1.5)
+    ('float', '{typeoffloat}')
+    >>> Cdef.regular_func_0()
+    >>> Regular.regular_func_0()
+    """.format(typeoffloat='Python object' if cython.compiled else 'float')
+if cython.compiled:
+    __doc__ += """
+    >>> fused_func_0['float']()
+    ('float', 'float')
+    """
diff --git a/tests/run/fused_cpdef.pyx b/tests/run/fused_cpdef.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2Z1c2VkX2NwZGVmLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2Z1c2VkX2NwZGVmLnB5eA== 100644
--- a/tests/run/fused_cpdef.pyx
+++ b/tests/run/fused_cpdef.pyx
@@ -1,1 +1,4 @@
+# cython: language_level=3
+# mode: run
+
 cimport cython
@@ -1,5 +4,6 @@
 cimport cython
+import sys, io
 
 cy = __import__("cython")
 
 cpdef func1(self, cython.integral x):
@@ -2,6 +6,6 @@
 
 cy = __import__("cython")
 
 cpdef func1(self, cython.integral x):
-    print "%s," % (self,),
+    print(f"{self},", end=' ')
     if cython.integral is int:
@@ -7,3 +11,3 @@
     if cython.integral is int:
-        print 'x is int', x, cython.typeof(x)
+        print('x is int', x, cython.typeof(x))
     else:
@@ -9,5 +13,5 @@
     else:
-        print 'x is long', x, cython.typeof(x)
+        print('x is long', x, cython.typeof(x))
 
 
 class A(object):
@@ -16,6 +20,18 @@
     def __str__(self):
         return "A"
 
+cdef class B:
+    cpdef int meth(self, cython.integral x):
+        print(f"{self},", end=' ')
+        if cython.integral is int:
+            print('x is int', x, cython.typeof(x))
+        else:
+            print('x is long', x, cython.typeof(x))
+        return 0
+
+    def __str__(self):
+        return "B"
+
 pyfunc = func1
 
 def test_fused_cpdef():
@@ -32,8 +48,10 @@
     A, x is long 2 long
     A, x is long 2 long
     A, x is long 2 long
+    <BLANKLINE>
+    B, x is long 2 long
     """
     func1[int](None, 2)
     func1[long](None, 2)
     func1(None, 2)
 
@@ -35,10 +53,10 @@
     """
     func1[int](None, 2)
     func1[long](None, 2)
     func1(None, 2)
 
-    print
+    print()
 
     pyfunc[cy.int](None, 2)
     pyfunc(None, 2)
 
@@ -41,11 +59,11 @@
 
     pyfunc[cy.int](None, 2)
     pyfunc(None, 2)
 
-    print
+    print()
 
     A.meth[cy.int](A(), 2)
     A.meth(A(), 2)
     A().meth[cy.long](2)
     A().meth(2)
 
@@ -46,9 +64,55 @@
 
     A.meth[cy.int](A(), 2)
     A.meth(A(), 2)
     A().meth[cy.long](2)
     A().meth(2)
 
+    print()
+
+    B().meth(2)
+
+
+midimport_run = io.StringIO()
+if sys.version_info.major < 3:
+    # Monkey-patch midimport_run.write to accept non-unicode strings under Python 2.
+    midimport_run.write = lambda c: io.StringIO.write(midimport_run, unicode(c))
+
+realstdout = sys.stdout
+sys.stdout = midimport_run
+
+try:
+    # Run `test_fused_cpdef()` during import and save the result for
+    #        `test_midimport_run()`.
+    test_fused_cpdef()
+except Exception as e:
+    midimport_run.write(f"{e!r}\n")
+finally:
+    sys.stdout = realstdout
+
+def test_midimport_run():
+    # At one point, dynamically calling fused cpdef functions during import
+    #        would fail because the type signature-matching indices weren't
+    #        yet initialized.
+    #        (See Compiler.FusedNode.FusedCFuncDefNode._fused_signature_index,
+    #        GH-3366.)
+    """
+    >>> test_midimport_run()
+    None, x is int 2 int
+    None, x is long 2 long
+    None, x is long 2 long
+    <BLANKLINE>
+    None, x is int 2 int
+    None, x is long 2 long
+    <BLANKLINE>
+    A, x is int 2 int
+    A, x is long 2 long
+    A, x is long 2 long
+    A, x is long 2 long
+    <BLANKLINE>
+    B, x is long 2 long
+    """
+    print(midimport_run.getvalue(), end='')
+
 
 def assert_raise(func, *args):
     try:
@@ -70,8 +134,16 @@
     assert_raise(A.meth)
     assert_raise(A().meth[cy.int])
     assert_raise(A.meth[cy.int])
+    assert_raise(B().meth, 1, 2, 3)
+
+def test_nomatch():
+    """
+    >>> func1(None, ())
+    Traceback (most recent call last):
+    TypeError: No matching signature found
+    """
 
 ctypedef long double long_double
 
 cpdef multiarg(cython.integral x, cython.floating y):
     if cython.integral is int:
@@ -73,7 +145,7 @@
 
 ctypedef long double long_double
 
 cpdef multiarg(cython.integral x, cython.floating y):
     if cython.integral is int:
-        print "x is an int,",
+        print("x is an int,", end=' ')
     else:
@@ -79,4 +151,4 @@
     else:
-        print "x is a long,",
+        print("x is a long,", end=' ')
 
     if cython.floating is long_double:
@@ -81,4 +153,4 @@
 
     if cython.floating is long_double:
-        print "y is a long double:",
+        print("y is a long double:", end=' ')
     elif float is cython.floating:
@@ -84,3 +156,3 @@
     elif float is cython.floating:
-        print "y is a float:",
+        print("y is a float:", end=' ')
     else:
@@ -86,3 +158,3 @@
     else:
-        print "y is a double:",
+        print("y is a double:", end=' ')
 
@@ -88,5 +160,5 @@
 
-    print x, y
+    print(x, y)
 
 def test_multiarg():
     """
@@ -104,3 +176,13 @@
     multiarg[int, float](1, 2.0)
     multiarg[cy.int, cy.float](1, 2.0)
     multiarg(4, 5.0)
+
+def test_ambiguousmatch():
+    """
+    >>> multiarg(5, ())
+    Traceback (most recent call last):
+    TypeError: Function call with ambiguous argument types
+    >>> multiarg((), 2.0)
+    Traceback (most recent call last):
+    TypeError: Function call with ambiguous argument types
+    """
diff --git a/tests/run/fused_cpp.pyx b/tests/run/fused_cpp.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2Z1c2VkX2NwcC5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2Z1c2VkX2NwcC5weXg= 100644
--- a/tests/run/fused_cpp.pyx
+++ b/tests/run/fused_cpp.pyx
@@ -2,6 +2,8 @@
 
 cimport cython
 from libcpp.vector cimport vector
+from libcpp.typeinfo cimport type_info
+from cython.operator cimport typeid
 
 def test_cpp_specialization(cython.floating element):
     """
@@ -14,3 +16,28 @@
     cdef vector[cython.floating] *v = new vector[cython.floating]()
     v.push_back(element)
     print cython.typeof(v), cython.typeof(element), v.at(0)
+
+cdef fused C:
+   int
+   object
+
+cdef const type_info* tidint = &typeid(int)
+def typeid_call(C x):
+    """
+    For GH issue 3203
+    >>> typeid_call(1)
+    True
+    """
+    cdef const type_info* a = &typeid(C)
+    return a[0] == tidint[0]
+
+cimport cython
+
+def typeid_call2(cython.integral x):
+    """
+    For GH issue 3203
+    >>> typeid_call2[int](1)
+    True
+    """
+    cdef const type_info* a = &typeid(cython.integral)
+    return a[0] == tidint[0]
diff --git a/tests/run/fused_def.pyx b/tests/run/fused_def.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2Z1c2VkX2RlZi5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2Z1c2VkX2RlZi5weXg= 100644
--- a/tests/run/fused_def.pyx
+++ b/tests/run/fused_def.pyx
@@ -54,5 +54,6 @@
 i = 9
 
 
-def opt_func(fused_t obj, cython.floating myf = 1.2, cython.integral myi = 7):
+def opt_func(fused_t obj, cython.floating myf = 1.2, cython.integral myi = 7,
+             another_opt = 2, yet_another_opt=3):
     """
@@ -58,5 +59,8 @@
     """
-    Test runtime dispatch, indexing of various kinds and optional arguments
+    Test runtime dispatch, indexing of various kinds and optional arguments.
+    Use 5 arguments because at one point the optional argument from the
+    5th argument was overwriting that of the __pyx_fused dispatcher.
+    https://github.com/cython/cython/issues/3511
 
     >>> opt_func("spam", f, i)
     str object double long
@@ -121,5 +125,5 @@
     >>> opt_func()
     Traceback (most recent call last):
     TypeError: Expected at least 1 argument, got 0
-    >>> opt_func("abc", f, i, 5)  # doctest: +ELLIPSIS
+    >>> opt_func("abc", f, i, 5, 5, 5)  # doctest: +ELLIPSIS
     Traceback (most recent call last):
@@ -125,5 +129,5 @@
     Traceback (most recent call last):
-    TypeError: ...at most 3...
+    TypeError: ...at most 5...
     >>> opt_func[ExtClassA, cy.float, cy.long](object(), f)
     Traceback (most recent call last):
     TypeError: Argument 'obj' has incorrect type (expected fused_def.ExtClassA, got object)
@@ -154,9 +158,9 @@
 def test_opt_func_introspection():
     """
     >>> opt_func.__defaults__
-    (1.2, 7)
+    (1.2, 7, 2, 3)
     >>> opt_func.__kwdefaults__
     >>> opt_func.__annotations__
     {}
 
     >>> opt_func[str, float, int].__defaults__
@@ -158,11 +162,11 @@
     >>> opt_func.__kwdefaults__
     >>> opt_func.__annotations__
     {}
 
     >>> opt_func[str, float, int].__defaults__
-    (1.2, 7)
+    (1.2, 7, 2, 3)
     >>> opt_func[str, float, int].__kwdefaults__
     >>> opt_func[str, float, int].__annotations__
     {}
 
     >>> opt_func[str, cy.double, cy.long].__defaults__
@@ -164,9 +168,9 @@
     >>> opt_func[str, float, int].__kwdefaults__
     >>> opt_func[str, float, int].__annotations__
     {}
 
     >>> opt_func[str, cy.double, cy.long].__defaults__
-    (1.2, 7)
+    (1.2, 7, 2, 3)
     >>> opt_func[str, cy.double, cy.long].__kwdefaults__
     >>> opt_func[str, cy.double, cy.long].__annotations__
     {}
diff --git a/tests/run/fused_types.pyx b/tests/run/fused_types.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2Z1c2VkX3R5cGVzLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2Z1c2VkX3R5cGVzLnB5eA== 100644
--- a/tests/run/fused_types.pyx
+++ b/tests/run/fused_types.pyx
@@ -1,4 +1,5 @@
 # mode: run
+# ticket: 1772
 
 cimport cython
 from cython.view cimport array
@@ -20,6 +21,7 @@
 ctypedef int *p_int
 fused_type3 = cython.fused_type(int, double)
 fused_composite = cython.fused_type(fused_type2, fused_type3)
+just_float = cython.fused_type(float)
 
 def test_pure():
     """
@@ -361,6 +363,22 @@
     """
     print cython.typeof(array1), cython.typeof(array2), cython.typeof(array3)
 
+def test_fused_const_memslice_dtype_repeated(const cython.floating[:] array1, cython.floating[:] array2):
+    """Test fused types memory view with one being const
+
+    >>> sorted(test_fused_const_memslice_dtype_repeated.__signatures__)
+    ['double', 'float']
+
+    >>> test_fused_const_memslice_dtype_repeated(get_array(8, 'd'), get_array(8, 'd'))
+    const double[:] double[:]
+    >>> test_fused_const_memslice_dtype_repeated(get_array(4, 'f'), get_array(4, 'f'))
+    const float[:] float[:]
+    >>> test_fused_const_memslice_dtype_repeated(get_array(8, 'd'), get_array(4, 'f'))
+    Traceback (most recent call last):
+    ValueError: Buffer dtype mismatch, expected 'double' but got 'float'
+    """
+    print cython.typeof(array1), cython.typeof(array2)
+
 def test_cython_numeric(cython.numeric arg):
     """
     Test to see whether complex numbers have their utility code declared
@@ -386,6 +404,18 @@
     """
     _test_index_fused_args[cython.floating, ints_t](f, i)
 
+cdef _test_index_const_fused_args(const cython.floating f, const ints_t i):
+    print(cython.typeof(f), cython.typeof(i))
+
+def test_index_const_fused_args(const cython.floating f, const ints_t i):
+    """Test indexing function implementation with const fused type args
+
+    >>> import cython
+    >>> test_index_const_fused_args[cython.double, cython.int](2.0, 3)
+    ('const double', 'const int')
+    """
+    _test_index_const_fused_args[cython.floating, ints_t](f, i)
+
 
 def test_composite(fused_composite x):
     """
@@ -400,3 +430,57 @@
         return x
     else:
         return 2 * x
+
+
+cdef cdef_func_const_fused_arg(const cython.floating val,
+                               const fused_type1 * ptr_to_const,
+                               const (cython.floating *) const_ptr):
+    print(val, cython.typeof(val))
+    print(ptr_to_const[0], cython.typeof(ptr_to_const[0]))
+    print(const_ptr[0], cython.typeof(const_ptr[0]))
+
+    ptr_to_const = NULL  # pointer is not const, value is const
+    const_ptr[0] = 0.0  # pointer is const, value is not const
+
+def test_cdef_func_with_const_fused_arg():
+    """Test cdef function with const fused type argument
+
+    >>> test_cdef_func_with_const_fused_arg()
+    (0.0, 'const float')
+    (1, 'const int')
+    (2.0, 'float')
+    """
+    cdef float arg0 = 0.0
+    cdef int arg1 = 1
+    cdef float arg2 = 2.0
+    cdef_func_const_fused_arg(arg0, &arg1, &arg2)
+
+
+cdef in_check_1(just_float x):
+    return just_float in floating
+
+cdef in_check_2(just_float x, floating y):
+    # the "floating" on the right-hand side of the in statement should not be specialized
+    # - the test should still work.
+    return just_float in floating
+
+cdef in_check_3(floating x):
+    # the floating on the left-hand side of the in statement should be specialized
+    # but the one of the right-hand side should not (so that the test can still work).
+    return floating in floating
+
+def test_fused_in_check():
+    """
+    It should be possible to use fused types on in "x in ...fused_type" statements
+    even if that type is specialized in the function.
+
+    >>> test_fused_in_check()
+    True
+    True
+    True
+    True
+    """
+    print(in_check_1(1.0))
+    print(in_check_2(1.0, 2.0))
+    print(in_check_2[float, double](1.0, 2.0))
+    print(in_check_3[float](1.0))
diff --git a/tests/run/generators.pyx b/tests/run/generators.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2dlbmVyYXRvcnMucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2dlbmVyYXRvcnMucHl4 100644
--- a/tests/run/generators.pyx
+++ b/tests/run/generators.pyx
@@ -504,6 +504,26 @@
     yield 1
 
 
+def test_generator_frame(a=1):
+    """
+    >>> gen = test_generator_frame()
+    >>> import types
+    >>> isinstance(gen.gi_frame, types.FrameType) or gen.gi_frame
+    True
+    >>> gen.gi_frame is gen.gi_frame  # assert that it's cached
+    True
+    >>> gen.gi_frame.f_code is not None
+    True
+    >>> code_obj = gen.gi_frame.f_code
+    >>> code_obj.co_argcount
+    1
+    >>> code_obj.co_varnames
+    ('a', 'b')
+    """
+    b = a + 1
+    yield b
+
+
 # GH Issue 3265 - **kwds could cause a crash in some cases due to not
 # handling NULL pointers (in testing it shows as a REFNANNY error).
 # This was on creation of the generator and
diff --git a/tests/run/generators_py35.py b/tests/run/generators_py35.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2dlbmVyYXRvcnNfcHkzNS5weQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2dlbmVyYXRvcnNfcHkzNS5weQ== 100644
--- a/tests/run/generators_py35.py
+++ b/tests/run/generators_py35.py
@@ -30,6 +30,6 @@
     >>> next(gen)
     2.0
     >>> ret, arg = sorted(anno_gen.__annotations__.items())
-    >>> print(ret[0]); print(ret[1])
+    >>> print(ret[0]); print(str(ret[1]).strip("'")) # strip makes it pass with/without PEP563
     return
     float
@@ -34,6 +34,6 @@
     return
     float
-    >>> print(arg[0]); print(arg[1])
+    >>> print(arg[0]); print(str(arg[1]).strip("'"))
     x
     int
     """
diff --git a/tests/run/if_and_or.pyx b/tests/run/if_and_or.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2lmX2FuZF9vci5weXg=
--- /dev/null
+++ b/tests/run/if_and_or.pyx
@@ -0,0 +1,119 @@
+# mode: run
+# tag: if, and, or
+
+def if_x(x):
+    """
+    >>> if_x(0)
+    2
+    >>> if_x(1)
+    1
+    """
+    if x:
+        return 1
+    else:
+        return 2
+
+def if_not(x):
+    """
+    >>> if_not(0)
+    1
+    >>> if_not(1)
+    2
+    """
+    if not x:
+        return 1
+    else:
+        return 2
+
+
+def if_and(a, b):
+    """
+    >>> if_and(3, 0)
+    2
+    >>> if_and(0, 3)
+    2
+    >>> if_and(0, 0)
+    2
+    >>> if_and(3, 3)
+    1
+    """
+    if a and b:
+        return 1
+    else:
+        return 2
+
+
+def if_not_and(a, b):
+    """
+    >>> if_not_and(3, 0)
+    1
+    >>> if_not_and(0, 3)
+    1
+    >>> if_not_and(0, 0)
+    1
+    >>> if_not_and(3, 3)
+    2
+    """
+    if not (a and b):
+        return 1
+    else:
+        return 2
+
+
+def if_or(a, b):
+    """
+    >>> if_or(3, 0)
+    1
+    >>> if_or(0, 3)
+    1
+    >>> if_or(0, 0)
+    2
+    >>> if_or(3, 3)
+    1
+    """
+    if a or b:
+        return 1
+    else:
+        return 2
+
+
+def if_not_or(a, b):
+    """
+    >>> if_not_or(3, 0)
+    2
+    >>> if_not_or(0, 3)
+    2
+    >>> if_not_or(0, 0)
+    1
+    >>> if_not_or(3, 3)
+    2
+    """
+    if not (a or b):
+        return 1
+    else:
+        return 2
+
+
+def if_and_or(a, b, c, d):
+    """
+    >>> if_and_or(3, 0, 0, 3)
+    1
+    >>> if_and_or(0, 3, 0, 3)
+    1
+    >>> if_and_or(0, 3, 3, 0)
+    1
+    >>> if_and_or(0, 3, 3, 0)
+    1
+    >>> if_and_or(0, 0, 0, 0)
+    2
+    >>> if_and_or(0, 3, 0, 0)
+    2
+    >>> if_and_or(0, 0, 3, 0)
+    2
+    >>> if_and_or(0, 0, 0, 3)
+    2
+    """
+    if (a or b) and (c or d):
+        return 1
+    else:
+        return 2
diff --git a/tests/run/importas.pyx b/tests/run/importas.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2ltcG9ydGFzLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2ltcG9ydGFzLnB5eA== 100644
--- a/tests/run/importas.pyx
+++ b/tests/run/importas.pyx
@@ -1,1 +1,4 @@
+# mode: run
+# tag: all_language_levels
+
 __doc__ = u"""
@@ -1,4 +4,11 @@
 __doc__ = u"""
+>>> try: sys
+... except NameError: pass
+... else: print("sys was defined!")
+>>> try: distutils
+... except NameError: pass
+... else: print("distutils was defined!")
+
 >>> import sys as sous
 >>> import distutils.core as corey
 >>> from copy import deepcopy as copey
diff --git a/tests/run/importfrom.pyx b/tests/run/importfrom.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2ltcG9ydGZyb20ucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2ltcG9ydGZyb20ucHl4 100644
--- a/tests/run/importfrom.pyx
+++ b/tests/run/importfrom.pyx
@@ -68,6 +68,10 @@
     try:
         from sys import version_info as maxunicode
     except TypeError, e:
+        if getattr(sys, "pypy_version_info", None):
+            # translate message
+            if e.args[0].startswith("int() argument must be"):
+                e = "an integer is required"
         print(e)
 
     try:
diff --git a/tests/run/initial_file_path.srctree b/tests/run/initial_file_path.srctree
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2luaXRpYWxfZmlsZV9wYXRoLnNyY3RyZWU=..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2luaXRpYWxfZmlsZV9wYXRoLnNyY3RyZWU= 100644
--- a/tests/run/initial_file_path.srctree
+++ b/tests/run/initial_file_path.srctree
@@ -29,8 +29,8 @@
     traceback.print_exc()
 
 def test():
-    print "FILE: ", initial_file
-    print "PATH: ", initial_path
+    print("FILE: ", initial_file)
+    print("PATH: ", initial_path)
     assert initial_path[0].endswith('my_test_package'), initial_path
     assert initial_file.endswith('__init__.py'), initial_file
     assert import_error is None, import_error
@@ -51,8 +51,8 @@
     traceback.print_exc()
 
 def test():
-    print "FILE: ", initial_file
-    print "PATH: ", initial_path
+    print("FILE: ", initial_file)
+    print("PATH: ", initial_path)
     assert initial_path[0].endswith('another'), initial_path
     assert initial_file.endswith('__init__.py'), initial_file
     assert import_error is None, import_error
diff --git a/tests/run/isnot.pyx b/tests/run/isnot.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2lzbm90LnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2lzbm90LnB5eA== 100644
--- a/tests/run/isnot.pyx
+++ b/tests/run/isnot.pyx
@@ -3,8 +3,13 @@
 
 cimport cython
 
+# Use a single global object for identity checks.
+# PyPy can optimise away integer objects, for example, and may fail the 'is' test.
+obj = object()
+
+
 @cython.test_fail_if_path_exists('//NotNode')
 def is_not(a, b):
     """
     >>> is_not(1, 2)
     True
@@ -6,9 +11,9 @@
 @cython.test_fail_if_path_exists('//NotNode')
 def is_not(a, b):
     """
     >>> is_not(1, 2)
     True
-    >>> x = 1
+    >>> x = obj
     >>> is_not(x, x)
     False
     """
@@ -20,7 +25,7 @@
     """
     >>> not_is_not(1, 2)
     False
-    >>> x = 1
+    >>> x = obj
     >>> not_is_not(x, x)
     True
     """
@@ -32,7 +37,7 @@
     """
     >>> not_is(1, 2)
     True
-    >>> x = 1
+    >>> x = obj
     >>> not_is(x, x)
     False
     """
diff --git a/tests/run/iterdict.pyx b/tests/run/iterdict.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2l0ZXJkaWN0LnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2l0ZXJkaWN0LnB5eA== 100644
--- a/tests/run/iterdict.pyx
+++ b/tests/run/iterdict.pyx
@@ -555,3 +555,19 @@
     for k, v in dict(*args, **kwargs).iteritems():
         result.append((k, v))
     return result
+
+
+cdef class NotADict:
+    """
+    >>> NotADict().listvalues()  # doctest: +IGNORE_EXCEPTION_DETAIL
+    Traceback (most recent call last):
+    ...
+    TypeError: descriptor 'values' for 'mappingproxy' objects doesn't apply to a 'iterdict.NotADict' object
+    """
+    cdef long v
+    def __cinit__(self):
+        self.v = 1
+    itervalues = type(object.__dict__).values
+
+    def listvalues(self):
+        return [v for v in self.itervalues()]
diff --git a/tests/run/knuth_man_or_boy_test.pyx b/tests/run/knuth_man_or_boy_test.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2tudXRoX21hbl9vcl9ib3lfdGVzdC5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2tudXRoX21hbl9vcl9ib3lfdGVzdC5weXg= 100644
--- a/tests/run/knuth_man_or_boy_test.pyx
+++ b/tests/run/knuth_man_or_boy_test.pyx
@@ -46,6 +46,8 @@
 def a(in_k, x1, x2, x3, x4, x5):
     """
     >>> import sys
-    >>> sys.setrecursionlimit(1350)
+    >>> old_limit = sys.getrecursionlimit()
+    >>> sys.setrecursionlimit(1350 if not getattr(sys, 'pypy_version_info', None) else 2700)
+
     >>> a(10, 1, -1, -1, 1, 0)
     -67
@@ -50,5 +52,7 @@
     >>> a(10, 1, -1, -1, 1, 0)
     -67
+
+    >>> sys.setrecursionlimit(old_limit)
     """
     k = [in_k]
     def b():
diff --git a/tests/run/kwargproblems.pyx b/tests/run/kwargproblems.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2t3YXJncHJvYmxlbXMucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2t3YXJncHJvYmxlbXMucHl4 100644
--- a/tests/run/kwargproblems.pyx
+++ b/tests/run/kwargproblems.pyx
@@ -4,7 +4,7 @@
     >>> d = {1 : 2}
     >>> test(**d)       # doctest: +ELLIPSIS
     Traceback (most recent call last):
-    TypeError: ...keywords must be strings
+    TypeError: ...keywords must be strings...
     >>> d
     {1: 2}
     >>> d = {}
diff --git a/tests/run/libcpp_algo.pyx b/tests/run/libcpp_algo.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2xpYmNwcF9hbGdvLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2xpYmNwcF9hbGdvLnB5eA== 100644
--- a/tests/run/libcpp_algo.pyx
+++ b/tests/run/libcpp_algo.pyx
@@ -1,3 +1,4 @@
+# mode: run
 # tag: cpp
 
 from libcpp cimport bool
@@ -1,8 +2,8 @@
 # tag: cpp
 
 from libcpp cimport bool
-from libcpp.algorithm cimport make_heap, sort_heap, sort, partial_sort
+from libcpp.algorithm cimport make_heap, sort_heap
 from libcpp.vector cimport vector
 
 
 # XXX should use std::greater, but I don't know how to wrap that.
@@ -5,8 +6,8 @@
 from libcpp.vector cimport vector
 
 
 # XXX should use std::greater, but I don't know how to wrap that.
-cdef inline bool greater(int x, int y):
+cdef inline bool greater(const int &x, const int &y):
     return x > y
 
 
@@ -27,33 +28,3 @@
         sort_heap(v.begin(), v.end())
 
     return v
-
-
-def partialsort(l, int k, reverse=False):
-    """
-    >>> partialsort([4, 2, 3, 1, 5], k=2)[:2]
-    [1, 2]
-    >>> partialsort([4, 2, 3, 1, 5], k=2, reverse=True)[:2]
-    [5, 4]
-    """
-    cdef vector[int] v = l
-    if reverse:
-        partial_sort(v.begin(), v.begin() + k, v.end(), &greater)
-    else:
-        partial_sort(v.begin(), v.begin() + k, v.end())
-    return v
-
-
-def stdsort(l, reverse=False):
-    """
-    >>> stdsort([3, 2, 1, 4, 5])
-    [1, 2, 3, 4, 5]
-    >>> stdsort([3, 2, 1, 4, 5], reverse=True)
-    [5, 4, 3, 2, 1]
-    """
-    cdef vector[int] v = l
-    if reverse:
-        sort(v.begin(), v.end(), &greater)
-    else:
-        sort(v.begin(), v.end())
-    return v
diff --git a/tests/run/libcpp_all.pyx b/tests/run/libcpp_all.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2xpYmNwcF9hbGwucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2xpYmNwcF9hbGwucHl4 100644
--- a/tests/run/libcpp_all.pyx
+++ b/tests/run/libcpp_all.pyx
@@ -4,6 +4,7 @@
 
 cimport libcpp
 
+# cimport libcpp.atomic
 cimport libcpp.deque
 cimport libcpp.list
 cimport libcpp.map
@@ -15,6 +16,7 @@
 cimport libcpp.complex
 cimport libcpp.limits
 
+# from libcpp.atomic cimport *
 from libcpp.deque  cimport *
 from libcpp.list   cimport *
 from libcpp.map    cimport *
@@ -26,6 +28,7 @@
 from libcpp.complex cimport *
 from libcpp.limits cimport *
 
+# cdef libcpp.atomic.atomc[int]  a1 = atomic[int]()
 cdef libcpp.deque.deque[int]   d1 = deque[int]()
 cdef libcpp.list.list[int]     l1 = list[int]()
 cdef libcpp.map.map[int,int]   m1 = map[int,int]()
diff --git a/tests/run/list_pop.pyx b/tests/run/list_pop.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2xpc3RfcG9wLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2xpc3RfcG9wLnB5eA== 100644
--- a/tests/run/list_pop.pyx
+++ b/tests/run/list_pop.pyx
@@ -206,7 +206,7 @@
     """
     >>> crazy_pop(list(range(10)))    # doctest: +ELLIPSIS
     Traceback (most recent call last):
-    TypeError: pop... at most ... argument...
+    TypeError: pop... argument...
     >>> crazy_pop(A())
     (1, 2, 3)
     """
diff --git a/tests/run/locals_T732.pyx b/tests/run/locals_T732.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL2xvY2Fsc19UNzMyLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL2xvY2Fsc19UNzMyLnB5eA== 100644
--- a/tests/run/locals_T732.pyx
+++ b/tests/run/locals_T732.pyx
@@ -23,8 +23,8 @@
     >>> klass = test_class_locals_and_dir()
     >>> 'visible' in klass.locs and 'not_visible' not in klass.locs
     True
-    >>> klass.names
-    ['__module__', '__qualname__', 'visible']
+    >>> [n for n in klass.names if n != "__qualname__"]
+    ['__module__', 'visible']
     """
     not_visible = 1234
     class Foo:
diff --git a/tests/run/metaclass.pyx b/tests/run/metaclass.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL21ldGFjbGFzcy5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL21ldGFjbGFzcy5weXg= 100644
--- a/tests/run/metaclass.pyx
+++ b/tests/run/metaclass.pyx
@@ -69,8 +69,8 @@
     321
     >>> obj.metaclass_was_here
     True
-    >>> obj._order
-    ['__module__', '__qualname__', '__doc__', 'bar', 'metaclass_was_here']
+    >>> [n for n in obj._order if n != "__qualname__"]
+    ['__module__', '__doc__', 'bar', 'metaclass_was_here']
     """
     bar = 321
 
@@ -81,8 +81,8 @@
     345
     >>> obj.metaclass_was_here
     True
-    >>> obj._order
-    ['__module__', '__qualname__', '__doc__', 'bar', 'metaclass_was_here']
+    >>> [n for n in obj._order if n != "__qualname__"]
+    ['__module__', '__doc__', 'bar', 'metaclass_was_here']
     """
     bar = 345
 
@@ -109,8 +109,8 @@
     123
     >>> obj.bar
     321
-    >>> obj._order
-    ['__module__', '__qualname__', '__doc__', 'bar', 'foo']
+    >>> [n for n in obj._order if n != "__qualname__"]
+    ['__module__', '__doc__', 'bar', 'foo']
     """
     bar = 321
 
@@ -122,8 +122,8 @@
     567
     >>> obj.bar
     321
-    >>> obj._order
-    ['__module__', '__qualname__', '__doc__', 'bar', 'foo']
+    >>> [n for n in obj._order if n != "__qualname__"]
+    ['__module__', '__doc__', 'bar', 'foo']
     """
     bar = 321
 
diff --git a/tests/run/methodmangling_T5.py b/tests/run/methodmangling_T5.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL21ldGhvZG1hbmdsaW5nX1Q1LnB5..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL21ldGhvZG1hbmdsaW5nX1Q1LnB5 100644
--- a/tests/run/methodmangling_T5.py
+++ b/tests/run/methodmangling_T5.py
@@ -1,6 +1,11 @@
 # mode: run
 # ticket: 5
 
+# A small number of extra tests checking:
+# 1) this works correctly with pure-Python-mode decorators - methodmangling_pure.py.
+# 2) this works correctly with cdef classes - methodmangling_cdef.pyx
+# 3) with "error_on_unknown_names" - methodmangling_unknown_names.py
+
 class CyTest(object):
     """
     >>> cy = CyTest()
@@ -15,5 +20,14 @@
 
     >>> '__x' in dir(cy)
     False
+    >>> cy._CyTest__y
+    2
+
+    >>> '_CyTest___more_than_two' in dir(cy)
+    True
+    >>> '___more_than_two' in dir(cy)
+    False
+    >>> '___more_than_two_special___' in dir(cy)
+    True
     """
     __x = 1
@@ -18,5 +32,11 @@
     """
     __x = 1
+    ___more_than_two = 3
+    ___more_than_two_special___ = 4
+
+    def __init__(self):
+        self.__y = 2
+
     def __private(self): return 8
 
     def get(self):
@@ -88,8 +108,14 @@
     1
     >>> ut.get()
     1
+    >>> ut._UnderscoreTest__UnderscoreNested().ret1()
+    1
+    >>> ut._UnderscoreTest__UnderscoreNested.__name__
+    '__UnderscoreNested'
+    >>> ut._UnderscoreTest__prop
+    1
     """
     __x = 1
 
     def get(self):
         return self.__x
@@ -91,5 +117,276 @@
     """
     __x = 1
 
     def get(self):
         return self.__x
+
+    class __UnderscoreNested(object):
+        def ret1(self):
+            return 1
+
+    @property
+    def __prop(self):
+        return self.__x
+
+class C:
+    error = """Traceback (most recent call last):
+...
+TypeError:
+"""
+    __doc__ = """
+>>> instance = C()
+
+Instance methods have their arguments mangled
+>>> instance.method1(__arg=1) # doctest: +IGNORE_EXCEPTION_DETAIL
+{error}
+>>> instance.method1(_C__arg=1)
+1
+>>> instance.method2(__arg=1) # doctest: +IGNORE_EXCEPTION_DETAIL
+{error}
+>>> instance.method2(_C__arg=1)
+1
+
+Works when optional argument isn't passed
+>>> instance.method2()
+None
+
+Where args are in the function's **kwargs dict, names aren't mangled
+>>> instance.method3(__arg=1) # doctest:
+1
+>>> instance.method3(_C__arg=1) # doctest: +IGNORE_EXCEPTION_DETAIL
+Traceback (most recent call last):
+...
+KeyError:
+
+Lambda functions behave in the same way:
+>>> instance.method_lambda(__arg=1) # doctest: +IGNORE_EXCEPTION_DETAIL
+{error}
+>>> instance.method_lambda(_C__arg=1)
+1
+
+Class methods - have their arguments mangled
+>>> instance.class_meth(__arg=1) # doctest: +IGNORE_EXCEPTION_DETAIL
+{error}
+>>> instance.class_meth(_C__arg=1)
+1
+>>> C.class_meth(__arg=1) # doctest: +IGNORE_EXCEPTION_DETAIL
+{error}
+>>> C.class_meth(_C__arg=1)
+1
+
+Static methods - have their arguments mangled
+>>> instance.static_meth(__arg=1) # doctest: +IGNORE_EXCEPTION_DETAIL
+{error}
+>>> instance.static_meth(_C__arg=1)
+1
+>>> C.static_meth(__arg=1) # doctest: +IGNORE_EXCEPTION_DETAIL
+{error}
+>>> C.static_meth(_C__arg=1)
+1
+
+Functions assigned to the class don't have their arguments mangled
+>>> instance.class_assigned_function(__arg=1)
+1
+>>> instance.class_assigned_function(_C__arg=1) # doctest: +IGNORE_EXCEPTION_DETAIL
+{error}
+
+Functions assigned to an instance don't have their arguments mangled
+>>> instance.instance_assigned_function = free_function2
+>>> instance.instance_assigned_function(__arg=1)
+1
+>>> instance.instance_assigned_function(_C__arg=1) # doctest: +IGNORE_EXCEPTION_DETAIL
+{error}
+
+Locals are reported as mangled
+>>> list(sorted(k for k in instance.get_locals(1).keys()))
+['_C__arg', 'self']
+""".format(error=error)
+
+    def method1(self, __arg):
+        print(__arg)
+
+    def method2(self, __arg=None):
+        # __arg is optional
+        print(__arg)
+
+    def method3(self, **kwargs):
+        print(kwargs['__arg'])
+
+    method_lambda = lambda self, __arg: __arg
+
+    def get_locals(self, __arg):
+        return locals()
+
+    @classmethod
+    def class_meth(cls, __arg):
+        print(__arg)
+
+    @staticmethod
+    def static_meth(__arg, dummy_arg=None):
+        # dummy_arg is to mask https://github.com/cython/cython/issues/3090
+        print(__arg)
+
+def free_function1(x, __arg):
+    print(__arg)
+
+def free_function2(__arg, dummy_arg=None):
+    # dummy_arg is to mask https://github.com/cython/cython/issues/3090
+    print(__arg)
+
+C.class_assigned_function = free_function1
+
+__global_arg = True
+
+_D__arg1 = None
+_D__global_arg = False # define these because otherwise Cython gives a compile-time error
+       # while Python gives a runtime error (which is difficult to test)
+def can_find_global_arg():
+    """
+    >>> can_find_global_arg()
+    True
+    """
+    return __global_arg
+
+def cant_find_global_arg():
+    """
+    Gets _D_global_arg instead
+    >>> cant_find_global_arg()
+    False
+    """
+    class D:
+        def f(self):
+            return __global_arg
+    return D().f()
+
+class CMultiplyNested:
+    def f1(self, __arg, name=None, return_closure=False):
+        """
+        >>> inst = CMultiplyNested()
+        >>> for name in [None, '__arg', '_CMultiplyNested__arg', '_D__arg']:
+        ...    try:
+        ...        print(inst.f1(1,name))
+        ...    except TypeError:
+        ...        print("TypeError") # not concerned about exact details
+        ...    # now test behaviour is the same in closures
+        ...    closure = inst.f1(1, return_closure=True)
+        ...    try:
+        ...        if name is None:
+        ...            print(closure(2))
+        ...        else:
+        ...            print(closure(**{ name: 2}))
+        ...    except TypeError:
+        ...        print("TypeError")
+        2
+        2
+        TypeError
+        TypeError
+        TypeError
+        TypeError
+        2
+        2
+        """
+        class D:
+            def g(self, __arg):
+                return __arg
+        if return_closure:
+            return D().g
+        if name is not None:
+            return D().g(**{ name: 2 })
+        else:
+            return D().g(2)
+
+    def f2(self, __arg1):
+        """
+        This finds the global name '_D__arg1'
+        It's tested in this way because without the global
+        Python gives a runtime error and Cython a compile error
+        >>> print(CMultiplyNested().f2(1))
+        None
+        """
+        class D:
+            def g(self):
+                return __arg1
+        return D().g()
+
+    def f3(self, arg, name):
+        """
+        >>> inst = CMultiplyNested()
+        >>> inst.f3(1, None)
+        2
+        >>> inst.f3(1, '__arg') # doctest: +IGNORE_EXCEPTION_DETAIL
+        Traceback (most recent call last):
+        ...
+        TypeError:
+        >>> inst.f3(1, '_CMultiplyNested__arg')
+        2
+        """
+        def g(__arg, dummy=1):
+            return __arg
+        if name is not None:
+            return g(**{ name: 2})
+        else:
+            return g(2)
+
+    def f4(self, __arg):
+        """
+        >>> CMultiplyNested().f4(1)
+        1
+        """
+        def g():
+            return __arg
+        return g()
+
+    def f5(self, __arg):
+        """
+        Default values are found in the outer scope correcly
+        >>> CMultiplyNested().f5(1)
+        1
+        """
+        def g(x=__arg):
+            return x
+        return g()
+
+    def f6(self, __arg1):
+        """
+        This will find the global name _D__arg1
+        >>> print(CMultiplyNested().f6(1))
+        None
+        """
+        class D:
+            def g(self, x=__arg1):
+                return x
+        return D().g()
+
+    def f7(self, __arg):
+        """
+        Lookup works in generator expressions
+        >>> list(CMultiplyNested().f7(1))
+        [1]
+        """
+        return (__arg for x in range(1))
+
+class __NameWithDunder:
+    """
+    >>> __NameWithDunder.__name__
+    '__NameWithDunder'
+    """
+    pass
+
+class Inherits(__NameWithDunder):
+    """
+    Compile check that it can find the base class
+    >>> x = Inherits()
+    """
+    pass
+
+def regular_function(__x, dummy=None):
+    # as before, dummy stops Cython creating a 1 arg, non-keyword call
+    return __x
+
+class CallsRegularFunction:
+    def call(self):
+        """
+        >>> CallsRegularFunction().call()
+        1
+        """
+        return regular_function(__x=1) # __x shouldn't be mangled as an argument elsewhere
diff --git a/tests/run/methodmangling_cdef.pxd b/tests/run/methodmangling_cdef.pxd
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL21ldGhvZG1hbmdsaW5nX2NkZWYucHhk
--- /dev/null
+++ b/tests/run/methodmangling_cdef.pxd
@@ -0,0 +1,3 @@
+cdef class InPxd:
+    cdef public int __y
+    cdef int __private_cdef(self)
diff --git a/tests/run/methodmangling_cdef.pyx b/tests/run/methodmangling_cdef.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL21ldGhvZG1hbmdsaW5nX2NkZWYucHl4
--- /dev/null
+++ b/tests/run/methodmangling_cdef.pyx
@@ -0,0 +1,95 @@
+# mode: run
+
+def call_cdt_private_cdef(CDefTest o):
+    return o._CDefTest__private_cdef()
+
+cdef __c_func():
+    return "cdef function"
+
+cdef __c_var = "Shouldn't see this"
+
+cdef class CDefTest:
+    """
+    >>> cd = CDefTest()
+    >>> '_CDefTest__private' in dir(cd)
+    True
+    >>> cd._CDefTest__private()
+    8
+    >>> call_cdt_private_cdef(cd)
+    8
+    >>> '__private' in dir(cd)
+    False
+    >>> '_CDefTest__x' in dir(cd)
+    True
+
+    >>> '__x' in dir(cd)
+    False
+    >>> cd._CDefTest__y
+    2
+    """
+    __x = 1
+    cdef public int __y
+
+    def __init__(self):
+        self.__y = 2
+
+    def __private(self): return 8
+
+    cdef __private_cdef(self): return 8
+
+    def get(self):
+        """
+        >>> CDefTest().get()
+        (1, 1, 8)
+        """
+        return self._CDefTest__x, self.__x, self.__private()
+
+    def get_inner(self):
+        """
+        >>> CDefTest().get_inner()
+        (1, 1, 8)
+        """
+        def get(o):
+            return o._CDefTest__x, o.__x, o.__private()
+        return get(self)
+
+    def get_c_func(self):
+        """
+        Should still be able to access C function with __names
+        >>> CDefTest().get_c_func()
+        'cdef function'
+        """
+        return __c_func()
+
+    def get_c_func2(self):
+        """
+        Should find mangled name before C __name
+        >>> CDefTest().get_c_func2()
+        'lambda'
+        """
+        _CDefTest__c_func = lambda: "lambda"
+        return __c_func()
+
+    def get_c_var(self):
+        """
+        >>> CDefTest().get_c_var()
+        'c var'
+        """
+        global __c_var
+        __c_var = "c var"
+        return __c_var
+
+def call_inpdx_private_cdef(InPxd o):
+    return o._InPxd__private_cdef()
+
+cdef class InPxd:
+    """
+    >>> InPxd()._InPxd__y
+    2
+    >>> call_inpdx_private_cdef(InPxd())
+    8
+    """
+    def __init__(self):
+        self.__y = 2
+
+    cdef int __private_cdef(self): return 8
diff --git a/tests/run/methodmangling_pure.py b/tests/run/methodmangling_pure.py
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL21ldGhvZG1hbmdsaW5nX3B1cmUucHk=
--- /dev/null
+++ b/tests/run/methodmangling_pure.py
@@ -0,0 +1,76 @@
+# mode: run
+# cython: language_level=3
+
+# This file tests that methodmangling is applied correctly to
+# pure Python decorated classes.
+
+import cython
+
+if cython.compiled:
+    # don't run in Python mode since a significant number of the tests
+    # are only for Cython features
+
+    def declare(**kwargs):
+        return kwargs['__x']
+
+    class RegularClass:
+        @cython.locals(__x=cython.int)
+        def f1(self, __x, dummy=None):
+            """
+            Is the locals decorator correctly applied
+            >>> c = RegularClass()
+            >>> c.f1(1)
+            1
+            >>> c.f1("a")
+            Traceback (most recent call last):
+            ...
+            TypeError: an integer is required
+            >>> c.f1(_RegularClass__x = 1)
+            1
+            """
+            return __x
+
+        def f2(self, x):
+            """
+            Is the locals decorator correctly applied
+            >>> c = RegularClass()
+            >>> c.f2(1)
+            1
+            >>> c.f2("a")
+            Traceback (most recent call last):
+            ...
+            TypeError: an integer is required
+            """
+            __x = cython.declare(cython.int, x)
+
+            return __x
+
+        def f3(self, x):
+            """
+            Is the locals decorator correctly applied
+            >>> c = RegularClass()
+            >>> c.f3(1)
+            1
+            >>> c.f3("a")
+            Traceback (most recent call last):
+            ...
+            TypeError: an integer is required
+            """
+            cython.declare(__x=cython.int)
+            __x = x
+
+            return __x
+
+        def f4(self, x):
+            """
+            We shouldn't be tripped up by a function called
+            "declare" that is nothing to do with cython
+            >>> RegularClass().f4(1)
+            1
+            """
+            return declare(__x=x)
+else:
+    __doc__ = """
+    >>> True
+    True
+    """ # stops Python2 from failing
diff --git a/tests/run/methodmangling_unknown_names.py b/tests/run/methodmangling_unknown_names.py
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL21ldGhvZG1hbmdsaW5nX3Vua25vd25fbmFtZXMucHk=
--- /dev/null
+++ b/tests/run/methodmangling_unknown_names.py
@@ -0,0 +1,25 @@
+# mode: run
+# tag: allow_unknown_names, pure2.0, pure3.0
+
+class Test(object):
+    def run(self):
+        """
+        >>> Test().run()
+        NameError1
+        NameError2
+        found mangled
+        """
+        try:
+            print(__something)
+        except NameError:
+            print("NameError1") # correct - shouldn't exist
+        globals()['__something'] = 'found unmangled'
+        try:
+            print(__something)
+        except NameError:
+            print("NameError2") # correct - shouldn't exist
+        globals()['_Test__something'] = 'found mangled'
+        try:
+            print(__something) # should print this
+        except NameError:
+            print("NameError3")
diff --git a/tests/run/modop.pyx b/tests/run/modop.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL21vZG9wLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL21vZG9wLnB5eA== 100644
--- a/tests/run/modop.pyx
+++ b/tests/run/modop.pyx
@@ -9,7 +9,7 @@
     '5'
     >>> modobj(1, 0)  # doctest: +ELLIPSIS
     Traceback (most recent call last):
-    ZeroDivisionError: integer division...
+    ZeroDivisionError: integer... modulo by zero
     """
     obj1 = obj2 % obj3
     return obj1
@@ -19,6 +19,10 @@
     """
     >>> mod_10_obj(0)  # doctest: +ELLIPSIS
     Traceback (most recent call last):
-    ZeroDivisionError: integer division...
+    ZeroDivisionError: ... modulo by zero
+    >>> 10 % 1
+    0
+    >>> mod_10_obj(1)
+    0
     >>> mod_10_obj(3)
     1
@@ -23,3 +27,9 @@
     >>> mod_10_obj(3)
     1
+    >>> 10 % -1
+    0
+    >>> mod_10_obj(-1)
+    0
+    >>> mod_10_obj(-10)
+    0
     """
@@ -25,5 +35,6 @@
     """
-    return 10 % int2
+    int1 = 10 % int2
+    return int1
 
 
 def mod_obj_10(int2):
@@ -168,6 +179,53 @@
     return int1
 
 
+def mod_int_17(int int2):
+    """
+    >>> 0 % 17
+    0
+    >>> mod_int_17(0)
+    0
+    >>> 1 % 17
+    1
+    >>> mod_int_17(1)
+    1
+    >>> (-1) % 17
+    16
+    >>> mod_int_17(-1)
+    16
+    >>> 9 % 17
+    9
+    >>> mod_int_17(16)
+    16
+    >>> 17 % 17
+    0
+    >>> mod_int_17(17)
+    0
+    >>> (-17) % 17
+    0
+    >>> mod_int_17(-17)
+    0
+    >>> (-18) % 17
+    16
+    >>> mod_int_17(-18)
+    16
+    >>> 10002 % 17
+    6
+    >>> mod_int_17(10002)
+    6
+    >>> int((2**25) % 17)
+    2
+    >>> int(mod_int_17(2**25))
+    2
+    >>> int((-2**25) % 17)
+    15
+    >>> int(mod_int_17(-2**25))
+    15
+    """
+    int1 = int2 % 17
+    return int1
+
+
 def mod_obj_m2(int2):
     """
     >>> 0 % -2
diff --git a/tests/run/mulop.pyx b/tests/run/mulop.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL211bG9wLnB5eA==
--- /dev/null
+++ b/tests/run/mulop.pyx
@@ -0,0 +1,166 @@
+# mode: run
+# tag: multiply
+
+import sys
+IS_PY2 = sys.version_info[0] < 3
+
+
+def print_long(x):
+    if IS_PY2:
+        x = str(x).rstrip('L')
+    print(x)
+
+
+def mul_10_obj(x):
+    """
+    >>> mul_10_obj(0)
+    0
+    >>> mul_10_obj(10)
+    100
+    >>> mul_10_obj(-10)
+    -100
+    >>> 10 * (2**14)
+    163840
+    >>> mul_10_obj(2**14)
+    163840
+    >>> mul_10_obj(-2**14)
+    -163840
+    >>> print_long(10 * (2**29))
+    5368709120
+    >>> print_long(mul_10_obj(2**29))
+    5368709120
+    >>> print_long(mul_10_obj(-2**29))
+    -5368709120
+    >>> print_long(10 * (2**30))
+    10737418240
+    >>> print_long(mul_10_obj(2**30))
+    10737418240
+    >>> print_long(mul_10_obj(-2**30))
+    -10737418240
+    >>> print_long(10 * (2**63))
+    92233720368547758080
+    >>> print_long(mul_10_obj(2**63))
+    92233720368547758080
+    >>> print_long(mul_10_obj(-2**63))
+    -92233720368547758080
+    >>> print_long(10 * (2**128))
+    3402823669209384634633746074317682114560
+    >>> print_long(mul_10_obj(2**128))
+    3402823669209384634633746074317682114560
+    >>> print_long(mul_10_obj(-2**128))
+    -3402823669209384634633746074317682114560
+    """
+    result = 10 * x
+    return result
+
+
+def mul_obj_10(x):
+    """
+    >>> mul_obj_10(0)
+    0
+    >>> mul_obj_10(10)
+    100
+    >>> mul_obj_10(-10)
+    -100
+    >>> 10 * (2**14)
+    163840
+    >>> mul_obj_10(2**14)
+    163840
+    >>> mul_obj_10(-2**14)
+    -163840
+    >>> print_long(10 * (2**29))
+    5368709120
+    >>> print_long(mul_obj_10(2**29))
+    5368709120
+    >>> print_long(mul_obj_10(-2**29))
+    -5368709120
+    >>> print_long(10 * (2**30))
+    10737418240
+    >>> print_long(mul_obj_10(2**30))
+    10737418240
+    >>> print_long(mul_obj_10(-2**30))
+    -10737418240
+    >>> print_long(10 * (2**63))
+    92233720368547758080
+    >>> print_long(mul_obj_10(2**63))
+    92233720368547758080
+    >>> print_long(mul_obj_10(-2**63))
+    -92233720368547758080
+    >>> print_long(10 * (2**128))
+    3402823669209384634633746074317682114560
+    >>> print_long(mul_obj_10(2**128))
+    3402823669209384634633746074317682114560
+    >>> print_long(mul_obj_10(-2**128))
+    -3402823669209384634633746074317682114560
+    """
+    result = x * 10
+    return result
+
+
+def mul_bigint_obj(x):
+    """
+    >>> mul_bigint_obj(0)
+    0
+    >>> print_long(mul_bigint_obj(1))
+    536870912
+    >>> print_long(mul_bigint_obj(2))
+    1073741824
+    >>> print_long(mul_bigint_obj(2**29))
+    288230376151711744
+    >>> print_long(mul_bigint_obj(-2**29))
+    -288230376151711744
+    >>> print_long(mul_bigint_obj(2**30))
+    576460752303423488
+    >>> print_long(mul_bigint_obj(-2**30))
+    -576460752303423488
+    >>> print_long(mul_bigint_obj(2**59))
+    309485009821345068724781056
+    >>> print_long(mul_bigint_obj(-2**59))
+    -309485009821345068724781056
+    """
+    result = (2**29) * x
+    return result
+
+
+def mul_obj_float(x):
+    """
+    >>> mul_obj_float(-0.0)
+    -0.0
+    >>> mul_obj_float(0)
+    0.0
+    >>> mul_obj_float(1.0)
+    2.0
+    >>> mul_obj_float(-2.0)
+    -4.0
+    >>> mul_obj_float(-0.5)
+    -1.0
+    """
+    result = x * 2.0
+    return result
+
+
+def mul_float_obj(x):
+    """
+    >>> mul_float_obj(0)
+    0.0
+    >>> mul_float_obj(2)
+    4.0
+    >>> mul_float_obj(-2)
+    -4.0
+    >>> 2.0 * (2**30-1)
+    2147483646.0
+    >>> mul_float_obj(2**30-1)
+    2147483646.0
+    >>> mul_float_obj(-(2**30-1))
+    -2147483646.0
+    >>> mul_float_obj(-0.0)
+    -0.0
+    >>> mul_float_obj(1.0)
+    2.0
+    >>> mul_float_obj(-2.0)
+    -4.0
+    >>> mul_float_obj(-0.5)
+    -1.0
+    """
+    result = 2.0 * x
+    return result
diff --git a/tests/run/no_gc_clear.pyx b/tests/run/no_gc_clear.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL25vX2djX2NsZWFyLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL25vX2djX2NsZWFyLnB5eA== 100644
--- a/tests/run/no_gc_clear.pyx
+++ b/tests/run/no_gc_clear.pyx
@@ -3,7 +3,7 @@
 tp_clear slot so that __dealloc__ will still see the original reference
 contents.
 
-Discussed here: http://article.gmane.org/gmane.comp.python.cython.devel/14986
+Discussed here: https://article.gmane.org/gmane.comp.python.cython.devel/14986
 """
 
 cimport cython
diff --git a/tests/run/nogil.pyx b/tests/run/nogil.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL25vZ2lsLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL25vZ2lsLnB5eA== 100644
--- a/tests/run/nogil.pyx
+++ b/tests/run/nogil.pyx
@@ -28,6 +28,6 @@
         y = x + 42
         return y
 
-cdef int with_gil_func() except 0 with gil:
+cdef int with_gil_func() except -1 with gil:
     raise Exception("error!")
 
@@ -32,6 +32,6 @@
     raise Exception("error!")
 
-cdef int nogil_func() nogil except 0:
+cdef int nogil_func() nogil except -1:
     with_gil_func()
 
 def test_nogil_exception_propagation():
diff --git a/tests/run/nogil_conditional.pyx b/tests/run/nogil_conditional.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL25vZ2lsX2NvbmRpdGlvbmFsLnB5eA==
--- /dev/null
+++ b/tests/run/nogil_conditional.pyx
@@ -0,0 +1,271 @@
+# mode: run
+
+try:
+    from StringIO import StringIO
+except ImportError:
+    from io import StringIO
+
+
+def test(int x):
+    """
+    >>> test(0)
+    110
+    """
+    with nogil(True):
+        x = f_nogil(x)
+        with gil(True):
+            x = f_gil(x)
+    return x
+
+
+cdef int f_nogil(int x) nogil:
+    cdef int y
+    y = x + 10
+    return y
+
+
+def f_gil(x):
+    y = 0
+    y = x + 100
+    return y
+
+
+cdef int with_gil_func() except? -1 with gil:
+    raise Exception("error!")
+
+
+cdef int nogil_func() nogil except? -1:
+    with_gil_func()
+
+
+def test_nogil_exception_propagation():
+    """
+    >>> test_nogil_exception_propagation()
+    Traceback (most recent call last):
+       ...
+    Exception: error!
+    """
+    with nogil:
+        with gil:
+            with nogil(True):
+                nogil_func()
+
+
+cdef int write_unraisable() nogil:
+    with gil:
+        raise ValueError()
+
+
+def test_unraisable():
+    """
+    >>> print(test_unraisable())  # doctest: +ELLIPSIS
+    ValueError
+    Exception...ignored...
+    """
+    import sys
+    old_stderr = sys.stderr
+    stderr = sys.stderr = StringIO()
+    try:
+        write_unraisable()
+    finally:
+        sys.stderr = old_stderr
+    return stderr.getvalue().strip()
+
+
+def test_nested():
+    """
+    >>> test_nested()
+    240
+    """
+    cdef int res = 0
+
+    with nogil(True):
+        res = f_nogil(res)
+        with gil(1 < 2):
+            res = f_gil(res)
+            with nogil:
+                res = f_nogil(res)
+
+        with gil:
+            res = f_gil(res)
+            with nogil(True):
+                res = f_nogil(res)
+            with nogil:
+                res = f_nogil(res)
+
+    return res
+
+
+DEF FREE_GIL = True
+DEF FREE_GIL_FALSE = False
+
+
+def test_nested_condition_false():
+    """
+    >>> test_nested_condition_false()
+    220
+    """
+    cdef int res = 0
+
+    with gil(FREE_GIL_FALSE):
+        res = f_gil(res)
+        with nogil(False):
+            res = f_gil(res)
+
+        with nogil(FREE_GIL):
+            res = f_nogil(res)
+            with gil(False):
+                res = f_nogil(res)
+
+    return res
+
+def test_try_finally():
+    """
+    >>> test_try_finally()
+    113
+    """
+    cdef int res = 0
+
+    try:
+        with nogil(True):
+            try:
+                res = f_nogil(res)
+                with gil(1 < 2):
+                    try:
+                        res = f_gil(res)
+                    finally:
+                        res += 1
+            finally:
+                res = res + 1
+    finally:
+        res += 1
+
+    return res
+
+
+ctypedef fused number_or_object:
+    int
+    float
+    object
+
+
+def test_fused(number_or_object x) -> number_or_object:
+    """
+    >>> test_fused[int](1)
+    2
+    >>> test_fused[float](1.0)
+    2.0
+    >>> test_fused[object](1)
+    2
+    >>> test_fused[object](1.0)
+    2.0
+    """
+    cdef number_or_object res = x
+
+    with nogil(number_or_object is not object):
+        res = res + 1
+
+    return res
+
+
+ctypedef fused int_or_object:
+    int
+    object
+
+
+def test_fused_object(int_or_object x):
+    """
+    >>> test_fused_object[object]("spam")
+    456
+    >>> test_fused_object[int](1000)
+    1000
+    """
+    cdef int res = 0
+
+    if int_or_object is object:
+        with nogil(False):
+            res += len(x)
+
+        try:
+            with nogil(int_or_object is object):
+                try:
+                    with gil(int_or_object is object):
+                        res = f_gil(res)
+                    with gil:
+                        res = f_gil(res)
+                    with gil(False):
+                        res = f_nogil(res)
+
+                    with gil(int_or_object is not object):
+                        res = f_nogil(res)
+                    with nogil(False):
+                        res = f_nogil(res)
+
+                    res = f_nogil(res)
+                finally:
+                    res = res + 1
+
+            with nogil(int_or_object is not object):
+                res = f_gil(res)
+
+            with gil(int_or_object is not object):
+                res = f_gil(res)
+
+                with nogil(int_or_object is object):
+                    res = f_nogil(res)
+
+        finally:
+            res += 1
+    else:
+        res = x
+
+    return res
+
+
+def test_fused_int(int_or_object x):
+    """
+    >>> test_fused_int[object]("spam")
+    4
+    >>> test_fused_int[int](1000)
+    1452
+    """
+    cdef int res = 0
+
+    if int_or_object is int:
+        res += x
+
+        try:
+            with nogil(int_or_object is int):
+                try:
+                    with gil(int_or_object is int):
+                        res = f_gil(res)
+                    with gil:
+                        res = f_gil(res)
+                    with gil(False):
+                        res = f_nogil(res)
+
+                    with gil(int_or_object is not int):
+                        res = f_nogil(res)
+                    with nogil(False):
+                        res = f_nogil(res)
+
+                    res = f_nogil(res)
+                finally:
+                    res = res + 1
+
+            with nogil(int_or_object is not int):
+                res = f_gil(res)
+
+            with gil(int_or_object is not int):
+                res = f_gil(res)
+
+                with nogil(int_or_object is int):
+                    res = f_nogil(res)
+
+        finally:
+            res += 1
+    else:
+        with nogil(False):
+            res = len(x)
+
+    return res
diff --git a/tests/run/numpy_bufacc_T155.pyx b/tests/run/numpy_bufacc_T155.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL251bXB5X2J1ZmFjY19UMTU1LnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL251bXB5X2J1ZmFjY19UMTU1LnB5eA== 100644
--- a/tests/run/numpy_bufacc_T155.pyx
+++ b/tests/run/numpy_bufacc_T155.pyx
@@ -1,5 +1,5 @@
 # ticket: 155
-# tag: numpy_old
+# tag: numpy
 
 """
 >>> myfunc()
@@ -17,4 +17,3 @@
         A[i, :] /= 2
     return A[0,0]
 
-include "numpy_common.pxi"
diff --git a/tests/run/numpy_cimport.pyx b/tests/run/numpy_cimport.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL251bXB5X2NpbXBvcnQucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL251bXB5X2NpbXBvcnQucHl4 100644
--- a/tests/run/numpy_cimport.pyx
+++ b/tests/run/numpy_cimport.pyx
@@ -6,4 +6,3 @@
 True
 """
 cimport numpy as np
-include "numpy_common.pxi"
diff --git a/tests/run/numpy_cimport_1.pyx b/tests/run/numpy_cimport_1.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL251bXB5X2NpbXBvcnRfMS5weXg=
--- /dev/null
+++ b/tests/run/numpy_cimport_1.pyx
@@ -0,0 +1,25 @@
+# mode: run
+# tag: warnings, numpy
+
+cimport numpy as np
+# np.import_array not called - should generate warning
+
+cdef extern from *:
+    """
+    static void** _check_array_api(void) {
+        return PyArray_API; /* should be non NULL */
+    }
+    """
+    void** _check_array_api()
+
+def check_array_api():
+    """
+    >>> check_array_api()
+    True
+    """
+    return _check_array_api() != NULL
+
+
+_WARNINGS = """
+4:8: 'numpy.import_array()' has been added automatically since 'numpy' was cimported but 'numpy.import_array' was not called.
+"""
diff --git a/tests/run/numpy_cimport_2.pyx b/tests/run/numpy_cimport_2.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL251bXB5X2NpbXBvcnRfMi5weXg=
--- /dev/null
+++ b/tests/run/numpy_cimport_2.pyx
@@ -0,0 +1,25 @@
+# mode: run
+# tag: warnings, numpy
+
+cimport numpy as np
+np.import_array()
+# np.import_array is called - no warning necessary
+
+cdef extern from *:
+    """
+    static void** _check_array_api(void) {
+        return PyArray_API; /* should be non NULL */
+    }
+    """
+    void** _check_array_api()
+
+def check_array_api():
+    """
+    >>> check_array_api()
+    True
+    """
+    return _check_array_api() != NULL
+
+
+_WARNINGS = """
+"""
diff --git a/tests/run/numpy_cimport_3.pyx b/tests/run/numpy_cimport_3.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL251bXB5X2NpbXBvcnRfMy5weXg=
--- /dev/null
+++ b/tests/run/numpy_cimport_3.pyx
@@ -0,0 +1,8 @@
+# mode: compile
+# tag: warnings, numpy
+
+import numpy as np
+# Numpy is only imported - no warning necessary
+
+_WARNINGS = """
+"""
diff --git a/tests/run/numpy_cimport_4.pyx b/tests/run/numpy_cimport_4.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL251bXB5X2NpbXBvcnRfNC5weXg=
--- /dev/null
+++ b/tests/run/numpy_cimport_4.pyx
@@ -0,0 +1,24 @@
+# mode: run
+# tag: warnings, numpy
+
+cimport numpy
+<void>numpy.import_array # dummy call should stop Cython auto-generating call to import_array
+
+cdef extern from *:
+    """
+    static void** _check_array_api(void) {
+        return PyArray_API; /* should be non NULL if initialized */
+    }
+    """
+    void** _check_array_api()
+
+def check_array_api():
+    """
+    >>> check_array_api()
+    True
+    """
+    return _check_array_api() == NULL # not initialized
+
+
+_WARNINGS = """
+"""
diff --git a/tests/run/numpy_cimport_5.pyx b/tests/run/numpy_cimport_5.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL251bXB5X2NpbXBvcnRfNS5weXg=
--- /dev/null
+++ b/tests/run/numpy_cimport_5.pyx
@@ -0,0 +1,25 @@
+# mode: run
+# tag: warnings, numpy
+
+from numpy cimport ndarray
+# np.import_array not called - should generate warning
+
+cdef extern from *:
+    """
+    static void** _check_array_api(void) {
+        return PyArray_API; /* should be non NULL */
+    }
+    """
+    void** _check_array_api()
+
+def check_array_api():
+    """
+    >>> check_array_api()
+    True
+    """
+    return _check_array_api() != NULL
+
+
+_WARNINGS = """
+4:0: 'numpy.import_array()' has been added automatically since 'numpy' was cimported but 'numpy.import_array' was not called.
+"""
diff --git a/tests/run/numpy_cimport_6.pyx b/tests/run/numpy_cimport_6.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL251bXB5X2NpbXBvcnRfNi5weXg=
--- /dev/null
+++ b/tests/run/numpy_cimport_6.pyx
@@ -0,0 +1,25 @@
+# mode: run
+# tag: warnings, numpy
+
+from numpy cimport ndarray, import_array
+import_array()
+# np.import_array is called - no warning necessary
+
+cdef extern from *:
+    """
+    static void** _check_array_api(void) {
+        return PyArray_API; /* should be non NULL */
+    }
+    """
+    void** _check_array_api()
+
+def check_array_api():
+    """
+    >>> check_array_api()
+    True
+    """
+    return _check_array_api() != NULL
+
+
+_WARNINGS = """
+"""
diff --git a/tests/run/numpy_common.pxi b/tests/run/numpy_common.pxi
deleted file mode 100644
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL251bXB5X2NvbW1vbi5weGk=..0000000000000000000000000000000000000000
--- a/tests/run/numpy_common.pxi
+++ /dev/null
@@ -1,10 +0,0 @@
-# hack to avoid C compiler warnings about unused functions in the NumPy header files
-
-cdef extern from *:
-   bint FALSE "0"
-   void import_array()
-#   void import_umath()
-
-if FALSE:
-    import_array()
-#    import_umath()
diff --git a/tests/run/numpy_parallel.pyx b/tests/run/numpy_parallel.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL251bXB5X3BhcmFsbGVsLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL251bXB5X3BhcmFsbGVsLnB5eA== 100644
--- a/tests/run/numpy_parallel.pyx
+++ b/tests/run/numpy_parallel.pyx
@@ -1,6 +1,6 @@
-# tag: numpy_old
+# tag: numpy
 # tag: openmp
 
 cimport cython
 from cython.parallel import prange
 cimport numpy as np
@@ -2,9 +2,8 @@
 # tag: openmp
 
 cimport cython
 from cython.parallel import prange
 cimport numpy as np
-include "numpy_common.pxi"
 
 
 @cython.boundscheck(False)
diff --git a/tests/run/numpy_pythran.pyx b/tests/run/numpy_pythran.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL251bXB5X3B5dGhyYW4ucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL251bXB5X3B5dGhyYW4ucHl4 100644
--- a/tests/run/numpy_pythran.pyx
+++ b/tests/run/numpy_pythran.pyx
@@ -55,3 +55,13 @@
         np.sum(seg3 * prog_seg3 + 939.57) +
         np.sum(seg4 * prog_seg4)
     ) / np.sum(d)
+
+def access_shape():
+    """
+    >>> access_shape()
+    10
+    """
+    cdef cnp.ndarray[double, ndim=2, mode='c'] array_in = \
+                    1e10 * np.ones((10, 10))
+
+    return array_in.shape[0]
diff --git a/tests/run/numpy_subarray.pyx b/tests/run/numpy_subarray.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL251bXB5X3N1YmFycmF5LnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL251bXB5X3N1YmFycmF5LnB5eA== 100644
--- a/tests/run/numpy_subarray.pyx
+++ b/tests/run/numpy_subarray.pyx
@@ -1,4 +1,4 @@
-# tag: numpy_old
+# tag: numpy
 
 cimport numpy as np
 cimport cython
diff --git a/tests/run/numpy_test.pyx b/tests/run/numpy_test.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL251bXB5X3Rlc3QucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL251bXB5X3Rlc3QucHl4 100644
--- a/tests/run/numpy_test.pyx
+++ b/tests/run/numpy_test.pyx
@@ -1,7 +1,6 @@
-# tag: numpy_old
-# cannot be named "numpy" in order to not clash with the numpy module!
+# tag: numpy
 
 cimport numpy as np
 cimport cython
 
 import re
@@ -3,9 +2,8 @@
 
 cimport numpy as np
 cimport cython
 
 import re
-import sys
 
 
 def little_endian():
@@ -20,7 +18,7 @@
 
 def testcase_have_buffer_interface(f):
     major, minor, *rest = np.__version__.split('.')
-    if (int(major), int(minor)) >= (1, 5) and sys.version_info[:2] >= (2, 6):
+    if (int(major), int(minor)) >= (1, 5):
         __test__[f.__name__] = f.__doc__
     return f
 
@@ -946,5 +944,3 @@
     cdef object obj = a
     return a == 0, obj == 0, a == 1, obj == 1
 
-
-include "numpy_common.pxi"
diff --git a/tests/run/pep448_extended_unpacking.pyx b/tests/run/pep448_extended_unpacking.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL3BlcDQ0OF9leHRlbmRlZF91bnBhY2tpbmcucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3BlcDQ0OF9leHRlbmRlZF91bnBhY2tpbmcucHl4 100644
--- a/tests/run/pep448_extended_unpacking.pyx
+++ b/tests/run/pep448_extended_unpacking.pyx
@@ -464,6 +464,10 @@
     return {**it}
 
 
+@cython.test_assert_path_exists('//MergedDictNode')
+@cython.test_fail_if_path_exists(
+    '//MergedDictNode//MergedDictNode',
+)
 def unpack_dict_from_iterable(it):
     """
     >>> d = unpack_dict_from_iterable(dict(a=1, b=2, c=3))
@@ -536,3 +540,28 @@
     True
     """
     return {**a, **b, 2: 4, **c}
+
+
+@cython.test_assert_path_exists(
+    '//MergedDictNode',
+    '//MergedDictNode//MergedDictNode',
+    '//MergedDictNode//MergedDictNode//DictNode',
+)
+def unpack_in_call(f):
+    """
+    >>> def f(a=1, test=2, **kwargs):
+    ...     return a, test, sorted(kwargs.items())
+    >>> wrapped = unpack_in_call(f)
+    >>> wrapped(1)
+    (1, 1, [('more', 2)])
+    >>> wrapped(test='overwritten')
+    (1, 1, [('more', 2)])
+    >>> wrapped(b=3)
+    (1, 1, [('b', 3), ('more', 2)])
+    >>> wrapped(more=4)
+    Traceback (most recent call last):
+    TypeError: function() got multiple values for keyword argument 'more'
+    """
+    def wrapper(*args, **kwargs):
+        return f(*args, more=2, **{**kwargs, 'test': 1})
+    return wrapper
diff --git a/tests/run/pep448_test_extcall.pyx b/tests/run/pep448_test_extcall.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL3BlcDQ0OF90ZXN0X2V4dGNhbGwucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3BlcDQ0OF90ZXN0X2V4dGNhbGwucHl4 100644
--- a/tests/run/pep448_test_extcall.pyx
+++ b/tests/run/pep448_test_extcall.pyx
@@ -326,7 +326,7 @@
     """
     >>> errors_non_string_kwarg()  # doctest: +ELLIPSIS
     Traceback (most recent call last):
-    TypeError: ...keywords must be strings
+    TypeError: ...keywords must be strings...
     """
     f(**{1:2})
 
@@ -463,6 +463,6 @@
 
 def call_builtin_nonempty_dict():
     """
-    >>> call_builtin_nonempty_dict()
+    >>> call_builtin_nonempty_dict() # doctest: +ELLIPSIS
     Traceback (most recent call last):
       ...
@@ -467,6 +467,6 @@
     Traceback (most recent call last):
       ...
-    TypeError: id() takes no keyword arguments
+    TypeError: id() ... keyword argument...
     """
     return id(1, **{'foo': 1})
 
@@ -474,7 +474,7 @@
 ''' Cython: currently just passes empty kwargs into f() while CPython keeps the content
 
 # A corner case of keyword dictionary items being deleted during
-# the function call setup. See <http://bugs.python.org/issue2016>.
+# the function call setup. See <https://bugs.python.org/issue2016>.
 
 def call_kwargs_modified_while_building():
     """
diff --git a/tests/run/pep563_annotations.py b/tests/run/pep563_annotations.py
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3BlcDU2M19hbm5vdGF0aW9ucy5weQ==
--- /dev/null
+++ b/tests/run/pep563_annotations.py
@@ -0,0 +1,27 @@
+# mode: run
+# tag: pep563, pure3.7
+
+from __future__ import annotations
+
+def f(a: 1+2==3, b: list, c: this_cant_evaluate, d: "Hello from inside a string") -> "Return me!":
+    """
+    The absolute exact strings aren't reproducible according to the PEP,
+    so be careful to avoid being too specific
+    >>> stypes = (type(""), type(u"")) # Python 2 is a bit awkward here
+    >>> eval(f.__annotations__['a'])
+    True
+    >>> isinstance(f.__annotations__['a'], stypes)
+    True
+    >>> print(f.__annotations__['b'])
+    list
+    >>> print(f.__annotations__['c'])
+    this_cant_evaluate
+    >>> isinstance(eval(f.__annotations__['d']), stypes)
+    True
+    >>> print(f.__annotations__['return'][1:-1]) # First and last could be either " or '
+    Return me!
+    >>> f.__annotations__['return'][0] == f.__annotations__['return'][-1]
+    True
+    """
+    pass
+
diff --git a/tests/run/posonly.py b/tests/run/posonly.py
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3Bvc29ubHkucHk=
--- /dev/null
+++ b/tests/run/posonly.py
@@ -0,0 +1,568 @@
+# cython: always_allow_keywords=True
+# mode: run
+# tag: posonly, pure3.8
+
+import cython
+import sys
+import pickle
+
+def test_optional_posonly_args1(a, b=10, /, c=100):
+    """
+    >>> test_optional_posonly_args1(1, 2, 3)
+    6
+    >>> test_optional_posonly_args1(1, 2, c=3)
+    6
+    >>> test_optional_posonly_args1(1, b=2, c=3)  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    TypeError: test_optional_posonly_args1() got ... keyword argument... 'b'
+    >>> test_optional_posonly_args1(1, 2)
+    103
+    >>> test_optional_posonly_args1(1, b=2)  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    TypeError: test_optional_posonly_args1() got ... keyword argument... 'b'
+    """
+    return a + b + c
+
+def test_optional_posonly_args2(a=1, b=10, /, c=100):
+    """
+    >>> test_optional_posonly_args2(1, 2, 3)
+    6
+    >>> test_optional_posonly_args2(1, 2, c=3)
+    6
+    >>> test_optional_posonly_args2(1, b=2, c=3)  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    TypeError: test_optional_posonly_args2() got ... keyword argument... 'b'
+    >>> test_optional_posonly_args2(1, 2)
+    103
+    >>> test_optional_posonly_args2(1, b=2)  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    TypeError: test_optional_posonly_args2() got ... keyword argument... 'b'
+    >>> test_optional_posonly_args2(1, c=2)
+    13
+    """
+    return a + b + c
+
+# TODO: this causes a line that is too long for old versions of Clang
+#def many_args(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20,a21,
+#              a22,a23,a24,a25,a26,a27,a28,a29,a30,a31,a32,a33,a34,a35,a36,a37,a38,a39,a40,
+#              a41,a42,a43,a44,a45,a46,a47,a48,a49,a50,a51,a52,a53,a54,a55,a56,a57,a58,a59,
+#              a60,a61,a62,a63,a64,a65,a66,a67,a68,a69,a70,a71,a72,a73,a74,a75,a76,a77,a78,
+#              a79,a80,a81,a82,a83,a84,a85,a86,a87,a88,a89,a90,a91,a92,a93,a94,a95,a96,a97,
+#              a98,a99,a100,a101,a102,a103,a104,a105,a106,a107,a108,a109,a110,a111,a112,
+#              a113,a114,a115,a116,a117,a118,a119,a120,a121,a122,a123,a124,a125,a126,a127,
+#              a128,a129,a130,a131,a132,a133,a134,a135,a136,a137,a138,a139,a140,a141,a142,
+#              a143,a144,a145,a146,a147,a148,a149,a150,a151,a152,a153,a154,a155,a156,a157,
+#              a158,a159,a160,a161,a162,a163,a164,a165,a166,a167,a168,a169,a170,a171,a172,
+#              a173,a174,a175,a176,a177,a178,a179,a180,a181,a182,a183,a184,a185,a186,a187,
+#              a188,a189,a190,a191,a192,a193,a194,a195,a196,a197,a198,a199,a200,a201,a202,
+#              a203,a204,a205,a206,a207,a208,a209,a210,a211,a212,a213,a214,a215,a216,a217,
+#              a218,a219,a220,a221,a222,a223,a224,a225,a226,a227,a228,a229,a230,a231,a232,
+#              a233,a234,a235,a236,a237,a238,a239,a240,a241,a242,a243,a244,a245,a246,a247,
+#              a248,a249,a250,a251,a252,a253,a254,a255,a256,a257,a258,a259,a260,a261,a262,
+#              a263,a264,a265,a266,a267,a268,a269,a270,a271,a272,a273,a274,a275,a276,a277,
+#              a278,a279,a280,a281,a282,a283,a284,a285,a286,a287,a288,a289,a290,a291,a292,
+#              a293,a294,a295,a296,a297,a298,a299,/,b,c=42,*,d):
+#    """
+#    >>> many_args(*range(299),b=1,c=2,d=3)
+#    (298, 1, 2, 3)
+#    >>> many_args(*range(299),b=1,d=3)
+#    (298, 1, 42, 3)
+#    >>> many_args(*range(300),d=3)
+#    (298, 299, 42, 3)
+#    """
+#    return (a299, b, c, d)
+
+#TODO: update this test for Python 3.8 final
+@cython.binding(True)
+def func_introspection1(a, b, c, /, d, e=1, *, f, g=2):
+    """
+    >>> if sys.version_info[0] < 3:
+    ...     assert func_introspection2.__code__.co_argcount == 7, func_introspection2.__code__.co_argcount
+    ... else:
+    ...     assert func_introspection2.__code__.co_argcount == 5, func_introspection2.__code__.co_argcount
+    >>> func_introspection1.__defaults__
+    (1,)
+    """
+
+@cython.binding(True)
+def func_introspection2(a, b, c=1, /, d=2, e=3, *, f, g=4):
+    """
+    >>> if sys.version_info[0] < 3:
+    ...     assert func_introspection2.__code__.co_argcount == 7, func_introspection2.__code__.co_argcount
+    ... else:
+    ...     assert func_introspection2.__code__.co_argcount == 5, func_introspection2.__code__.co_argcount
+    >>> func_introspection2.__defaults__
+    (1, 2, 3)
+    """
+
+def test_pos_only_call_via_unpacking(a, b, /):
+    """
+    >>> test_pos_only_call_via_unpacking(*[1,2])
+    3
+    """
+    return a + b
+
+def test_use_positional_as_keyword1(a, /):
+    """
+    >>> test_use_positional_as_keyword1(1)
+    >>> test_use_positional_as_keyword1(a=1)  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    TypeError: test_use_positional_as_keyword1() ... keyword arguments...
+    """
+
+def test_use_positional_as_keyword2(a, /, b):
+    """
+    >>> test_use_positional_as_keyword2(1, 2)
+    >>> test_use_positional_as_keyword2(1, b=2)
+    >>> test_use_positional_as_keyword2(a=1, b=2)  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    TypeError: test_use_positional_as_keyword2() ... positional...arguments...
+    """
+
+def test_use_positional_as_keyword3(a, b, /):
+    """
+    >>> test_use_positional_as_keyword3(1, 2)
+    >>> test_use_positional_as_keyword3(a=1, b=2) # doctest:+ELLIPSIS
+    Traceback (most recent call last):
+    TypeError: test_use_positional_as_keyword3() got ... keyword argument...
+    """
+
+def test_positional_only_and_arg_invalid_calls(a, b, /, c):
+    """
+    >>> test_positional_only_and_arg_invalid_calls(1, 2, 3)
+    >>> test_positional_only_and_arg_invalid_calls(1, 2, c=3)
+    >>> test_positional_only_and_arg_invalid_calls(1, 2)  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    TypeError: test_positional_only_and_arg_invalid_calls() ... positional argument...
+    >>> test_positional_only_and_arg_invalid_calls(1)  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    TypeError: test_positional_only_and_arg_invalid_calls() ... positional arguments...
+    >>> test_positional_only_and_arg_invalid_calls(1,2,3,4)  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    TypeError: test_positional_only_and_arg_invalid_calls() takes ... positional arguments ...4 ...given...
+    """
+
+def test_positional_only_and_optional_arg_invalid_calls(a, b, /, c=3):
+    """
+    >>> test_positional_only_and_optional_arg_invalid_calls(1, 2)
+    >>> test_positional_only_and_optional_arg_invalid_calls(1)  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    TypeError: test_positional_only_and_optional_arg_invalid_calls() ... positional argument...
+    >>> test_positional_only_and_optional_arg_invalid_calls()  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    TypeError: test_positional_only_and_optional_arg_invalid_calls() ... positional arguments...
+    >>> test_positional_only_and_optional_arg_invalid_calls(1, 2, 3, 4)  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    TypeError: test_positional_only_and_optional_arg_invalid_calls() takes ... positional arguments ...4 ...given...
+    """
+
+def test_positional_only_and_kwonlyargs_invalid_calls(a, b, /, c, *, d, e):
+    """
+    >>> test_positional_only_and_kwonlyargs_invalid_calls(1, 2, 3, d=1, e=2)
+    >>> test_positional_only_and_kwonlyargs_invalid_calls(1, 2, 3, e=2)  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    TypeError: test_positional_only_and_kwonlyargs_invalid_calls() ... keyword-only argument...d...
+    >>> test_positional_only_and_kwonlyargs_invalid_calls(1, 2, 3)  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    TypeError: test_positional_only_and_kwonlyargs_invalid_calls() ... keyword-only argument...d...
+    >>> test_positional_only_and_kwonlyargs_invalid_calls(1, 2)  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    TypeError: test_positional_only_and_kwonlyargs_invalid_calls() ... positional argument...
+    >>> test_positional_only_and_kwonlyargs_invalid_calls(1)  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    TypeError: test_positional_only_and_kwonlyargs_invalid_calls() ... positional arguments...
+    >>> test_positional_only_and_kwonlyargs_invalid_calls()  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    TypeError: test_positional_only_and_kwonlyargs_invalid_calls() ... positional arguments...
+    >>> test_positional_only_and_kwonlyargs_invalid_calls(1, 2, 3, 4, 5, 6, d=7, e=8)  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    TypeError: test_positional_only_and_kwonlyargs_invalid_calls() takes ... positional arguments ...
+    >>> test_positional_only_and_kwonlyargs_invalid_calls(1, 2, 3, d=1, e=4, f=56)  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    TypeError: test_positional_only_and_kwonlyargs_invalid_calls() got an unexpected keyword argument 'f'
+    """
+
+def test_positional_only_invalid_calls(a, b, /):
+    """
+    >>> test_positional_only_invalid_calls(1, 2)
+    >>> test_positional_only_invalid_calls(1)  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    TypeError: test_positional_only_invalid_calls() ... positional argument...
+    >>> test_positional_only_invalid_calls()  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    TypeError: test_positional_only_invalid_calls() ... positional arguments...
+    >>> test_positional_only_invalid_calls(1, 2, 3)  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    TypeError: test_positional_only_invalid_calls() takes ... positional arguments ...3 ...given...
+    """
+
+def test_positional_only_with_optional_invalid_calls(a, b=2, /):
+    """
+    >>> test_positional_only_with_optional_invalid_calls(1)
+    >>> test_positional_only_with_optional_invalid_calls()  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    TypeError: test_positional_only_with_optional_invalid_calls() ... positional argument...
+    >>> test_positional_only_with_optional_invalid_calls(1, 2, 3)  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    TypeError: test_positional_only_with_optional_invalid_calls() takes ... positional arguments ...3 ...given...
+    """
+
+def test_no_standard_args_usage(a, b, /, *, c):
+    """
+    >>> test_no_standard_args_usage(1, 2, c=3)
+    >>> test_no_standard_args_usage(1, b=2, c=3)  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    TypeError: test_no_standard_args_usage() ... positional... arguments...
+    """
+
+#def test_change_default_pos_only():
+# TODO: probably remove this, since  __defaults__ is not writable in Cython?
+#    """
+#    >>> test_change_default_pos_only()
+#    True
+#    True
+#    """
+#    def f(a, b=2, /, c=3):
+#        return a + b + c
+#
+#    print((2,3) == f.__defaults__)
+#    f.__defaults__ = (1, 2, 3)
+#    print(f(1, 2, 3) == 6)
+
+def test_lambdas():
+    """
+    >>> test_lambdas()
+    3
+    3
+    3
+    3
+    3
+    """
+    x = lambda a, /, b: a + b
+    print(x(1,2))
+    print(x(1,b=2))
+
+    x = lambda a, /, b=2: a + b
+    print(x(1))
+
+    x = lambda a, b, /: a + b
+    print(x(1, 2))
+
+    x = lambda a, b, /, : a + b
+    print(x(1, 2))
+
+class TestPosonlyMethods(object):
+    """
+    >>> TestPosonlyMethods().f(1,2)
+    (1, 2)
+    >>> TestPosonlyMethods.f(TestPosonlyMethods(), 1, 2)
+    (1, 2)
+    >>> try:
+    ...     TestPosonlyMethods.f(1,2)
+    ... except TypeError:
+    ...    print("Got type error")
+    Got type error
+    >>> TestPosonlyMethods().f(1, b=2)  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    TypeError: f() got ... keyword argument... 'b'
+    """
+    def f(self, a, b, /):
+        return a, b
+
+class TestMangling(object):
+    """
+    >>> TestMangling().f()
+    42
+    >>> TestMangling().f2()
+    42
+
+    #>>> TestMangling().f3()
+    #(42, 43)
+    #>>> TestMangling().f4()
+    #(42, 43, 44)
+
+    >>> TestMangling().f2(1)
+    1
+
+    #>>> TestMangling().f3(1, _TestMangling__b=2)
+    #(1, 2)
+    #>>> TestMangling().f4(1, _TestMangling__b=2, _TestMangling__c=3)
+    #(1, 2, 3)
+    """
+    def f(self, *, __a=42):
+        return __a
+
+    def f2(self, __a=42, /):
+        return __a
+
+# FIXME: https://github.com/cython/cython/issues/1382
+#    def f3(self, __a=42, /, __b=43):
+#        return (__a, __b)
+
+#    def f4(self, __a=42, /, __b=43, *, __c=44):
+#        return (__a, __b, __c)
+
+def test_module_function(a, b, /):
+    """
+    >>> test_module_function(1, 2)
+    >>> test_module_function()  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    TypeError: test_module_function() ... positional arguments...
+    """
+
+def test_closures1(x,y):
+    """
+    >>> test_closures1(1,2)(3,4)
+    10
+    >>> test_closures1(1,2)(3)  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    TypeError: g() ... positional argument...
+    >>> test_closures1(1,2)(3,4,5)  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    TypeError: g() ... positional argument...
+    """
+    def g(x2,/,y2):
+        return x + y + x2 + y2
+    return g
+
+def test_closures2(x,/,y):
+    """
+    >>> test_closures2(1,2)(3,4)
+    10
+    """
+    def g(x2,y2):
+        return x + y + x2 + y2
+    return g
+
+
+def test_closures3(x,/,y):
+    """
+    >>> test_closures3(1,2)(3,4)
+    10
+    >>> test_closures3(1,2)(3)  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    TypeError: g() ... positional argument...
+    >>> test_closures3(1,2)(3,4,5)  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    TypeError: g() ... positional argument...
+    """
+    def g(x2,/,y2):
+        return x + y + x2 + y2
+    return g
+
+
+def test_same_keyword_as_positional_with_kwargs(something, /, **kwargs):
+    """
+    >>> test_same_keyword_as_positional_with_kwargs(42, something=42)
+    (42, {'something': 42})
+    >>> test_same_keyword_as_positional_with_kwargs(something=42)  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    TypeError: test_same_keyword_as_positional_with_kwargs() ... positional argument...
+    >>> test_same_keyword_as_positional_with_kwargs(42)
+    (42, {})
+    """
+    return (something, kwargs)
+
+def test_serialization1(a, b, /):
+    """
+    >>> pickled_posonly = pickle.dumps(test_serialization1)
+    >>> unpickled_posonly = pickle.loads(pickled_posonly)
+    >>> unpickled_posonly(1, 2)
+    (1, 2)
+    >>> unpickled_posonly(a=1, b=2)  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    TypeError: test_serialization1() got ... keyword argument...
+    """
+    return (a, b)
+
+def test_serialization2(a, /, b):
+    """
+    >>> pickled_optional = pickle.dumps(test_serialization2)
+    >>> unpickled_optional = pickle.loads(pickled_optional)
+    >>> unpickled_optional(1, 2)
+    (1, 2)
+    >>> unpickled_optional(a=1, b=2)  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    TypeError: test_serialization2() ... positional... arguments...
+    """
+    return (a, b)
+
+def test_serialization3(a=1, /, b=2):
+    """
+    >>> pickled_defaults = pickle.dumps(test_serialization3)
+    >>> unpickled_defaults = pickle.loads(pickled_defaults)
+    >>> unpickled_defaults(1, 2)
+    (1, 2)
+    >>> unpickled_defaults(a=1, b=2)  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    TypeError: test_serialization3() got ... keyword argument... 'a'
+    """
+    return (a, b)
+
+
+async def test_async(a=1, /, b=2):
+    """
+    >>> test_async(a=1, b=2)  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    TypeError: test_async() got ... keyword argument... 'a'
+    """
+    return a, b
+
+
+def test_async_call(*args, **kwargs):
+    """
+    >>> test_async_call(1, 2)
+    >>> test_async_call(1, b=2)
+    >>> test_async_call(1)
+    >>> test_async_call()
+    """
+    if sys.version_info < (3, 6):
+        return
+    try:
+        coro = test_async(*args, **kwargs)
+        coro.send(None)
+    except StopIteration as e:
+        result = e.value
+    assert result == (1, 2), result
+
+
+def test_generator(a=1, /, b=2):
+    """
+    >>> test_generator(a=1, b=2)  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    TypeError: test_generator() got ... keyword argument... 'a'
+    >>> gen = test_generator(1, 2)
+    >>> next(gen)
+    (1, 2)
+    >>> gen = test_generator(1, b=2)
+    >>> next(gen)
+    (1, 2)
+    >>> gen = test_generator(1)
+    >>> next(gen)
+    (1, 2)
+    >>> gen = test_generator()
+    >>> next(gen)
+    (1, 2)
+    """
+    yield a, b
+
+def f_call_1_0_0(a,/):
+    """
+    >>> f_call_1_0_0(1)
+    (1,)
+    """
+    return (a,)
+
+def f_call_1_1_0(a,/,b):
+    """
+    >>> f_call_1_1_0(1,2)
+    (1, 2)
+    """
+    return (a,b)
+
+def f_call_1_1_1(a,/,b,*,c):
+    """
+    >>> f_call_1_1_1(1,2,c=3)
+    (1, 2, 3)
+    """
+    return (a,b,c)
+
+def f_call_1_1_1_star(a,/,b,*args,c):
+    """
+    >>> f_call_1_1_1_star(1,2,c=3)
+    (1, 2, (), 3)
+    >>> f_call_1_1_1_star(1,2,3,4,5,6,7,8,c=9)
+    (1, 2, (3, 4, 5, 6, 7, 8), 9)
+    """
+    return (a,b,args,c)
+
+def f_call_1_1_1_kwds(a,/,b,*,c,**kwds):
+    """
+    >>> f_call_1_1_1_kwds(1,2,c=3)
+    (1, 2, 3, {})
+    >>> f_call_1_1_1_kwds(1,2,c=3,d=4,e=5) == (1, 2, 3, {'d': 4, 'e': 5})
+    True
+    """
+    return (a,b,c,kwds)
+
+def f_call_1_1_1_star_kwds(a,/,b,*args,c,**kwds):
+    """
+    >>> f_call_1_1_1_star_kwds(1,2,c=3,d=4,e=5) == (1, 2, (), 3, {'d': 4, 'e': 5})
+    True
+    >>> f_call_1_1_1_star_kwds(1,2,3,4,c=5,d=6,e=7) == (1, 2, (3, 4), 5, {'d': 6, 'e': 7})
+    True
+    """
+    return (a,b,args,c,kwds)
+
+def f_call_one_optional_kwd(a,/,*,b=2):
+    """
+    >>> f_call_one_optional_kwd(1)
+    (1, 2)
+    >>> f_call_one_optional_kwd(1, b=3)
+    (1, 3)
+    """
+    return (a,b)
+
+def f_call_posonly_stararg(a,/,*args):
+    """
+    >>> f_call_posonly_stararg(1)
+    (1, ())
+    >>> f_call_posonly_stararg(1, 2, 3, 4)
+    (1, (2, 3, 4))
+    """
+    return (a,args)
+
+def f_call_posonly_kwarg(a,/,**kw):
+    """
+    >>> f_call_posonly_kwarg(1)
+    (1, {})
+    >>> all_args = f_call_posonly_kwarg(1, b=2, c=3, d=4)
+    >>> all_args == (1, {'b': 2, 'c': 3, 'd': 4}) or all_args
+    True
+    """
+    return (a,kw)
+
+def f_call_posonly_stararg_kwarg(a,/,*args,**kw):
+    """
+    >>> f_call_posonly_stararg_kwarg(1)
+    (1, (), {})
+    >>> f_call_posonly_stararg_kwarg(1, 2)
+    (1, (2,), {})
+    >>> all_args = f_call_posonly_stararg_kwarg(1, b=3, c=4)
+    >>> all_args == (1, (), {'b': 3, 'c': 4}) or all_args
+    True
+    >>> all_args = f_call_posonly_stararg_kwarg(1, 2, b=3, c=4)
+    >>> all_args == (1, (2,), {'b': 3, 'c': 4}) or all_args
+    True
+    """
+    return (a,args,kw)
+
+def test_empty_kwargs(a, b, /):
+    """
+    >>> test_empty_kwargs(1, 2)
+    (1, 2)
+    >>> test_empty_kwargs(1, 2, **{})
+    (1, 2)
+    >>> test_empty_kwargs(1, 2, **{'c': 3})
+    Traceback (most recent call last):
+    TypeError: test_empty_kwargs() got an unexpected keyword argument 'c'
+    """
+    return (a,b)
+
+
+@cython.cclass
+class TestExtensionClass:
+    """
+    >>> t = TestExtensionClass()
+    >>> t.f(1,2)
+    (1, 2, 3)
+    >>> t.f(1,2,4)
+    (1, 2, 4)
+    >>> t.f(1, 2, c=4)
+    (1, 2, 4)
+    >>> t.f(1, 2, 5, c=6)  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    TypeError: f() got multiple values for ...argument 'c'
+    """
+    def f(self, a, b, /, c=3):
+        return (a,b,c)
diff --git a/tests/run/powop.pyx b/tests/run/powop.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL3Bvd29wLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3Bvd29wLnB5eA== 100644
--- a/tests/run/powop.pyx
+++ b/tests/run/powop.pyx
@@ -123,5 +123,5 @@
     0.5
     >>> optimised_pow2(0.5) == 2 ** 0.5
     True
-    >>> optimised_pow2('test')
+    >>> optimised_pow2('test') # doctest: +ELLIPSIS
     Traceback (most recent call last):
@@ -127,5 +127,5 @@
     Traceback (most recent call last):
-    TypeError: unsupported operand type(s) for ** or pow(): 'int' and 'str'
+    TypeError: ...operand... **...
     """
     if isinstance(n, (int, long)) and 0 <= n < 1000:
         assert isinstance(2.0 ** n, float), 'float %s' % n
@@ -153,5 +153,5 @@
     0.5
     >>> optimised_pow2_inplace(0.5) == 2 ** 0.5
     True
-    >>> optimised_pow2_inplace('test')
+    >>> optimised_pow2_inplace('test') # doctest: +ELLIPSIS
     Traceback (most recent call last):
@@ -157,5 +157,5 @@
     Traceback (most recent call last):
-    TypeError: unsupported operand type(s) for ** or pow(): 'int' and 'str'
+    TypeError: ...operand... **...
     """
     x = 2
     x **= n
diff --git a/tests/run/pstats_profile_test.pyx b/tests/run/pstats_profile_test.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL3BzdGF0c19wcm9maWxlX3Rlc3QucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3BzdGF0c19wcm9maWxlX3Rlc3QucHl4 100644
--- a/tests/run/pstats_profile_test.pyx
+++ b/tests/run/pstats_profile_test.pyx
@@ -12,9 +12,7 @@
     >>> short_stats['f_cdef']
     100
     >>> short_stats['f_cpdef']
-    200
-    >>> short_stats['f_cpdef (wrapper)']
-    100
+    300
     >>> short_stats['f_inline']
     100
     >>> short_stats['f_inline_prof']
@@ -50,9 +48,7 @@
     >>> short_stats['m_cdef']
     100
     >>> short_stats['m_cpdef']
-    200
-    >>> short_stats['m_cpdef (wrapper)']
-    100
+    300
 
     >>> try:
     ...    os.unlink(statsfile)
@@ -60,6 +56,6 @@
     ...    pass
 
     >>> sorted(callees(s, 'test_profile'))  #doctest: +NORMALIZE_WHITESPACE
-    ['f_cdef', 'f_cpdef', 'f_cpdef (wrapper)', 'f_def',
+    ['f_cdef', 'f_cpdef', 'f_def',
      'f_inline', 'f_inline_prof',
      'f_raise',
@@ -64,6 +60,6 @@
      'f_inline', 'f_inline_prof',
      'f_raise',
-     'm_cdef', 'm_cpdef', 'm_cpdef (wrapper)', 'm_def',
+     'm_cdef', 'm_cpdef', 'm_def',
      'withgil_prof']
 
     >>> profile.runctx("test_generators()", locals(), globals(), statsfile)
diff --git a/tests/run/pstats_profile_test_pycfunc.pyx b/tests/run/pstats_profile_test_pycfunc.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3BzdGF0c19wcm9maWxlX3Rlc3RfcHljZnVuYy5weXg=
--- /dev/null
+++ b/tests/run/pstats_profile_test_pycfunc.pyx
@@ -0,0 +1,228 @@
+# tag: pstats
+# cython: profile = True
+# cython: binding = False
+
+__doc__ = u"""
+    >>> import os, tempfile, cProfile as profile, pstats
+    >>> statsfile = tempfile.mkstemp()[1]
+    >>> profile.runctx("test_profile(100)", locals(), globals(), statsfile)
+    >>> s = pstats.Stats(statsfile)
+    >>> short_stats = dict([(k[2], v[1]) for k,v in s.stats.items()])
+    >>> short_stats['f_def']
+    100
+    >>> short_stats['f_cdef']
+    100
+    >>> short_stats['f_cpdef']
+    200
+    >>> short_stats['f_cpdef (wrapper)']
+    100
+    >>> short_stats['f_inline']
+    100
+    >>> short_stats['f_inline_prof']
+    100
+    >>> short_stats['f_noprof']
+    Traceback (most recent call last):
+    ...
+    KeyError: 'f_noprof'
+    >>> short_stats['f_raise']
+    100
+
+    >>> short_stats['withgil_prof']
+    100
+    >>> short_stats['withgil_noprof']
+    Traceback (most recent call last):
+    ...
+    KeyError: 'withgil_noprof'
+
+    >>> short_stats['nogil_prof']
+    Traceback (most recent call last):
+    ...
+    KeyError: 'nogil_prof'
+    >>> short_stats['nogil_noprof']
+    Traceback (most recent call last):
+    ...
+    KeyError: 'nogil_noprof'
+
+    >>> short_stats['f_raise']
+    100
+
+    >>> short_stats['m_def']
+    200
+    >>> short_stats['m_cdef']
+    100
+    >>> short_stats['m_cpdef']
+    200
+    >>> short_stats['m_cpdef (wrapper)']
+    100
+
+    >>> try:
+    ...    os.unlink(statsfile)
+    ... except:
+    ...    pass
+
+    >>> sorted(callees(s, 'test_profile'))  #doctest: +NORMALIZE_WHITESPACE
+    ['f_cdef', 'f_cpdef', 'f_cpdef (wrapper)', 'f_def',
+     'f_inline', 'f_inline_prof',
+     'f_raise',
+     'm_cdef', 'm_cpdef', 'm_cpdef (wrapper)', 'm_def',
+     'withgil_prof']
+
+    >>> profile.runctx("test_generators()", locals(), globals(), statsfile)
+    >>> s = pstats.Stats(statsfile)
+    >>> short_stats = dict([(k[2], v[1]) for k,v in s.stats.items()])
+    >>> short_stats['generator']
+    3
+
+    >>> short_stats['generator_exception']
+    2
+
+    >>> short_stats['genexpr']
+    11
+
+    >>> sorted(callees(s, 'test_generators'))
+    ['call_generator', 'call_generator_exception', 'generator_expr']
+
+    >>> list(callees(s, 'call_generator'))
+    ['generator']
+
+    >>> list(callees(s, 'generator'))
+    []
+
+    >>> list(callees(s, 'generator_exception'))
+    []
+
+    >>> list(callees(s, 'generator_expr'))
+    ['genexpr']
+
+    >>> list(callees(s, 'genexpr'))
+    []
+
+    >>> def python_generator():
+    ...   yield 1
+    ...   yield 2
+    >>> def call_python_generator():
+    ...   list(python_generator())
+
+    >>> profile.runctx("call_python_generator()", locals(), globals(), statsfile)
+    >>> python_stats = pstats.Stats(statsfile)
+    >>> python_stats_dict = dict([(k[2], v[1]) for k,v in python_stats.stats.items()])
+
+    >>> profile.runctx("call_generator()", locals(), globals(), statsfile)
+    >>> cython_stats = pstats.Stats(statsfile)
+    >>> cython_stats_dict = dict([(k[2], v[1]) for k,v in cython_stats.stats.items()])
+
+    >>> python_stats_dict['python_generator'] == cython_stats_dict['generator']
+    True
+
+    >>> try:
+    ...    os.unlink(statsfile)
+    ... except:
+    ...    pass
+"""
+
+cimport cython
+
+def callees(pstats, target_caller):
+    pstats.calc_callees()
+    for (_, _, caller), callees in pstats.all_callees.items():
+      if caller == target_caller:
+        for (file, line, callee) in callees.keys():
+            if 'pyx' in file:
+                yield callee
+
+def test_profile(long N):
+    cdef long i, n = 0
+    cdef A a = A()
+    for i from 0 <= i < N:
+        n += f_def(i)
+        n += f_cdef(i)
+        n += f_cpdef(i)
+        n += (<object>f_cpdef)(i)
+        n += f_inline(i)
+        n += f_inline_prof(i)
+        n += f_noprof(i)
+        n += nogil_noprof(i)
+        n += nogil_prof(i)
+        n += withgil_noprof(i)
+        n += withgil_prof(i)
+        n += a.m_def(i)
+        n += (<object>a).m_def(i)
+        n += a.m_cpdef(i)
+        n += (<object>a).m_cpdef(i)
+        n += a.m_cdef(i)
+        try:
+            n += f_raise(i+2)
+        except RuntimeError:
+            pass
+    return n
+
+def f_def(long a):
+    return a
+
+cdef long f_cdef(long a):
+    return a
+
+cpdef long f_cpdef(long a):
+    return a
+
+cdef inline long f_inline(long a):
+    return a
+
+@cython.profile(True)
+cdef inline long f_inline_prof(long a):
+    return a
+
+@cython.profile(False)
+cdef int f_noprof(long a):
+    return a
+
+cdef long f_raise(long) except -2:
+    raise RuntimeError
+
+@cython.profile(False)
+cdef int withgil_noprof(long a) with gil:
+    return (a)
+@cython.profile(True)
+cdef int withgil_prof(long a) with gil:
+    return (a)
+
+@cython.profile(False)
+cdef int nogil_noprof(long a) nogil:
+    return a
+@cython.profile(True)
+cdef int nogil_prof(long a) nogil:
+    return a
+
+cdef class A(object):
+    def m_def(self, long a):
+        return a
+    cpdef m_cpdef(self, long a):
+        return a
+    cdef m_cdef(self, long a):
+        return a
+
+def test_generators():
+    call_generator()
+    call_generator_exception()
+    generator_expr()
+
+def call_generator():
+    list(generator())
+
+def generator():
+    yield 1
+    yield 2
+
+def call_generator_exception():
+    try:
+        list(generator_exception())
+    except ValueError:
+        pass
+
+def generator_exception():
+    yield 1
+    raise ValueError(2)
+
+def generator_expr():
+    e = (x for x in range(10))
+    return sum(e)
diff --git a/tests/run/public_fused_types.srctree b/tests/run/public_fused_types.srctree
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL3B1YmxpY19mdXNlZF90eXBlcy5zcmN0cmVl..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3B1YmxpY19mdXNlZF90eXBlcy5zcmN0cmVl 100644
--- a/tests/run/public_fused_types.srctree
+++ b/tests/run/public_fused_types.srctree
@@ -196,8 +196,8 @@
 def ae(result, expected):
     "assert equals"
     if result != expected:
-        print 'result  :', result
-        print 'expected:', expected
+        print('result  :', result)
+        print('expected:', expected)
 
     assert result == expected
 
@@ -227,7 +227,7 @@
 
 d = {'obj': obj, 'myobj': myobj, 'ae': ae}
 
-exec s in d
+exec(s, d)
 
 # Test def methods
 # ae(obj.def_method(12, 14.9), 26)
diff --git a/tests/run/pure.pyx b/tests/run/pure.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL3B1cmUucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3B1cmUucHl4 100644
--- a/tests/run/pure.pyx
+++ b/tests/run/pure.pyx
@@ -25,6 +25,8 @@
     (100, 100)
     >>> test_declare(100.5)
     (100, 100)
-    >>> test_declare(None)
+
+    # CPython: "TypeError: an integer is required"
+    >>> test_declare(None) # doctest: +ELLIPSIS
     Traceback (most recent call last):
     ...
@@ -29,6 +31,6 @@
     Traceback (most recent call last):
     ...
-    TypeError: an integer is required
+    TypeError: ...int...
     """
     x = cython.declare(cython.int)
     y = cython.declare(cython.int, n)
diff --git a/tests/run/pure_fused.pxd b/tests/run/pure_fused.pxd
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3B1cmVfZnVzZWQucHhk
--- /dev/null
+++ b/tests/run/pure_fused.pxd
@@ -0,0 +1,9 @@
+cimport cython
+
+ctypedef fused NotInPy:
+    int
+    float
+
+cdef class TestCls:
+    @cython.locals(loc = NotInPy)
+    cpdef cpfunc(self, NotInPy arg)
diff --git a/tests/run/pure_fused.py b/tests/run/pure_fused.py
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3B1cmVfZnVzZWQucHk=
--- /dev/null
+++ b/tests/run/pure_fused.py
@@ -0,0 +1,64 @@
+# mode: run
+# tag: fused, pure3.6
+
+#cython: annotation_typing=True
+
+import cython
+
+InPy = cython.fused_type(cython.int, cython.float)
+
+class TestCls:
+    # although annotations as strings isn't recommended and generates a warning
+    # it does allow the test to run on more (pure) Python versions
+    def func1(self, arg: 'NotInPy'):
+        """
+        >>> TestCls().func1(1.0)
+        'float'
+        >>> TestCls().func1(2)
+        'int'
+        """
+        loc: 'NotInPy' = arg
+        return cython.typeof(arg)
+
+    if cython.compiled:
+        @cython.locals(arg=NotInPy, loc=NotInPy)  # NameError for 'NotInPy' in pure Python
+        def func2(self, arg):
+            """
+            >>> TestCls().func2(1.0)
+            'float'
+            >>> TestCls().func2(2)
+            'int'
+            """
+            loc = arg
+            return cython.typeof(arg)
+
+    def cpfunc(self, arg):
+        """
+        >>> TestCls().cpfunc(1.0)
+        'float'
+        >>> TestCls().cpfunc(2)
+        'int'
+        """
+        loc = arg
+        return cython.typeof(arg)
+
+    def func1_inpy(self, arg: InPy):
+        """
+        >>> TestCls().func1_inpy(1.0)
+        'float'
+        >>> TestCls().func1_inpy(2)
+        'int'
+        """
+        loc: InPy = arg
+        return cython.typeof(arg)
+
+    @cython.locals(arg = InPy, loc = InPy)
+    def func2_inpy(self, arg):
+        """
+        >>> TestCls().func2_inpy(1.0)
+        'float'
+        >>> TestCls().func2_inpy(2)
+        'int'
+        """
+        loc = arg
+        return cython.typeof(arg)
diff --git a/tests/run/pure_py.py b/tests/run/pure_py.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL3B1cmVfcHkucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3B1cmVfcHkucHk= 100644
--- a/tests/run/pure_py.py
+++ b/tests/run/pure_py.py
@@ -36,10 +36,6 @@
     (100, 100)
     >>> test_declare(100.5)
     (100, 100)
-    >>> test_declare(None) #doctest: +ELLIPSIS
-    Traceback (most recent call last):
-    ...
-    TypeError: ...
     """
     x = cython.declare(cython.int)
     y = cython.declare(cython.int, n)
@@ -422,3 +418,133 @@
     True
     """
     def meth(self): pass
+
+@cython.cclass
+class Foo:
+    a = cython.declare(cython.double)
+    b = cython.declare(cython.double)
+    c = cython.declare(cython.double)
+
+    @cython.locals(a=cython.double, b=cython.double, c=cython.double)
+    def __init__(self, a, b, c):
+        self.a = a
+        self.b = b
+        self.c = c
+
+@cython.cclass
+class EmptyClass(object):
+    def __init__(self, *args):
+        pass
+
+def same_type_cast():
+    """
+    >>> same_type_cast()
+    True
+    """
+
+    f = EmptyClass()
+    return f is cython.cast(EmptyClass, f)
+
+def multi_args_init_cast():
+    """
+    >>> multi_args_init_cast()
+    True
+    """
+    f = Foo(10, 20, 30)
+    return cython.cast(Foo, f) is f
+
+def multi_args_init_declare():
+    """
+    >>> multi_args_init_declare() is None
+    True
+    """
+    f = cython.declare(Foo)
+
+    if cython.compiled:
+        f = None
+
+    return f
+
+EmptyClassSyn = cython.typedef(EmptyClass)
+
+def empty_declare():
+    """
+    >>> empty_declare()
+    []
+    """
+
+    r0 = cython.declare(EmptyClass)
+    r1 = cython.declare(EmptyClassSyn)
+    r2 = cython.declare(MyStruct)
+    r3 = cython.declare(MyUnion)
+    r4 = cython.declare(MyStruct2)
+    r5 = cython.declare(cython.int[2])
+
+    if cython.compiled:
+        r0 = None
+        r1 = None
+
+    res = [
+        r0 is None,
+        r1 is None,
+        r2 is not None,
+        r3 is not None,
+        r4 is not None,
+        r5 is not None
+    ]
+
+    r2.is_integral = True
+    assert( r2.is_integral == True )
+
+    r3.x = 12.3
+    assert( r3.x == 12.3 )
+
+    #It generates a correct C code, but raises an exception when interpreted
+    if cython.compiled:
+        r4[0].is_integral = True
+        assert( r4[0].is_integral == True )
+
+    r5[0] = 42
+    assert ( r5[0] == 42 )
+
+    return [i for i, x in enumerate(res) if not x]
+
+def same_declare():
+    """
+    >>> same_declare()
+    True
+    """
+
+    f = EmptyClass()
+    f2 = cython.declare(EmptyClass, f)
+    return f2 is f
+
+def none_cast():
+    """
+    >>> none_cast() is None
+    True
+    """
+
+    f = None
+    return cython.cast(EmptyClass, f)
+
+def none_declare():
+    """
+    >>> none_declare() is None
+    True
+    """
+
+    f = None
+    f2 = cython.declare(Foo, f)
+    return f2
+
+def array_init_with_list():
+    """
+    >>> array_init_with_list()
+    [10, 42]
+    """
+    x = cython.declare(cython.int[20], list(range(20)))
+    x[12] = 42
+
+    return [x[10], x[12]]
+
diff --git a/tests/run/py_hash_t.pyx b/tests/run/py_hash_t.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL3B5X2hhc2hfdC5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3B5X2hhc2hfdC5weXg= 100644
--- a/tests/run/py_hash_t.pyx
+++ b/tests/run/py_hash_t.pyx
@@ -2,9 +2,16 @@
 cimport cython
 
 
+class IntLike(object):
+  def __init__(self, value):
+    self.value = value
+  def __index__(self):
+    return self.value
+
+
 def assign_py_hash_t(x):
     """
     >>> assign_py_hash_t(12)
     12
     >>> assign_py_hash_t(-12)
     -12
@@ -5,9 +12,20 @@
 def assign_py_hash_t(x):
     """
     >>> assign_py_hash_t(12)
     12
     >>> assign_py_hash_t(-12)
     -12
+
+    >>> assign_py_hash_t(IntLike(-3))
+    -3
+    >>> assign_py_hash_t(IntLike(1 << 100))  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    ...
+    OverflowError: ...
+    >>> assign_py_hash_t(IntLike(1.5))  # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    ...
+    TypeError: __index__ ... (type ...float...)
     """
     cdef Py_hash_t h = x
     return h
diff --git a/tests/run/py_ucs4_type.pyx b/tests/run/py_ucs4_type.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL3B5X3VjczRfdHlwZS5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3B5X3VjczRfdHlwZS5weXg= 100644
--- a/tests/run/py_ucs4_type.pyx
+++ b/tests/run/py_ucs4_type.pyx
@@ -132,7 +132,7 @@
         uchar.isupper(),
         ]
 
-@cython.test_assert_path_exists('//PythonCapiCallNode')
-@cython.test_fail_if_path_exists('//SimpleCallNode')
+#@cython.test_assert_path_exists('//PythonCapiCallNode')
+#@cython.test_fail_if_path_exists('//SimpleCallNode')
 def unicode_methods(Py_UCS4 uchar):
     """
@@ -137,4 +137,6 @@
 def unicode_methods(Py_UCS4 uchar):
     """
-    >>> unicode_methods(ord('A')) == ['a', 'A', 'A']
+    >>> unicode_methods(ord('A')) == ['a', 'A', 'A'] or unicode_methods(ord('A'))
+    True
+    >>> unicode_methods(ord('a')) == ['a', 'A', 'A'] or unicode_methods(ord('a'))
     True
@@ -140,4 +142,9 @@
     True
-    >>> unicode_methods(ord('a')) == ['a', 'A', 'A']
+    >>> unicode_methods(0x1E9E) == [u'\\xdf', u'\\u1e9e', u'\\u1e9e'] or unicode_methods(0x1E9E)
+    True
+    >>> unicode_methods(0x0130) in (
+    ...     [u'i\\u0307', u'\\u0130', u'\\u0130'],  # Py3
+    ...     [u'i', u'\\u0130', u'\\u0130'],  # Py2
+    ... ) or unicode_methods(0x0130)
     True
     """
@@ -142,5 +149,7 @@
     True
     """
+    # \u1E9E == 'LATIN CAPITAL LETTER SHARP S'
+    # \u0130 == 'LATIN CAPITAL LETTER I WITH DOT ABOVE'
     return [
         # character conversion
         uchar.lower(),
@@ -149,11 +158,11 @@
         ]
 
 
-@cython.test_assert_path_exists('//PythonCapiCallNode')
-@cython.test_fail_if_path_exists(
-    '//SimpleCallNode',
-    '//CoerceFromPyTypeNode',
-)
+#@cython.test_assert_path_exists('//PythonCapiCallNode')
+#@cython.test_fail_if_path_exists(
+#    '//SimpleCallNode',
+#    '//CoerceFromPyTypeNode',
+#)
 def unicode_method_return_type(Py_UCS4 uchar):
     """
     >>> unicode_method_return_type(ord('A'))
@@ -366,5 +375,5 @@
 
 
 _WARNINGS = """
-364:16: Item lookup of unicode character codes now always converts to a Unicode string. Use an explicit C integer cast to get back the previous integer lookup behaviour.
+373:16: Item lookup of unicode character codes now always converts to a Unicode string. Use an explicit C integer cast to get back the previous integer lookup behaviour.
 """
diff --git a/tests/run/py_unicode_type.pyx b/tests/run/py_unicode_type.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL3B5X3VuaWNvZGVfdHlwZS5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3B5X3VuaWNvZGVfdHlwZS5weXg= 100644
--- a/tests/run/py_unicode_type.pyx
+++ b/tests/run/py_unicode_type.pyx
@@ -123,8 +123,8 @@
         uchar.isupper(),
         ]
 
-@cython.test_assert_path_exists('//PythonCapiCallNode')
-@cython.test_fail_if_path_exists('//SimpleCallNode')
+#@cython.test_assert_path_exists('//PythonCapiCallNode')
+#@cython.test_fail_if_path_exists('//SimpleCallNode')
 def unicode_methods(Py_UNICODE uchar):
     """
     >>> unicode_methods(ord('A')) == ['a', 'A', 'A']
diff --git a/tests/run/pyintop.pyx b/tests/run/pyintop.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL3B5aW50b3AucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3B5aW50b3AucHl4 100644
--- a/tests/run/pyintop.pyx
+++ b/tests/run/pyintop.pyx
@@ -25,6 +25,8 @@
 @cython.test_fail_if_path_exists('//IntBinopNode')
 def or_int(obj2):
     """
+    >>> or_int(0)
+    16
     >>> or_int(1)
     17
     >>> or_int(16)
@@ -47,6 +49,8 @@
 @cython.test_fail_if_path_exists('//IntBinopNode')
 def xor_int(obj2):
     """
+    >>> xor_int(0)
+    16
     >>> xor_int(2)
     18
     >>> xor_int(16)
@@ -69,7 +73,9 @@
 @cython.test_fail_if_path_exists('//IntBinopNode')
 def and_int(obj2):
     """
+    >>> and_int(0)
+    0
     >>> and_int(1)
     0
     >>> and_int(18)
     16
@@ -72,7 +78,9 @@
     >>> and_int(1)
     0
     >>> and_int(18)
     16
+    >>> and_int(-1)
+    16
     """
     obj1 = obj2 & 0x10
     return obj1
@@ -98,6 +106,25 @@
     return obj1
 
 
+@cython.test_assert_path_exists('//IntBinopNode')
+def rshift_int_obj(obj3):
+    """
+    >>> rshift_int_obj(3)
+    0
+    >>> rshift_int_obj(2)
+    0
+    >>> rshift_int_obj(1)
+    1
+    >>> rshift_int_obj(0)
+    2
+    >>> rshift_int_obj(-1)
+    Traceback (most recent call last):
+    ValueError: negative shift count
+    """
+    obj1 = 2 >> obj3
+    return obj1
+
+
 @cython.test_fail_if_path_exists('//IntBinopNode')
 def rshift_int(obj2):
     """
@@ -101,6 +128,8 @@
 @cython.test_fail_if_path_exists('//IntBinopNode')
 def rshift_int(obj2):
     """
+    >>> rshift_int(0)
+    0
     >>> rshift_int(2)
     0
 
@@ -226,6 +255,8 @@
 )
 def mixed_int(obj2):
     """
+    >>> mixed_int(0)
+    16
     >>> mixed_int(2)
     18
     >>> mixed_int(16)
diff --git a/tests/run/r_docstrings.pyx b/tests/run/r_docstrings.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL3JfZG9jc3RyaW5ncy5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3JfZG9jc3RyaW5ncy5weXg= 100644
--- a/tests/run/r_docstrings.pyx
+++ b/tests/run/r_docstrings.pyx
@@ -14,5 +14,10 @@
 
     >>> C.__doc__
     '\\n    This is a class docstring.\\n    '
+    >>> C.docstring_copy_C
+    '\\n    This is a class docstring.\\n    '
+    >>> CS.docstring_copy_C
+    '\\n    This is a class docstring.\\n    '
+
     >>> CS.__doc__
     '\\n    This is a subclass docstring.\\n    '
@@ -17,4 +22,8 @@
     >>> CS.__doc__
     '\\n    This is a subclass docstring.\\n    '
+    >>> CS.docstring_copy_CS
+    '\\n    This is a subclass docstring.\\n    '
+    >>> CSS.docstring_copy_CS
+    '\\n    This is a subclass docstring.\\n    '
     >>> print(CSS.__doc__)
     None
@@ -19,5 +28,7 @@
     >>> print(CSS.__doc__)
     None
+    >>> CSS.docstring_copy_CSS
+    'A module docstring'
 
     >>> T.__doc__
     '\\n    This is an extension type docstring.\\n    '
@@ -34,7 +45,7 @@
     >>> Pyf.__doc__
     '\\n    This is a function docstring.\\n    '
 
-    >>> class PyC:
+    >>> class PyC(object):
     ...     '''
     ...     This is a class docstring.
     ...     '''
@@ -38,7 +49,8 @@
     ...     '''
     ...     This is a class docstring.
     ...     '''
-    >>> class PyCS(C):
+    ...     docstring_copy_C = __doc__
+    >>> class PyCS(PyC):
     ...     '''
     ...     This is a subclass docstring.
     ...     '''
@@ -42,8 +54,9 @@
     ...     '''
     ...     This is a subclass docstring.
     ...     '''
-    >>> class PyCSS(CS):
-    ...     pass
+    ...     docstring_copy_CS = __doc__
+    >>> class PyCSS(PyCS):
+    ...     docstring_copy_CSS = __doc__
 
     >>> PyC.__doc__
     '\\n    This is a class docstring.\\n    '
@@ -47,5 +60,12 @@
 
     >>> PyC.__doc__
     '\\n    This is a class docstring.\\n    '
+    >>> PyC.docstring_copy_C
+    '\\n    This is a class docstring.\\n    '
+    >>> PyCS.docstring_copy_C
+    '\\n    This is a class docstring.\\n    '
+    >>> PyCSS.docstring_copy_C
+    '\\n    This is a class docstring.\\n    '
+
     >>> PyCS.__doc__
     '\\n    This is a subclass docstring.\\n    '
@@ -50,3 +70,8 @@
     >>> PyCS.__doc__
     '\\n    This is a subclass docstring.\\n    '
+    >>> PyCS.docstring_copy_CS
+    '\\n    This is a subclass docstring.\\n    '
+    >>> PyCSS.docstring_copy_CS
+    '\\n    This is a subclass docstring.\\n    '
+
     >>> PyCSS.__doc__
@@ -52,4 +77,6 @@
     >>> PyCSS.__doc__
+    >>> PyCSS.docstring_copy_CSS
+    'A module docstring'
 """
 
 __test__ = {"test_docstrings" : doctest}
@@ -59,7 +86,8 @@
     This is a function docstring.
     """
 
-class C:
+
+class C(object):
     """
     This is a class docstring.
     """
@@ -63,8 +91,10 @@
     """
     This is a class docstring.
     """
+    docstring_copy_C = __doc__
+
 
 class CS(C):
     """
     This is a subclass docstring.
     """
@@ -66,7 +96,9 @@
 
 class CS(C):
     """
     This is a subclass docstring.
     """
+    docstring_copy_CS = __doc__
+
 
 class CSS(CS):
@@ -71,6 +103,7 @@
 
 class CSS(CS):
-    pass
+    docstring_copy_CSS = __doc__
+
 
 cdef class T:
     """
diff --git a/tests/run/reduce_pickle.pyx b/tests/run/reduce_pickle.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL3JlZHVjZV9waWNrbGUucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3JlZHVjZV9waWNrbGUucHl4 100644
--- a/tests/run/reduce_pickle.pyx
+++ b/tests/run/reduce_pickle.pyx
@@ -287,3 +287,20 @@
           return "Wrapper(...)"
       else:
           return "Wrapper(%r)" % self.ref
+
+
+# Non-regression test for pickling bound and unbound methods of non-extension
+# classes
+if sys.version_info[:2] >= (3, 5):
+    # builtin methods not picklable for python <= 3.4
+    class MyClass(object):
+        """
+        >>> import pickle
+        >>> pickle.loads(pickle.dumps(MyClass.my_method)) is MyClass.my_method
+        True
+        >>> bound_method = pickle.loads(pickle.dumps(MyClass().my_method))
+        >>> bound_method(1)
+        1
+        """
+        def my_method(self, x):
+            return x
diff --git a/tests/run/reimport_failure.srctree b/tests/run/reimport_failure.srctree
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3JlaW1wb3J0X2ZhaWx1cmUuc3JjdHJlZQ==
--- /dev/null
+++ b/tests/run/reimport_failure.srctree
@@ -0,0 +1,38 @@
+# mode: run
+# tag: pep489
+
+"""
+PYTHON setup.py build_ext -i
+PYTHON tester.py
+"""
+
+######## setup.py ########
+
+from Cython.Build.Dependencies import cythonize
+from distutils.core import setup
+
+setup(
+  ext_modules = cythonize("*.pyx"),
+)
+
+
+######## failure.pyx ########
+
+if globals():  # runtime True to confuse dead code removal
+    raise ImportError
+
+cdef class C:
+    cdef int a
+
+
+######## tester.py ########
+
+try:
+    try:
+        import failure  # 1
+    except ImportError:
+        import failure  # 2
+except ImportError:
+    pass
+else:
+    raise RuntimeError("ImportError was not raised on second import!")
diff --git a/tests/run/reimport_from_package.srctree b/tests/run/reimport_from_package.srctree
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL3JlaW1wb3J0X2Zyb21fcGFja2FnZS5zcmN0cmVl..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3JlaW1wb3J0X2Zyb21fcGFja2FnZS5zcmN0cmVl 100644
--- a/tests/run/reimport_from_package.srctree
+++ b/tests/run/reimport_from_package.srctree
@@ -17,8 +17,8 @@
 
 import sys
 import a
-assert a in sys.modules.values(), list(sys.modules)
-assert sys.modules['a'] is a, list(sys.modules)
+assert a in sys.modules.values(), sorted(sys.modules)
+assert sys.modules['a'] is a, sorted(sys.modules)
 
 from atest.package import module
 
@@ -33,8 +33,8 @@
 
 import a
 import atest.package.module as module
-assert module in sys.modules.values(), list(sys.modules)
-assert sys.modules['atest.package.module'] is module, list(sys.modules)
+assert module in sys.modules.values(), sorted(sys.modules)
+assert sys.modules['atest.package.module'] is module, sorted(sys.modules)
 
 if sys.version_info >= (3, 5):
     from . import pymodule
diff --git a/tests/run/relative_cimport.srctree b/tests/run/relative_cimport.srctree
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL3JlbGF0aXZlX2NpbXBvcnQuc3JjdHJlZQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3JlbGF0aXZlX2NpbXBvcnQuc3JjdHJlZQ== 100644
--- a/tests/run/relative_cimport.srctree
+++ b/tests/run/relative_cimport.srctree
@@ -3,6 +3,7 @@
 
 PYTHON setup.py build_ext --inplace
 PYTHON -c "from pkg.b import test; assert test() == (1, 2)"
+PYTHON -c "from pkg.b_py2 import test; assert test() == (1, 2)"
 PYTHON -c "from pkg.sub.c import test; assert test() == (1, 2)"
 
 ######## setup.py ########
@@ -42,7 +43,23 @@
 
 from . cimport a
 from .a cimport test_pxd
-cimport a as implicitly_relative_a
+
+assert a.test_pxd is test_pxd
+
+def test():
+    cdef test_pxd obj = test_pxd()
+    obj.x = 1
+    obj.y = 2
+    return (obj.x, obj.y)
+
+
+######## pkg/b_py2.pyx ########
+
+# cython: language_level=2
+
+from . cimport a
+from .a cimport test_pxd
+cimport a as implicitly_relative_a  # <-- Py2 "feature"
 
 assert a.test_pxd is test_pxd
 assert implicitly_relative_a.test_pxd is test_pxd
diff --git a/tests/run/relativeimport_T542.srctree b/tests/run/relativeimport_T542.srctree
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL3JlbGF0aXZlaW1wb3J0X1Q1NDIuc3JjdHJlZQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3JlbGF0aXZlaW1wb3J0X1Q1NDIuc3JjdHJlZQ== 100644
--- a/tests/run/relativeimport_T542.srctree
+++ b/tests/run/relativeimport_T542.srctree
@@ -26,7 +26,8 @@
 except ImportError:
     pass
 else:
-    assert False, "absolute import succeeded"
+    import sys
+    assert False, "absolute import succeeded: %s" % sorted(sys.modules)
 
 import relimport.a
 import relimport.bmod
diff --git a/tests/run/sequential_parallel.pyx b/tests/run/sequential_parallel.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL3NlcXVlbnRpYWxfcGFyYWxsZWwucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3NlcXVlbnRpYWxfcGFyYWxsZWwucHl4 100644
--- a/tests/run/sequential_parallel.pyx
+++ b/tests/run/sequential_parallel.pyx
@@ -656,7 +656,7 @@
         sum += inner_parallel_section()
     return sum
 
-cdef int nogil_cdef_except_clause() nogil except 0:
+cdef int nogil_cdef_except_clause() nogil except -1:
     return 1
 
 cdef void nogil_cdef_except_star() nogil except *:
diff --git a/tests/run/set_item.pyx b/tests/run/set_item.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3NldF9pdGVtLnB5eA==
--- /dev/null
+++ b/tests/run/set_item.pyx
@@ -0,0 +1,75 @@
+# mode: run
+# tag: list, dict, setitem, delitem
+
+def set_item(obj, key, value):
+    """
+    >>> set_item([1, 2, 3], 1, -1)
+    [1, -1, 3]
+    >>> set_item([1, 2, 3], -1, -1)
+    [1, 2, -1]
+    >>> set_item({}, 'abc', 5)
+    {'abc': 5}
+    >>> set_item({}, -1, 5)
+    {-1: 5}
+    >>> class D(dict): pass
+    >>> set_item(D({}), 'abc', 5)
+    {'abc': 5}
+    >>> set_item(D({}), -1, 5)
+    {-1: 5}
+    """
+    obj[key] = value
+    return obj
+
+
+def set_item_int(obj, int key, value):
+    """
+    >>> set_item_int([1, 2, 3], 1, -1)
+    [1, -1, 3]
+    >>> set_item_int([1, 2, 3], -1, -1)
+    [1, 2, -1]
+    >>> set_item_int({}, 1, 5)
+    {1: 5}
+    >>> set_item_int({}, -1, 5)
+    {-1: 5}
+    >>> class D(dict): pass
+    >>> set_item_int(D({}), 1, 5)
+    {1: 5}
+    >>> set_item_int(D({}), -1, 5)
+    {-1: 5}
+    """
+    obj[key] = value
+    return obj
+
+
+def del_item(obj, key):
+    """
+    >>> del_item([1, 2, 3], 1)
+    [1, 3]
+    >>> del_item([1, 2, 3], -3)
+    [2, 3]
+    >>> class D(dict): pass
+    >>> del_item({'abc': 1, 'def': 2}, 'abc')
+    {'def': 2}
+    >>> del_item(D({'abc': 1, 'def': 2}), 'abc')
+    {'def': 2}
+    >>> del_item(D({-1: 1, -2: 2}), -1)
+    {-2: 2}
+    """
+    del obj[key]
+    return obj
+
+
+def del_item_int(obj, int key):
+    """
+    >>> del_item_int([1, 2, 3], 1)
+    [1, 3]
+    >>> del_item_int([1, 2, 3], -3)
+    [2, 3]
+    >>> class D(dict): pass
+    >>> del_item_int(D({-1: 1, 1: 2}), 1)
+    {-1: 1}
+    >>> del_item_int(D({-1: 1, -2: 2}), -1)
+    {-2: 2}
+    """
+    del obj[key]
+    return obj
diff --git a/tests/run/set_new.py b/tests/run/set_new.py
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3NldF9uZXcucHk=
--- /dev/null
+++ b/tests/run/set_new.py
@@ -0,0 +1,21 @@
+"""
+>>> X = make_class_with_new(cynew)
+>>> X.__new__ is cynew
+True
+>>> X().__new__ is cynew
+True
+>>> def pynew(cls): return object.__new__(cls)
+>>> X = make_class_with_new(pynew)
+>>> X.__new__ is pynew
+True
+>>> X().__new__ is pynew
+True
+"""
+
+def make_class_with_new(n):
+    class X(object):
+        __new__ = n
+    return X
+
+def cynew(cls):
+    return object.__new__(cls)
diff --git a/tests/run/starargs.pyx b/tests/run/starargs.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL3N0YXJhcmdzLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3N0YXJhcmdzLnB5eA== 100644
--- a/tests/run/starargs.pyx
+++ b/tests/run/starargs.pyx
@@ -1,7 +1,6 @@
 cdef sorteditems(d):
-    l = list(d.items())
-    l.sort()
-    return tuple(l)
+    return tuple(sorted(d.items()))
+
 
 def spam(x, y, z):
     """
@@ -79,6 +78,8 @@
     >>> onlyt(1, a=2)
     Traceback (most recent call last):
     TypeError: onlyt() got an unexpected keyword argument 'a'
+    >>> test_no_copy_args(onlyt)
+    True
     """
     return a
 
@@ -114,3 +115,20 @@
     (1, ('a', 1), ('b', 2))
     """
     return a + sorteditems(k)
+
+def t_kwonly(*a, k):
+    """
+    >>> test_no_copy_args(t_kwonly, k=None)
+    True
+    """
+    return a
+
+
+def test_no_copy_args(func, **kw):
+    """
+    func is a function such that func(*args, **kw) returns args.
+    We test that no copy is made of the args tuple.
+    This tests both the caller side and the callee side.
+    """
+    args = (1, 2, 3)
+    return func(*args, **kw) is args
diff --git a/tests/run/staticmethod.pyx b/tests/run/staticmethod.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL3N0YXRpY21ldGhvZC5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3N0YXRpY21ldGhvZC5weXg= 100644
--- a/tests/run/staticmethod.pyx
+++ b/tests/run/staticmethod.pyx
@@ -1,19 +1,2 @@
-__doc__ = u"""
->>> class1.plus1(1)
-2
->>> class2.plus1(1)
-2
->>> class3.plus1(1)
-2
->>> class4.plus1(1)
-2
->>> class4().plus1(1)
-2
->>> class4.bplus1(1)
-2
->>> class4().bplus1(1)
-2
-"""
-
 cimport cython
 
@@ -18,6 +1,4 @@
 cimport cython
 
-def f_plus(a):
-    return a + 1
 
 class class1:
@@ -22,14 +3,15 @@
 
 class class1:
-    plus1 = f_plus
-
-class class2(object):
-    plus1 = f_plus
-
-cdef class class3:
-    plus1 = f_plus
-
-class class4:
+    u"""
+    >>> class1.plus1(1)
+    2
+    >>> class1().plus1(1)
+    2
+    >>> class1.bplus1(1)
+    2
+    >>> class1().bplus1(1)
+    2
+    """
     @staticmethod
     def plus1(a):
         return a + 1
@@ -49,10 +31,10 @@
     >>> obj.plus1(1)
     2
     """
-    class class5(object):
+    class class2(object):
         def __new__(cls): # implicit staticmethod
             return object.__new__(cls)
 
         @staticmethod
         def plus1(a):
             return a + 1
@@ -53,10 +35,10 @@
         def __new__(cls): # implicit staticmethod
             return object.__new__(cls)
 
         @staticmethod
         def plus1(a):
             return a + 1
-    return class5
+    return class2
 
 
 cdef class BaseClass(object):
diff --git a/tests/run/str_subclass_kwargs.pyx b/tests/run/str_subclass_kwargs.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3N0cl9zdWJjbGFzc19rd2FyZ3MucHl4
--- /dev/null
+++ b/tests/run/str_subclass_kwargs.pyx
@@ -0,0 +1,21 @@
+def test_str_subclass_kwargs(k=None):
+    """
+    Test passing keywords with names that are not of type ``str``
+    but a subclass:
+
+    >>> class StrSubclass(str):
+    ...     pass
+    >>> class StrNoCompare(str):
+    ...     def __eq__(self, other):
+    ...         raise RuntimeError("do not compare me")
+    ...     def __hash__(self):
+    ...         return hash(str(self))
+    >>> kwargs = {StrSubclass('k'): 'value'}
+    >>> test_str_subclass_kwargs(**kwargs)
+    'value'
+    >>> kwargs = {StrNoCompare('k'): 'value'}
+    >>> test_str_subclass_kwargs(**kwargs)
+    Traceback (most recent call last):
+    RuntimeError: do not compare me
+    """
+    return k
diff --git a/tests/run/strfunction.pyx b/tests/run/strfunction.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL3N0cmZ1bmN0aW9uLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3N0cmZ1bmN0aW9uLnB5eA== 100644
--- a/tests/run/strfunction.pyx
+++ b/tests/run/strfunction.pyx
@@ -5,6 +5,8 @@
    'test'
 """
 
+cimport cython
+
 s = str
 z = str('test')
 
@@ -39,3 +41,33 @@
 
 #def csub(string):
 #    return csubs(string)
+
+
+@cython.test_fail_if_path_exists("//SimpleCallNode")
+@cython.test_assert_path_exists("//PythonCapiCallNode")
+def typed(str s):
+    """
+    >>> print(typed(None))
+    None
+    >>> type(typed(None)) is type(typed(None))
+    True
+    >>> print(typed('abc'))
+    abc
+    >>> type(typed('abc')) is type(typed('abc'))
+    True
+    """
+    return str(s)
+
+
+@cython.test_fail_if_path_exists(
+    "//SimpleCallNode",
+    "//PythonCapiCallNode",
+)
+def typed_not_none(str s not None):
+    """
+    >>> print(typed('abc'))
+    abc
+    >>> type(typed('abc')) is type(typed('abc'))
+    True
+    """
+    return str(s)
diff --git a/tests/run/struct_conversion.pyx b/tests/run/struct_conversion.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL3N0cnVjdF9jb252ZXJzaW9uLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3N0cnVjdF9jb252ZXJzaW9uLnB5eA== 100644
--- a/tests/run/struct_conversion.pyx
+++ b/tests/run/struct_conversion.pyx
@@ -28,5 +28,5 @@
     """
     >>> sorted(test_constructor_kwds(1.25, 2.5, 128).items())
     [('color', 128), ('x', 1.25), ('y', 2.5)]
-    >>> test_constructor_kwds(1.25, 2.5, None)
+    >>> test_constructor_kwds(1.25, 2.5, None)  # doctest: +ELLIPSIS
     Traceback (most recent call last):
@@ -32,6 +32,5 @@
     Traceback (most recent call last):
-    ...
-    TypeError: an integer is required
+    TypeError:... int...
     """
     cdef Point p = Point(x=x, y=y, color=color)
     return p
@@ -41,5 +40,5 @@
     """
     >>> sorted(return_constructor_kwds(1.25, 2.5, 128).items())
     [('color', 128), ('x', 1.25), ('y', 2.5)]
-    >>> return_constructor_kwds(1.25, 2.5, None)
+    >>> return_constructor_kwds(1.25, 2.5, None)  # doctest: +ELLIPSIS
     Traceback (most recent call last):
@@ -45,6 +44,5 @@
     Traceback (most recent call last):
-    ...
-    TypeError: an integer is required
+    TypeError:... int...
     """
     return Point(x=x, y=y, color=color)
 
@@ -169,3 +167,19 @@
                                             nested.mystruct.s.decode('UTF-8'),
                                             nested.d)
 
+cdef struct OverriddenCname:
+    int x "not_x"
+
+def test_obj_to_struct_cnames(OverriddenCname s):
+    """
+    >>> test_obj_to_struct_cnames({ 'x': 1 })
+    1
+    """
+    print(s.x)
+
+def test_struct_to_obj_cnames():
+    """
+    >>> test_struct_to_obj_cnames()
+    {'x': 2}
+    """
+    return OverriddenCname(2)
diff --git a/tests/run/subop.pyx b/tests/run/subop.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL3N1Ym9wLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3N1Ym9wLnB5eA== 100644
--- a/tests/run/subop.pyx
+++ b/tests/run/subop.pyx
@@ -191,3 +191,27 @@
     ... except TypeError: pass
     """
     return 2**30 - x
+
+
+def sub0(x):
+    """
+    >>> sub0(0)
+    (0, 0)
+    >>> sub0(1)
+    (1, -1)
+    >>> sub0(-1)
+    (-1, 1)
+    >>> sub0(99)
+    (99, -99)
+    >>> a, b = sub0(2**32)
+    >>> bigint(a)
+    4294967296
+    >>> bigint(b)
+    -4294967296
+    >>> a, b = sub0(-2**32)
+    >>> bigint(a)
+    -4294967296
+    >>> bigint(b)
+    4294967296
+    """
+    return x - 0, 0 - x
diff --git a/tests/run/test_asyncgen.py b/tests/run/test_asyncgen.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL3Rlc3RfYXN5bmNnZW4ucHk=..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3Rlc3RfYXN5bmNnZW4ucHk= 100644
--- a/tests/run/test_asyncgen.py
+++ b/tests/run/test_asyncgen.py
@@ -247,16 +247,6 @@
             else:
                 self.assertTrue(False)
 
-    if sys.version_info < (2, 7):
-        def assertIn(self, x, container):
-            self.assertTrue(x in container)
-
-        def assertIs(self, x, y):
-            self.assertTrue(x is y)
-
-        assertRaises = assertRaisesRegex
-
-
     def compare_generators(self, sync_gen, async_gen):
         def sync_iterate(g):
             res = []
@@ -273,4 +263,5 @@
         def async_iterate(g):
             res = []
             while True:
+                an = g.__anext__()
                 try:
@@ -276,5 +267,19 @@
                 try:
-                    next(g.__anext__())
+                    while True:
+                        try:
+                            next(an)
+                        except StopIteration as ex:
+                            if ex.args:
+                                res.append(ex.args[0])
+                                break
+                            else:
+                                res.append('EMPTY StopIteration')
+                                break
+                        except StopAsyncIteration:
+                            raise
+                        except Exception as ex:
+                            res.append(str(type(ex)))
+                            break
                 except StopAsyncIteration:
                     res.append('STOP')
                     break
@@ -278,14 +283,6 @@
                 except StopAsyncIteration:
                     res.append('STOP')
                     break
-                except StopIteration as ex:
-                    if ex.args:
-                        res.append(ex.args[0])
-                    else:
-                        res.append('EMPTY StopIteration')
-                        break
-                except Exception as ex:
-                    res.append(str(type(ex)))
             return res
 
         sync_gen_result = sync_iterate(sync_gen)
@@ -313,6 +310,8 @@
 
         g = gen()
         ai = g.__aiter__()
-        self.assertEqual(next(ai.__anext__()), ('result',))
+
+        an = ai.__anext__()
+        self.assertEqual(next(an), ('result',))
 
         try:
@@ -317,8 +316,8 @@
 
         try:
-            next(ai.__anext__())
+            next(an)
         except StopIteration as ex:
             self.assertEqual(ex.args[0], 123)
         else:
             self.fail('StopIteration was not raised')
 
@@ -320,8 +319,9 @@
         except StopIteration as ex:
             self.assertEqual(ex.args[0], 123)
         else:
             self.fail('StopIteration was not raised')
 
-        self.assertEqual(next(ai.__anext__()), ('result',))
+        an = ai.__anext__()
+        self.assertEqual(next(an), ('result',))
 
         try:
@@ -326,6 +326,6 @@
 
         try:
-            next(ai.__anext__())
+            next(an)
         except StopAsyncIteration as ex:
             self.assertFalse(ex.args)
         else:
@@ -349,6 +349,8 @@
 
         g = gen()
         ai = g.__aiter__()
-        self.assertEqual(next(ai.__anext__()), ('result',))
+
+        an = ai.__anext__()
+        self.assertEqual(next(an), ('result',))
 
         try:
@@ -353,6 +355,6 @@
 
         try:
-            next(ai.__anext__())
+            next(an)
         except StopIteration as ex:
             self.assertEqual(ex.args[0], 123)
         else:
@@ -459,6 +461,37 @@
                                     "non-None value .* async generator"):
             gen().__anext__().send(100)
 
+    def test_async_gen_exception_11(self):
+        def sync_gen():
+            yield 10
+            yield 20
+
+        def sync_gen_wrapper():
+            yield 1
+            sg = sync_gen()
+            sg.send(None)
+            try:
+                sg.throw(GeneratorExit())
+            except GeneratorExit:
+                yield 2
+            yield 3
+
+        async def async_gen():
+            yield 10
+            yield 20
+
+        async def async_gen_wrapper():
+            yield 1
+            asg = async_gen()
+            await asg.asend(None)
+            try:
+                await asg.athrow(GeneratorExit())
+            except GeneratorExit:
+                yield 2
+            yield 3
+
+        self.compare_generators(sync_gen_wrapper(), async_gen_wrapper())
+
     def test_async_gen_api_01(self):
         async def gen():
             yield 123
@@ -752,6 +785,4 @@
             gen = foo()
             it = gen.__aiter__()
             self.assertEqual(await it.__anext__(), 1)
-            t = self.loop.create_task(it.__anext__())
-            await asyncio.sleep(0.01, loop=self.loop)
             await gen.aclose()
@@ -757,3 +788,2 @@
             await gen.aclose()
-            return t
 
@@ -759,6 +789,6 @@
 
-        t = self.loop.run_until_complete(run())
+        self.loop.run_until_complete(run())
         self.assertEqual(DONE, 1)
 
         # Silence ResourceWarnings
         fut.cancel()
@@ -761,8 +791,7 @@
         self.assertEqual(DONE, 1)
 
         # Silence ResourceWarnings
         fut.cancel()
-        t.cancel()
         self.loop.run_until_complete(asyncio.sleep(0.01, loop=self.loop))
 
     @needs_py36_asyncio
@@ -860,6 +889,33 @@
         self.loop.run_until_complete(run())
         self.assertEqual(DONE, 10)
 
+    def test_async_gen_asyncio_aclose_12(self):
+        DONE = 0
+
+        async def target():
+            await asyncio.sleep(0.01)
+            1 / ZERO
+
+        async def foo():
+            nonlocal DONE
+            task = self.loop.create_task(target())
+            try:
+                yield 1
+            finally:
+                try:
+                    await task
+                except ZeroDivisionError:
+                    DONE = 1
+
+        async def run():
+            gen = foo()
+            it = gen.__aiter__()
+            await it.__anext__()
+            await gen.aclose()
+
+        self.loop.run_until_complete(run())
+        self.assertEqual(DONE, 1)
+
     def test_async_gen_asyncio_asend_01(self):
         DONE = 0
 
@@ -1162,9 +1218,7 @@
 
         self.loop.run_until_complete(asyncio.sleep(0.1, loop=self.loop))
 
-        self.loop.run_until_complete(self.loop.shutdown_asyncgens())
-        self.assertEqual(finalized, 2)
 
         # Silence warnings
         t1.cancel()
         t2.cancel()
@@ -1167,17 +1221,5 @@
 
         # Silence warnings
         t1.cancel()
         t2.cancel()
-        self.loop.run_until_complete(asyncio.sleep(0.1, loop=self.loop))
-
-    @needs_py36_asyncio
-    def test_async_gen_asyncio_shutdown_02(self):
-        logged = 0
-
-        def logger(loop, context):
-            nonlocal logged
-            self.assertIn('asyncgen', context)
-            expected = 'an error occurred during closing of asynchronous'
-            if expected in context['message']:
-                logged += 1
 
@@ -1183,8 +1225,6 @@
 
-        async def waiter(timeout):
-            try:
-                await asyncio.sleep(timeout, loop=self.loop)
-                yield 1
-            finally:
-                1 / ZERO
+        with self.assertRaises(asyncio.CancelledError):
+            self.loop.run_until_complete(t1)
+        with self.assertRaises(asyncio.CancelledError):
+            self.loop.run_until_complete(t2)
 
@@ -1190,11 +1230,3 @@
 
-        async def wait():
-            async for _ in waiter(1):
-                pass
-
-        t = self.loop.create_task(wait())
-        self.loop.run_until_complete(asyncio.sleep(0.1, loop=self.loop))
-
-        self.loop.set_exception_handler(logger)
         self.loop.run_until_complete(self.loop.shutdown_asyncgens())
 
@@ -1199,4 +1231,66 @@
         self.loop.run_until_complete(self.loop.shutdown_asyncgens())
 
-        self.assertEqual(logged, 1)
+        self.assertEqual(finalized, 2)
+
+    """
+    def test_async_gen_expression_01(self):
+        async def arange(n):
+            for i in range(n):
+                await asyncio.sleep(0.01)
+                yield i
+
+        def make_arange(n):
+            # This syntax is legal starting with Python 3.7
+            return (i * 2 async for i in arange(n))
+
+        async def run():
+            return [i async for i in make_arange(10)]
+
+        res = self.loop.run_until_complete(run())
+        self.assertEqual(res, [i * 2 for i in range(10)])
+
+    def test_async_gen_expression_02(self):
+        async def wrap(n):
+            await asyncio.sleep(0.01)
+            return n
+
+        def make_arange(n):
+            # This syntax is legal starting with Python 3.7
+            return (i * 2 for i in range(n) if await wrap(i))
+
+        async def run():
+            return [i async for i in make_arange(10)]
+
+        res = self.loop.run_until_complete(run())
+        self.assertEqual(res, [i * 2 for i in range(1, 10)])
+    """
+
+    def test_asyncgen_nonstarted_hooks_are_cancellable(self):
+        # See https://bugs.python.org/issue38013
+        messages = []
+
+        def exception_handler(loop, context):
+            messages.append(context)
+
+        async def async_iterate():
+            yield 1
+            yield 2
+
+        async def main():
+            # loop = asyncio.get_running_loop()
+            loop = self.loop
+            loop.set_exception_handler(exception_handler)
+
+            async for i in async_iterate():
+                break
+
+        # asyncio.run(main())
+        self.loop.run_until_complete(main())
+
+        self.assertEqual([], messages)
+
+    def test_async_gen_await_same_anext_coro_twice(self):
+        async def async_iterate():
+            yield 1
+            yield 2
 
@@ -1202,7 +1296,78 @@
 
-        # Silence warnings
-        t.cancel()
-        self.loop.run_until_complete(asyncio.sleep(0.1, loop=self.loop))
+        async def run():
+            it = async_iterate()
+            nxt = it.__anext__()
+            await nxt
+            with self.assertRaisesRegex(
+                    RuntimeError,
+                    r"cannot reuse already awaited __anext__\(\)/asend\(\)"
+            ):
+                await nxt
+
+            await it.aclose()  # prevent unfinished iterator warning
+
+        self.loop.run_until_complete(run())
+
+    def test_async_gen_await_same_aclose_coro_twice(self):
+        async def async_iterate():
+            yield 1
+            yield 2
+
+        async def run():
+            it = async_iterate()
+            nxt = it.aclose()
+            await nxt
+            with self.assertRaisesRegex(
+                    RuntimeError,
+                    r"cannot reuse already awaited aclose\(\)/athrow\(\)"
+            ):
+                await nxt
+
+        self.loop.run_until_complete(run())
+
+    def test_async_gen_aclose_twice_with_different_coros(self):
+        # Regression test for https://bugs.python.org/issue39606
+        async def async_iterate():
+            yield 1
+            yield 2
+
+        async def run():
+            it = async_iterate()
+            await it.aclose()
+            await it.aclose()
+
+        self.loop.run_until_complete(run())
+
+    def test_async_gen_aclose_after_exhaustion(self):
+        # Regression test for https://bugs.python.org/issue39606
+        async def async_iterate():
+            yield 1
+            yield 2
+
+        async def run():
+            it = async_iterate()
+            async for _ in it:
+                pass
+            await it.aclose()
+
+        self.loop.run_until_complete(run())
+
+    """
+    def test_async_gen_aclose_compatible_with_get_stack(self):
+        async def async_generator():
+            yield object()
+
+        async def run():
+            ag = async_generator()
+            self.loop.create_task(ag.aclose())
+            tasks = asyncio.all_tasks()
+            for task in tasks:
+                # No AttributeError raised
+                task.get_stack()
+
+        self.loop.run_until_complete(run())
+    """
+
 
 if __name__ == "__main__":
     unittest.main()
diff --git a/tests/run/test_coroutines_pep492.pyx b/tests/run/test_coroutines_pep492.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL3Rlc3RfY29yb3V0aW5lc19wZXA0OTIucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3Rlc3RfY29yb3V0aW5lc19wZXA0OTIucHl4 100644
--- a/tests/run/test_coroutines_pep492.pyx
+++ b/tests/run/test_coroutines_pep492.pyx
@@ -149,17 +149,6 @@
         gc.collect()
 
 
-def min_py27(method):
-    return None if sys.version_info < (2, 7) else method
-
-
-def ignore_py26(manager):
-    @contextlib.contextmanager
-    def dummy():
-        yield
-    return dummy() if sys.version_info < (2, 7) else manager
-
-
 @contextlib.contextmanager
 def captured_stderr():
     try:
@@ -213,9 +202,10 @@
                 pass
             """,
 
-            """async def foo(a:await something()):
-                pass
-            """,
+            #"""async def foo(a:await something()):
+            #    pass
+            #""", # No longer an error with pep-563 (although still nonsense)
+            # Some other similar tests have also been commented out
 
             """async def foo():
                 def bar():
@@ -413,9 +403,9 @@
                    pass
             """,
 
-            """async def foo(a:await b):
-                   pass
-            """,
+            #"""async def foo(a:await b):
+            #       pass
+            #""",
 
             """def baz():
                    async def foo(a=await b):
@@ -628,9 +618,9 @@
                    pass
             """,
 
-            """async def foo(a:await b):
-                   pass
-            """,
+            #"""async def foo(a:await b):
+            #       pass
+            #""",
 
             """def baz():
                    async def foo(a=await b):
@@ -1091,7 +1081,7 @@
             c.close()
 
     def test_func_15(self):
-        # See http://bugs.python.org/issue25887 for details
+        # See https://bugs.python.org/issue25887 for details
 
         async def spammer():
             return 'spam'
@@ -1108,7 +1098,7 @@
             reader(spammer_coro).send(None)
 
     def test_func_16(self):
-        # See http://bugs.python.org/issue25887 for details
+        # See https://bugs.python.org/issue25887 for details
 
         @types_coroutine
         def nop():
@@ -1139,7 +1129,7 @@
             reader.throw(Exception('wat'))
 
     def test_func_17(self):
-        # See http://bugs.python.org/issue25887 for details
+        # See https://bugs.python.org/issue25887 for details
 
         async def coroutine():
             return 'spam'
@@ -1162,7 +1152,7 @@
         coro.close()
 
     def test_func_18(self):
-        # See http://bugs.python.org/issue25887 for details
+        # See https://bugs.python.org/issue25887 for details
 
         async def coroutine():
             return 'spam'
@@ -1831,7 +1821,7 @@
 
         buffer = []
         async def test1():
-            with ignore_py26(self.assertWarnsRegex(DeprecationWarning, "legacy")):
+            with self.assertWarnsRegex(DeprecationWarning, "legacy"):
                 async for i1, i2 in AsyncIter():
                     buffer.append(i1 + i2)
 
@@ -1845,7 +1835,7 @@
         buffer = []
         async def test2():
             nonlocal buffer
-            with ignore_py26(self.assertWarnsRegex(DeprecationWarning, "legacy")):
+            with self.assertWarnsRegex(DeprecationWarning, "legacy"):
                 async for i in AsyncIter():
                     buffer.append(i[0])
                     if i[0] == 20:
@@ -1864,7 +1854,7 @@
         buffer = []
         async def test3():
             nonlocal buffer
-            with ignore_py26(self.assertWarnsRegex(DeprecationWarning, "legacy")):
+            with self.assertWarnsRegex(DeprecationWarning, "legacy"):
                 async for i in AsyncIter():
                     if i[0] > 20:
                         continue
@@ -2081,7 +2071,6 @@
         self.assertEqual(CNT, 0)
 
     # old-style pre-Py3.5.2 protocol - no longer supported
-    @min_py27
     def __test_for_9(self):
         # Test that DeprecationWarning can safely be converted into
         # an exception (__aiter__ should not have a chance to raise
@@ -2099,7 +2088,6 @@
                 run_async(foo())
 
     # old-style pre-Py3.5.2 protocol - no longer supported
-    @min_py27
     def __test_for_10(self):
         # Test that DeprecationWarning can safely be converted into
         # an exception.
diff --git a/tests/run/test_fstring.pyx b/tests/run/test_fstring.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL3Rlc3RfZnN0cmluZy5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3Rlc3RfZnN0cmluZy5weXg= 100644
--- a/tests/run/test_fstring.pyx
+++ b/tests/run/test_fstring.pyx
@@ -10,7 +10,6 @@
 
 import sys
 IS_PY2 = sys.version_info[0] < 3
-IS_PY26 = sys.version_info[:2] < (2, 7)
 
 from Cython.Build.Inline import cython_inline
 from Cython.TestUtils import CythonTest
@@ -63,17 +62,4 @@
                     first = stripped_first.decode('unicode_escape')
             super(TestCase, self).assertEqual(first, second, msg)
 
-        if IS_PY26:
-            @contextlib.contextmanager
-            def assertRaises(self, exc):
-                try:
-                    yield
-                except exc:
-                    pass
-                else:
-                    assert False, "exception '%s' not raised" % exc
-
-            def assertIn(self, value, collection):
-                self.assertTrue(value in collection)
-
     def test__format__lookup(self):
@@ -79,7 +65,5 @@
     def test__format__lookup(self):
-        if IS_PY26:
-            return
-        elif IS_PY2:
+        if IS_PY2:
             raise unittest.SkipTest("Py3-only")
 
         # Make sure __format__ is looked up on the type, not the instance.
@@ -109,7 +93,7 @@
         self.assertEqual(type(y).__format__(y, ''), 'class')
 
     def __test_ast(self):
-        # Inspired by http://bugs.python.org/issue24975
+        # Inspired by https://bugs.python.org/issue24975
         class X:
             def __init__(self):
                 self.called = False
@@ -271,8 +255,12 @@
         width = 1
 
         # Test around 256.
-        for i in range(250, 260):
-            self.assertEqual(cy_eval(build_fstr(i), x=x, width=width), (x+' ')*i)
+        # for i in range(250, 260):
+        #     self.assertEqual(cy_eval(build_fstr(i), x=x, width=width), (x+' ')*i)
+        self.assertEqual(
+            cy_eval('[' + ', '.join(build_fstr(i) for i in range(250, 260)) + ']', x=x, width=width),
+            [(x+' ')*i for i in range(250, 260)],
+        )
 
         # Test concatenating 2 largs fstrings.
         self.assertEqual(cy_eval(build_fstr(255)*3, x=x, width=width), (x+' ')*(255*3))  # CPython uses 255*256
@@ -288,12 +276,11 @@
         width = 10
         precision = 4
         value = decimal.Decimal('12.34567')
-        if not IS_PY26:
-            self.assertEqual(f'result: {value:{width}.{precision}}', 'result:      12.35')
-            self.assertEqual(f'result: {value:{width!r}.{precision}}', 'result:      12.35')
-            self.assertEqual(f'result: {value:{width:0}.{precision:1}}', 'result:      12.35')
-            self.assertEqual(f'result: {value:{1}{0:0}.{precision:1}}', 'result:      12.35')
-            self.assertEqual(f'result: {value:{ 1}{ 0:0}.{ precision:1}}', 'result:      12.35')
+        self.assertEqual(f'result: {value:{width}.{precision}}', 'result:      12.35')
+        self.assertEqual(f'result: {value:{width!r}.{precision}}', 'result:      12.35')
+        self.assertEqual(f'result: {value:{width:0}.{precision:1}}', 'result:      12.35')
+        self.assertEqual(f'result: {value:{1}{0:0}.{precision:1}}', 'result:      12.35')
+        self.assertEqual(f'result: {value:{ 1}{ 0:0}.{ precision:1}}', 'result:      12.35')
         self.assertEqual(f'{10:#{1}0x}', '       0xa')
         self.assertEqual(f'{10:{"#"}1{0}{"x"}}', '       0xa')
         self.assertEqual(f'{-10:-{"#"}1{0}x}', '      -0xa')
@@ -312,8 +299,7 @@
                              ])
 
         # CYTHON: The nesting restriction seems rather arbitrary. Ignoring it for now and instead test that it works.
-        if not IS_PY26:
-            self.assertEqual(f'result: {value:{width:{0}}.{precision:1}}', 'result:      12.35')
+        self.assertEqual(f'result: {value:{width:{0}}.{precision:1}}', 'result:      12.35')
         #self.assertAllRaise(SyntaxError, "f-string: expressions nested too deeply",
         #                    [# Can't nest format specifiers.
         #                     "f'result: {value:{width:{0}}.{precision:1}}'",
@@ -678,10 +664,9 @@
 
     def test_conversions(self):
         self.assertEqual(f'{3.14:10.10}', '      3.14')
-        if not IS_PY26:
-            self.assertEqual(f'{3.14!s:10.10}', '3.14      ')
-            self.assertEqual(f'{3.14!r:10.10}', '3.14      ')
-            self.assertEqual(f'{3.14!a:10.10}', '3.14      ')
+        self.assertEqual(f'{3.14!s:10.10}', '3.14      ')
+        self.assertEqual(f'{3.14!r:10.10}', '3.14      ')
+        self.assertEqual(f'{3.14!a:10.10}', '3.14      ')
 
         self.assertEqual(f'{"a"}', 'a')
         self.assertEqual(f'{"a"!r}', "'a'")
diff --git a/tests/run/test_genericclass.py b/tests/run/test_genericclass.py
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3Rlc3RfZ2VuZXJpY2NsYXNzLnB5
--- /dev/null
+++ b/tests/run/test_genericclass.py
@@ -0,0 +1,139 @@
+# mode: run
+# tag: pure3.7
+# cython: language_level=3
+
+# COPIED FROM CPython 3.7
+
+import unittest
+import sys
+
+
+class TestClassGetitem(unittest.TestCase):
+    # BEGIN - Additional tests from cython
+    def test_no_class_getitem(self):
+        class C: ...
+        with self.assertRaises(TypeError):
+            C[int]
+
+    # END - Additional tests from cython
+
+    def test_class_getitem(self):
+        getitem_args = []
+        class C:
+            def __class_getitem__(*args, **kwargs):
+                getitem_args.extend([args, kwargs])
+                return None
+        C[int, str]
+        self.assertEqual(getitem_args[0], (C, (int, str)))
+        self.assertEqual(getitem_args[1], {})
+
+    def test_class_getitem_format(self):
+        class C:
+            def __class_getitem__(cls, item):
+                return f'C[{item.__name__}]'
+        self.assertEqual(C[int], 'C[int]')
+        self.assertEqual(C[C], 'C[C]')
+
+    def test_class_getitem_inheritance(self):
+        class C:
+            def __class_getitem__(cls, item):
+                return f'{cls.__name__}[{item.__name__}]'
+        class D(C): ...
+        self.assertEqual(D[int], 'D[int]')
+        self.assertEqual(D[D], 'D[D]')
+
+    def test_class_getitem_inheritance_2(self):
+        class C:
+            def __class_getitem__(cls, item):
+                return 'Should not see this'
+        class D(C):
+            def __class_getitem__(cls, item):
+                return f'{cls.__name__}[{item.__name__}]'
+        self.assertEqual(D[int], 'D[int]')
+        self.assertEqual(D[D], 'D[D]')
+
+    def test_class_getitem_classmethod(self):
+        class C:
+            @classmethod
+            def __class_getitem__(cls, item):
+                return f'{cls.__name__}[{item.__name__}]'
+        class D(C): ...
+        self.assertEqual(D[int], 'D[int]')
+        self.assertEqual(D[D], 'D[D]')
+
+    @unittest.skipIf(sys.version_info < (3, 6), "__init_subclass__() requires Py3.6+ (PEP 487)")
+    def test_class_getitem_patched(self):
+        class C:
+            def __init_subclass__(cls):
+                def __class_getitem__(cls, item):
+                    return f'{cls.__name__}[{item.__name__}]'
+                cls.__class_getitem__ = classmethod(__class_getitem__)
+        class D(C): ...
+        self.assertEqual(D[int], 'D[int]')
+        self.assertEqual(D[D], 'D[D]')
+
+    def test_class_getitem_with_builtins(self):
+        class A(dict):
+            called_with = None
+
+            def __class_getitem__(cls, item):
+                cls.called_with = item
+        class B(A):
+            pass
+        self.assertIs(B.called_with, None)
+        B[int]
+        self.assertIs(B.called_with, int)
+
+    def test_class_getitem_errors(self):
+        class C_too_few:
+            def __class_getitem__(cls):
+                return None
+        with self.assertRaises(TypeError):
+            C_too_few[int]
+        class C_too_many:
+            def __class_getitem__(cls, one, two):
+                return None
+        with self.assertRaises(TypeError):
+            C_too_many[int]
+
+    def test_class_getitem_errors_2(self):
+        class C:
+            def __class_getitem__(cls, item):
+                return None
+        with self.assertRaises(TypeError):
+            C()[int]
+        class E: ...
+        e = E()
+        e.__class_getitem__ = lambda cls, item: 'This will not work'
+        with self.assertRaises(TypeError):
+            e[int]
+        class C_not_callable:
+            __class_getitem__ = "Surprise!"
+        with self.assertRaises(TypeError):
+            C_not_callable[int]
+
+    def test_class_getitem_metaclass(self):
+        class Meta(type):
+            def __class_getitem__(cls, item):
+                return f'{cls.__name__}[{item.__name__}]'
+        self.assertEqual(Meta[int], 'Meta[int]')
+
+    def test_class_getitem_with_metaclass(self):
+        class Meta(type): pass
+        class C(metaclass=Meta):
+            def __class_getitem__(cls, item):
+                return f'{cls.__name__}[{item.__name__}]'
+        self.assertEqual(C[int], 'C[int]')
+
+    def test_class_getitem_metaclass_first(self):
+        class Meta(type):
+            def __getitem__(cls, item):
+                return 'from metaclass'
+        class C(metaclass=Meta):
+            def __class_getitem__(cls, item):
+                return 'from __class_getitem__'
+        self.assertEqual(C[int], 'from metaclass')
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/tests/run/test_grammar.py b/tests/run/test_grammar.py
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL3Rlc3RfZ3JhbW1hci5weQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3Rlc3RfZ3JhbW1hci5weQ== 100644
--- a/tests/run/test_grammar.py
+++ b/tests/run/test_grammar.py
@@ -1,5 +1,6 @@
 ### COPIED FROM CPython 3.5 - ADDED PART FOLLOWS ###
 # cython: language_level=3
 
+import cython
 import contextlib
 from tempfile import NamedTemporaryFile
@@ -4,6 +5,22 @@
 import contextlib
 from tempfile import NamedTemporaryFile
-from Cython.Compiler.Main import compile as cython_compile
+from Cython.Compiler.Main import compile as cython_compile, CompileError
+from Cython.Build.Inline import cython_inline
+
+
+@contextlib.contextmanager
+def hidden_stderr():
+    try:
+        from StringIO import StringIO
+    except ImportError:
+        from io import StringIO
+
+    old_stderr = sys.stderr
+    try:
+        sys.stderr = StringIO()
+        yield
+    finally:
+        sys.stderr = old_stderr
 
 
 def _compile(code):
@@ -11,12 +28,5 @@
         f.write(code.encode('utf8'))
         f.flush()
 
-        try:
-            from StringIO import StringIO
-        except ImportError:
-            from io import StringIO
-
-        old_stderr = sys.stderr
-        try:
-            sys.stderr = StringIO()
+        with hidden_stderr():
             result = cython_compile(f.name, language_level=3)
@@ -22,6 +32,4 @@
             result = cython_compile(f.name, language_level=3)
-        finally:
-            sys.stderr = old_stderr
     return result
 
 
@@ -25,8 +33,8 @@
     return result
 
 
-def check_syntax_error(test, code):
+def check_syntax_error(test, code, msg=None):
     result = _compile(code)
     assert not result.c_file
 
 
@@ -29,10 +37,11 @@
     result = _compile(code)
     assert not result.c_file
 
 
-def compile(code, name, what):
-    assert what == 'exec'
-    result = _compile(code)
-    if not result.c_file:
-        raise SyntaxError('unexpected EOF')  # see usage of compile() below
+if cython.compiled:
+    def compile(code, name, what):
+        assert what == 'exec'
+        result = _compile(code)
+        if not result.c_file:
+            raise SyntaxError('unexpected EOF')  # see usage of compile() below
 
@@ -38,2 +47,6 @@
 
+    def exec(code):
+        result = _compile(code)
+        if not result.c_file:
+            raise SyntaxError('unexpected EOF')  # see usage of compile() below
 
@@ -39,8 +52,10 @@
 
-def exec(code):
-    result = _compile(code)
-    if not result.c_file:
-        raise SyntaxError('unexpected EOF')  # see usage of compile() below
+    def eval(code):
+        try:
+            with hidden_stderr():
+                return cython_inline(code)
+        except CompileError as exc:
+            raise SyntaxError(str(exc))
 
 
 import unittest
@@ -76,6 +91,7 @@
 import inspect
 import unittest
 import sys
+import warnings
 # testing import *
 from sys import *
 
@@ -79,6 +95,95 @@
 # testing import *
 from sys import *
 
+# different import patterns to check that __annotations__ does not interfere
+# with import machinery
+#import test.ann_module as ann_module
+#import typing
+#from collections import ChainMap
+#from test import ann_module2
+#import test
+
+# These are shared with test_tokenize and other test modules.
+#
+# Note: since several test cases filter out floats by looking for "e" and ".",
+# don't add hexadecimal literals that contain "e" or "E".
+VALID_UNDERSCORE_LITERALS = [
+    '0_0_0',
+    '4_2',
+    '1_0000_0000',
+    '0b1001_0100',
+    '0xffff_ffff',
+    '0o5_7_7',
+    '1_00_00.5',
+    '1_00_00.5e5',
+    '1_00_00e5_1',
+    '1e1_0',
+    '.1_4',
+    '.1_4e1',
+    '0b_0',
+    '0x_f',
+    '0o_5',
+    '1_00_00j',
+    '1_00_00.5j',
+    '1_00_00e5_1j',
+    '.1_4j',
+    '(1_2.5+3_3j)',
+    '(.5_6j)',
+]
+INVALID_UNDERSCORE_LITERALS = [
+    # Trailing underscores:
+    '0_',
+    '42_',
+    '1.4j_',
+    '0x_',
+    '0b1_',
+    '0xf_',
+    '0o5_',
+    '0 if 1_Else 1',
+    # Underscores in the base selector:
+    '0_b0',
+    '0_xf',
+    '0_o5',
+    # Old-style octal, still disallowed:
+    '0_7',
+    '09_99',
+    # Multiple consecutive underscores:
+    '4_______2',
+    '0.1__4',
+    '0.1__4j',
+    '0b1001__0100',
+    '0xffff__ffff',
+    '0x___',
+    '0o5__77',
+    '1e1__0',
+    '1e1__0j',
+    # Underscore right before a dot:
+    '1_.4',
+    '1_.4j',
+    # Underscore right after a dot:
+    '1._4',
+    '1._4j',
+    '._5',
+    '._5j',
+    # Underscore right after a sign:
+    '1.0e+_1',
+    '1.0e+_1j',
+    # Underscore right before j:
+    '1.4_j',
+    '1.4e5_j',
+    # Underscore right before e:
+    '1_e1',
+    '1.4_e1',
+    '1.4_e1j',
+    # Underscore right after e:
+    '1e_1',
+    '1.4e_1',
+    '1.4e_1j',
+    # Complex cases with parens:
+    '(1+1.5_j_)',
+    '(1+1.5_j)',
+]
+
 
 class TokenTests(unittest.TestCase):
 
@@ -82,6 +187,8 @@
 
 class TokenTests(unittest.TestCase):
 
+    check_syntax_error = check_syntax_error
+
     def test_backslash(self):
         # Backslash means line continuation:
         x = 1 \
@@ -158,6 +265,38 @@
         self.assertEqual(1 if 0else 0, 0)
         self.assertRaises(SyntaxError, eval, "0 if 1Else 0")
 
+    @skip("Done more efficiently in TestGrammar")
+    def test_underscore_literals(self):
+        for lit in VALID_UNDERSCORE_LITERALS:
+            self.assertEqual(eval(lit), eval(lit.replace('_', '')))
+        for lit in INVALID_UNDERSCORE_LITERALS:
+            self.assertRaises(SyntaxError, eval, lit)
+        # Sanity check: no literal begins with an underscore
+        self.assertRaises(NameError, eval, "_0")
+
+    def test_bad_numerical_literals(self):
+        check = self.check_syntax_error
+        check("0b12", "invalid digit '2' in binary literal")
+        check("0b1_2", "invalid digit '2' in binary literal")
+        check("0b2", "invalid digit '2' in binary literal")
+        check("0b1_", "invalid binary literal")
+        check("0b", "invalid binary literal")
+        check("0o18", "invalid digit '8' in octal literal")
+        check("0o1_8", "invalid digit '8' in octal literal")
+        check("0o8", "invalid digit '8' in octal literal")
+        check("0o1_", "invalid octal literal")
+        check("0o", "invalid octal literal")
+        check("0x1_", "invalid hexadecimal literal")
+        check("0x", "invalid hexadecimal literal")
+        check("1_", "invalid decimal literal")
+        # FIXME: must still support PY_VERSION_HEX < 3 :(
+        #check("012",
+        #      "leading zeros in decimal integer literals are not permitted; "
+        #      "use an 0o prefix for octal integers")
+        check("1.2_", "invalid decimal literal")
+        check("1e2_", "invalid decimal literal")
+        check("1e+", "invalid decimal literal")
+
     def test_string_literals(self):
         x = ''; y = ""; self.assertTrue(len(x) == 0 and x == y)
         x = '\''; y = "'"; self.assertTrue(len(x) == 1 and x == y and ord(x) == 39)
@@ -201,7 +340,8 @@
     def test_ellipsis(self):
         x = ...
         self.assertTrue(x is Ellipsis)
-        self.assertRaises(SyntaxError, eval, ".. .")
+        # FIXME: why is this not rejected ???
+        #self.assertRaises(SyntaxError, eval, ".. .")
 
     def test_eof_error(self):
         samples = ("def foo(", "\ndef foo(", "def foo(\n")
@@ -225,6 +365,8 @@
 
 class GrammarTests(unittest.TestCase):
 
+    check_syntax_error = check_syntax_error
+
     # single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE
     # XXX can't test in a script -- this rule is only used when interactive
 
@@ -403,6 +545,16 @@
         exec('X: str', {}, CNS2())
         self.assertEqual(nonloc_ns['__annotations__']['x'], str)
 
+    @skip("Depends on 3-args compiled exec()")
+    def test_var_annot_rhs(self):
+        ns = {}
+        exec('x: tuple = 1, 2', ns)
+        self.assertEqual(ns['x'], (1, 2))
+        stmt = ('def f():\n'
+                '    x: int = yield')
+        exec(stmt, ns)
+        self.assertEqual(list(ns['f']()), [None])
+
     def test_funcdef(self):
         ### [decorators] 'def' NAME parameters ['->' test] ':' suite
         ### decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
@@ -598,7 +750,7 @@
         def f(x) -> list: pass
         self.assertEqual(f.__annotations__, {'return': list})
 
-        # test MAKE_CLOSURE with a variety of oparg's
+        # test closures with a variety of opargs
         closure = 1
         def f(): return closure
         def f(x=1): return closure
@@ -848,6 +1000,59 @@
                 break
         self.assertEqual(count, 0)
 
+    def test_continue_in_finally(self):
+        count = 0
+        while count < 2:
+            count += 1
+            try:
+                pass
+            finally:
+                continue
+            break
+        self.assertEqual(count, 2)
+
+        count = 0
+        while count < 2:
+            count += 1
+            try:
+                break
+            finally:
+                continue
+        self.assertEqual(count, 2)
+
+        count = 0
+        while count < 2:
+            count += 1
+            try:
+                1/0
+            finally:
+                continue
+            break
+        self.assertEqual(count, 2)
+
+        for count in [0, 1]:
+            try:
+                pass
+            finally:
+                continue
+            break
+        self.assertEqual(count, 1)
+
+        for count in [0, 1]:
+            try:
+                break
+            finally:
+                continue
+        self.assertEqual(count, 1)
+
+        for count in [0, 1]:
+            try:
+                1/0
+            finally:
+                continue
+            break
+        self.assertEqual(count, 1)
+
     def test_return_in_finally(self):
         def g1():
             try:
@@ -895,7 +1100,7 @@
         def g(): f((yield from ()), 1)
         # Do not require parenthesis for tuple unpacking
         def g(): rest = 4, 5, 6; yield 1, 2, 3, *rest
-        self.assertEquals(list(g()), [(1, 2, 3, 4, 5, 6)])
+        self.assertEqual(list(g()), [(1, 2, 3, 4, 5, 6)])
         check_syntax_error(self, "def g(): f(yield 1)")
         check_syntax_error(self, "def g(): f(yield 1, 1)")
         check_syntax_error(self, "def g(): f(yield from ())")
@@ -907,7 +1112,7 @@
         check_syntax_error(self, "class foo:yield 1")
         check_syntax_error(self, "class foo:yield from ()")
         # Check annotation refleak on SyntaxError
-        check_syntax_error(self, "def g(a:(yield)): pass")
+        #check_syntax_error(self, "def g(a:(yield)): pass") # no longer a syntax error with PEP563
 
     @skip("DeprecationWarning not implemented")
     def test_yield_in_comprehensions(self):
@@ -1132,7 +1337,7 @@
         if 1 > 1: pass
         if 1 <= 1: pass
         if 1 >= 1: pass
-        if 1 is 1: pass
-        if 1 is not 1: pass
+        if x is x: pass
+        if x is not x: pass
         if 1 in (): pass
         if 1 not in (): pass
@@ -1137,6 +1342,29 @@
         if 1 in (): pass
         if 1 not in (): pass
-        if 1 < 1 > 1 == 1 >= 1 <= 1 != 1 in 1 not in 1 is 1 is not 1: pass
+        if 1 < 1 > 1 == 1 >= 1 <= 1 != 1 in 1 not in x is x is not x: pass
+
+    @skip("DeprecationWarning not implemented")
+    def test_comparison_is_literal(self):
+        def check(test, msg='"is" with a literal'):
+            with self.assertWarnsRegex(SyntaxWarning, msg):
+                compile(test, '<testcase>', 'exec')
+            with warnings.catch_warnings():
+                warnings.filterwarnings('error', category=SyntaxWarning)
+                with self.assertRaisesRegex(SyntaxError, msg):
+                    compile(test, '<testcase>', 'exec')
+
+        check('x is 1')
+        check('x is "thing"')
+        check('1 is x')
+        check('x is y is 1')
+        check('x is not 1', '"is not" with a literal')
+
+        with warnings.catch_warnings():
+            warnings.filterwarnings('error', category=SyntaxWarning)
+            compile('x is None', '<testcase>', 'exec')
+            compile('x is False', '<testcase>', 'exec')
+            compile('x is True', '<testcase>', 'exec')
+            compile('x is ...', '<testcase>', 'exec')
 
     def test_binary_mask_ops(self):
         x = 1 & 1
@@ -1399,7 +1627,7 @@
         # Test ifelse expressions in various cases
         def _checkeval(msg, ret):
             "helper to check that evaluation of expressions is done correctly"
-            print(x)
+            print(msg)
             return ret
 
         # the next line is not allowed anymore
@@ -1426,9 +1654,11 @@
         self.assertEqual(16 // (4 // 2), 8)
         self.assertEqual((16 // 4) // 2, 2)
         self.assertEqual(16 // 4 // 2, 2)
-        self.assertTrue(False is (2 is 3))
-        self.assertFalse((False is 2) is 3)
-        self.assertFalse(False is 2 is 3)
+        x = 2
+        y = 3
+        self.assertTrue(False is (x is y))
+        self.assertFalse((False is x) is y)
+        self.assertFalse(False is x is y)
 
     def test_matrix_mul(self):
         # This is not intended to be a comprehensive test, rather just to be few
@@ -1520,24 +1750,6 @@
 
 GrammarTests.assertRaisesRegex = lambda self, exc, msg: self.assertRaises(exc)
 
-if sys.version_info < (2, 7):
-    def assertRaises(self, exc_type, func=None, *args, **kwargs):
-        if func is not None:
-            return unittest.TestCase.assertRaises(self, exc_type, func, *args, **kwargs)
-        @contextlib.contextmanager
-        def assertRaisesCM():
-            class Result(object):
-                exception = exc_type("unexpected EOF")  # see usage above
-            try:
-                yield Result()
-            except exc_type:
-                self.assertTrue(True)
-            else:
-                self.assertTrue(False)
-        return assertRaisesCM()
-    GrammarTests.assertRaises = assertRaises
-    TokenTests.assertRaises = assertRaises
-
 
 if not hasattr(unittest.TestCase, 'subTest'):
     @contextlib.contextmanager
@@ -1550,13 +1762,7 @@
     GrammarTests.subTest = subTest
 
 
-if not hasattr(unittest.TestCase, 'assertIn'):
-    def assertIn(self, member, container, msg=None):
-        self.assertTrue(member in container, msg)
-    TokenTests.assertIn = assertIn
-
-
 # FIXME: disabling some tests for real Cython bugs here
 del GrammarTests.test_comprehension_specials  # iterable pre-calculation in generator expression
 del GrammarTests.test_funcdef  # annotation mangling
 
@@ -1559,11 +1765,7 @@
 # FIXME: disabling some tests for real Cython bugs here
 del GrammarTests.test_comprehension_specials  # iterable pre-calculation in generator expression
 del GrammarTests.test_funcdef  # annotation mangling
 
-# this test is difficult to enable in Py2.6
-if sys.version_info < (2,7):
-    del GrammarTests.test_former_statements_refer_to_builtins
-
 
 if __name__ == '__main__':
     unittest.main()
diff --git a/tests/run/test_subclassinit.py b/tests/run/test_subclassinit.py
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3Rlc3Rfc3ViY2xhc3Npbml0LnB5
--- /dev/null
+++ b/tests/run/test_subclassinit.py
@@ -0,0 +1,316 @@
+# mode: run
+# tag: pure3.6
+# cython: language_level=3str
+
+import sys
+HAS_NATIVE_SUPPORT = sys.version_info >= (3, 6)
+IS_PY2 = sys.version_info[0] == 2
+
+import re
+import types
+import unittest
+
+ZERO = 0
+
+skip_if_not_native = unittest.skipIf(not HAS_NATIVE_SUPPORT, "currently requires Python 3.6+")
+
+
+class Test(unittest.TestCase):
+    if not hasattr(unittest.TestCase, 'assertRegex'):
+        def assertRegex(self, value, regex):
+            self.assertTrue(re.search(regex, str(value)),
+                            "'%s' did not match '%s'" % (value, regex))
+
+    if not hasattr(unittest.TestCase, 'assertCountEqual'):
+        def assertCountEqual(self, first, second):
+            self.assertEqual(set(first), set(second))
+            self.assertEqual(len(first), len(second))
+
+    def test_init_subclass(self):
+        class A:
+            initialized = False
+
+            def __init_subclass__(cls):
+                if HAS_NATIVE_SUPPORT:
+                    super().__init_subclass__()
+                cls.initialized = True
+
+        class B(A):
+            pass
+
+        self.assertFalse(A.initialized)
+        self.assertTrue(B.initialized)
+
+    def test_init_subclass_dict(self):
+        class A(dict):
+            initialized = False
+
+            def __init_subclass__(cls):
+                if HAS_NATIVE_SUPPORT:
+                    super().__init_subclass__()
+                cls.initialized = True
+
+        class B(A):
+            pass
+
+        self.assertFalse(A.initialized)
+        self.assertTrue(B.initialized)
+
+    def test_init_subclass_kwargs(self):
+        class A:
+            def __init_subclass__(cls, **kwargs):
+                cls.kwargs = kwargs
+
+        class B(A, x=3):
+            pass
+
+        self.assertEqual(B.kwargs, dict(x=3))
+
+    def test_init_subclass_error(self):
+        class A:
+            def __init_subclass__(cls):
+                raise RuntimeError
+
+        with self.assertRaises(RuntimeError):
+            class B(A):
+                pass
+
+    def test_init_subclass_wrong(self):
+        class A:
+            def __init_subclass__(cls, whatever):
+                pass
+
+        with self.assertRaises(TypeError):
+            class B(A):
+                pass
+
+    def test_init_subclass_skipped(self):
+        class BaseWithInit:
+            def __init_subclass__(cls, **kwargs):
+                if HAS_NATIVE_SUPPORT:
+                    super().__init_subclass__(**kwargs)
+                cls.initialized = cls
+
+        class BaseWithoutInit(BaseWithInit):
+            pass
+
+        class A(BaseWithoutInit):
+            pass
+
+        self.assertIs(A.initialized, A)
+        self.assertIs(BaseWithoutInit.initialized, BaseWithoutInit)
+
+    def test_init_subclass_diamond(self):
+        class Base:
+            def __init_subclass__(cls, **kwargs):
+                if HAS_NATIVE_SUPPORT:
+                    super().__init_subclass__(**kwargs)
+                cls.calls = []
+
+        class Left(Base):
+            pass
+
+        class Middle:
+            def __init_subclass__(cls, middle, **kwargs):
+                super().__init_subclass__(**kwargs)
+                cls.calls += [middle]
+
+        class Right(Base):
+            def __init_subclass__(cls, right="right", **kwargs):
+                super().__init_subclass__(**kwargs)
+                cls.calls += [right]
+
+        class A(Left, Middle, Right, middle="middle"):
+            pass
+
+        self.assertEqual(A.calls, ["right", "middle"])
+        self.assertEqual(Left.calls, [])
+        self.assertEqual(Right.calls, [])
+
+    def test_set_name(self):
+        class Descriptor:
+            def __set_name__(self, owner, name):
+                self.owner = owner
+                self.name = name
+
+        class A:
+            d = Descriptor()
+
+        self.assertEqual(A.d.name, "d")
+        self.assertIs(A.d.owner, A)
+
+    @skip_if_not_native
+    def test_set_name_metaclass(self):
+        class Meta(type):
+            def __new__(cls, name, bases, ns):
+                ret = super().__new__(cls, name, bases, ns)
+                self.assertEqual(ret.d.name, "d")
+                self.assertIs(ret.d.owner, ret)
+                return 0
+
+        class Descriptor:
+            def __set_name__(self, owner, name):
+                self.owner = owner
+                self.name = name
+
+        class A(metaclass=Meta):
+            d = Descriptor()
+        self.assertEqual(A, 0)
+
+    def test_set_name_error(self):
+        class Descriptor:
+            def __set_name__(self, owner, name):
+                1 / ZERO
+
+        with self.assertRaises(RuntimeError) as cm:
+            class NotGoingToWork:
+                attr = Descriptor()
+
+        exc = cm.exception
+        self.assertRegex(str(exc), r'\bNotGoingToWork\b')
+        self.assertRegex(str(exc), r'\battr\b')
+        self.assertRegex(str(exc), r'\bDescriptor\b')
+        if HAS_NATIVE_SUPPORT:
+            self.assertIsInstance(exc.__cause__, ZeroDivisionError)
+
+    def test_set_name_wrong(self):
+        class Descriptor:
+            def __set_name__(self):
+                pass
+
+        with self.assertRaises(RuntimeError) as cm:
+            class NotGoingToWork:
+                attr = Descriptor()
+
+        exc = cm.exception
+        self.assertRegex(str(exc), r'\bNotGoingToWork\b')
+        self.assertRegex(str(exc), r'\battr\b')
+        self.assertRegex(str(exc), r'\bDescriptor\b')
+        if HAS_NATIVE_SUPPORT:
+            self.assertIsInstance(exc.__cause__, TypeError)
+
+    def test_set_name_lookup(self):
+        resolved = []
+        class NonDescriptor:
+            def __getattr__(self, name):
+                resolved.append(name)
+
+        class A:
+            d = NonDescriptor()
+
+        self.assertNotIn('__set_name__', resolved,
+                         '__set_name__ is looked up in instance dict')
+
+    @skip_if_not_native
+    def test_set_name_init_subclass(self):
+        class Descriptor:
+            def __set_name__(self, owner, name):
+                self.owner = owner
+                self.name = name
+
+        class Meta(type):
+            def __new__(cls, name, bases, ns):
+                self = super().__new__(cls, name, bases, ns)
+                self.meta_owner = self.owner
+                self.meta_name = self.name
+                return self
+
+        class A:
+            def __init_subclass__(cls):
+                cls.owner = cls.d.owner
+                cls.name = cls.d.name
+
+        class B(A, metaclass=Meta):
+            d = Descriptor()
+
+        self.assertIs(B.owner, B)
+        self.assertEqual(B.name, 'd')
+        self.assertIs(B.meta_owner, B)
+        self.assertEqual(B.name, 'd')
+
+    def test_set_name_modifying_dict(self):
+        notified = []
+        class Descriptor:
+            def __set_name__(self, owner, name):
+                setattr(owner, name + 'x', None)
+                notified.append(name)
+
+        class A:
+            a = Descriptor()
+            b = Descriptor()
+            c = Descriptor()
+            d = Descriptor()
+            e = Descriptor()
+
+        self.assertCountEqual(notified, ['a', 'b', 'c', 'd', 'e'])
+
+    def test_errors(self):
+        class MyMeta(type):
+            pass
+
+        with self.assertRaises(TypeError):
+            class MyClass(metaclass=MyMeta, otherarg=1):
+                pass
+
+        if not IS_PY2:
+            with self.assertRaises(TypeError):
+                types.new_class("MyClass", (object,),
+                                dict(metaclass=MyMeta, otherarg=1))
+            types.prepare_class("MyClass", (object,),
+                                dict(metaclass=MyMeta, otherarg=1))
+
+        class MyMeta(type):
+            def __init__(self, name, bases, namespace, otherarg):
+                super().__init__(name, bases, namespace)
+
+        with self.assertRaises(TypeError):
+            class MyClass(metaclass=MyMeta, otherarg=1):
+                pass
+
+        class MyMeta(type):
+            def __new__(cls, name, bases, namespace, otherarg):
+                return super().__new__(cls, name, bases, namespace)
+
+            def __init__(self, name, bases, namespace, otherarg):
+                super().__init__(name, bases, namespace)
+                self.otherarg = otherarg
+
+        class MyClass(metaclass=MyMeta, otherarg=1):
+            pass
+
+        self.assertEqual(MyClass.otherarg, 1)
+
+    @skip_if_not_native
+    def test_errors_changed_pep487(self):
+        # These tests failed before Python 3.6, PEP 487
+        class MyMeta(type):
+            def __new__(cls, name, bases, namespace):
+                return super().__new__(cls, name=name, bases=bases,
+                                       dict=namespace)
+
+        with self.assertRaises(TypeError):
+            class MyClass(metaclass=MyMeta):
+                pass
+
+        class MyMeta(type):
+            def __new__(cls, name, bases, namespace, otherarg):
+                self = super().__new__(cls, name, bases, namespace)
+                self.otherarg = otherarg
+                return self
+
+        class MyClass(metaclass=MyMeta, otherarg=1):
+            pass
+
+        self.assertEqual(MyClass.otherarg, 1)
+
+    def test_type(self):
+        t = type('NewClass', (object,), {})
+        self.assertIsInstance(t, type)
+        self.assertEqual(t.__name__, 'NewClass')
+
+        with self.assertRaises(TypeError):
+            type(name='NewClass', bases=(object,), dict={})
+
+
+if __name__ == "__main__":
+    unittest.main()
diff --git a/tests/run/test_unicode.pyx b/tests/run/test_unicode.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL3Rlc3RfdW5pY29kZS5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3Rlc3RfdW5pY29kZS5weXg= 100644
--- a/tests/run/test_unicode.pyx
+++ b/tests/run/test_unicode.pyx
@@ -846,7 +846,6 @@
             self.assertEqual('finnish'.capitalize(), 'FInnish')
         else:
             self.assertEqual('finnish'.capitalize(), 'Finnish')
-
         self.assertEqual('A\u0345\u03a3'.capitalize(), 'A\u0345\u03c2')
 
     def test_title(self):
diff --git a/tests/run/tp_new.pyx b/tests/run/tp_new.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL3RwX25ldy5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3RwX25ldy5weXg= 100644
--- a/tests/run/tp_new.pyx
+++ b/tests/run/tp_new.pyx
@@ -1,3 +1,5 @@
+# mode: run
+# tag: exttype, tpnew
 # ticket: 808
 
 cimport cython
diff --git a/tests/run/tracebacks.pyx b/tests/run/tracebacks.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL3RyYWNlYmFja3MucHl4..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3RyYWNlYmFja3MucHl4 100644
--- a/tests/run/tracebacks.pyx
+++ b/tests/run/tracebacks.pyx
@@ -1,4 +1,4 @@
-import traceback
+# tag: traceback
 
 def foo1():
   foo2()
@@ -21,6 +21,7 @@
   try:
     foo1()
   except:
+    import traceback
     tb_string = traceback.format_exc()
     expected = (
       'tracebacks.pyx',
diff --git a/tests/run/trashcan.pyx b/tests/run/trashcan.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3RyYXNoY2FuLnB5eA==
--- /dev/null
+++ b/tests/run/trashcan.pyx
@@ -0,0 +1,148 @@
+# mode: run
+
+cimport cython
+
+
+# Count number of times an object was deallocated twice. This should remain 0.
+cdef int double_deallocations = 0
+def assert_no_double_deallocations():
+    global double_deallocations
+    err = double_deallocations
+    double_deallocations = 0
+    assert not err
+
+
+# Compute x = f(f(f(...(None)...))) nested n times and throw away the result.
+# The real test happens when exiting this function: then a big recursive
+# deallocation of x happens. We are testing two things in the tests below:
+# that Python does not crash and that no double deallocation happens.
+# See also https://github.com/python/cpython/pull/11841
+def recursion_test(f, int n=2**20):
+    x = None
+    cdef int i
+    for i in range(n):
+        x = f(x)
+
+
+@cython.trashcan(True)
+cdef class Recurse:
+    """
+    >>> recursion_test(Recurse)
+    >>> assert_no_double_deallocations()
+    """
+    cdef public attr
+    cdef int deallocated
+
+    def __cinit__(self, x):
+        self.attr = x
+
+    def __dealloc__(self):
+        # Check that we're not being deallocated twice
+        global double_deallocations
+        double_deallocations += self.deallocated
+        self.deallocated = 1
+
+
+cdef class RecurseSub(Recurse):
+    """
+    >>> recursion_test(RecurseSub)
+    >>> assert_no_double_deallocations()
+    """
+    cdef int subdeallocated
+
+    def __dealloc__(self):
+        # Check that we're not being deallocated twice
+        global double_deallocations
+        double_deallocations += self.subdeallocated
+        self.subdeallocated = 1
+
+
+@cython.freelist(4)
+@cython.trashcan(True)
+cdef class RecurseFreelist:
+    """
+    >>> recursion_test(RecurseFreelist)
+    >>> recursion_test(RecurseFreelist, 1000)
+    >>> assert_no_double_deallocations()
+    """
+    cdef public attr
+    cdef int deallocated
+
+    def __cinit__(self, x):
+        self.attr = x
+
+    def __dealloc__(self):
+        # Check that we're not being deallocated twice
+        global double_deallocations
+        double_deallocations += self.deallocated
+        self.deallocated = 1
+
+
+# Subclass of list => uses trashcan by default
+# As long as https://github.com/python/cpython/pull/11841 is not fixed,
+# this does lead to double deallocations, so we skip that check.
+cdef class RecurseList(list):
+    """
+    >>> RecurseList(42)
+    [42]
+    >>> recursion_test(RecurseList)
+    """
+    def __init__(self, x):
+        super().__init__((x,))
+
+
+# Some tests where the trashcan is NOT used. When the trashcan is not used
+# in a big recursive deallocation, the __dealloc__s of the base classes are
+# only run after the __dealloc__s of the subclasses.
+# We use this to detect trashcan usage.
+cdef int base_deallocated = 0
+cdef int trashcan_used = 0
+def assert_no_trashcan_used():
+    global base_deallocated, trashcan_used
+    err = trashcan_used
+    trashcan_used = base_deallocated = 0
+    assert not err
+
+
+cdef class Base:
+    def __dealloc__(self):
+        global base_deallocated
+        base_deallocated = 1
+
+
+# Trashcan disabled by default
+cdef class Sub1(Base):
+    """
+    >>> recursion_test(Sub1, 100)
+    >>> assert_no_trashcan_used()
+    """
+    cdef public attr
+
+    def __cinit__(self, x):
+        self.attr = x
+
+    def __dealloc__(self):
+        global base_deallocated, trashcan_used
+        trashcan_used += base_deallocated
+
+
+@cython.trashcan(True)
+cdef class Middle(Base):
+    cdef public foo
+
+
+# Trashcan disabled explicitly
+@cython.trashcan(False)
+cdef class Sub2(Middle):
+    """
+    >>> recursion_test(Sub2, 1000)
+    >>> assert_no_trashcan_used()
+    """
+    cdef public attr
+
+    def __cinit__(self, x):
+        self.attr = x
+
+    def __dealloc__(self):
+        global base_deallocated, trashcan_used
+        trashcan_used += base_deallocated
diff --git a/tests/run/unicode_identifiers.pxd b/tests/run/unicode_identifiers.pxd
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3VuaWNvZGVfaWRlbnRpZmllcnMucHhk
--- /dev/null
+++ b/tests/run/unicode_identifiers.pxd
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# cython: language_level=3
+
+cdef Fα1()
+cdef class Γναμε2:
+    cdef public int α
+    cdef boring_cdef(self)
+    cdef εxciting_cdef(self)
+    cpdef boring_cpdef(self)
+    cpdef εxciting_cpdef(self)
diff --git a/tests/run/unicode_identifiers.pyx b/tests/run/unicode_identifiers.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3VuaWNvZGVfaWRlbnRpZmllcnMucHl4
--- /dev/null
+++ b/tests/run/unicode_identifiers.pyx
@@ -0,0 +1,227 @@
+# -*- coding: utf-8 -*-
+# cython: language_level=3
+# mode: run
+# tag: pep3131, traceback
+
+# Code with unicode identifiers can be compiled with Cython running either Python 2 or 3.
+# However Python access to unicode identifiers is only possible in Python 3. In Python 2
+# it's only really safe to use the unicode identifiers for purely Cython interfaces
+# (although this isn't enforced...). Therefore the majority of the doctests are
+# Python3 only and only a limited set are run in Python2.
+# This is controlled by putting the Python3 only tests in the module __doc__ attribute
+# Most of the individual function and class docstrings are only present as a compile test
+
+import sys
+
+if sys.version_info[0]>2:
+    __doc__ = """
+    >>> f()()
+    2
+    >>> f().__name__
+    'nεsted'
+
+    The test is mainly to see if the traceback is generated correctly
+    >>> print_traceback_name()
+    unicode_identifiers.Fα1
+
+    Just check that a cpdef function is callable
+    >>> Fα3()
+    1
+
+    >>> Γναμε2.ναμε3
+    1
+    >>> x = Γναμε2()
+    >>> print(x.α)
+    100
+    >>> x.α = 200
+    >>> print(x.α)
+    200
+
+    Test generation of locals()
+    >>> sorted(Γναμε2().boring_function(1,2).keys())
+    ['self', 'somevalue', 'x', 'ναμε5', 'ναμε6']
+
+    >>> Γναμε2().boring_cpdef() - Γναμε2().εxciting_cpdef()
+    0
+    >>> function_taking_fancy_argument(Γναμε2()).ναμε3
+    1
+    >>> NormalClassΓΓ().ναμε
+    10
+    >>> NormalClassΓΓ().εxciting_function(None).__qualname__
+    'NormalClassΓΓ.εxciting_function.<locals>.nestεd'
+
+    Do kwargs work?
+    >>> unicode_kwarg(αrγ=5)
+    5
+    >>> unicode_kwarg_from_cy()
+    1
+
+    Normalization of attributes
+    (The cdef class version is testable in Python 2 too)
+    >>> NormalizeAttrPy().get()
+    5
+    """
+else:
+    __doc__ = ""
+
+global_ναμε1 = None
+cdef double global_ναμε2 = 1.2
+
+def f():
+    """docstring"""
+    ναμε2 = 2
+    def nεsted():
+        return ναμε2
+    return nεsted
+
+# Ƒ is notably awkward because its punycode starts with "2" causing
+# C compile errors. Therefore try a few different variations...
+cdef class A:
+    cdef int ναμε
+    def __init__(self):
+        self.ναμε = 1
+    cdef Ƒ(self):
+        return self.ναμε==1
+    def regular_function(self):
+        """
+        Can use unicode cdef functions and (private) attributes internally
+        >>> A().regular_function()
+        True
+        """
+        return self.Ƒ()
+cdef class B:
+    cpdef Ƒ(self):
+        pass
+cdef class C:
+    def Ƒ(self):
+        pass
+cdef class D:
+    cdef int Ƒ
+
+def regular_function():
+    """
+    Unicode names can be used internally on python2
+    >>> regular_function()
+    10
+    """
+    cdef int variableƑ = 5
+    ναμε2 = 2
+    return variableƑ*ναμε2
+
+cdef Fα1():
+    """docstring"""
+    ναμε2 = 2
+    raise RuntimeError() # forces generation of a traceback
+
+def print_traceback_name():
+    try:
+        Fα1()
+    except RuntimeError as e:
+        import traceback
+        # get the name of one level up in the traceback
+        print(traceback.extract_tb(e.__traceback__,2)[1][2])
+
+
+def Fα2():
+    """docstring"""
+    def nested_normal():
+        """docstring"""
+        pass
+    def nεstεd_uni():
+        """docstring"""
+        pass
+    return nested_normal, nεstεd_uni
+
+cpdef Fα3():
+    """docstring"""
+    return 1
+
+cdef class Γναμε2:
+    """
+    docstring
+    """
+    ναμε3 = 1
+
+    def __init__(self):
+        self.α = 100
+    def boring_function(self,x,ναμε5):
+        """docstring"""
+        ναμε6 = ναμε5
+        somevalue = global_ναμε1 == self.ναμε3
+        return locals()
+    def εxciting_function(self,y):
+        """docstring"""
+        def nestεd():
+            pass
+        return nestεd
+
+    cdef boring_cdef(self):
+        """docstring"""
+        pass
+    cdef εxciting_cdef(self):
+        """docstring"""
+        pass
+
+    cpdef boring_cpdef(self):
+        """docstring"""
+        return 2
+    cpdef εxciting_cpdef(self):
+        """docstring"""
+        return 2
+
+cdef class Derived(Γναμε2):
+    pass
+
+cdef Γναμε2 global_ναμε3 = Γναμε2()
+
+def function_taking_fancy_argument(Γναμε2 αrγ):
+    return αrγ
+
+class NormalClassΓΓ(Γναμε2):
+    """
+    docstring
+    """
+    def __init__(self):
+        self.ναμε = 10
+
+    def boring_function(self,x,ναμε5):
+        """docstring"""
+        ναμε6 = ναμε5
+        somevalue = global_ναμε1 == self.ναμε3
+        return locals()
+    def εxciting_function(self,y):
+        """docstring"""
+        def nestεd():
+            pass
+        return nestεd
+
+def unicode_kwarg(*, αrγ):
+    return αrγ
+
+def unicode_kwarg_from_cy():
+    return unicode_kwarg(αrγ=1)
+
+class NormalizeAttrPy:
+    """Python normalizes identifier names before they are used;
+    therefore fi and fi should access the same attribute"""
+    def __init__(self):
+        self.fi = 5 # note unicode ligature symbol
+    def get(self):
+        return self.fi
+
+cdef class NormalizeAttrCdef:
+    """Python normalizes identifier names before they are used;
+    therefore fi and fi should access the same attribute
+    >>> NormalizeAttrCdef().get()
+    5
+    """
+    cdef int fi # note unicode ligature symbol
+    def __init__(self):
+        self.fi = 5
+    def get(self):
+        return self.fi
+
+if sys.version_info[0]<=2:
+    # These symbols are causing problems for doctest
+    del NormalClassΓΓ
+    del globals()[u'Γναμε2'.encode('utf-8')]
diff --git a/tests/run/unicode_identifiers_import.pyx b/tests/run/unicode_identifiers_import.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3VuaWNvZGVfaWRlbnRpZmllcnNfaW1wb3J0LnB5eA==
--- /dev/null
+++ b/tests/run/unicode_identifiers_import.pyx
@@ -0,0 +1,31 @@
+# -*- coding: utf-8 -*-
+# cython: language_level = 3
+# mode: compile
+# tag: pep3131
+
+# compile only test since there's no way to get
+# it to import another test module at runtime
+
+# this test looks at [c]importing unicode stuff
+from unicode_identifiers cimport Fα1, Γναμε2
+cimport unicode_identifiers
+from unicode_identifiers cimport Γναμε2 as Γναμε3
+
+from unicode_identifiers import NormalClassΓΓ
+from unicode_identifiers import NormalClassΓΓ as NörmalCläss
+
+
+cdef class C(unicode_identifiers.Γναμε2):
+    pass
+
+cdef class D(Γναμε2):
+    pass
+
+cdef class E(Γναμε3):
+    pass
+
+def f():
+    Fα1()
+    unicode_identifiers.Fα1()
+
+
diff --git a/tests/run/unicode_identifiers_normalization.srctree b/tests/run/unicode_identifiers_normalization.srctree
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3VuaWNvZGVfaWRlbnRpZmllcnNfbm9ybWFsaXphdGlvbi5zcmN0cmVl
--- /dev/null
+++ b/tests/run/unicode_identifiers_normalization.srctree
@@ -0,0 +1,83 @@
+# -*- coding: utf-8 -*-
+# mode: run
+# tag: pure3.0, pep3131
+
+PYTHON build_tests.py
+# show behaviour in Python mode
+PYTHON -m doctest test0.py
+PYTHON -m doctest test1.py
+PYTHON -m doctest test2.py
+
+PYTHON setup.py build_ext --inplace
+# test in Cython mode
+PYTHON -c "import doctest; import test0 as m; exit(doctest.testmod(m)[0])"
+PYTHON -c "import doctest; import test1 as m; exit(doctest.testmod(m)[0])"
+PYTHON -c "import doctest; import test2 as m; exit(doctest.testmod(m)[0])"
+
+########## setup.py #########
+
+from Cython.Build.Dependencies import cythonize
+from distutils.core import setup
+
+setup(
+  ext_modules = cythonize("test*.py"),
+)
+
+######### build_tests.py ########
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+import sys
+import unicodedata
+
+# a few pairs of unicode strings that should be equivalent after normalization
+string_pairs = [("fi", "fi"), # ligature and two letters
+                ("a\u0301", '\u00e1'), # a with acute accent with combining character or as 1 character
+                ("α\u0334\u0362", "α\u0362\u0334") # alpha with a pair of combining characters
+                    # in a different order. No single character to normalize to
+                ]
+
+# Show that the pairs genuinely aren't equal before normalization
+for sp in string_pairs:
+    assert sp[0] != sp[1]
+    assert unicodedata.normalize('NFKC', sp[0]) == unicodedata.normalize('NFKC', sp[1])
+    
+# some code that accesses the identifiers through the two different names
+#  contains doctests
+example_code = [
+"""
+class C:
+    '''
+    >>> C().get()
+    True
+    '''
+    def __init__(self):
+        self.{0} = True
+    def get(self):
+        return self.{1}
+""", """
+def pass_through({0}):
+    '''
+    >>> pass_through(True)
+    True
+    '''
+    return {1}
+""", """
+import cython
+{0} = True
+def test():
+    '''
+    >>> test()
+    True
+    '''
+    return {1}
+"""]
+
+from io import open
+
+for idx, (code, strings) in enumerate(zip(example_code, string_pairs)):
+    with open("test{0}.py".format(idx), "w", encoding="utf8") as f:
+        code = code.format(*strings)
+        f.write("# -*- coding: utf-8 -*-\n")
+        # The code isn't Py2 compatible. Only write actual code in Py3+.
+        if sys.version_info[0] > 2:
+            f.write(code)
diff --git a/tests/run/unicode_imports.srctree b/tests/run/unicode_imports.srctree
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3VuaWNvZGVfaW1wb3J0cy5zcmN0cmVl
--- /dev/null
+++ b/tests/run/unicode_imports.srctree
@@ -0,0 +1,105 @@
+# -*- coding: utf-8 -*-
+# tag: py3, pep489
+
+PYTHON setup.py build_ext --inplace
+PYTHON -m mydoctest
+
+########### mydoctest.py #######
+
+import sys
+if sys.version_info < (3, 5):
+    # The module is only Cythonized and not build for these versions
+    # so don't run the tests
+    exit()
+    
+import doctest
+import from_py
+val = doctest.testmod(from_py)[0]
+import from_cy
+val += doctest.testmod(from_cy)[0]
+
+exit(val)
+
+########### setup.py ########
+
+# -*- coding: utf-8 -*-
+
+from __future__ import unicode_literals
+
+import sys
+from Cython.Build import cythonize
+
+files = ["mymoð.pyx", "from_cy.pyx"]
+
+
+# For Python 2 and Python <= 3.4 just run pyx->c; 
+# don't compile the C file
+modules = cythonize(files)
+
+if sys.version_info >= (3, 5):
+    from distutils.core import setup
+
+    setup(
+        ext_modules = modules
+    )
+
+############ mymoð.pyx #########
+
+def f():
+    return True
+
+cdef public api void cdef_func():
+    pass
+
+############ pxd_moð.pxd ##########
+
+cdef struct S:
+    int x
+    
+cdef public api void cdef_func() # just to test generation of headers
+    
+############ from_py.py #########
+
+# -*- coding: utf-8 -*-
+
+import mymoð
+from mymoð import f
+
+__doc__ = """
+>>> mymoð.f()
+True
+>>> f()
+True
+"""
+
+######### from_cy.pyx ##########
+
+# -*- coding: utf-8 -*-
+
+import mymoð
+
+from mymoð import f
+
+cimport pxd_moð
+from pxd_moð cimport S
+
+
+def test_imported():
+    """
+    >>> test_imported()
+    True
+    """
+    return mymoð.f() and f() # True and True
+
+
+def test_cimported():
+    """
+    >>> test_cimported()
+    3
+    """
+    cdef pxd_moð.S v1
+    v1.x = 1
+    cdef S v2
+    v2.x = 2
+    return v1.x + v2.x
+    
diff --git a/tests/run/unicode_slicing.pyx b/tests/run/unicode_slicing.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL3VuaWNvZGVfc2xpY2luZy5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3VuaWNvZGVfc2xpY2luZy5weXg= 100644
--- a/tests/run/unicode_slicing.pyx
+++ b/tests/run/unicode_slicing.pyx
@@ -151,5 +151,20 @@
     >>> slice_none_none(None, 2, 4)
     Traceback (most recent call last):    
     TypeError: 'NoneType' object is not subscriptable
+
+    >>> slice_start_end(u'abcdef', SSIZE_T_MAX, SSIZE_T_MIN)
+    <BLANKLINE>
+    >>> slice_start(u'abcdef', SSIZE_T_MAX, SSIZE_T_MIN)
+    <BLANKLINE>
+    >>> slice_end(u'abcdef', SSIZE_T_MAX, SSIZE_T_MIN)
+    abcdef
+    >>> slice_all(u'abcdef', SSIZE_T_MAX, SSIZE_T_MIN)
+    abcdef
+    >>> slice_start_none(u'abcdef', SSIZE_T_MAX, SSIZE_T_MIN)
+    <BLANKLINE>
+    >>> slice_none_end(u'abcdef', SSIZE_T_MAX, SSIZE_T_MIN)
+    abcdef
+    >>> slice_none_none(u'abcdef', SSIZE_T_MAX, SSIZE_T_MIN)
+    abcdef
 """
 
@@ -154,7 +169,14 @@
 """
 
+cdef extern from *:
+    cdef Py_ssize_t PY_SSIZE_T_MIN
+    cdef Py_ssize_t PY_SSIZE_T_MAX
+
+SSIZE_T_MAX = PY_SSIZE_T_MAX
+SSIZE_T_MIN = PY_SSIZE_T_MIN
+
 import sys
 
 if sys.version_info[0] >= 3:
     __doc__ = __doc__.replace(u"(u'", u"('").replace(u" u'", u" '")
 
@@ -156,8 +178,8 @@
 import sys
 
 if sys.version_info[0] >= 3:
     __doc__ = __doc__.replace(u"(u'", u"('").replace(u" u'", u" '")
 
-def slice_start_end(unicode s, int i, int j):
+def slice_start_end(unicode s, Py_ssize_t i, Py_ssize_t j):
     print(s[i:j])
 
@@ -162,5 +184,5 @@
     print(s[i:j])
 
-def slice_start(unicode s, int i, int j):
+def slice_start(unicode s, Py_ssize_t i, Py_ssize_t j):
     print(s[i:])
 
@@ -165,5 +187,5 @@
     print(s[i:])
 
-def slice_end(unicode s, int i, int j):
+def slice_end(unicode s, Py_ssize_t i, Py_ssize_t j):
     print(s[:i])
 
@@ -168,5 +190,5 @@
     print(s[:i])
 
-def slice_all(unicode s, int i, int j):
+def slice_all(unicode s, Py_ssize_t i, Py_ssize_t j):
     print(s[:])
 
@@ -171,5 +193,5 @@
     print(s[:])
 
-def slice_start_none(unicode s, int i, int j):
+def slice_start_none(unicode s, Py_ssize_t i, Py_ssize_t j):
     print(s[i:None])
 
@@ -174,5 +196,5 @@
     print(s[i:None])
 
-def slice_none_end(unicode s, int i, int j):
+def slice_none_end(unicode s, Py_ssize_t i, Py_ssize_t j):
     print(s[None:i])
 
@@ -177,4 +199,4 @@
     print(s[None:i])
 
-def slice_none_none(unicode s, int i, int j):
+def slice_none_none(unicode s, Py_ssize_t i, Py_ssize_t j):
     print(s[None:None])
diff --git a/tests/run/unicodeliterals.pyx b/tests/run/unicodeliterals.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL3VuaWNvZGVsaXRlcmFscy5weXg=..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3VuaWNvZGVsaXRlcmFscy5weXg= 100644
--- a/tests/run/unicodeliterals.pyx
+++ b/tests/run/unicodeliterals.pyx
@@ -87,5 +87,4 @@
     True
     >>> ustring_in_constant_tuple == ('a', u'abc', u'\\N{SNOWMAN}', u'x' * 3, u'\\N{SNOWMAN}' * 4 + u'O')  or  ustring_in_constant_tuple  # unescaped by Python
     True
-"""
 
@@ -91,7 +90,4 @@
 
-if sys.version_info >= (2,6,5):
-    # this doesn't work well in older Python versions
-    __doc__ += u"""\
     >>> expected = u'\U00101234'    # unescaped by Cython
     >>> if wide_literal == expected: print(True)
     ... else: print(repr(wide_literal), repr(expected), sys.maxunicode)
diff --git a/tests/run/with_gil.pyx b/tests/run/with_gil.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL3dpdGhfZ2lsLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3dpdGhfZ2lsLnB5eA== 100644
--- a/tests/run/with_gil.pyx
+++ b/tests/run/with_gil.pyx
@@ -1,3 +1,6 @@
+# mode: run
+# tag: nogil, withgil
+
 """
 Test the 'with gil:' statement.
 """
diff --git a/tests/run/with_gil_automatic.pyx b/tests/run/with_gil_automatic.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3dpdGhfZ2lsX2F1dG9tYXRpYy5weXg=
--- /dev/null
+++ b/tests/run/with_gil_automatic.pyx
@@ -0,0 +1,138 @@
+# mode: run
+# tag: nogil
+# cython: language_level=2
+
+cimport cython
+
+
+#### print
+
+@cython.test_assert_path_exists(
+    "//GILStatNode",
+    "//GILStatNode//GILStatNode",
+    "//GILStatNode//GILStatNode//PrintStatNode",
+)
+def test_print_in_nogil_section(x):
+    """
+    >>> test_print_in_nogil_section(123)
+    --123--
+    """
+    with nogil:
+        print f"--{x}--"
+
+
+@cython.test_assert_path_exists(
+    "//GILStatNode",
+    "//GILStatNode//PrintStatNode",
+)
+@cython.test_fail_if_path_exists(
+    "//GILStatNode//GILStatNode",
+)
+cpdef int test_print_in_nogil_func(x) nogil except -1:
+    """
+    >>> _ = test_print_in_nogil_func(123)
+    --123--
+    """
+    print f"--{x}--"
+
+
+#### raise
+
+@cython.test_assert_path_exists(
+    "//GILStatNode",
+    "//GILStatNode//GILStatNode",
+    "//GILStatNode//GILStatNode//RaiseStatNode",
+)
+def test_raise_in_nogil_section(x):
+    """
+    >>> try: test_raise_in_nogil_section(123)
+    ... except ValueError as exc: print(exc)
+    ... else: print("NOT RAISED !")
+    --123--
+    """
+    with nogil:
+        raise ValueError(f"--{x}--")
+
+
+@cython.test_assert_path_exists(
+    "//GILStatNode",
+    "//GILStatNode//RaiseStatNode",
+)
+@cython.test_fail_if_path_exists(
+    "//GILStatNode//GILStatNode",
+)
+cpdef int test_raise_in_nogil_func(x) nogil except -1:
+    """
+    >>> test_raise_in_nogil_func(123)
+    Traceback (most recent call last):
+    ValueError: --123--
+    """
+    raise ValueError(f"--{x}--")
+
+
+#### assert
+
+@cython.test_assert_path_exists(
+    "//GILStatNode",
+    "//GILStatNode//AssertStatNode",
+    "//GILStatNode//AssertStatNode//GILStatNode",
+    "//GILStatNode//AssertStatNode//GILStatNode//RaiseStatNode",
+)
+def assert_in_nogil_section(int x):
+    """
+    >>> assert_in_nogil_section(123)
+    >>> assert_in_nogil_section(0)
+    Traceback (most recent call last):
+    AssertionError
+    """
+    with nogil:
+        assert x
+
+
+@cython.test_assert_path_exists(
+    "//GILStatNode",
+    "//GILStatNode//AssertStatNode",
+    "//GILStatNode//AssertStatNode//GILStatNode",
+    "//GILStatNode//AssertStatNode//GILStatNode//RaiseStatNode",
+)
+def assert_in_nogil_section_ustring(int x):
+    """
+    >>> assert_in_nogil_section_string(123)
+    >>> assert_in_nogil_section_string(0)
+    Traceback (most recent call last):
+    AssertionError: failed!
+    """
+    with nogil:
+        assert x, u"failed!"
+
+
+@cython.test_assert_path_exists(
+    "//GILStatNode",
+    "//GILStatNode//AssertStatNode",
+    "//GILStatNode//AssertStatNode//GILStatNode",
+    "//GILStatNode//AssertStatNode//GILStatNode//RaiseStatNode",
+)
+def assert_in_nogil_section_string(int x):
+    """
+    >>> assert_in_nogil_section_string(123)
+    >>> assert_in_nogil_section_string(0)
+    Traceback (most recent call last):
+    AssertionError: failed!
+    """
+    with nogil:
+        assert x, "failed!"
+
+
+@cython.test_assert_path_exists(
+    "//AssertStatNode",
+    "//AssertStatNode//GILStatNode",
+    "//AssertStatNode//GILStatNode//RaiseStatNode",
+)
+cpdef int assert_in_nogil_func(int x) nogil except -1:
+    """
+    >>> _ = assert_in_nogil_func(123)
+    >>> assert_in_nogil_func(0)
+    Traceback (most recent call last):
+    AssertionError: failed!
+    """
+    assert x, "failed!"
diff --git a/tests/run/yield_from_pep380.pyx b/tests/run/yield_from_pep380.pyx
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvcnVuL3lpZWxkX2Zyb21fcGVwMzgwLnB5eA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvcnVuL3lpZWxkX2Zyb21fcGVwMzgwLnB5eA== 100644
--- a/tests/run/yield_from_pep380.pyx
+++ b/tests/run/yield_from_pep380.pyx
@@ -4,7 +4,7 @@
 Test suite for PEP 380 implementation
 
 adapted from original tests written by Greg Ewing
-see <http://www.cosc.canterbury.ac.nz/greg.ewing/python/yield-from/YieldFrom-Python3.1.2-rev5.zip>
+see <https://www.cosc.canterbury.ac.nz/greg.ewing/python/yield-from/YieldFrom-Python3.1.2-rev5.zip>
 """
 
 import sys
diff --git a/tests/windows_bugs.txt b/tests/windows_bugs.txt
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dGVzdHMvd2luZG93c19idWdzLnR4dA==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dGVzdHMvd2luZG93c19idWdzLnR4dA== 100644
--- a/tests/windows_bugs.txt
+++ b/tests/windows_bugs.txt
@@ -25,3 +25,9 @@
 queue2
 queue3
 lunch
+
+# "C linkage function cannot return C++ class" (uses public C++ cdef function)
+cpp_template_subclasses
+
+# MSVC lacks "complex.h"
+complex_numbers_cmath_T2891
diff --git a/tox.ini b/tox.ini
index 036fed8fdf0b7167741b03ac22ae1dd2fe789b41_dG94LmluaQ==..162972e7c0335748b70e02edc37e5e3bbb4858ae_dG94LmluaQ== 100644
--- a/tox.ini
+++ b/tox.ini
@@ -10,9 +10,3 @@
 setenv = CFLAGS=-O0 -ggdb
 commands =
     {envpython} runtests.py -vv
-
-[pycodestyle]
-ignore = W, E
-select = E711, E714, E501, W291
-max-line-length = 150
-format = pylint