summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/release/upcoming_changes/21807.improvement.rst7
-rw-r--r--numpy/core/defchararray.py16
-rw-r--r--numpy/core/src/multiarray/datetime.c3
-rw-r--r--numpy/f2py/auxfuncs.py8
-rwxr-xr-xnumpy/f2py/rules.py4
-rw-r--r--numpy/f2py/tests/src/value_attrspec/gh21665.f909
-rw-r--r--numpy/f2py/tests/test_value_attrspec.py14
-rw-r--r--numpy/lib/npyio.py16
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: