From 80d3b7bc6deb74c1ec9ede395ded89dc661de606 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Wed, 22 Sep 2021 01:45:57 +0200 Subject: [PATCH] MAINT: Fix typo in public API By keeping both variants of the keyowrd parameter, we achieve backwards compatibility. The old mispelled variant has been removed from the documentation, the new variant does appear in the documentation and using noth variants raises a TypeError. Additionally, the old variant can only be used as a keyword argument, not as a positional argument. Co-authored-by: Eric Wieser --- .../upcoming_changes/19921.deprecation.rst | 3 +++ numpy/ma/mrecords.py | 22 ++++++++++++++----- numpy/ma/mrecords.pyi | 4 +++- numpy/ma/tests/test_deprecations.py | 21 ++++++++++++++++++ numpy/ma/tests/test_mrecords.py | 2 +- 5 files changed, 45 insertions(+), 7 deletions(-) create mode 100644 doc/release/upcoming_changes/19921.deprecation.rst diff --git a/doc/release/upcoming_changes/19921.deprecation.rst b/doc/release/upcoming_changes/19921.deprecation.rst new file mode 100644 index 000000000000..17fa0f605be0 --- /dev/null +++ b/doc/release/upcoming_changes/19921.deprecation.rst @@ -0,0 +1,3 @@ +* the misspelled keyword argument ``delimitor`` of + ``numpy.ma.mrecords.fromtextfile()`` has been changed into + ``delimiter``, using it will emit a deprecation warning. diff --git a/numpy/ma/mrecords.py b/numpy/ma/mrecords.py index 10b1b209c20e..5611a2bff288 100644 --- a/numpy/ma/mrecords.py +++ b/numpy/ma/mrecords.py @@ -667,8 +667,9 @@ def openfile(fname): raise NotImplementedError("Wow, binary file") -def fromtextfile(fname, delimitor=None, commentchar='#', missingchar='', - varnames=None, vartypes=None): +def fromtextfile(fname, delimiter=None, commentchar='#', missingchar='', + varnames=None, vartypes=None, + *, delimitor=np._NoValue): # backwards compatibility """ Creates a mrecarray from data stored in the file `filename`. @@ -676,7 +677,7 @@ def fromtextfile(fname, delimitor=None, commentchar='#', missingchar='', ---------- fname : {file name/handle} Handle of an opened file. - delimitor : {None, string}, optional + delimiter : {None, string}, optional Alphanumeric character used to separate columns in the file. If None, any (group of) white spacestring(s) will be used. commentchar : {'#', string}, optional @@ -692,6 +693,17 @@ def fromtextfile(fname, delimitor=None, commentchar='#', missingchar='', Ultra simple: the varnames are in the header, one line""" + if delimitor is not np._NoValue: + if delimiter is not None: + raise TypeError("fromtextfile() got multiple values for argument " + "'delimiter'") + # NumPy 1.22.0, 2021-09-22 + warnings.warn("The 'delimitor' keyword argument of " + "numpy.ma.mrecords.fromtextfile() is deprecated " + "since NumPy 1.22.0, use 'delimiter' instead.", + DeprecationWarning, stacklevel=2) + delimiter = delimitor + # Try to open the file. ftext = openfile(fname) @@ -699,14 +711,14 @@ def fromtextfile(fname, delimitor=None, commentchar='#', missingchar='', while True: line = ftext.readline() firstline = line[:line.find(commentchar)].strip() - _varnames = firstline.split(delimitor) + _varnames = firstline.split(delimiter) if len(_varnames) > 1: break if varnames is None: varnames = _varnames # Get the data. - _variables = masked_array([line.strip().split(delimitor) for line in ftext + _variables = masked_array([line.strip().split(delimiter) for line in ftext if line[0] != commentchar and len(line) > 1]) (_, nfields) = _variables.shape ftext.close() diff --git a/numpy/ma/mrecords.pyi b/numpy/ma/mrecords.pyi index 92d5afb897e2..1f284ada9b77 100644 --- a/numpy/ma/mrecords.pyi +++ b/numpy/ma/mrecords.pyi @@ -78,11 +78,13 @@ def fromrecords( def fromtextfile( fname, - delimitor=..., + delimiter=..., commentchar=..., missingchar=..., varnames=..., vartypes=..., + # NOTE: deprecated: NumPy 1.22.0, 2021-09-22 + # delimitor=..., ): ... def addfield(mrecord, newfield, newfieldname=...): ... diff --git a/numpy/ma/tests/test_deprecations.py b/numpy/ma/tests/test_deprecations.py index 14f69737583f..6d5bff383750 100644 --- a/numpy/ma/tests/test_deprecations.py +++ b/numpy/ma/tests/test_deprecations.py @@ -1,10 +1,13 @@ """Test deprecation and future warnings. """ +import pytest import numpy as np from numpy.testing import assert_warns from numpy.ma.testutils import assert_equal from numpy.ma.core import MaskedArrayFutureWarning +import io +import textwrap class TestArgsort: """ gh-8701 """ @@ -66,3 +69,21 @@ def test_axis_default(self): result = ma_max(data1d) assert_equal(result, ma_max(data1d, axis=None)) assert_equal(result, ma_max(data1d, axis=0)) + + +class TestFromtextfile: + def test_fromtextfile_delimitor(self): + # NumPy 1.22.0, 2021-09-22 + + textfile = io.StringIO(textwrap.dedent( + """ + A,B,C,D + 'string 1';1;1.0;'mixed column' + 'string 2';2;2.0; + 'string 3';3;3.0;123 + 'string 4';4;4.0;3.14 + """ + )) + + with pytest.warns(DeprecationWarning): + result = np.ma.mrecords.fromtextfile(textfile, delimitor=';') diff --git a/numpy/ma/tests/test_mrecords.py b/numpy/ma/tests/test_mrecords.py index 27df519d266a..4b2c01df9947 100644 --- a/numpy/ma/tests/test_mrecords.py +++ b/numpy/ma/tests/test_mrecords.py @@ -468,7 +468,7 @@ def test_fromtextfile(self): with temppath() as path: with open(path, 'w') as f: f.write(fcontent) - mrectxt = fromtextfile(path, delimitor=',', varnames='ABCDEFG') + mrectxt = fromtextfile(path, delimiter=',', varnames='ABCDEFG') assert_(isinstance(mrectxt, MaskedRecords)) assert_equal(mrectxt.F, [1, 1, 1, 1]) assert_equal(mrectxt.E._mask, [1, 1, 1, 1])