1"""
2Functions in the ``as*array`` family that promote array-likes into arrays.
3
4`require` fits this category despite its name not matching this pattern.
5"""
6from .overrides import (
7 array_function_dispatch,
8 set_array_function_like_doc,
9 set_module,
10)
11from .multiarray import array, asanyarray
12
13
14__all__ = ["require"]
15
16
17POSSIBLE_FLAGS = {
18 'C': 'C', 'C_CONTIGUOUS': 'C', 'CONTIGUOUS': 'C',
19 'F': 'F', 'F_CONTIGUOUS': 'F', 'FORTRAN': 'F',
20 'A': 'A', 'ALIGNED': 'A',
21 'W': 'W', 'WRITEABLE': 'W',
22 'O': 'O', 'OWNDATA': 'O',
23 'E': 'E', 'ENSUREARRAY': 'E'
24}
25
26
27def _require_dispatcher(a, dtype=None, requirements=None, *, like=None):
28 return (like,)
29
30
31@set_array_function_like_doc
32@set_module('numpy')
33def require(a, dtype=None, requirements=None, *, like=None):
34 """
35 Return an ndarray of the provided type that satisfies requirements.
36
37 This function is useful to be sure that an array with the correct flags
38 is returned for passing to compiled code (perhaps through ctypes).
39
40 Parameters
41 ----------
42 a : array_like
43 The object to be converted to a type-and-requirement-satisfying array.
44 dtype : data-type
45 The required data-type. If None preserve the current dtype. If your
46 application requires the data to be in native byteorder, include
47 a byteorder specification as a part of the dtype specification.
48 requirements : str or sequence of str
49 The requirements list can be any of the following
50
51 * 'F_CONTIGUOUS' ('F') - ensure a Fortran-contiguous array
52 * 'C_CONTIGUOUS' ('C') - ensure a C-contiguous array
53 * 'ALIGNED' ('A') - ensure a data-type aligned array
54 * 'WRITEABLE' ('W') - ensure a writable array
55 * 'OWNDATA' ('O') - ensure an array that owns its own data
56 * 'ENSUREARRAY', ('E') - ensure a base array, instead of a subclass
57 ${ARRAY_FUNCTION_LIKE}
58
59 .. versionadded:: 1.20.0
60
61 Returns
62 -------
63 out : ndarray
64 Array with specified requirements and type if given.
65
66 See Also
67 --------
68 asarray : Convert input to an ndarray.
69 asanyarray : Convert to an ndarray, but pass through ndarray subclasses.
70 ascontiguousarray : Convert input to a contiguous array.
71 asfortranarray : Convert input to an ndarray with column-major
72 memory order.
73 ndarray.flags : Information about the memory layout of the array.
74
75 Notes
76 -----
77 The returned array will be guaranteed to have the listed requirements
78 by making a copy if needed.
79
80 Examples
81 --------
82 >>> x = np.arange(6).reshape(2,3)
83 >>> x.flags
84 C_CONTIGUOUS : True
85 F_CONTIGUOUS : False
86 OWNDATA : False
87 WRITEABLE : True
88 ALIGNED : True
89 WRITEBACKIFCOPY : False
90
91 >>> y = np.require(x, dtype=np.float32, requirements=['A', 'O', 'W', 'F'])
92 >>> y.flags
93 C_CONTIGUOUS : False
94 F_CONTIGUOUS : True
95 OWNDATA : True
96 WRITEABLE : True
97 ALIGNED : True
98 WRITEBACKIFCOPY : False
99
100 """
101 if like is not None:
102 return _require_with_like(
103 a,
104 dtype=dtype,
105 requirements=requirements,
106 like=like,
107 )
108
109 if not requirements:
110 return asanyarray(a, dtype=dtype)
111
112 requirements = {POSSIBLE_FLAGS[x.upper()] for x in requirements}
113
114 if 'E' in requirements:
115 requirements.remove('E')
116 subok = False
117 else:
118 subok = True
119
120 order = 'A'
121 if requirements >= {'C', 'F'}:
122 raise ValueError('Cannot specify both "C" and "F" order')
123 elif 'F' in requirements:
124 order = 'F'
125 requirements.remove('F')
126 elif 'C' in requirements:
127 order = 'C'
128 requirements.remove('C')
129
130 arr = array(a, dtype=dtype, order=order, copy=False, subok=subok)
131
132 for prop in requirements:
133 if not arr.flags[prop]:
134 return arr.copy(order)
135 return arr
136
137
138_require_with_like = array_function_dispatch(
139 _require_dispatcher, use_like=True
140)(require)