summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.circleci/config.yml4
-rw-r--r--doc/Makefile2
-rw-r--r--doc/neps/.gitignore1
-rw-r--r--doc/neps/Makefile9
-rw-r--r--doc/neps/index.rst.tmpl (renamed from doc/neps/index.rst)31
-rw-r--r--doc/neps/nep-0000.rst15
-rw-r--r--doc/neps/nep-0001-npy-format.rst7
-rw-r--r--doc/neps/nep-0002-warnfix.rst39
-rw-r--r--doc/neps/nep-0003-math_config_clean.rst1
-rw-r--r--doc/neps/nep-0004-datetime-proposal3.rst2
-rw-r--r--doc/neps/nep-0005-generalized-ufuncs.rst2
-rw-r--r--doc/neps/nep-0006-newbugtracker.rst1
-rw-r--r--doc/neps/nep-0007-datetime-proposal.rst2
-rw-r--r--doc/neps/nep-0008-groupby_additions.rst18
-rw-r--r--doc/neps/nep-0009-structured_array_extensions.rst2
-rw-r--r--doc/neps/nep-0010-new-iterator-ufunc.rst1
-rw-r--r--doc/neps/nep-0011-deferred-ufunc-evaluation.rst1
-rw-r--r--doc/neps/nep-0012-missing-data.rst1
-rw-r--r--doc/neps/nep-0013-ufunc-overrides.rst8
-rw-r--r--doc/neps/nep-0014-dropping-python2.7-proposal.rst3
-rw-r--r--doc/neps/nep-template.rst2
-rw-r--r--doc/neps/tools/build_index.py99
-rw-r--r--doc/release/1.15.0-notes.rst20
-rw-r--r--doc/source/user/building.rst2
-rwxr-xr-xdoc/summarize.py2
-rw-r--r--numpy/__init__.py1
-rw-r--r--numpy/add_newdocs.py2
-rw-r--r--numpy/core/__init__.py1
-rw-r--r--numpy/core/code_generators/generate_umath.py4
-rw-r--r--numpy/core/code_generators/ufunc_docstrings.py278
-rw-r--r--numpy/core/fromnumeric.py16
-rw-r--r--numpy/core/include/numpy/npy_common.h16
-rw-r--r--numpy/core/include/numpy/npy_cpu.h3
-rw-r--r--numpy/core/include/numpy/npy_endian.h3
-rw-r--r--numpy/core/numeric.py2
-rw-r--r--numpy/core/setup.py1
-rw-r--r--numpy/core/setup_common.py1
-rw-r--r--numpy/core/src/multiarray/conversion_utils.c4
-rw-r--r--numpy/core/src/multiarray/datetime_strings.c2
-rw-r--r--numpy/core/src/multiarray/scalartypes.c.src37
-rw-r--r--numpy/core/src/umath/cpuid.c56
-rw-r--r--numpy/core/src/umath/cpuid.h9
-rw-r--r--numpy/core/tests/test_datetime.py7
-rw-r--r--numpy/core/tests/test_multiarray.py2
-rw-r--r--numpy/core/tests/test_records.py2
-rw-r--r--numpy/core/tests/test_scalarprint.py17
-rw-r--r--numpy/core/tests/test_ufunc.py4
-rw-r--r--numpy/distutils/__init__.py4
-rw-r--r--numpy/doc/subclassing.py2
-rw-r--r--numpy/f2py/__init__.py1
-rwxr-xr-xnumpy/f2py/crackfortran.py2
-rw-r--r--numpy/fft/__init__.py1
-rw-r--r--numpy/lib/__init__.py1
-rw-r--r--numpy/lib/function_base.py3
-rw-r--r--numpy/linalg/__init__.py1
-rw-r--r--numpy/ma/__init__.py1
-rw-r--r--numpy/ma/core.py4
-rw-r--r--numpy/ma/tests/test_core.py6
-rw-r--r--numpy/matrixlib/__init__.py1
-rw-r--r--numpy/matrixlib/tests/test_defmatrix.py2
-rw-r--r--numpy/polynomial/__init__.py1
-rw-r--r--numpy/random/__init__.py1
-rw-r--r--numpy/testing/__init__.py11
-rw-r--r--numpy/testing/_private/__init__.py (renamed from numpy/testing/nose_tools/__init__.py)0
-rw-r--r--numpy/testing/_private/decorators.py (renamed from numpy/testing/nose_tools/decorators.py)2
-rw-r--r--numpy/testing/_private/noseclasses.py (renamed from numpy/testing/nose_tools/noseclasses.py)0
-rw-r--r--numpy/testing/_private/nosetester.py (renamed from numpy/testing/nose_tools/nosetester.py)0
-rw-r--r--numpy/testing/_private/parameterized.py (renamed from numpy/testing/nose_tools/parameterized.py)0
-rw-r--r--numpy/testing/_private/pytesttester.py175
-rw-r--r--numpy/testing/_private/utils.py (renamed from numpy/testing/nose_tools/utils.py)0
-rw-r--r--numpy/testing/decorators.py7
-rw-r--r--numpy/testing/noseclasses.py8
-rw-r--r--numpy/testing/nosetester.py6
-rw-r--r--numpy/testing/pytest_tools/decorators.py2
-rwxr-xr-xnumpy/testing/setup.py2
-rw-r--r--numpy/testing/utils.py7
-rw-r--r--pytest.ini18
77 files changed, 761 insertions, 251 deletions
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 70cb8adc0..86470e086 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -21,6 +21,8 @@ jobs:
python3 -m venv venv
. venv/bin/activate
pip install cython sphinx matplotlib
+ sudo apt-get update
+ sudo apt-get install -y graphviz
- run:
name: build numpy
@@ -93,7 +95,7 @@ jobs:
if [ "${CIRCLE_BRANCH}" == "master" ]; then
touch doc/neps/_build/html/.nojekyll
- ./tools/push_to_repo.py doc/neps/_build/html \
+ ./tools/ci/push_docs_to_repo.py doc/neps/_build/html \
git@github.com:numpy/neps.git \
--committer "numpy-circleci-bot" \
--email "numpy-circleci-bot@nomail" \
diff --git a/doc/Makefile b/doc/Makefile
index d414d26d7..667dbef29 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -1,7 +1,7 @@
# Makefile for Sphinx documentation
#
-PYVER = 2.7
+PYVER = 3.6
PYTHON = python$(PYVER)
# You can set these variables from the command line.
diff --git a/doc/neps/.gitignore b/doc/neps/.gitignore
new file mode 100644
index 000000000..04163f707
--- /dev/null
+++ b/doc/neps/.gitignore
@@ -0,0 +1 @@
+index.rst
diff --git a/doc/neps/Makefile b/doc/neps/Makefile
index 2d1a063de..3c023ae9b 100644
--- a/doc/neps/Makefile
+++ b/doc/neps/Makefile
@@ -2,7 +2,7 @@
#
# You can set these variables from the command line.
-SPHINXOPTS =
+SPHINXOPTS = -W
SPHINXBUILD = sphinx-build
SPHINXPROJ = NumPyEnhancementProposals
SOURCEDIR = .
@@ -12,9 +12,12 @@ BUILDDIR = _build
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
-.PHONY: help Makefile
+.PHONY: help Makefile index
+
+index:
+ python tools/build_index.py
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
-%: Makefile
+%: Makefile index
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff --git a/doc/neps/index.rst b/doc/neps/index.rst.tmpl
index 8a2df4078..8d0c5da77 100644
--- a/doc/neps/index.rst
+++ b/doc/neps/index.rst.tmpl
@@ -14,9 +14,11 @@ Meta-NEPs (NEPs about NEPs or Processes)
.. toctree::
:maxdepth: 1
- nep-0000
- nep-template
+{% for nep, tags in neps.items() if tags['Type'] == 'Process' %}
+ NEP {{ nep }} — {{ tags['Title'] }} <{{ tags['Filename'] }}>
+{% endfor %}
+ nep-template
Accepted NEPs, implementation in progress
-----------------------------------------
@@ -24,8 +26,9 @@ Accepted NEPs, implementation in progress
.. toctree::
:maxdepth: 1
- nep-0014-dropping-python2.7-proposal
-
+{% for nep, tags in neps.items() if tags['Status'] == 'Accepted' %}
+ NEP {{ nep }} — {{ tags['Title'] }} <{{ tags['Filename'] }}>
+{% endfor %}
Implemented NEPs
----------------
@@ -33,12 +36,9 @@ Implemented NEPs
.. toctree::
:maxdepth: 1
- nep-0001-npy-format
- nep-0005-generalized-ufuncs
- nep-0007-datetime-proposal
- nep-0010-new-iterator-ufunc
- nep-0013-ufunc-overrides
-
+{% for nep, tags in neps.items() if tags['Status'] == 'Final' %}
+ NEP {{ nep }} — {{ tags['Title'] }} <{{ tags['Filename'] }}>
+{% endfor %}
Defunct NEPs
------------
@@ -46,11 +46,6 @@ Defunct NEPs
.. toctree::
:maxdepth: 1
- nep-0002-warnfix
- nep-0003-math_config_clean
- nep-0004-datetime-proposal3
- nep-0006-newbugtracker
- nep-0008-groupby_additions
- nep-0009-structured_array_extensions
- nep-0011-deferred-ufunc-evaluation
- nep-0012-missing-data
+{% for nep, tags in neps.items() if tags['Status'] == 'Deferred' %}
+ NEP {{ nep }} — {{ tags['Title'] }} <{{ tags['Filename'] }}>
+{% endfor %}
diff --git a/doc/neps/nep-0000.rst b/doc/neps/nep-0000.rst
index ae8603c62..a7d6d7115 100644
--- a/doc/neps/nep-0000.rst
+++ b/doc/neps/nep-0000.rst
@@ -1,6 +1,6 @@
-=======================
-NEP Purpose and Process
-=======================
+===================
+Purpose and Process
+===================
:Author: Jarrod Millman <millman@berkeley.edu>
:Status: Draft
@@ -121,9 +121,12 @@ updated accordingly. In addition to updating the status field, at the very
least the ``Resolution`` header should be added with a link to the relevant
post in the mailing list archives.
-NEPs can also be ``Replaced`` by a different NEP, rendering the original
-obsolete. Process NEPs may also have a status of
-``Active`` if they are never meant to be completed. E.g. NEP 0 (this NEP).
+NEPs can also be ``Superseded`` by a different NEP, rendering the
+original obsolete. The ``Replaced-By`` and ``Replaces`` headers
+should be added to the original and new NEPs respectively.
+
+Process NEPs may also have a status of ``Active`` if they are never
+meant to be completed, e.g. NEP 0 (this NEP).
Maintenance
diff --git a/doc/neps/nep-0001-npy-format.rst b/doc/neps/nep-0001-npy-format.rst
index 3f12e1bf1..2057aed83 100644
--- a/doc/neps/nep-0001-npy-format.rst
+++ b/doc/neps/nep-0001-npy-format.rst
@@ -2,10 +2,9 @@
A Simple File Format for NumPy Arrays
=====================================
-Author: Robert Kern <robert.kern@gmail.com>
-Status: Draft
-Created: 20-Dec-2007
-
+:Author: Robert Kern <robert.kern@gmail.com>
+:Status: Final
+:Created: 20-Dec-2007
Abstract
--------
diff --git a/doc/neps/nep-0002-warnfix.rst b/doc/neps/nep-0002-warnfix.rst
index 4b0a2a56e..60dc885b2 100644
--- a/doc/neps/nep-0002-warnfix.rst
+++ b/doc/neps/nep-0002-warnfix.rst
@@ -5,6 +5,7 @@ A proposal to build numpy without warning with a big set of warning flags
:Author: David Cournapeau
:Contact: david@ar.media.kyoto-u.ac.jp
:Date: 2008-09-04
+:Status: Deferred
Executive summary
=================
@@ -20,13 +21,13 @@ Warning flags
=============
Each compiler detects a different set of potential errors. The baseline will
-be gcc -Wall -W -Wextra. Ideally, a complete set would be nice:
+be gcc -Wall -W -Wextra. Ideally, a complete set would be nice::
--W -Wall -Wextra -Wstrict-prototypes -Wmissing-prototypes -Waggregate-return
--Wcast-align -Wcast-qual -Wnested-externs -Wshadow -Wbad-function-cast
--Wwrite-strings "
+ -W -Wall -Wextra -Wstrict-prototypes -Wmissing-prototypes -Waggregate-return
+ -Wcast-align -Wcast-qual -Wnested-externs -Wshadow -Wbad-function-cast
+ -Wwrite-strings "
-Intel compiler, VS with /W3 /Wall, Sun compilers have extra warnings too.
+Intel compiler, VS with ``/W3 /Wall``, Sun compilers have extra warnings too.
Kind of warnings
================
@@ -46,27 +47,29 @@ solve it is to tag the function argument with a macro NPY_UNUSED. This macro
uses compiler specific code to tag the variable, and mangle it such as it is
not possible to use it accidentally once it is tagged.
-The code to apply compiler specific option could be:
+The code to apply compiler specific option could be::
-#if defined(__GNUC__)
- #define __COMP_NPY_UNUSED __attribute__ ((__unused__))
-# elif defined(__ICC)
- #define __COMP_NPY_UNUSED __attribute__ ((__unused__))
-#else
- #define __COMP_NPY_UNUSED
-#endif
+ #if defined(__GNUC__)
+ #define __COMP_NPY_UNUSED __attribute__ ((__unused__))
+ # elif defined(__ICC)
+ #define __COMP_NPY_UNUSED __attribute__ ((__unused__))
+ #else
+ #define __COMP_NPY_UNUSED
+ #endif
-The variable mangling would be:
+The variable mangling would be::
-#define NPY_UNUSED(x) (__NPY_UNUSED_TAGGED ## x) __COMP_NPY_UNUSED
+ #define NPY_UNUSED(x) (__NPY_UNUSED_TAGGED ## x) __COMP_NPY_UNUSED
-When applied to a variable, one would get:
+When applied to a variable, one would get::
-int foo(int * NPY_UNUSED(dummy))
+ int foo(int * NPY_UNUSED(dummy))
expanded to
-int foo(int * __NPY_UNUSED_TAGGEDdummy __COMP_NPY_UNUSED)
+::
+
+ int foo(int * __NPY_UNUSED_TAGGEDdummy __COMP_NPY_UNUSED)
Thus avoiding any accidental use of the variable. The mangling is pure C, and
thuse portable. The per-variable warning disabling is compiler specific.
diff --git a/doc/neps/nep-0003-math_config_clean.rst b/doc/neps/nep-0003-math_config_clean.rst
index 27c0adfa1..5af907437 100644
--- a/doc/neps/nep-0003-math_config_clean.rst
+++ b/doc/neps/nep-0003-math_config_clean.rst
@@ -5,6 +5,7 @@ Cleaning the math configuration of numpy.core
:Author: David Cournapeau
:Contact: david@ar.media.kyoto-u.ac.jp
:Date: 2008-09-04
+:Status: Deferred
Executive summary
=================
diff --git a/doc/neps/nep-0004-datetime-proposal3.rst b/doc/neps/nep-0004-datetime-proposal3.rst
index fcfb39e54..46d8e314b 100644
--- a/doc/neps/nep-0004-datetime-proposal3.rst
+++ b/doc/neps/nep-0004-datetime-proposal3.rst
@@ -7,7 +7,7 @@
:Author: Ivan Vilata i Balaguer
:Contact: ivan@selidor.net
:Date: 2008-07-30
-
+:Status: Deferred
Executive summary
=================
diff --git a/doc/neps/nep-0005-generalized-ufuncs.rst b/doc/neps/nep-0005-generalized-ufuncs.rst
index 98e436990..54b2b370e 100644
--- a/doc/neps/nep-0005-generalized-ufuncs.rst
+++ b/doc/neps/nep-0005-generalized-ufuncs.rst
@@ -2,6 +2,8 @@
Generalized Universal Functions
===============================
+:Status: Final
+
There is a general need for looping over not only functions on scalars
but also over functions on vectors (or arrays), as explained on
http://scipy.org/scipy/numpy/wiki/GeneralLoopingFunctions. We propose
diff --git a/doc/neps/nep-0006-newbugtracker.rst b/doc/neps/nep-0006-newbugtracker.rst
index 5af633552..2b9344ed0 100644
--- a/doc/neps/nep-0006-newbugtracker.rst
+++ b/doc/neps/nep-0006-newbugtracker.rst
@@ -3,6 +3,7 @@ Replacing Trac with a different bug tracker
===========================================
:Author: David Cournapeau, Stefan van der Walt
+:Status: Deferred
Some release managers of both numpy and scipy are becoming more and more
dissatisfied with the current development workflow, in particular for bug
diff --git a/doc/neps/nep-0007-datetime-proposal.rst b/doc/neps/nep-0007-datetime-proposal.rst
index 76c361f4f..72d48d244 100644
--- a/doc/neps/nep-0007-datetime-proposal.rst
+++ b/doc/neps/nep-0007-datetime-proposal.rst
@@ -5,6 +5,7 @@
:Author: Travis Oliphant
:Contact: oliphant@enthought.com
:Date: 2009-06-09
+:Status: Final
Revised only slightly from the third proposal by
@@ -14,7 +15,6 @@ Revised only slightly from the third proposal by
:Contact: ivan@selidor.net
:Date: 2008-07-30
-
Executive summary
=================
diff --git a/doc/neps/nep-0008-groupby_additions.rst b/doc/neps/nep-0008-groupby_additions.rst
index a86bdd642..fa02f2f9c 100644
--- a/doc/neps/nep-0008-groupby_additions.rst
+++ b/doc/neps/nep-0008-groupby_additions.rst
@@ -5,6 +5,7 @@
:Author: Travis Oliphant
:Contact: oliphant@enthought.com
:Date: 2010-04-27
+:Status: Deferred
Executive summary
@@ -22,9 +23,9 @@ Example Use Case
================
Suppose you have a NumPy structured array containing information about
the number of purchases at several stores over multiple days. To be clear, the
-structured array data-type is:
+structured array data-type is::
-dt = [('year', i2), ('month', i1), ('day', i1), ('time', float),
+ dt = [('year', i2), ('month', i1), ('day', i1), ('time', float),
('store', i4), ('SKU', 'S6'), ('number', i4)]
Suppose there is a 1-d NumPy array of this data-type and you would like
@@ -98,14 +99,5 @@ reduceby::
Functions proposed
==================
-segment::
-
-
-edges::
-
-
-.. Local Variables:
-.. mode: rst
-.. coding: utf-8
-.. fill-column: 72
-.. End:
+- segment
+- edges
diff --git a/doc/neps/nep-0009-structured_array_extensions.rst b/doc/neps/nep-0009-structured_array_extensions.rst
index a4248362c..695d0d516 100644
--- a/doc/neps/nep-0009-structured_array_extensions.rst
+++ b/doc/neps/nep-0009-structured_array_extensions.rst
@@ -2,6 +2,8 @@
Structured array extensions
===========================
+:Status: Deferred
+
1. Create with-style context that makes "named-columns" available as names in the namespace.
with np.columns(array):
diff --git a/doc/neps/nep-0010-new-iterator-ufunc.rst b/doc/neps/nep-0010-new-iterator-ufunc.rst
index 7a9e7627c..7b388a974 100644
--- a/doc/neps/nep-0010-new-iterator-ufunc.rst
+++ b/doc/neps/nep-0010-new-iterator-ufunc.rst
@@ -5,6 +5,7 @@ Optimizing Iterator/UFunc Performance
:Author: Mark Wiebe <mwwiebe@gmail.com>
:Content-Type: text/x-rst
:Created: 25-Nov-2010
+:Status: Final
*****************
Table of Contents
diff --git a/doc/neps/nep-0011-deferred-ufunc-evaluation.rst b/doc/neps/nep-0011-deferred-ufunc-evaluation.rst
index b00c0dd2d..5f5de3518 100644
--- a/doc/neps/nep-0011-deferred-ufunc-evaluation.rst
+++ b/doc/neps/nep-0011-deferred-ufunc-evaluation.rst
@@ -5,6 +5,7 @@ Deferred UFunc Evaluation
:Author: Mark Wiebe <mwwiebe@gmail.com>
:Content-Type: text/x-rst
:Created: 30-Nov-2010
+:Status: Deferred
********
Abstract
diff --git a/doc/neps/nep-0012-missing-data.rst b/doc/neps/nep-0012-missing-data.rst
index 00a6034f4..1553339f4 100644
--- a/doc/neps/nep-0012-missing-data.rst
+++ b/doc/neps/nep-0012-missing-data.rst
@@ -6,6 +6,7 @@ Missing Data Functionality in NumPy
:Copyright: Copyright 2011 by Enthought, Inc
:License: CC By-SA 3.0 (http://creativecommons.org/licenses/by-sa/3.0/)
:Date: 2011-06-23
+:Status: Deferred
*****************
Table of Contents
diff --git a/doc/neps/nep-0013-ufunc-overrides.rst b/doc/neps/nep-0013-ufunc-overrides.rst
index 90869e1ac..c97b69023 100644
--- a/doc/neps/nep-0013-ufunc-overrides.rst
+++ b/doc/neps/nep-0013-ufunc-overrides.rst
@@ -1,5 +1,3 @@
-.. _neps.ufunc-overrides:
-
=================================
A Mechanism for Overriding Ufuncs
=================================
@@ -19,6 +17,8 @@ A Mechanism for Overriding Ufuncs
:Author: Stephan Hoyer
:Date: 2017-03-31
+:Status: Final
+
Executive summary
=================
@@ -154,8 +154,8 @@ Here:
- *ufunc* is the ufunc object that was called.
- *method* is a string indicating how the Ufunc was called, either
``"__call__"`` to indicate it was called directly, or one of its
- :ref:`methods<ufuncs.methods>`: ``"reduce"``, ``"accumulate"``,
- ``"reduceat"``, ``"outer"``, or ``"at"``.
+ methods: ``"reduce"``, ``"accumulate"``, ``"reduceat"``, ``"outer"``,
+ or ``"at"``.
- *inputs* is a tuple of the input arguments to the ``ufunc``
- *kwargs* contains any optional or keyword arguments passed to the
function. This includes any ``out`` arguments, which are always
diff --git a/doc/neps/nep-0014-dropping-python2.7-proposal.rst b/doc/neps/nep-0014-dropping-python2.7-proposal.rst
index 3cfe50bd0..6cfd4707f 100644
--- a/doc/neps/nep-0014-dropping-python2.7-proposal.rst
+++ b/doc/neps/nep-0014-dropping-python2.7-proposal.rst
@@ -2,6 +2,9 @@
Plan for dropping Python 2.7 support
====================================
+:Status: Accepted
+:Resolution: https://mail.python.org/pipermail/numpy-discussion/2017-November/077419.html
+
The Python core team plans to stop supporting Python 2 in 2020. The NumPy
project has supported both Python 2 and Python 3 in parallel since 2010, and
has found that supporting Python 2 is an increasing burden on our limited
diff --git a/doc/neps/nep-template.rst b/doc/neps/nep-template.rst
index d51ad3688..56b06049e 100644
--- a/doc/neps/nep-template.rst
+++ b/doc/neps/nep-template.rst
@@ -4,7 +4,7 @@ NEP Template and Instructions
:Author: <list of authors' real names and optionally, email addresses>
:Status: <Draft | Active | Accepted | Deferred | Rejected | Withdrawn | Final | Superseded>
-:Type: <Standards Track | Informational | Process>
+:Type: <Standards Track | Process>
:Created: <date created on, in yyyy-mm-dd format>
diff --git a/doc/neps/tools/build_index.py b/doc/neps/tools/build_index.py
new file mode 100644
index 000000000..65225c995
--- /dev/null
+++ b/doc/neps/tools/build_index.py
@@ -0,0 +1,99 @@
+"""
+Scan the directory of nep files and extract their metadata. The
+metadata is passed to Jinja for filling out `index.rst.tmpl`.
+"""
+
+import os
+import sys
+import jinja2
+import glob
+import re
+
+
+def render(tpl_path, context):
+ path, filename = os.path.split(tpl_path)
+ return jinja2.Environment(
+ loader=jinja2.FileSystemLoader(path or './')
+ ).get_template(filename).render(context)
+
+def nep_metadata():
+ ignore = ('nep-template.rst')
+ sources = sorted(glob.glob(r'nep-*.rst'))
+ sources = [s for s in sources if not s in ignore]
+
+ meta_re = r':([a-zA-Z\-]*): (.*)'
+
+ neps = {}
+ print('Loading metadata for:')
+ for source in sources:
+ print(f' - {source}')
+ nr = int(re.match(r'nep-([0-9]{4}).*\.rst', source).group(1))
+
+ with open(source) as f:
+ lines = f.readlines()
+ tags = [re.match(meta_re, line) for line in lines]
+ tags = [match.groups() for match in tags if match is not None]
+ tags = {tag[0]: tag[1] for tag in tags}
+
+ # We could do a clever regexp, but for now just assume the title is
+ # the second line of the document
+ tags['Title'] = lines[1].strip()
+ tags['Filename'] = source
+
+
+ if tags['Status'] in ('Accepted', 'Rejected', 'Withdrawn'):
+ if not 'Resolution' in tags:
+ raise RuntimeError(
+ f'NEP {nr} is Accepted/Rejected/Withdrawn but '
+ 'has no Resolution tag'
+ )
+
+ neps[nr] = tags
+
+ # Now that we have all of the NEP metadata, do some global consistency
+ # checks
+
+ for nr, tags in neps.items():
+ if tags['Status'] == 'Superseded':
+ if not 'Replaced-By' in tags:
+ raise RuntimeError(
+ f'NEP {nr} has been Superseded, but has no Replaced-By tag'
+ )
+
+ replaced_by = int(tags['Replaced-By'])
+ replacement_nep = neps[replaced_by]
+
+ if not 'Replaces' in replacement_nep:
+ raise RuntimeError(
+ f'NEP {nr} is superseded by {replaced_by}, but that NEP has '
+ f"no Replaces tag."
+ )
+
+ if not int(replacement_nep['Replaces']) == nr:
+ raise RuntimeError(
+ f'NEP {nr} is superseded by {replaced_by}, but that NEP has a '
+ f"Replaces tag of `{replacement_nep['Replaces']}`."
+ )
+
+ if 'Replaces' in tags:
+ replaced_nep = int(tags['Replaces'])
+ replaced_nep_tags = neps[replaced_nep]
+ if not replaced_nep_tags['Status'] == 'Superseded':
+ raise RuntimeError(
+ f'NEP {nr} replaces {replaced_nep}, but that NEP has not '
+ f'been set to Superseded'
+ )
+
+ return {'neps': neps}
+
+
+infile = 'index.rst.tmpl'
+outfile = 'index.rst'
+
+meta = nep_metadata()
+
+print(f'Compiling {infile} -> {outfile}')
+index = render(infile, meta)
+
+with open(outfile, 'w') as f:
+ f.write(index)
diff --git a/doc/release/1.15.0-notes.rst b/doc/release/1.15.0-notes.rst
index c7bf0b7bc..cff75c477 100644
--- a/doc/release/1.15.0-notes.rst
+++ b/doc/release/1.15.0-notes.rst
@@ -19,7 +19,7 @@ New functions
for the scope of the ``with`` block::
>>> with np.printoptions(precision=2):
- ... print(np.array([2.0])) / 3
+ ... print(np.array([2.0]) / 3)
[0.67]
* `np.histogram_bin_edges`, a function to get the edges of the bins used by a histogram
@@ -92,6 +92,10 @@ Creating a full iOS-compatible NumPy package requires building for the 5
architectures supported by iOS (i386, x86_64, armv7, armv7s and arm64), and
combining these 5 compiled builds products into a single "fat" binary.
+Build system
+------------
+Added experimental support for the 64-bit RISC-V architecture.
+
Improvements
============
@@ -175,5 +179,19 @@ This change makes it easier to write Python 2/3 compatible code using
``from __future__ import unicode_literals``, which previously would cause
string literal field names to raise a TypeError in Python 2.
+``sort`` functions accept ``kind='stable'``
+-------------------------------------------
+Up until now, to perform a stable sort on the data, the user must do::
+
+ >>> np.sort([5, 2, 6, 2, 1], kind='mergesort')
+ [1, 2, 2, 5, 6]
+
+because merge sort is the only stable sorting algorithm available in
+NumPy. However, having kind='mergesort' does not make it explicit that
+the user wants to perform a stable sort thus harming the readability.
+
+This change allows the user to specify kind='stable' thus clarifying
+the intent.
+
Changes
=======
diff --git a/doc/source/user/building.rst b/doc/source/user/building.rst
index b98f89c2d..76eb48487 100644
--- a/doc/source/user/building.rst
+++ b/doc/source/user/building.rst
@@ -132,6 +132,8 @@ Supplying additional compiler flags
Additional compiler flags can be supplied by setting the ``OPT``,
``FOPT`` (for Fortran), and ``CC`` environment variables.
+When providing options that should improve the performance of the code ensure
+that you also set ``-DNDEBUG`` so that debugging code is not executed.
Building with ATLAS support
diff --git a/doc/summarize.py b/doc/summarize.py
index 972e298f4..cfce2713e 100755
--- a/doc/summarize.py
+++ b/doc/summarize.py
@@ -9,7 +9,7 @@ from __future__ import division, absolute_import, print_function
import os, glob, re, sys, inspect, optparse
try:
- # Accessing collections abstact classes from collections
+ # Accessing collections abstract classes from collections
# has been deprecated since Python 3.3
import collections.abc as collections_abc
except ImportError:
diff --git a/numpy/__init__.py b/numpy/__init__.py
index db99294bc..db7bc0368 100644
--- a/numpy/__init__.py
+++ b/numpy/__init__.py
@@ -150,7 +150,6 @@ else:
# no-one else in the world is using it (though I hope not)
from .testing import Tester, _numpy_tester
test = _numpy_tester().test
- bench = _numpy_tester().bench
# Allow distributors to run custom init code
from . import _distributor_init
diff --git a/numpy/add_newdocs.py b/numpy/add_newdocs.py
index 316b38e77..0a7b2b13d 100644
--- a/numpy/add_newdocs.py
+++ b/numpy/add_newdocs.py
@@ -4494,7 +4494,7 @@ add_newdoc('numpy.core.multiarray', 'ndarray', ('sort',
axis : int, optional
Axis along which to sort. Default is -1, which means sort along the
last axis.
- kind : {'quicksort', 'mergesort', 'heapsort'}, optional
+ kind : {'quicksort', 'mergesort', 'heapsort', 'stable'}, optional
Sorting algorithm. Default is 'quicksort'.
order : str or list of str, optional
When `a` is an array with fields defined, this argument specifies
diff --git a/numpy/core/__init__.py b/numpy/core/__init__.py
index 6db484de4..264324503 100644
--- a/numpy/core/__init__.py
+++ b/numpy/core/__init__.py
@@ -73,7 +73,6 @@ __all__ += einsumfunc.__all__
from numpy.testing import _numpy_tester
test = _numpy_tester().test
-bench = _numpy_tester().bench
# Make it possible so that ufuncs can be pickled
# Here are the loading and unloading functions
diff --git a/numpy/core/code_generators/generate_umath.py b/numpy/core/code_generators/generate_umath.py
index ebcf864ea..1d3550e06 100644
--- a/numpy/core/code_generators/generate_umath.py
+++ b/numpy/core/code_generators/generate_umath.py
@@ -966,7 +966,7 @@ def make_arrays(funcdict):
for vt in t.simd:
code2list.append(textwrap.dedent("""\
#ifdef HAVE_ATTRIBUTE_TARGET_{ISA}
- if (NPY_CPU_SUPPORTS_{ISA}) {{
+ if (npy_cpu_supports("{ISA}")) {{
{fname}_functions[{idx}] = {type}_{fname}_{isa};
}}
#endif
@@ -1073,7 +1073,7 @@ def make_code(funcdict, filename):
Please make changes to the code generator program (%s)
**/
-
+ #include "cpuid.h"
%s
static int
diff --git a/numpy/core/code_generators/ufunc_docstrings.py b/numpy/core/code_generators/ufunc_docstrings.py
index 75dee7084..c7e5cf600 100644
--- a/numpy/core/code_generators/ufunc_docstrings.py
+++ b/numpy/core/code_generators/ufunc_docstrings.py
@@ -18,23 +18,36 @@ def get(name):
return docdict.get(name)
# common parameter text to all ufuncs
-_params_text = textwrap.dedent("""
- out : ndarray, None, or tuple of ndarray and None, optional
- A location into which the result is stored. If provided, it must have
- a shape that the inputs broadcast to. If not provided or `None`,
- a freshly-allocated array is returned. A tuple (possible only as a
- keyword argument) must have length equal to the number of outputs.
- where : array_like, optional
- Values of True indicate to calculate the ufunc at that position, values
- of False indicate to leave the value in the output alone.
- **kwargs
- For other keyword-only arguments, see the
- :ref:`ufunc docs <ufuncs.kwargs>`.
-""").strip()
+subst = {
+ 'PARAMS': textwrap.dedent("""
+ out : ndarray, None, or tuple of ndarray and None, optional
+ A location into which the result is stored. If provided, it must have
+ a shape that the inputs broadcast to. If not provided or `None`,
+ a freshly-allocated array is returned. A tuple (possible only as a
+ keyword argument) must have length equal to the number of outputs.
+ where : array_like, optional
+ Values of True indicate to calculate the ufunc at that position, values
+ of False indicate to leave the value in the output alone.
+ **kwargs
+ For other keyword-only arguments, see the
+ :ref:`ufunc docs <ufuncs.kwargs>`.
+ """).strip(),
+ 'OUT_SCALAR_1': "This is a scalar if `x` is a scalar.",
+ 'OUT_SCALAR_2': "This is a scalar if both `x1` and `x2` are scalars.",
+}
def add_newdoc(place, name, doc):
doc = textwrap.dedent(doc).strip()
- doc = doc.replace('$PARAMS', _params_text)
+
+ if name[0] != '_':
+ if '\nx :' in doc:
+ assert '$OUT_SCALAR_1' in doc, "in {}".format(name)
+ elif '\nx2 :' in doc or '\nx1, x2 :' in doc:
+ assert '$OUT_SCALAR_2' in doc, "in {}".format(name)
+ else:
+ assert False, "Could not detect number of inputs in {}".format(name)
+ for k, v in subst.items():
+ doc = doc.replace('$' + k, v)
docdict['.'.join((place, name))] = doc
@@ -57,6 +70,7 @@ add_newdoc('numpy.core.umath', 'absolute',
An ndarray containing the absolute value of
each element in `x`. For complex input, ``a + ib``, the
absolute value is :math:`\\sqrt{ a^2 + b^2 }`.
+ $OUT_SCALAR_1
Examples
--------
@@ -97,8 +111,8 @@ add_newdoc('numpy.core.umath', 'add',
Returns
-------
add : ndarray or scalar
- The sum of `x1` and `x2`, element-wise. Returns a scalar if
- both `x1` and `x2` are scalars.
+ The sum of `x1` and `x2`, element-wise.
+ $OUT_SCALAR_2
Notes
-----
@@ -134,9 +148,8 @@ add_newdoc('numpy.core.umath', 'arccos',
-------
angle : ndarray
The angle of the ray intersecting the unit circle at the given
- `x`-coordinate in radians [0, pi]. If `x` is a scalar then a
- scalar is returned, otherwise an array of the same shape as `x`
- is returned.
+ `x`-coordinate in radians [0, pi].
+ $OUT_SCALAR_1
See Also
--------
@@ -194,6 +207,7 @@ add_newdoc('numpy.core.umath', 'arccosh',
-------
arccosh : ndarray
Array of the same shape as `x`.
+ $OUT_SCALAR_1
See Also
--------
@@ -244,8 +258,8 @@ add_newdoc('numpy.core.umath', 'arcsin',
-------
angle : ndarray
The inverse sine of each element in `x`, in radians and in the
- closed interval ``[-pi/2, pi/2]``. If `x` is a scalar, a scalar
- is returned, otherwise an array.
+ closed interval ``[-pi/2, pi/2]``.
+ $OUT_SCALAR_1
See Also
--------
@@ -296,8 +310,9 @@ add_newdoc('numpy.core.umath', 'arcsinh',
Returns
-------
- out : ndarray
+ out : ndarray or scalar
Array of the same shape as `x`.
+ $OUT_SCALAR_1
Notes
-----
@@ -342,10 +357,10 @@ add_newdoc('numpy.core.umath', 'arctan',
Returns
-------
- out : ndarray
+ out : ndarray or scalar
Out has the same shape as `x`. Its real part is in
``[-pi/2, pi/2]`` (``arctan(+/-inf)`` returns ``+/-pi/2``).
- It is a scalar if `x` is a scalar.
+ $OUT_SCALAR_1
See Also
--------
@@ -424,6 +439,7 @@ add_newdoc('numpy.core.umath', 'arctan2',
-------
angle : ndarray
Array of angles in radians, in the range ``[-pi, pi]``.
+ $OUT_SCALAR_2
See Also
--------
@@ -490,8 +506,9 @@ add_newdoc('numpy.core.umath', 'arctanh',
Returns
-------
- out : ndarray
+ out : ndarray or scalar
Array of the same shape as `x`.
+ $OUT_SCALAR_1
See Also
--------
@@ -543,8 +560,9 @@ add_newdoc('numpy.core.umath', 'bitwise_and',
Returns
-------
- out : array_like
+ out : ndarray or scalar
Result.
+ $OUT_SCALAR_2
See Also
--------
@@ -595,8 +613,9 @@ add_newdoc('numpy.core.umath', 'bitwise_or',
Returns
-------
- out : array_like
+ out : ndarray or scalar
Result.
+ $OUT_SCALAR_2
See Also
--------
@@ -652,8 +671,9 @@ add_newdoc('numpy.core.umath', 'bitwise_xor',
Returns
-------
- out : array_like
+ out : ndarray or scalar
Result.
+ $OUT_SCALAR_2
See Also
--------
@@ -703,6 +723,7 @@ add_newdoc('numpy.core.umath', 'ceil',
-------
y : ndarray or scalar
The ceiling of each element in `x`, with `float` dtype.
+ $OUT_SCALAR_1
See Also
--------
@@ -734,6 +755,7 @@ add_newdoc('numpy.core.umath', 'trunc',
-------
y : ndarray or scalar
The truncated value of each element in `x`.
+ $OUT_SCALAR_1
See Also
--------
@@ -768,6 +790,7 @@ add_newdoc('numpy.core.umath', 'conjugate',
-------
y : ndarray
The complex conjugate of `x`, with same dtype as `y`.
+ $OUT_SCALAR_1
Examples
--------
@@ -795,6 +818,7 @@ add_newdoc('numpy.core.umath', 'cos',
-------
y : ndarray
The corresponding cosine values.
+ $OUT_SCALAR_1
Notes
-----
@@ -838,8 +862,9 @@ add_newdoc('numpy.core.umath', 'cosh',
Returns
-------
- out : ndarray
+ out : ndarray or scalar
Output array of same shape as `x`.
+ $OUT_SCALAR_1
Examples
--------
@@ -870,6 +895,7 @@ add_newdoc('numpy.core.umath', 'degrees',
y : ndarray of floats
The corresponding degree values; if `out` was supplied this is a
reference to it.
+ $OUT_SCALAR_1
See Also
--------
@@ -905,6 +931,7 @@ add_newdoc('numpy.core.umath', 'rad2deg',
-------
y : ndarray
The corresponding angle in degrees.
+ $OUT_SCALAR_1
See Also
--------
@@ -946,8 +973,9 @@ add_newdoc('numpy.core.umath', 'heaviside',
Returns
-------
- out : ndarray
+ out : ndarray or scalar
The output array, element-wise Heaviside step function of `x1`.
+ $OUT_SCALAR_2
Notes
-----
@@ -981,8 +1009,8 @@ add_newdoc('numpy.core.umath', 'divide',
Returns
-------
y : ndarray or scalar
- The quotient ``x1/x2``, element-wise. Returns a scalar if
- both ``x1`` and ``x2`` are scalars.
+ The quotient ``x1/x2``, element-wise.
+ $OUT_SCALAR_2
See Also
--------
@@ -1050,7 +1078,8 @@ add_newdoc('numpy.core.umath', 'equal',
Returns
-------
out : ndarray or bool
- Output array of bools, or a single bool if x1 and x2 are scalars.
+ Output array of bools.
+ $OUT_SCALAR_2
See Also
--------
@@ -1081,8 +1110,9 @@ add_newdoc('numpy.core.umath', 'exp',
Returns
-------
- out : ndarray
+ out : ndarray or scalar
Output array, element-wise exponential of `x`.
+ $OUT_SCALAR_1
See Also
--------
@@ -1145,8 +1175,9 @@ add_newdoc('numpy.core.umath', 'exp2',
Returns
-------
- out : ndarray
+ out : ndarray or scalar
Element-wise 2 to the power `x`.
+ $OUT_SCALAR_1
See Also
--------
@@ -1177,8 +1208,9 @@ add_newdoc('numpy.core.umath', 'expm1',
Returns
-------
- out : ndarray
+ out : ndarray or scalar
Element-wise exponential minus one: ``out = exp(x) - 1``.
+ $OUT_SCALAR_1
See Also
--------
@@ -1222,6 +1254,7 @@ add_newdoc('numpy.core.umath', 'fabs',
-------
y : ndarray or scalar
The absolute values of `x`, the returned values are always floats.
+ $OUT_SCALAR_1
See Also
--------
@@ -1253,6 +1286,7 @@ add_newdoc('numpy.core.umath', 'floor',
-------
y : ndarray or scalar
The floor of each element in `x`.
+ $OUT_SCALAR_1
See Also
--------
@@ -1291,7 +1325,7 @@ add_newdoc('numpy.core.umath', 'floor_divide',
-------
y : ndarray
y = floor(`x1`/`x2`)
-
+ $OUT_SCALAR_2
See Also
--------
@@ -1322,15 +1356,16 @@ add_newdoc('numpy.core.umath', 'fmod',
Parameters
----------
x1 : array_like
- Dividend.
+ Dividend.
x2 : array_like
- Divisor.
+ Divisor.
$PARAMS
Returns
-------
y : array_like
- The remainder of the division of `x1` by `x2`.
+ The remainder of the division of `x1` by `x2`.
+ $OUT_SCALAR_2
See Also
--------
@@ -1381,7 +1416,8 @@ add_newdoc('numpy.core.umath', 'greater',
Returns
-------
out : bool or ndarray of bool
- Array of bools, or a single bool if `x1` and `x2` are scalars.
+ Array of bools.
+ $OUT_SCALAR_2
See Also
@@ -1417,7 +1453,8 @@ add_newdoc('numpy.core.umath', 'greater_equal',
Returns
-------
out : bool or ndarray of bool
- Array of bools, or a single bool if `x1` and `x2` are scalars.
+ Array of bools.
+ $OUT_SCALAR_2
See Also
--------
@@ -1449,6 +1486,7 @@ add_newdoc('numpy.core.umath', 'hypot',
-------
z : ndarray
The hypotenuse of the triangle(s).
+ $OUT_SCALAR_2
Examples
--------
@@ -1489,8 +1527,9 @@ add_newdoc('numpy.core.umath', 'invert',
Returns
-------
- out : array_like
+ out : ndarray or scalar
Result.
+ $OUT_SCALAR_1
See Also
--------
@@ -1562,15 +1601,9 @@ add_newdoc('numpy.core.umath', 'isfinite',
Returns
-------
y : ndarray, bool
- For scalar input, the result is a new boolean with value True
- if the input is finite; otherwise the value is False (input is
- either positive infinity, negative infinity or Not a Number).
-
- For array input, the result is a boolean array with the same
- dimensions as the input and the values are True if the
- corresponding element of the input is finite; otherwise the values
- are False (element is either positive infinity, negative infinity
- or Not a Number).
+ True where ``x`` is not positive infinity, negative infinity,
+ or NaN; false otherwise.
+ $OUT_SCALAR_1
See Also
--------
@@ -1628,18 +1661,8 @@ add_newdoc('numpy.core.umath', 'isinf',
Returns
-------
y : bool (scalar) or boolean ndarray
- For scalar input, the result is a new boolean with value True if
- the input is positive or negative infinity; otherwise the value is
- False.
-
- For array input, the result is a boolean array with the same shape
- as the input and the values are True where the corresponding
- element of the input is positive or negative infinity; elsewhere
- the values are False. If a second argument was supplied the result
- is stored there. If the type of that array is a numeric type the
- result is represented as zeros and ones, if the type is boolean
- then as False and True, respectively. The return value `y` is then
- a reference to that array.
+ True where ``x`` is positive or negative infinity, false otherwise.
+ $OUT_SCALAR_1
See Also
--------
@@ -1687,13 +1710,8 @@ add_newdoc('numpy.core.umath', 'isnan',
Returns
-------
y : ndarray or bool
- For scalar input, the result is a new boolean with value True if
- the input is NaN; otherwise the value is False.
-
- For array input, the result is a boolean array of the same
- dimensions as the input and the values are True if the
- corresponding element of the input is NaN; otherwise the values are
- False.
+ True where ``x`` is NaN, false otherwise.
+ $OUT_SCALAR_1
See Also
--------
@@ -1728,13 +1746,8 @@ add_newdoc('numpy.core.umath', 'isnat',
Returns
-------
y : ndarray or bool
- For scalar input, the result is a new boolean with value True if
- the input is NaT; otherwise the value is False.
-
- For array input, the result is a boolean array of the same
- dimensions as the input and the values are True if the
- corresponding element of the input is NaT; otherwise the values are
- False.
+ True where ``x`` is NaT, false otherwise.
+ $OUT_SCALAR_1
See Also
--------
@@ -1771,6 +1784,7 @@ add_newdoc('numpy.core.umath', 'left_shift',
-------
out : array of integer type
Return `x1` with bits shifted `x2` times to the left.
+ $OUT_SCALAR_2
See Also
--------
@@ -1807,7 +1821,8 @@ add_newdoc('numpy.core.umath', 'less',
Returns
-------
out : bool or ndarray of bool
- Array of bools, or a single bool if `x1` and `x2` are scalars.
+ Array of bools.
+ $OUT_SCALAR_2
See Also
--------
@@ -1835,7 +1850,8 @@ add_newdoc('numpy.core.umath', 'less_equal',
Returns
-------
out : bool or ndarray of bool
- Array of bools, or a single bool if `x1` and `x2` are scalars.
+ Array of bools.
+ $OUT_SCALAR_2
See Also
--------
@@ -1866,6 +1882,7 @@ add_newdoc('numpy.core.umath', 'log',
-------
y : ndarray
The natural logarithm of `x`, element-wise.
+ $OUT_SCALAR_1
See Also
--------
@@ -1914,6 +1931,7 @@ add_newdoc('numpy.core.umath', 'log10',
y : ndarray
The logarithm to the base 10 of `x`, element-wise. NaNs are
returned where x is negative.
+ $OUT_SCALAR_1
See Also
--------
@@ -1961,6 +1979,7 @@ add_newdoc('numpy.core.umath', 'log2',
-------
y : ndarray
Base-2 logarithm of `x`.
+ $OUT_SCALAR_1
See Also
--------
@@ -2015,6 +2034,7 @@ add_newdoc('numpy.core.umath', 'logaddexp',
-------
result : ndarray
Logarithm of ``exp(x1) + exp(x2)``.
+ $OUT_SCALAR_2
See Also
--------
@@ -2056,6 +2076,7 @@ add_newdoc('numpy.core.umath', 'logaddexp2',
-------
result : ndarray
Base-2 logarithm of ``2**x1 + 2**x2``.
+ $OUT_SCALAR_2
See Also
--------
@@ -2093,6 +2114,7 @@ add_newdoc('numpy.core.umath', 'log1p',
-------
y : ndarray
Natural logarithm of `1 + x`, element-wise.
+ $OUT_SCALAR_1
See Also
--------
@@ -2146,6 +2168,7 @@ add_newdoc('numpy.core.umath', 'logical_and',
y : ndarray or bool
Boolean result with the same shape as `x1` and `x2` of the logical
AND operation on corresponding elements of `x1` and `x2`.
+ $OUT_SCALAR_2
See Also
--------
@@ -2180,6 +2203,7 @@ add_newdoc('numpy.core.umath', 'logical_not',
y : bool or ndarray of bool
Boolean result with the same shape as `x` of the NOT operation
on elements of `x`.
+ $OUT_SCALAR_1
See Also
--------
@@ -2214,6 +2238,7 @@ add_newdoc('numpy.core.umath', 'logical_or',
y : ndarray or bool
Boolean result with the same shape as `x1` and `x2` of the logical
OR operation on elements of `x1` and `x2`.
+ $OUT_SCALAR_2
See Also
--------
@@ -2250,6 +2275,7 @@ add_newdoc('numpy.core.umath', 'logical_xor',
Boolean result of the logical XOR operation applied to the elements
of `x1` and `x2`; the shape is determined by whether or not
broadcasting of one or both arrays was required.
+ $OUT_SCALAR_2
See Also
--------
@@ -2295,8 +2321,8 @@ add_newdoc('numpy.core.umath', 'maximum',
Returns
-------
y : ndarray or scalar
- The maximum of `x1` and `x2`, element-wise. Returns scalar if
- both `x1` and `x2` are scalars.
+ The maximum of `x1` and `x2`, element-wise.
+ $OUT_SCALAR_2
See Also
--------
@@ -2354,8 +2380,8 @@ add_newdoc('numpy.core.umath', 'minimum',
Returns
-------
y : ndarray or scalar
- The minimum of `x1` and `x2`, element-wise. Returns scalar if
- both `x1` and `x2` are scalars.
+ The minimum of `x1` and `x2`, element-wise.
+ $OUT_SCALAR_2
See Also
--------
@@ -2413,8 +2439,8 @@ add_newdoc('numpy.core.umath', 'fmax',
Returns
-------
y : ndarray or scalar
- The maximum of `x1` and `x2`, element-wise. Returns scalar if
- both `x1` and `x2` are scalars.
+ The maximum of `x1` and `x2`, element-wise.
+ $OUT_SCALAR_2
See Also
--------
@@ -2471,8 +2497,8 @@ add_newdoc('numpy.core.umath', 'fmin',
Returns
-------
y : ndarray or scalar
- The minimum of `x1` and `x2`, element-wise. Returns scalar if
- both `x1` and `x2` are scalars.
+ The minimum of `x1` and `x2`, element-wise.
+ $OUT_SCALAR_2
See Also
--------
@@ -2525,8 +2551,10 @@ add_newdoc('numpy.core.umath', 'modf',
-------
y1 : ndarray
Fractional part of `x`.
+ $OUT_SCALAR_1
y2 : ndarray
Integral part of `x`.
+ $OUT_SCALAR_1
Notes
-----
@@ -2560,7 +2588,8 @@ add_newdoc('numpy.core.umath', 'multiply',
-------
y : ndarray
The product of `x1` and `x2`, element-wise. Returns a scalar if
- both `x1` and `x2` are scalars.
+ both `x1` and `x2` are scalars.
+ $OUT_SCALAR_2
Notes
-----
@@ -2594,6 +2623,7 @@ add_newdoc('numpy.core.umath', 'negative',
-------
y : ndarray or scalar
Returned array or scalar: `y = -x`.
+ $OUT_SCALAR_1
Examples
--------
@@ -2617,6 +2647,7 @@ add_newdoc('numpy.core.umath', 'positive',
-------
y : ndarray or scalar
Returned array or scalar: `y = +x`.
+ $OUT_SCALAR_1
Notes
-----
@@ -2632,14 +2663,15 @@ add_newdoc('numpy.core.umath', 'not_equal',
Parameters
----------
x1, x2 : array_like
- Input arrays.
+ Input arrays.
$PARAMS
Returns
-------
not_equal : ndarray bool, scalar bool
- For each element in `x1, x2`, return True if `x1` is not equal
- to `x2` and False otherwise.
+ For each element in `x1, x2`, return True if `x1` is not equal
+ to `x2` and False otherwise.
+ $OUT_SCALAR_2
See Also
@@ -2688,6 +2720,7 @@ add_newdoc('numpy.core.umath', 'power',
-------
y : ndarray
The bases in `x1` raised to the exponents in `x2`.
+ $OUT_SCALAR_2
See Also
--------
@@ -2746,6 +2779,7 @@ add_newdoc('numpy.core.umath', 'float_power',
-------
y : ndarray
The bases in `x1` raised to the exponents in `x2`.
+ $OUT_SCALAR_2
See Also
--------
@@ -2793,6 +2827,7 @@ add_newdoc('numpy.core.umath', 'radians',
-------
y : ndarray
The corresponding radian values.
+ $OUT_SCALAR_1
See Also
--------
@@ -2829,6 +2864,7 @@ add_newdoc('numpy.core.umath', 'deg2rad',
-------
y : ndarray
The corresponding angle in radians.
+ $OUT_SCALAR_1
See Also
--------
@@ -2864,6 +2900,7 @@ add_newdoc('numpy.core.umath', 'reciprocal',
-------
y : ndarray
Return array.
+ $OUT_SCALAR_1
Notes
-----
@@ -2914,7 +2951,7 @@ add_newdoc('numpy.core.umath', 'remainder',
-------
y : ndarray
The element-wise remainder of the quotient ``floor_divide(x1, x2)``.
- Returns a scalar if both `x1` and `x2` are scalars.
+ $OUT_SCALAR_2
See Also
--------
@@ -2959,8 +2996,10 @@ add_newdoc('numpy.core.umath', 'divmod',
-------
out1 : ndarray
Element-wise quotient resulting from floor division.
+ $OUT_SCALAR_2
out2 : ndarray
Element-wise remainder from floor division.
+ $OUT_SCALAR_2
See Also
--------
@@ -2996,6 +3035,7 @@ add_newdoc('numpy.core.umath', 'right_shift',
-------
out : ndarray, int
Return `x1` with bits shifted `x2` times to the right.
+ $OUT_SCALAR_2
See Also
--------
@@ -3031,6 +3071,7 @@ add_newdoc('numpy.core.umath', 'rint',
-------
out : ndarray or scalar
Output array is same shape and type as `x`.
+ $OUT_SCALAR_1
See Also
--------
@@ -3059,13 +3100,14 @@ add_newdoc('numpy.core.umath', 'sign',
Parameters
----------
x : array_like
- Input values.
+ Input values.
$PARAMS
Returns
-------
y : ndarray
- The sign of `x`.
+ The sign of `x`.
+ $OUT_SCALAR_1
Notes
-----
@@ -3098,6 +3140,7 @@ add_newdoc('numpy.core.umath', 'signbit',
-------
result : ndarray of bool
Output array, or reference to `out` if that was supplied.
+ $OUT_SCALAR_1
Examples
--------
@@ -3126,8 +3169,9 @@ add_newdoc('numpy.core.umath', 'copysign',
Returns
-------
- out : array_like
+ out : ndarray or scalar
The values of `x1` with the sign of `x2`.
+ $OUT_SCALAR_2
Examples
--------
@@ -3159,8 +3203,9 @@ add_newdoc('numpy.core.umath', 'nextafter',
Returns
-------
- out : array_like
+ out : ndarray or scalar
The next representable values of `x1` in the direction of `x2`.
+ $OUT_SCALAR_2
Examples
--------
@@ -3184,8 +3229,9 @@ add_newdoc('numpy.core.umath', 'spacing',
Returns
-------
- out : array_like
- The spacing of values of `x1`.
+ out : ndarray or scalar
+ The spacing of values of `x`.
+ $OUT_SCALAR_1
Notes
-----
@@ -3217,6 +3263,7 @@ add_newdoc('numpy.core.umath', 'sin',
-------
y : array_like
The sine of each element of x.
+ $OUT_SCALAR_1
See Also
--------
@@ -3277,6 +3324,7 @@ add_newdoc('numpy.core.umath', 'sinh',
-------
y : ndarray
The corresponding hyperbolic sine values.
+ $OUT_SCALAR_1
Notes
-----
@@ -3330,6 +3378,7 @@ add_newdoc('numpy.core.umath', 'sqrt',
negative reals are calculated). If all of the elements in `x`
are real, so is `y`, with negative elements returning ``nan``.
If `out` was provided, `y` is a reference to it.
+ $OUT_SCALAR_1
See Also
--------
@@ -3374,6 +3423,7 @@ add_newdoc('numpy.core.umath', 'cbrt',
An array of the same shape as `x`, containing the cube
cube-root of each element in `x`.
If `out` was provided, `y` is a reference to it.
+ $OUT_SCALAR_1
Examples
@@ -3395,9 +3445,9 @@ add_newdoc('numpy.core.umath', 'square',
Returns
-------
- out : ndarray
+ out : ndarray or scalar
Element-wise `x*x`, of the same shape and dtype as `x`.
- Returns scalar if `x` is a scalar.
+ $OUT_SCALAR_1
See Also
--------
@@ -3425,8 +3475,8 @@ add_newdoc('numpy.core.umath', 'subtract',
Returns
-------
y : ndarray
- The difference of `x1` and `x2`, element-wise. Returns a scalar if
- both `x1` and `x2` are scalars.
+ The difference of `x1` and `x2`, element-wise.
+ $OUT_SCALAR_2
Notes
-----
@@ -3455,13 +3505,14 @@ add_newdoc('numpy.core.umath', 'tan',
Parameters
----------
x : array_like
- Input array.
+ Input array.
$PARAMS
Returns
-------
y : ndarray
- The corresponding tangent values.
+ The corresponding tangent values.
+ $OUT_SCALAR_1
Notes
-----
@@ -3509,6 +3560,7 @@ add_newdoc('numpy.core.umath', 'tanh',
-------
y : ndarray
The corresponding hyperbolic tangent values.
+ $OUT_SCALAR_1
Notes
-----
@@ -3561,8 +3613,8 @@ add_newdoc('numpy.core.umath', 'true_divide',
Returns
-------
- out : ndarray
- Result is scalar if both inputs are scalar, ndarray otherwise.
+ out : ndarray or scalar
+ $OUT_SCALAR_2
Notes
-----
@@ -3614,9 +3666,12 @@ add_newdoc('numpy.core.umath', 'frexp',
Returns
-------
- (mantissa, exponent) : tuple of ndarrays, (float, int)
- `mantissa` is a float array with values between -1 and 1.
- `exponent` is an int array which represents the exponent of 2.
+ mantissa : ndarray
+ Floating values between -1 and 1.
+ $OUT_SCALAR_1
+ exponent : ndarray
+ Integer exponents of 2.
+ $OUT_SCALAR_1
See Also
--------
@@ -3659,6 +3714,7 @@ add_newdoc('numpy.core.umath', 'ldexp',
-------
y : ndarray or scalar
The result of ``x1 * 2**x2``.
+ $OUT_SCALAR_2
See Also
--------
@@ -3695,6 +3751,7 @@ add_newdoc('numpy.core.umath', 'gcd',
-------
y : ndarray or scalar
The greatest common divisor of the absolute value of the inputs
+ $OUT_SCALAR_2
See Also
--------
@@ -3724,6 +3781,7 @@ add_newdoc('numpy.core.umath', 'lcm',
-------
y : ndarray or scalar
The lowest common multiple of the absolute value of the inputs
+ $OUT_SCALAR_2
See Also
--------
diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py
index e81a4a039..5f1aadbf5 100644
--- a/numpy/core/fromnumeric.py
+++ b/numpy/core/fromnumeric.py
@@ -764,7 +764,7 @@ def sort(a, axis=-1, kind='quicksort', order=None):
axis : int or None, optional
Axis along which to sort. If None, the array is flattened before
sorting. The default is -1, which sorts along the last axis.
- kind : {'quicksort', 'mergesort', 'heapsort'}, optional
+ kind : {'quicksort', 'mergesort', 'heapsort', 'stable'}, optional
Sorting algorithm. Default is 'quicksort'.
order : str or list of str, optional
When `a` is an array with fields defined, this argument specifies
@@ -794,13 +794,13 @@ def sort(a, axis=-1, kind='quicksort', order=None):
order. The three available algorithms have the following
properties:
- =========== ======= ============= ============ =======
- kind speed worst case work space stable
- =========== ======= ============= ============ =======
+ =========== ======= ============= ============ ========
+ kind speed worst case work space stable
+ =========== ======= ============= ============ ========
'quicksort' 1 O(n^2) 0 no
'mergesort' 2 O(n*log(n)) ~n/2 yes
'heapsort' 3 O(n*log(n)) 0 no
- =========== ======= ============= ============ =======
+ =========== ======= ============= ============ ========
All the sort algorithms make temporary copies of the data when
sorting along any but the last axis. Consequently, sorting along
@@ -829,6 +829,10 @@ def sort(a, axis=-1, kind='quicksort', order=None):
heapsort when it does not make enough progress. This makes its
worst case O(n*log(n)).
+ 'stable' automatically choses the best stable sorting algorithm
+ for the data type being sorted. It is currently mapped to
+ merge sort.
+
Examples
--------
>>> a = np.array([[1,4],[3,1]])
@@ -886,7 +890,7 @@ def argsort(a, axis=-1, kind='quicksort', order=None):
axis : int or None, optional
Axis along which to sort. The default is -1 (the last axis). If None,
the flattened array is used.
- kind : {'quicksort', 'mergesort', 'heapsort'}, optional
+ kind : {'quicksort', 'mergesort', 'heapsort', 'stable'}, optional
Sorting algorithm.
order : str or list of str, optional
When `a` is an array with fields defined, this argument specifies
diff --git a/numpy/core/include/numpy/npy_common.h b/numpy/core/include/numpy/npy_common.h
index b7634a930..5faff4385 100644
--- a/numpy/core/include/numpy/npy_common.h
+++ b/numpy/core/include/numpy/npy_common.h
@@ -101,22 +101,6 @@
#endif
#endif
-#ifdef HAVE___BUILTIN_CPU_SUPPORTS
- #ifdef HAVE_ATTRIBUTE_TARGET_AVX2
- #define NPY_CPU_SUPPORTS_AVX2 __builtin_cpu_supports("avx2")
- #else
- #define NPY_CPU_SUPPORTS_AVX2 0
- #endif
- #ifdef HAVE_ATTRIBUTE_TARGET_AVX
- #define NPY_CPU_SUPPORTS_AVX __builtin_cpu_supports("avx")
- #else
- #define NPY_CPU_SUPPORTS_AVX 0
- #endif
-#else
- #define NPY_CPU_SUPPORTS_AVX 0
- #define NPY_CPU_SUPPORTS_AVX2 0
-#endif
-
#if defined(_MSC_VER)
#define NPY_INLINE __inline
#elif defined(__GNUC__)
diff --git a/numpy/core/include/numpy/npy_cpu.h b/numpy/core/include/numpy/npy_cpu.h
index 84653ea18..106ffa450 100644
--- a/numpy/core/include/numpy/npy_cpu.h
+++ b/numpy/core/include/numpy/npy_cpu.h
@@ -17,6 +17,7 @@
* NPY_CPU_SH_BE
* NPY_CPU_ARCEL
* NPY_CPU_ARCEB
+ * NPY_CPU_RISCV64
*/
#ifndef _NPY_CPUARCH_H_
#define _NPY_CPUARCH_H_
@@ -82,6 +83,8 @@
#define NPY_CPU_ARCEL
#elif defined(__arc__) && defined(__BIG_ENDIAN__)
#define NPY_CPU_ARCEB
+#elif defined(__riscv) && defined(__riscv_xlen) && __riscv_xlen == 64
+ #define NPY_CPU_RISCV64
#else
#error Unknown CPU, please report this to numpy maintainers with \
information about your platform (OS, CPU and compiler)
diff --git a/numpy/core/include/numpy/npy_endian.h b/numpy/core/include/numpy/npy_endian.h
index 1a42121db..649bdb0a6 100644
--- a/numpy/core/include/numpy/npy_endian.h
+++ b/numpy/core/include/numpy/npy_endian.h
@@ -46,7 +46,8 @@
|| defined(NPY_CPU_SH_LE) \
|| defined(NPY_CPU_MIPSEL) \
|| defined(NPY_CPU_PPC64LE) \
- || defined(NPY_CPU_ARCEL)
+ || defined(NPY_CPU_ARCEL) \
+ || defined(NPY_CPU_RISCV64)
#define NPY_BYTE_ORDER NPY_LITTLE_ENDIAN
#elif defined(NPY_CPU_PPC) \
|| defined(NPY_CPU_SPARC) \
diff --git a/numpy/core/numeric.py b/numpy/core/numeric.py
index aa5059180..d154206c5 100644
--- a/numpy/core/numeric.py
+++ b/numpy/core/numeric.py
@@ -1,7 +1,7 @@
from __future__ import division, absolute_import, print_function
try:
- # Accessing collections abstact classes from collections
+ # Accessing collections abstract classes from collections
# has been deprecated since Python 3.3
import collections.abc as collections_abc
except ImportError:
diff --git a/numpy/core/setup.py b/numpy/core/setup.py
index d519e0eb8..15f6e1522 100644
--- a/numpy/core/setup.py
+++ b/numpy/core/setup.py
@@ -888,6 +888,7 @@ def configuration(parent_package='',top_path=None):
join('src', 'umath', 'loops.c.src'),
join('src', 'umath', 'ufunc_object.c'),
join('src', 'umath', 'extobj.c'),
+ join('src', 'umath', 'cpuid.c'),
join('src', 'umath', 'scalarmath.c.src'),
join('src', 'umath', 'ufunc_type_resolution.c'),
join('src', 'umath', 'override.c'),
diff --git a/numpy/core/setup_common.py b/numpy/core/setup_common.py
index 1fe953910..f36d61f55 100644
--- a/numpy/core/setup_common.py
+++ b/numpy/core/setup_common.py
@@ -146,6 +146,7 @@ OPTIONAL_INTRINSICS = [("__builtin_isnan", '5.'),
"stdio.h", "LINK_AVX"),
("__asm__ volatile", '"vpand %ymm1, %ymm2, %ymm3"',
"stdio.h", "LINK_AVX2"),
+ ("__asm__ volatile", '"xgetbv"', "stdio.h", "XGETBV"),
]
# function attributes
diff --git a/numpy/core/src/multiarray/conversion_utils.c b/numpy/core/src/multiarray/conversion_utils.c
index b39834266..7e92e5991 100644
--- a/numpy/core/src/multiarray/conversion_utils.c
+++ b/numpy/core/src/multiarray/conversion_utils.c
@@ -419,6 +419,10 @@ PyArray_SortkindConverter(PyObject *obj, NPY_SORTKIND *sortkind)
else if (str[0] == 'm' || str[0] == 'M') {
*sortkind = NPY_MERGESORT;
}
+ else if (str[0] == 's' || str[0] == 'S') {
+ /* mergesort is the only stable sorting method in numpy */
+ *sortkind = NPY_MERGESORT;
+ }
else {
PyErr_Format(PyExc_ValueError,
"%s is an unrecognized kind of sort",
diff --git a/numpy/core/src/multiarray/datetime_strings.c b/numpy/core/src/multiarray/datetime_strings.c
index 96cb66b95..4f9d8fa41 100644
--- a/numpy/core/src/multiarray/datetime_strings.c
+++ b/numpy/core/src/multiarray/datetime_strings.c
@@ -374,7 +374,7 @@ parse_iso_8601_datetime(char *str, Py_ssize_t len,
}
/* Leading '-' sign for negative year */
- if (*substr == '-') {
+ if (*substr == '-' || *substr == '+') {
++substr;
--sublen;
}
diff --git a/numpy/core/src/multiarray/scalartypes.c.src b/numpy/core/src/multiarray/scalartypes.c.src
index e101c3779..9df635dee 100644
--- a/numpy/core/src/multiarray/scalartypes.c.src
+++ b/numpy/core/src/multiarray/scalartypes.c.src
@@ -4174,6 +4174,37 @@ initialize_casting_tables(void)
}
}
+#ifndef NPY_PY3K
+/*
+ * In python2, the `float` and `complex` types still implement the obsolete
+ * "tp_print" method, which uses CPython's float-printing routines to print the
+ * float. Numpy's float_/cfloat inherit from Python float/complex, but
+ * override its tp_repr and tp_str methods. In order to avoid an inconsistency
+ * with the inherited tp_print, we need to override it too.
+ *
+ * In python3 the tp_print method is reserved/unused.
+ */
+static int
+doubletype_print(PyObject *o, FILE *fp, int flags)
+{
+ int ret;
+ PyObject *to_print;
+ if (flags & Py_PRINT_RAW) {
+ to_print = PyObject_Str(o);
+ }
+ else {
+ to_print = PyObject_Repr(o);
+ }
+
+ if (to_print == NULL) {
+ return -1;
+ }
+
+ ret = PyObject_Print(to_print, fp, flags);
+ Py_DECREF(to_print);
+ return ret;
+}
+#endif
static PyNumberMethods longdoubletype_as_number;
static PyNumberMethods clongdoubletype_as_number;
@@ -4226,6 +4257,12 @@ initialize_numeric_types(void)
/**end repeat**/
+#ifndef NPY_PY3K
+ PyDoubleArrType_Type.tp_print = &doubletype_print;
+ PyCDoubleArrType_Type.tp_print = &doubletype_print;
+#endif
+
+
PyBoolArrType_Type.tp_as_number->nb_index = (unaryfunc)bool_index;
PyStringArrType_Type.tp_alloc = NULL;
diff --git a/numpy/core/src/umath/cpuid.c b/numpy/core/src/umath/cpuid.c
new file mode 100644
index 000000000..912d51eeb
--- /dev/null
+++ b/numpy/core/src/umath/cpuid.c
@@ -0,0 +1,56 @@
+#define _UMATHMODULE
+#define NPY_NO_DEPRECATED_API NPY_API_VERSION
+
+#include <Python.h>
+
+#include "npy_config.h"
+
+#define PY_ARRAY_UNIQUE_SYMBOL _npy_umathmodule_ARRAY_API
+#define NO_IMPORT_ARRAY
+
+#include "cpuid.h"
+
+#define XCR_XFEATURE_ENABLED_MASK 0x0
+#define XSTATE_SSE 0x2
+#define XSTATE_YMM 0x4
+
+/*
+ * verify the OS supports avx instructions
+ * it can be disabled in some OS, e.g. with the nosavex boot option of linux
+ */
+static NPY_INLINE
+int os_avx_support(void)
+{
+#if HAVE_XGETBV
+ /*
+ * use bytes for xgetbv to avoid issues with compiler not knowing the
+ * instruction
+ */
+ unsigned int eax, edx;
+ unsigned int ecx = XCR_XFEATURE_ENABLED_MASK;
+ __asm__("xgetbv" : "=a" (eax), "=d" (edx) : "c" (ecx));
+ return (eax & (XSTATE_SSE | XSTATE_YMM)) == (XSTATE_SSE | XSTATE_YMM);
+#else
+ return 0;
+#endif
+}
+
+
+/*
+ * Primitive cpu feature detect function
+ * Currently only supports checking for avx on gcc compatible compilers.
+ */
+NPY_NO_EXPORT int
+npy_cpu_supports(const char * feature)
+{
+#ifdef HAVE___BUILTIN_CPU_SUPPORTS
+ if (strcmp(feature, "avx2") == 0) {
+ return __builtin_cpu_supports("avx2") && os_avx_support();
+ }
+ else if (strcmp(feature, "avx") == 0) {
+ return __builtin_cpu_supports("avx") && os_avx_support();
+ }
+#endif
+
+ return 0;
+}
diff --git a/numpy/core/src/umath/cpuid.h b/numpy/core/src/umath/cpuid.h
new file mode 100644
index 000000000..33702ed41
--- /dev/null
+++ b/numpy/core/src/umath/cpuid.h
@@ -0,0 +1,9 @@
+#ifndef _NPY_PRIVATE__CPUID_H_
+#define _NPY_PRIVATE__CPUID_H_
+
+#include <numpy/ndarraytypes.h> /* for NPY_NO_EXPORT */
+
+NPY_NO_EXPORT int
+npy_cpu_supports(const char * feature);
+
+#endif
diff --git a/numpy/core/tests/test_datetime.py b/numpy/core/tests/test_datetime.py
index 638994aee..ba291737a 100644
--- a/numpy/core/tests/test_datetime.py
+++ b/numpy/core/tests/test_datetime.py
@@ -1255,12 +1255,19 @@ class TestDateTime(object):
# Allow space instead of 'T' between date and time
assert_equal(np.array(['1980-02-29T01:02:03'], np.dtype('M8[s]')),
np.array(['1980-02-29 01:02:03'], np.dtype('M8[s]')))
+ # Allow positive years
+ assert_equal(np.array(['+1980-02-29T01:02:03'], np.dtype('M8[s]')),
+ np.array(['+1980-02-29 01:02:03'], np.dtype('M8[s]')))
# Allow negative years
assert_equal(np.array(['-1980-02-29T01:02:03'], np.dtype('M8[s]')),
np.array(['-1980-02-29 01:02:03'], np.dtype('M8[s]')))
# UTC specifier
with assert_warns(DeprecationWarning):
assert_equal(
+ np.array(['+1980-02-29T01:02:03'], np.dtype('M8[s]')),
+ np.array(['+1980-02-29 01:02:03Z'], np.dtype('M8[s]')))
+ with assert_warns(DeprecationWarning):
+ assert_equal(
np.array(['-1980-02-29T01:02:03'], np.dtype('M8[s]')),
np.array(['-1980-02-29 01:02:03Z'], np.dtype('M8[s]')))
# Time zone offset
diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py
index 00e2a1e31..d861da4b6 100644
--- a/numpy/core/tests/test_multiarray.py
+++ b/numpy/core/tests/test_multiarray.py
@@ -1,7 +1,7 @@
from __future__ import division, absolute_import, print_function
try:
- # Accessing collections abstact classes from collections
+ # Accessing collections abstract classes from collections
# has been deprecated since Python 3.3
import collections.abc as collections_abc
except ImportError:
diff --git a/numpy/core/tests/test_records.py b/numpy/core/tests/test_records.py
index 32ce5dc42..8e261d226 100644
--- a/numpy/core/tests/test_records.py
+++ b/numpy/core/tests/test_records.py
@@ -2,7 +2,7 @@ from __future__ import division, absolute_import, print_function
import sys
try:
- # Accessing collections abstact classes from collections
+ # Accessing collections abstract classes from collections
# has been deprecated since Python 3.3
import collections.abc as collections_abc
except ImportError:
diff --git a/numpy/core/tests/test_scalarprint.py b/numpy/core/tests/test_scalarprint.py
index d57f1a890..47cd2a40a 100644
--- a/numpy/core/tests/test_scalarprint.py
+++ b/numpy/core/tests/test_scalarprint.py
@@ -6,6 +6,7 @@ from __future__ import division, absolute_import, print_function
import numpy as np
from numpy.testing import assert_, assert_equal, run_module_suite
+import sys, tempfile
class TestRealScalars(object):
@@ -45,6 +46,22 @@ class TestRealScalars(object):
check(1e15)
check(1e16)
+ def test_py2_float_print(self):
+ # gh-10753
+ # In python2, the python float type implements an obsolte method
+ # tp_print, which overrides tp_repr and tp_str when using "print" to
+ # output to a "real file" (ie, not a StringIO). Make sure we don't
+ # inherit it.
+ x = np.double(0.1999999999999)
+ with tempfile.TemporaryFile('r+t') as f:
+ print(x, file=f)
+ f.seek(0)
+ output = f.read()
+ assert_equal(output, str(x) + '\n')
+ # In python2 the value float('0.1999999999999') prints with reduced
+ # precision as '0.2', but we want numpy's np.double('0.1999999999999')
+ # to print the unique value, '0.1999999999999'.
+
def test_dragon4(self):
# these tests are adapted from Ryan Juckett's dragon4 implementation,
# see dragon4.c for details.
diff --git a/numpy/core/tests/test_ufunc.py b/numpy/core/tests/test_ufunc.py
index b690c8132..576ecaf0d 100644
--- a/numpy/core/tests/test_ufunc.py
+++ b/numpy/core/tests/test_ufunc.py
@@ -626,7 +626,7 @@ class TestUfunc(object):
assert_array_equal(c, (a * b).sum(0))
c = in1d(a, b, axes=[0, 2])
assert_array_equal(c, (a.transpose(1, 2, 0) * b).sum(-1))
- # Check errors for inproperly constructed axes arguments.
+ # Check errors for improperly constructed axes arguments.
# should have list.
assert_raises(TypeError, in1d, a, b, axes=-1)
# needs enough elements
@@ -671,7 +671,7 @@ class TestUfunc(object):
d = mm(a, b, out=c, axes=[(-2, -1), (-2, -1), (3, 0)])
assert_(c is d)
assert_array_equal(c, np.matmul(a, b).transpose(3, 0, 1, 2))
- # Check errors for inproperly constructed axes arguments.
+ # Check errors for improperly constructed axes arguments.
# wrong argument
assert_raises(TypeError, mm, a, b, axis=1)
# axes should be list
diff --git a/numpy/distutils/__init__.py b/numpy/distutils/__init__.py
index 0450334ff..d5921b399 100644
--- a/numpy/distutils/__init__.py
+++ b/numpy/distutils/__init__.py
@@ -17,7 +17,7 @@ try:
# Normally numpy is installed if the above import works, but an interrupted
# in-place build could also have left a __config__.py. In that case the
# next import may still fail, so keep it inside the try block.
- from numpy.testing.nosetester import _numpy_tester
+ from numpy.testing import _numpy_tester
test = _numpy_tester().test
except ImportError:
pass
@@ -26,7 +26,7 @@ except ImportError:
def customized_fcompiler(plat=None, compiler=None):
from numpy.distutils.fcompiler import new_fcompiler
c = new_fcompiler(plat=plat, compiler=compiler)
- c.customize()
+ c.customize()
return c
def customized_ccompiler(plat=None, compiler=None):
diff --git a/numpy/doc/subclassing.py b/numpy/doc/subclassing.py
index 467e31cea..3be3d94b3 100644
--- a/numpy/doc/subclassing.py
+++ b/numpy/doc/subclassing.py
@@ -562,7 +562,7 @@ pass on to ``A.__array_ufunc__``, the ``super`` call in ``A`` would go to
Prior to numpy 1.13, the behaviour of ufuncs could only be tuned using
``__array_wrap__`` and ``__array_prepare__``. These two allowed one to
-change the output type of a ufunc, but, in constrast to
+change the output type of a ufunc, but, in contrast to
``__array_ufunc__``, did not allow one to make any changes to the inputs.
It is hoped to eventually deprecate these, but ``__array_wrap__`` is also
used by other numpy functions and methods, such as ``squeeze``, so at the
diff --git a/numpy/f2py/__init__.py b/numpy/f2py/__init__.py
index 250c4322b..86cc45b42 100644
--- a/numpy/f2py/__init__.py
+++ b/numpy/f2py/__init__.py
@@ -71,4 +71,3 @@ def compile(source,
from numpy.testing import _numpy_tester
test = _numpy_tester().test
-bench = _numpy_tester().bench
diff --git a/numpy/f2py/crackfortran.py b/numpy/f2py/crackfortran.py
index dc560f98e..19ce8c145 100755
--- a/numpy/f2py/crackfortran.py
+++ b/numpy/f2py/crackfortran.py
@@ -612,7 +612,7 @@ multilinepattern = re.compile(
def split_by_unquoted(line, characters):
"""
Splits the line into (line[:i], line[i:]),
- where i is the index of first occurence of one of the characters
+ where i is the index of first occurrence of one of the characters
not within quotes, or len(line) if no such index exists
"""
assert not (set('"\'') & set(characters)), "cannot split by unquoted quotes"
diff --git a/numpy/fft/__init__.py b/numpy/fft/__init__.py
index 72d61a728..d1716bd4b 100644
--- a/numpy/fft/__init__.py
+++ b/numpy/fft/__init__.py
@@ -8,4 +8,3 @@ from .helper import *
from numpy.testing import _numpy_tester
test = _numpy_tester().test
-bench = _numpy_tester().bench
diff --git a/numpy/lib/__init__.py b/numpy/lib/__init__.py
index cc05232a2..0c2e6dfab 100644
--- a/numpy/lib/__init__.py
+++ b/numpy/lib/__init__.py
@@ -48,4 +48,3 @@ __all__ += histograms.__all__
from numpy.testing import _numpy_tester
test = _numpy_tester().test
-bench = _numpy_tester().bench
diff --git a/numpy/lib/function_base.py b/numpy/lib/function_base.py
index 9ccbfafa2..8440be52e 100644
--- a/numpy/lib/function_base.py
+++ b/numpy/lib/function_base.py
@@ -184,21 +184,18 @@ def flip(m, axis):
>>> A
array([[[0, 1],
[2, 3]],
-
[[4, 5],
[6, 7]]])
>>> flip(A, 0)
array([[[4, 5],
[6, 7]],
-
[[0, 1],
[2, 3]]])
>>> flip(A, 1)
array([[[2, 3],
[0, 1]],
-
[[6, 7],
[4, 5]]])
diff --git a/numpy/linalg/__init__.py b/numpy/linalg/__init__.py
index 2537926c5..1510a8448 100644
--- a/numpy/linalg/__init__.py
+++ b/numpy/linalg/__init__.py
@@ -52,4 +52,3 @@ from .linalg import *
from numpy.testing import _numpy_tester
test = _numpy_tester().test
-bench = _numpy_tester().bench
diff --git a/numpy/ma/__init__.py b/numpy/ma/__init__.py
index fbefc47a4..0689f2932 100644
--- a/numpy/ma/__init__.py
+++ b/numpy/ma/__init__.py
@@ -53,4 +53,3 @@ __all__ += extras.__all__
from numpy.testing import _numpy_tester
test = _numpy_tester().test
-bench = _numpy_tester().bench
diff --git a/numpy/ma/core.py b/numpy/ma/core.py
index 5f53dfdae..91cf8ed0f 100644
--- a/numpy/ma/core.py
+++ b/numpy/ma/core.py
@@ -5317,7 +5317,7 @@ class MaskedArray(ndarray):
originally intended.
Until then, the axis should be given explicitly when
``arr.ndim > 1``, to avoid a FutureWarning.
- kind : {'quicksort', 'mergesort', 'heapsort'}, optional
+ kind : {'quicksort', 'mergesort', 'heapsort', 'stable'}, optional
Sorting algorithm.
order : list, optional
When `a` is an array with fields defined, this argument specifies
@@ -5468,7 +5468,7 @@ class MaskedArray(ndarray):
axis : int, optional
Axis along which to sort. If None, the array is flattened before
sorting. The default is -1, which sorts along the last axis.
- kind : {'quicksort', 'mergesort', 'heapsort'}, optional
+ kind : {'quicksort', 'mergesort', 'heapsort', 'stable'}, optional
Sorting algorithm. Default is 'quicksort'.
order : list, optional
When `a` is a structured array, this argument specifies which fields
diff --git a/numpy/ma/tests/test_core.py b/numpy/ma/tests/test_core.py
index 4c6bb2b42..ff1e087b5 100644
--- a/numpy/ma/tests/test_core.py
+++ b/numpy/ma/tests/test_core.py
@@ -3200,6 +3200,12 @@ class TestMaskedArrayMethods(object):
assert_equal(sortedx._data, [1, 2, -2, -1, 0])
assert_equal(sortedx._mask, [1, 1, 0, 0, 0])
+ def test_stable_sort(self):
+ x = array([1, 2, 3, 1, 2, 3], dtype=np.uint8)
+ expected = array([0, 3, 1, 4, 2, 5])
+ computed = argsort(x, kind='stable')
+ assert_equal(computed, expected)
+
def test_argsort_matches_sort(self):
x = array([1, 4, 2, 3], mask=[0, 1, 0, 0], dtype=np.uint8)
diff --git a/numpy/matrixlib/__init__.py b/numpy/matrixlib/__init__.py
index 11dce2928..95713580d 100644
--- a/numpy/matrixlib/__init__.py
+++ b/numpy/matrixlib/__init__.py
@@ -9,4 +9,3 @@ __all__ = defmatrix.__all__
from numpy.testing import _numpy_tester
test = _numpy_tester().test
-bench = _numpy_tester().bench
diff --git a/numpy/matrixlib/tests/test_defmatrix.py b/numpy/matrixlib/tests/test_defmatrix.py
index 9575f9c8a..d5435a1a3 100644
--- a/numpy/matrixlib/tests/test_defmatrix.py
+++ b/numpy/matrixlib/tests/test_defmatrix.py
@@ -1,7 +1,7 @@
from __future__ import division, absolute_import, print_function
try:
- # Accessing collections abstact classes from collections
+ # Accessing collections abstract classes from collections
# has been deprecated since Python 3.3
import collections.abc as collections_abc
except ImportError:
diff --git a/numpy/polynomial/__init__.py b/numpy/polynomial/__init__.py
index ae5b1f078..f7cbc19b0 100644
--- a/numpy/polynomial/__init__.py
+++ b/numpy/polynomial/__init__.py
@@ -24,4 +24,3 @@ from .laguerre import Laguerre
from numpy.testing import _numpy_tester
test = _numpy_tester().test
-bench = _numpy_tester().bench
diff --git a/numpy/random/__init__.py b/numpy/random/__init__.py
index 869818a22..409f50ec0 100644
--- a/numpy/random/__init__.py
+++ b/numpy/random/__init__.py
@@ -119,4 +119,3 @@ def __RandomState_ctor():
from numpy.testing import _numpy_tester
test = _numpy_tester().test
-bench = _numpy_tester().bench
diff --git a/numpy/testing/__init__.py b/numpy/testing/__init__.py
index 9485b455e..f4970b06b 100644
--- a/numpy/testing/__init__.py
+++ b/numpy/testing/__init__.py
@@ -9,7 +9,12 @@ from __future__ import division, absolute_import, print_function
from unittest import TestCase
-from . import decorators as dec
-from .nosetester import run_module_suite, NoseTester as Tester, _numpy_tester
-from .utils import *
+from ._private.utils import *
+from ._private import decorators as dec
+from ._private.nosetester import (
+ run_module_suite, NoseTester as Tester, _numpy_tester,
+ )
+
+__all__ = _private.utils.__all__ + ['TestCase', 'run_module_suite']
+
test = _numpy_tester().test
diff --git a/numpy/testing/nose_tools/__init__.py b/numpy/testing/_private/__init__.py
index e69de29bb..e69de29bb 100644
--- a/numpy/testing/nose_tools/__init__.py
+++ b/numpy/testing/_private/__init__.py
diff --git a/numpy/testing/nose_tools/decorators.py b/numpy/testing/_private/decorators.py
index dee832404..60d3f968f 100644
--- a/numpy/testing/nose_tools/decorators.py
+++ b/numpy/testing/_private/decorators.py
@@ -16,7 +16,7 @@ function name, setup and teardown functions and so on - see
from __future__ import division, absolute_import, print_function
try:
- # Accessing collections abstact classes from collections
+ # Accessing collections abstract classes from collections
# has been deprecated since Python 3.3
import collections.abc as collections_abc
except ImportError:
diff --git a/numpy/testing/nose_tools/noseclasses.py b/numpy/testing/_private/noseclasses.py
index 08dec0ca9..08dec0ca9 100644
--- a/numpy/testing/nose_tools/noseclasses.py
+++ b/numpy/testing/_private/noseclasses.py
diff --git a/numpy/testing/nose_tools/nosetester.py b/numpy/testing/_private/nosetester.py
index c2cf58377..c2cf58377 100644
--- a/numpy/testing/nose_tools/nosetester.py
+++ b/numpy/testing/_private/nosetester.py
diff --git a/numpy/testing/nose_tools/parameterized.py b/numpy/testing/_private/parameterized.py
index 53e67517d..53e67517d 100644
--- a/numpy/testing/nose_tools/parameterized.py
+++ b/numpy/testing/_private/parameterized.py
diff --git a/numpy/testing/_private/pytesttester.py b/numpy/testing/_private/pytesttester.py
new file mode 100644
index 000000000..6a92a52fd
--- /dev/null
+++ b/numpy/testing/_private/pytesttester.py
@@ -0,0 +1,175 @@
+"""
+Pytest test running.
+
+This module implements the ``test()`` function for NumPy modules. The usual
+boiler plate for doing that is to put the following in the module
+``__init__.py`` file::
+
+ from numpy.testing import PytestTester
+ test = PytestTester(__name__).test
+ del PytestTester
+
+
+Warnings filtering and other runtime settings should be dealt with in the
+``pytest.ini`` file in the numpy repo root. The behavior of the test depends on
+whether or not that file is found as follows:
+
+* ``pytest.ini`` is present (develop mode)
+ All warnings except those explicily filtered out are raised as error.
+* ``pytest.ini`` is absent (release mode)
+ DeprecationWarnings and PendingDeprecationWarnings are ignored, other
+ warnings are passed through.
+
+In practice, tests run from the numpy repo are run in develop mode. That
+includes the standard ``python runtests.py`` invocation.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import sys
+import os
+
+__all__ = ['PytestTester']
+
+
+def _show_numpy_info():
+ import numpy as np
+
+ print("NumPy version %s" % np.__version__)
+ relaxed_strides = np.ones((10, 1), order="C").flags.f_contiguous
+ print("NumPy relaxed strides checking option:", relaxed_strides)
+
+
+class PytestTester(object):
+ """
+ Pytest test runner.
+
+ This class is made available in ``numpy.testing``, and a test function
+ is typically added to a package's __init__.py like so::
+
+ from numpy.testing import PytestTester
+ test = PytestTester(__name__).test
+ del PytestTester
+
+ Calling this test function finds and runs all tests associated with the
+ module and all its sub-modules.
+
+ Attributes
+ ----------
+ module_name : str
+ Full path to the package to test.
+
+ Parameters
+ ----------
+ module_name : module name
+ The name of the module to test.
+
+ """
+ def __init__(self, module_name):
+ self.module_name = module_name
+
+ def test(self, label='fast', verbose=1, extra_argv=None,
+ doctests=False, coverage=False, timer=0, tests=None):
+ """
+ Run tests for module using pytest.
+
+ Parameters
+ ----------
+ label : {'fast', 'full'}, optional
+ Identifies the tests to run. When set to 'fast', tests decorated
+ with `pytest.mark.slow` are skipped, when 'full', the slow marker
+ is ignored.
+ verbose : int, optional
+ Verbosity value for test outputs, in the range 1-3. Default is 1.
+ extra_argv : list, optional
+ List with any extra arguments to pass to pytests.
+ doctests : bool, optional
+ .. note:: Not supported
+ coverage : bool, optional
+ If True, report coverage of NumPy code. Default is False.
+ Requires installation of (pip) pytest-cov.
+ timer : int, optional
+ If > 0, report the time of the slowest `timer` tests. Default is 0.
+
+ tests : test or list of tests
+ Tests to be executed with pytest '--pyargs'
+
+ Returns
+ -------
+ result : bool
+ Return True on success, false otherwise.
+
+ Notes
+ -----
+ Each NumPy module exposes `test` in its namespace to run all tests for it.
+ For example, to run all tests for numpy.lib:
+
+ >>> np.lib.test() #doctest: +SKIP
+
+ Examples
+ --------
+ >>> result = np.lib.test() #doctest: +SKIP
+ Running unit tests for numpy.lib
+ ...
+ Ran 976 tests in 3.933s
+
+ OK
+
+ >>> result.errors #doctest: +SKIP
+ []
+ >>> result.knownfail #doctest: +SKIP
+ []
+
+ """
+ import pytest
+
+ #FIXME This is no longer needed? Assume it was for use in tests.
+ # cap verbosity at 3, which is equivalent to the pytest '-vv' option
+ #from . import utils
+ #verbose = min(int(verbose), 3)
+ #utils.verbose = verbose
+ #
+
+ module = sys.modules[self.module_name]
+ module_path = os.path.abspath(module.__path__[0])
+
+ # setup the pytest arguments
+ pytest_args = ['-l']
+
+ if doctests:
+ raise ValueError("Doctests not supported")
+
+ if extra_argv:
+ pytest_args += list(extra_argv)
+
+ if verbose > 1:
+ pytest_args += ["-" + "v"*(verbose - 1)]
+ else:
+ pytest_args += ["-q"]
+
+ if coverage:
+ pytest_args += ["--cov=" + module_path]
+
+ if label == "fast":
+ pytest_args += ["-m", "not slow"]
+ elif label != "full":
+ pytest_args += ["-m", label]
+
+ if timer > 0:
+ pytest_args += ["--durations=%s" % timer]
+
+ if tests is None:
+ tests = [self.module_name]
+
+ pytest_args += ['--pyargs'] + list(tests)
+
+
+ # run tests.
+ _show_numpy_info()
+
+ try:
+ code = pytest.main(pytest_args)
+ except SystemExit as exc:
+ code = exc.code
+
+ return code == 0
diff --git a/numpy/testing/nose_tools/utils.py b/numpy/testing/_private/utils.py
index 507ecb1e2..507ecb1e2 100644
--- a/numpy/testing/nose_tools/utils.py
+++ b/numpy/testing/_private/utils.py
diff --git a/numpy/testing/decorators.py b/numpy/testing/decorators.py
index 21bcdd798..1988afd29 100644
--- a/numpy/testing/decorators.py
+++ b/numpy/testing/decorators.py
@@ -3,6 +3,9 @@ Back compatibility decorators module. It will import the appropriate
set of tools
"""
-import os
+import warnings
-from .nose_tools.decorators import *
+warnings.warn("Import from numpy.testing, not numpy.testing.decorators",
+ ImportWarning)
+
+from ._private.decorators import *
diff --git a/numpy/testing/noseclasses.py b/numpy/testing/noseclasses.py
index 144c4e7e4..dde62e825 100644
--- a/numpy/testing/noseclasses.py
+++ b/numpy/testing/noseclasses.py
@@ -2,4 +2,10 @@
Back compatibility noseclasses module. It will import the appropriate
set of tools
"""
-from .nose_tools.noseclasses import * \ No newline at end of file
+import warnings
+
+warnings.warn("Import from numpy.testing, not numpy.testing.noseclasses",
+ ImportWarning)
+
+from ._private.noseclasses import *
+
diff --git a/numpy/testing/nosetester.py b/numpy/testing/nosetester.py
index 949fae03e..772bff305 100644
--- a/numpy/testing/nosetester.py
+++ b/numpy/testing/nosetester.py
@@ -3,10 +3,12 @@ Back compatibility nosetester module. It will import the appropriate
set of tools
"""
-import os
+import warnings
-from .nose_tools.nosetester import *
+warnings.warn("Import from numpy.testing, not numpy.testing.nosetester",
+ ImportWarning)
+from ._private.nosetester import *
__all__ = ['get_package_name', 'run_module_suite', 'NoseTester',
'_numpy_tester', 'get_package_name', 'import_nose',
diff --git a/numpy/testing/pytest_tools/decorators.py b/numpy/testing/pytest_tools/decorators.py
index f8addb9c8..e72b1eb0b 100644
--- a/numpy/testing/pytest_tools/decorators.py
+++ b/numpy/testing/pytest_tools/decorators.py
@@ -13,7 +13,7 @@ function name, setup and teardown functions and so on.
from __future__ import division, absolute_import, print_function
try:
- # Accessing collections abstact classes from collections
+ # Accessing collections abstract classes from collections
# has been deprecated since Python 3.3
import collections.abc as collections_abc
except ImportError:
diff --git a/numpy/testing/setup.py b/numpy/testing/setup.py
index 5a0f977d9..b00e5e029 100755
--- a/numpy/testing/setup.py
+++ b/numpy/testing/setup.py
@@ -6,7 +6,7 @@ def configuration(parent_package='',top_path=None):
from numpy.distutils.misc_util import Configuration
config = Configuration('testing', parent_package, top_path)
- config.add_subpackage('nose_tools')
+ config.add_subpackage('_private')
config.add_subpackage('pytest_tools')
config.add_data_dir('tests')
return config
diff --git a/numpy/testing/utils.py b/numpy/testing/utils.py
index a0218c4e6..3cd89e639 100644
--- a/numpy/testing/utils.py
+++ b/numpy/testing/utils.py
@@ -3,9 +3,12 @@ Back compatibility utils module. It will import the appropriate
set of tools
"""
-import os
+import warnings
-from .nose_tools.utils import *
+warnings.warn("Import from numpy.testing, not numpy.testing.utils",
+ ImportWarning)
+
+from ._private.utils import *
__all__ = [
'assert_equal', 'assert_almost_equal', 'assert_approx_equal',
diff --git a/pytest.ini b/pytest.ini
index d3d7142d4..e901beb8c 100644
--- a/pytest.ini
+++ b/pytest.ini
@@ -1,9 +1,21 @@
[pytest]
+addopts = -l -q
norecursedirs = doc tools numpy/linalg/lapack_lite numpy/core/code_generators
doctest_optionflags = NORMALIZE_WHITESPACE
-testpaths = numpy
+filterwarnings =
+ error
+# Filter out annoying import messages.
+ ignore:Not importing directory
+ ignore:numpy.dtype size changed
+ ignore:numpy.ufunc size changed
+# Ignore python2.7 -3 warnings
+ ignore:sys\.exc_clear\(\) not supported in 3\.x:DeprecationWarning
+ ignore:in 3\.x, __setslice__:DeprecationWarning
+ ignore:in 3\.x, __getslice__:DeprecationWarning
+ ignore:buffer\(\) not supported in 3\.x:DeprecationWarning
+ ignore:CObject type is not supported in 3\.x:DeprecationWarning
+ ignore:comparing unequal types not supported in 3\.x:DeprecationWarning
+ ignore:the commands module has been removed in Python 3\.0:DeprecationWarning
env =
PYTHONHASHSEED=0
-
-# addopts = --doctest-modules --ignore=numpy/f2py/__main__.py --ignore=numpy/core/cversions.py --ignore=numpy/ma/core.py --ignore=numpy/ma/version.py --ignore=numpy/testing/utils.py --ignore=numpy/testing/decorators.py