1"""

2 Functions 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"""

6 from .overrides import (

7 array_function_dispatch,

8 set_array_function_like_doc,

9 set_module,

10)

11 from .multiarray import array, asanyarray

12

13

14__all__ = ["require"]

15

16

17 POSSIBLE_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

27 def _require_dispatcher(a, dtype=None, requirements=None, *, like=None):

28 return (like,)

29

30

31@set_array_function_like_doc

32@set_module('numpy')

33 def 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

140)(require)