diff options
| -rw-r--r-- | doc/neps/dropping-python2.7-proposal.rst | 52 | ||||
| -rw-r--r-- | doc/source/neps/dropping-python2.7-proposal.rst | 1 | ||||
| -rw-r--r-- | doc/source/neps/index.rst | 1 | ||||
| -rw-r--r-- | numpy/core/src/multiarray/methods.c | 6 | ||||
| -rw-r--r-- | numpy/core/src/multiarray/strfuncs.c | 32 | ||||
| -rw-r--r-- | numpy/core/src/multiarray/strfuncs.h | 5 | ||||
| -rw-r--r-- | numpy/core/tests/test_arrayprint.py | 4 | ||||
| -rw-r--r-- | numpy/ma/core.py | 8 | ||||
| -rw-r--r-- | numpy/ma/tests/test_core.py | 10 |
9 files changed, 118 insertions, 1 deletions
diff --git a/doc/neps/dropping-python2.7-proposal.rst b/doc/neps/dropping-python2.7-proposal.rst new file mode 100644 index 000000000..3cfe50bd0 --- /dev/null +++ b/doc/neps/dropping-python2.7-proposal.rst @@ -0,0 +1,52 @@ +==================================== +Plan for dropping Python 2.7 support +==================================== + +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 +resources; thus, we plan to eventually drop Python 2 support as well. Now that +we're entering the final years of community-supported Python 2, the NumPy +project wants to clarify our plans, with the goal of to helping our downstream +ecosystem make plans and accomplish the transition with as little disruption as +possible. + +Our current plan is as follows. + +Until **December 31, 2018**, all NumPy releases will fully support both +Python2 and Python3. + +Starting on **January 1, 2019**, any new feature releases will support only +Python3. + +The last Python2 supporting release will be designated as a long term support +(LTS) release, meaning that we will continue to merge bug fixes and make bug +fix releases for a longer period than usual. Specifically, it will be +supported by the community until **December 31, 2019**. + +On **January 1, 2020** we will raise a toast to Python2, and community support +for the last Python2 supporting release will come to an end. However, it will +continue to be available on PyPI indefinitely, and if any commercial vendors +wish to extend the LTS support past this point then we are open to letting them +use the LTS branch in the official NumPy repository to coordinate that. + +If you are a NumPy user who requires ongoing Python2 support in 2020 or later, +then please contact your vendor. If you are a vendor who wishes to continue to +support NumPy on Python2 in 2020+, please get in touch; ideally we'd like you +to get involved in maintaining the LTS before it actually hits end of life so +that we can make a clean handoff. + +To minimize disruption, running ``pip install numpy`` on Python 2 will continue +to give the last working release in perpetuity, but after January 1, 2019 it +may not contain the latest features, and after January 1, 2020 it may not +contain the latest bug fixes. + +For more information on the scientific Python ecosystem's transition +to Python3 only, see the python3-statement_. + +For more information on porting your code to run on Python 3, see the +python3-howto_. + +.. _python3-statement: http://www.python3statement.org/ + +.. _python3-howto: https://docs.python.org/3/howto/pyporting.html diff --git a/doc/source/neps/dropping-python2.7-proposal.rst b/doc/source/neps/dropping-python2.7-proposal.rst new file mode 100644 index 000000000..c67a626be --- /dev/null +++ b/doc/source/neps/dropping-python2.7-proposal.rst @@ -0,0 +1 @@ +.. include:: ../../neps/dropping-python2.7-proposal.rst diff --git a/doc/source/neps/index.rst b/doc/source/neps/index.rst index de4cd64b6..d85f33606 100644 --- a/doc/source/neps/index.rst +++ b/doc/source/neps/index.rst @@ -35,3 +35,4 @@ Other NEPs structured_array_extensions datetime-proposal datetime-proposal3 + dropping-python2.7-proposal diff --git a/numpy/core/src/multiarray/methods.c b/numpy/core/src/multiarray/methods.c index 572352304..3f461b375 100644 --- a/numpy/core/src/multiarray/methods.c +++ b/numpy/core/src/multiarray/methods.c @@ -2505,6 +2505,12 @@ NPY_NO_EXPORT PyMethodDef array_methods[] = { (PyCFunction)array_ufunc, METH_VARARGS | METH_KEYWORDS, NULL}, +#ifndef NPY_PY3K + {"__unicode__", + (PyCFunction)array_unicode, + METH_NOARGS, NULL}, +#endif + /* for the sys module */ {"__sizeof__", (PyCFunction) array_sizeof, diff --git a/numpy/core/src/multiarray/strfuncs.c b/numpy/core/src/multiarray/strfuncs.c index bb94eb9f3..646d15cdb 100644 --- a/numpy/core/src/multiarray/strfuncs.c +++ b/numpy/core/src/multiarray/strfuncs.c @@ -225,3 +225,35 @@ array_format(PyArrayObject *self, PyObject *args) ); } } + +#ifndef NPY_PY3K + +NPY_NO_EXPORT PyObject * +array_unicode(PyArrayObject *self) +{ + PyObject *uni; + + if (PyArray_NDIM(self) == 0) { + PyObject *item = PyArray_ToScalar(PyArray_DATA(self), self); + if (item == NULL){ + return NULL; + } + + /* defer to invoking `unicode` on the scalar */ + uni = PyObject_CallFunctionObjArgs( + (PyObject *)&PyUnicode_Type, item, NULL); + Py_DECREF(item); + } + else { + /* Do what unicode(self) would normally do */ + PyObject *str = PyObject_Str((PyObject *)self); + if (str == NULL){ + return NULL; + } + uni = PyUnicode_FromObject(str); + Py_DECREF(str); + } + return uni; +} + +#endif diff --git a/numpy/core/src/multiarray/strfuncs.h b/numpy/core/src/multiarray/strfuncs.h index 5dd661a20..7e869d926 100644 --- a/numpy/core/src/multiarray/strfuncs.h +++ b/numpy/core/src/multiarray/strfuncs.h @@ -13,4 +13,9 @@ array_str(PyArrayObject *self); NPY_NO_EXPORT PyObject * array_format(PyArrayObject *self, PyObject *args); +#ifndef NPY_PY3K + NPY_NO_EXPORT PyObject * + array_unicode(PyArrayObject *self); +#endif + #endif diff --git a/numpy/core/tests/test_arrayprint.py b/numpy/core/tests/test_arrayprint.py index f344ce910..62b5cf580 100644 --- a/numpy/core/tests/test_arrayprint.py +++ b/numpy/core/tests/test_arrayprint.py @@ -260,8 +260,10 @@ class TestPrintOptions(object): assert_equal(repr(x), "array([0., 1., 2.])") def test_0d_arrays(self): + unicode = type(u'') + assert_equal(unicode(np.array(u'café', np.unicode_)), u'café') + if sys.version_info[0] >= 3: - assert_equal(str(np.array('café', np.unicode_)), 'café') assert_equal(repr(np.array('café', np.unicode_)), "array('café',\n dtype='<U4')") else: diff --git a/numpy/ma/core.py b/numpy/ma/core.py index b71e8fa06..0d02bb315 100644 --- a/numpy/ma/core.py +++ b/numpy/ma/core.py @@ -3867,6 +3867,10 @@ class MaskedArray(ndarray): def __str__(self): return str(self._insert_masked_print()) + if sys.version_info.major < 3: + def __unicode__(self): + return unicode(self._insert_masked_print()) + def __repr__(self): """ Literal string representation. @@ -6238,6 +6242,10 @@ class MaskedConstant(MaskedArray): def __str__(self): return str(masked_print_option._display) + if sys.version_info.major < 3: + def __unicode__(self): + return unicode(masked_print_option._display) + def __repr__(self): if self is MaskedConstant.__singleton: return 'masked' diff --git a/numpy/ma/tests/test_core.py b/numpy/ma/tests/test_core.py index fd8d629f9..03de71f81 100644 --- a/numpy/ma/tests/test_core.py +++ b/numpy/ma/tests/test_core.py @@ -500,6 +500,16 @@ class TestMaskedArray(object): ' fill_value = 999999)\n' ) + def test_0d_unicode(self): + u = u'caf\xe9' + utype = type(u) + + arr_nomask = np.ma.array(u) + arr_masked = np.ma.array(u, mask=True) + + assert_equal(utype(arr_nomask), u) + assert_equal(utype(arr_masked), u'--') + def test_pickling(self): # Tests pickling for dtype in (int, float, str, object): |
