diff options
| -rw-r--r-- | doc/release/upcoming_changes/21807.improvement.rst | 7 | ||||
| -rw-r--r-- | numpy/core/defchararray.py | 16 | ||||
| -rw-r--r-- | numpy/core/src/multiarray/datetime.c | 3 | ||||
| -rw-r--r-- | numpy/f2py/auxfuncs.py | 8 | ||||
| -rwxr-xr-x | numpy/f2py/rules.py | 4 | ||||
| -rw-r--r-- | numpy/f2py/tests/src/value_attrspec/gh21665.f90 | 9 | ||||
| -rw-r--r-- | numpy/f2py/tests/test_value_attrspec.py | 14 | ||||
| -rw-r--r-- | numpy/lib/npyio.py | 16 |
8 files changed, 70 insertions, 7 deletions
diff --git a/doc/release/upcoming_changes/21807.improvement.rst b/doc/release/upcoming_changes/21807.improvement.rst new file mode 100644 index 000000000..c0043cad3 --- /dev/null +++ b/doc/release/upcoming_changes/21807.improvement.rst @@ -0,0 +1,7 @@ +F2PY supports the value attribute +================================= + +The Fortran standard requires that variables declared with the ``value`` +attribute must be passed by value instead of reference. F2PY now supports this +use pattern correctly. So ``integer, intent(in), value :: x`` in Fortran codes +will have correct wrappers generated. diff --git a/numpy/core/defchararray.py b/numpy/core/defchararray.py index 3521e778e..fdda44e56 100644 --- a/numpy/core/defchararray.py +++ b/numpy/core/defchararray.py @@ -445,6 +445,22 @@ def center(a, width, fillchar=' '): See Also -------- str.center + + Notes + ----- + This function is intended to work with arrays of strings. The + fill character is not applied to numeric types. + + Examples + -------- + >>> c = np.array(['a1b2','1b2a','b2a1','2a1b']); c + array(['a1b2', '1b2a', 'b2a1', '2a1b'], dtype='<U4') + >>> np.char.center(c, width=9) + array([' a1b2 ', ' 1b2a ', ' b2a1 ', ' 2a1b '], dtype='<U9') + >>> np.char.center(c, width=9, fillchar='*') + array(['***a1b2**', '***1b2a**', '***b2a1**', '***2a1b**'], dtype='<U9') + >>> np.char.center(c, width=1) + array(['a', '1', 'b', '2'], dtype='<U1') """ a_arr = numpy.asarray(a) diff --git a/numpy/core/src/multiarray/datetime.c b/numpy/core/src/multiarray/datetime.c index 99096be56..70b54f26a 100644 --- a/numpy/core/src/multiarray/datetime.c +++ b/numpy/core/src/multiarray/datetime.c @@ -3904,7 +3904,8 @@ datetime_to_timedelta_resolve_descriptors( PyArrayMethodObject *NPY_UNUSED(self), PyArray_DTypeMeta *dtypes[2], PyArray_Descr *given_descrs[2], - PyArray_Descr *loop_descrs[2]) + PyArray_Descr *loop_descrs[2], + npy_intp *NPY_UNUSED(view_offset)) { loop_descrs[0] = NPY_DT_CALL_ensure_canonical(given_descrs[0]); if (loop_descrs[0] == NULL) { diff --git a/numpy/f2py/auxfuncs.py b/numpy/f2py/auxfuncs.py index 98c9eff78..3f9b0ceaf 100644 --- a/numpy/f2py/auxfuncs.py +++ b/numpy/f2py/auxfuncs.py @@ -47,7 +47,7 @@ __all__ = [ 'isunsigned_chararray', 'isunsigned_long_long', 'isunsigned_long_longarray', 'isunsigned_short', 'isunsigned_shortarray', 'l_and', 'l_not', 'l_or', 'outmess', - 'replace', 'show', 'stripcomma', 'throw_error', + 'replace', 'show', 'stripcomma', 'throw_error', 'isattr_value' ] @@ -298,6 +298,9 @@ def issubroutine_wrap(rout): return 0 return issubroutine(rout) and hasassumedshape(rout) +def isattr_value(var): + return 'value' in var.get('attrspec', []) + def hasassumedshape(rout): if rout.get('hasassumedshape'): @@ -692,7 +695,8 @@ def getcallprotoargument(rout, cb_map={}): elif isstring(var): pass else: - ctype = ctype + '*' + if not isattr_value(var): + ctype = ctype + '*' if ((isstring(var) or isarrayofstrings(var) # obsolete? or isstringarray(var))): diff --git a/numpy/f2py/rules.py b/numpy/f2py/rules.py index 63c48a878..1bac87102 100755 --- a/numpy/f2py/rules.py +++ b/numpy/f2py/rules.py @@ -71,7 +71,7 @@ from .auxfuncs import ( islong_double, islong_doublefunction, islong_long, islong_longfunction, ismoduleroutine, isoptional, isrequired, isscalar, issigned_long_longarray, isstring, isstringarray, - isstringfunction, issubroutine, + isstringfunction, issubroutine, isattr_value, issubroutine_wrap, isthreadsafe, isunsigned, isunsigned_char, isunsigned_chararray, isunsigned_long_long, isunsigned_long_longarray, isunsigned_short, isunsigned_shortarray, @@ -874,7 +874,7 @@ if (#varname#_cb.capi==Py_None) { { # Common 'decl': ' #ctype# #varname# = 0;', 'pyobjfrom': {debugcapi: ' fprintf(stderr,"#vardebugshowvalue#\\n",#varname#);'}, - 'callfortran': {isintent_c: '#varname#,', l_not(isintent_c): '&#varname#,'}, + 'callfortran': {l_or(isintent_c, isattr_value): '#varname#,', l_not(l_or(isintent_c, isattr_value)): '&#varname#,'}, 'return': {isintent_out: ',#varname#'}, '_check': l_and(isscalar, l_not(iscomplex)) }, { diff --git a/numpy/f2py/tests/src/value_attrspec/gh21665.f90 b/numpy/f2py/tests/src/value_attrspec/gh21665.f90 new file mode 100644 index 000000000..7d9dc0fd4 --- /dev/null +++ b/numpy/f2py/tests/src/value_attrspec/gh21665.f90 @@ -0,0 +1,9 @@ +module fortfuncs + implicit none +contains + subroutine square(x,y) + integer, intent(in), value :: x + integer, intent(out) :: y + y = x*x + end subroutine square +end module fortfuncs diff --git a/numpy/f2py/tests/test_value_attrspec.py b/numpy/f2py/tests/test_value_attrspec.py new file mode 100644 index 000000000..83aaf6c91 --- /dev/null +++ b/numpy/f2py/tests/test_value_attrspec.py @@ -0,0 +1,14 @@ +import os +import pytest + +from . import util + +class TestValueAttr(util.F2PyTest): + sources = [util.getpath("tests", "src", "value_attrspec", "gh21665.f90")] + + # gh-21665 + def test_long_long_map(self): + inp = 2 + out = self.module.fortfuncs.square(inp) + exp_out = 4 + assert out == exp_out diff --git a/numpy/lib/npyio.py b/numpy/lib/npyio.py index 52bcf25f8..471f85976 100644 --- a/numpy/lib/npyio.py +++ b/numpy/lib/npyio.py @@ -1067,8 +1067,6 @@ def loadtxt(fname, dtype=float, comments='#', delimiter=None, r""" Load data from a text file. - Each row in the text file must have the same number of values. - Parameters ---------- fname : file, str, pathlib.Path, list of str, generator @@ -1171,6 +1169,11 @@ def loadtxt(fname, dtype=float, comments='#', delimiter=None, `genfromtxt` function provides more sophisticated handling of, e.g., lines with missing values. + Each row in the input text file must have the same number of values to be + able to read all values. If all rows do not have same number of values, a + subset of up to n columns (where n is the least number of values present + in all rows) can be read by specifying the columns via `usecols`. + .. versionadded:: 1.10.0 The strings produced by the Python float.hex method can be used as @@ -1279,6 +1282,15 @@ def loadtxt(fname, dtype=float, comments='#', delimiter=None, >>> np.loadtxt(s, dtype="U", delimiter=",", quotechar='"') array('Hello, my name is "Monty"!', dtype='<U26') + Read subset of columns when all rows do not contain equal number of values: + + >>> d = StringIO("1 2\n2 4\n3 9 12\n4 16 20") + >>> np.loadtxt(d, usecols=(0, 1)) + array([[ 1., 2.], + [ 2., 4.], + [ 3., 9.], + [ 4., 16.]]) + """ if like is not None: |
