Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes15kdownloads
test_array_from_pyobj.py679 linesDownload Raw Back to tests
1import copy
2import platform
3import sys
4from pathlib import Path
5
6import pytest
7
8import numpy as np
9from numpy._core._type_aliases import c_names_dict as _c_names_dict
10
11from . import util
12
13wrap = None
14
15# Extend core typeinfo with CHARACTER to test dtype('c')
16c_names_dict = dict(
17    CHARACTER=np.dtype("c"),
18    **_c_names_dict
19)
20
21
22def get_testdir():
23    testroot = Path(__file__).resolve().parent / "src"
24    return testroot / "array_from_pyobj"
25
26def setup_module():
27    """
28    Build the required testing extension module
29
30    """
31    global wrap
32
33    if wrap is None:
34        src = [
35            get_testdir() / "wrapmodule.c",
36        ]
37        wrap = util.build_meson(src, module_name="test_array_from_pyobj_ext")
38
39
40def flags_info(arr):
41    flags = wrap.array_attrs(arr)[6]
42    return flags2names(flags)
43
44
45def flags2names(flags):
46    info = []
47    for flagname in [
48            "CONTIGUOUS",
49            "FORTRAN",
50            "OWNDATA",
51            "ENSURECOPY",
52            "ENSUREARRAY",
53            "ALIGNED",
54            "NOTSWAPPED",
55            "WRITEABLE",
56            "WRITEBACKIFCOPY",
57            "UPDATEIFCOPY",
58            "BEHAVED",
59            "BEHAVED_RO",
60            "CARRAY",
61            "FARRAY",
62    ]:
63        if abs(flags) & getattr(wrap, flagname, 0):
64            info.append(flagname)
65    return info
66
67
68class Intent:
69    def __init__(self, intent_list=[]):
70        self.intent_list = intent_list[:]
71        flags = 0
72        for i in intent_list:
73            if i == "optional":
74                flags |= wrap.F2PY_OPTIONAL
75            else:
76                flags |= getattr(wrap, "F2PY_INTENT_" + i.upper())
77        self.flags = flags
78
79    def __getattr__(self, name):
80        name = name.lower()
81        if name == "in_":
82            name = "in"
83        return self.__class__(self.intent_list + [name])
84
85    def __str__(self):
86        return f"intent({','.join(self.intent_list)})"
87
88    def __repr__(self):
89        return f"Intent({self.intent_list!r})"
90
91    def is_intent(self, *names):
92        return all(name in self.intent_list for name in names)
93
94    def is_intent_exact(self, *names):
95        return len(self.intent_list) == len(names) and self.is_intent(*names)
96
97
98intent = Intent()
99
100_type_names = [
101    "BOOL",
102    "BYTE",
103    "UBYTE",
104    "SHORT",
105    "USHORT",
106    "INT",
107    "UINT",
108    "LONG",
109    "ULONG",
110    "LONGLONG",
111    "ULONGLONG",
112    "FLOAT",
113    "DOUBLE",
114    "CFLOAT",
115    "STRING1",
116    "STRING5",
117    "CHARACTER",
118]
119
120_cast_dict = {"BOOL": ["BOOL"]}
121_cast_dict["BYTE"] = _cast_dict["BOOL"] + ["BYTE"]
122_cast_dict["UBYTE"] = _cast_dict["BOOL"] + ["UBYTE"]
123_cast_dict["BYTE"] = ["BYTE"]
124_cast_dict["UBYTE"] = ["UBYTE"]
125_cast_dict["SHORT"] = _cast_dict["BYTE"] + ["UBYTE", "SHORT"]
126_cast_dict["USHORT"] = _cast_dict["UBYTE"] + ["BYTE", "USHORT"]
127_cast_dict["INT"] = _cast_dict["SHORT"] + ["USHORT", "INT"]
128_cast_dict["UINT"] = _cast_dict["USHORT"] + ["SHORT", "UINT"]
129
130_cast_dict["LONG"] = _cast_dict["INT"] + ["LONG"]
131_cast_dict["ULONG"] = _cast_dict["UINT"] + ["ULONG"]
132
133_cast_dict["LONGLONG"] = _cast_dict["LONG"] + ["LONGLONG"]
134_cast_dict["ULONGLONG"] = _cast_dict["ULONG"] + ["ULONGLONG"]
135
136_cast_dict["FLOAT"] = _cast_dict["SHORT"] + ["USHORT", "FLOAT"]
137_cast_dict["DOUBLE"] = _cast_dict["INT"] + ["UINT", "FLOAT", "DOUBLE"]
138
139_cast_dict["CFLOAT"] = _cast_dict["FLOAT"] + ["CFLOAT"]
140
141_cast_dict['STRING1'] = ['STRING1']
142_cast_dict['STRING5'] = ['STRING5']
143_cast_dict['CHARACTER'] = ['CHARACTER']
144
145# 32 bit system malloc typically does not provide the alignment required by
146# 16 byte long double types this means the inout intent cannot be satisfied
147# and several tests fail as the alignment flag can be randomly true or false
148# when numpy gains an aligned allocator the tests could be enabled again
149#
150# Furthermore, on macOS ARM64 and AIX, LONGDOUBLE is an alias for DOUBLE.
151if ((np.intp().dtype.itemsize != 4 or np.clongdouble().dtype.alignment <= 8)
152        and sys.platform not in ["win32", "aix"]
153        and (platform.system(), platform.processor()) != ("Darwin", "arm")):
154    _type_names.extend(["LONGDOUBLE", "CDOUBLE", "CLONGDOUBLE"])
155    _cast_dict["LONGDOUBLE"] = _cast_dict["LONG"] + [
156        "ULONG",
157        "FLOAT",
158        "DOUBLE",
159        "LONGDOUBLE",
160    ]
161    _cast_dict["CLONGDOUBLE"] = _cast_dict["LONGDOUBLE"] + [
162        "CFLOAT",
163        "CDOUBLE",
164        "CLONGDOUBLE",
165    ]
166    _cast_dict["CDOUBLE"] = _cast_dict["DOUBLE"] + ["CFLOAT", "CDOUBLE"]
167
168
169class Type:
170    _type_cache = {}
171
172    def __new__(cls, name):
173        if isinstance(name, np.dtype):
174            dtype0 = name
175            name = None
176            for n, i in c_names_dict.items():
177                if not isinstance(i, type) and dtype0.type is i.type:
178                    name = n
179                    break
180        obj = cls._type_cache.get(name.upper(), None)
181        if obj is not None:
182            return obj
183        obj = object.__new__(cls)
184        obj._init(name)
185        cls._type_cache[name.upper()] = obj
186        return obj
187
188    def _init(self, name):
189        self.NAME = name.upper()
190
191        if self.NAME == 'CHARACTER':
192            info = c_names_dict[self.NAME]
193            self.type_num = wrap.NPY_STRING
194            self.elsize = 1
195            self.dtype = np.dtype('c')
196        elif self.NAME.startswith('STRING'):
197            info = c_names_dict[self.NAME[:6]]
198            self.type_num = wrap.NPY_STRING
199            self.elsize = int(self.NAME[6:] or 0)
200            self.dtype = np.dtype(f'S{self.elsize}')
201        else:
202            info = c_names_dict[self.NAME]
203            self.type_num = getattr(wrap, 'NPY_' + self.NAME)
204            self.elsize = info.itemsize
205            self.dtype = np.dtype(info.type)
206
207        assert self.type_num == info.num
208        self.type = info.type
209        self.dtypechar = info.char
210
211    def __repr__(self):
212        return (f"Type({self.NAME})|type_num={self.type_num},"
213                f" dtype={self.dtype},"
214                f" type={self.type}, elsize={self.elsize},"
215                f" dtypechar={self.dtypechar}")
216
217    def cast_types(self):
218        return [self.__class__(_m) for _m in _cast_dict[self.NAME]]
219
220    def all_types(self):
221        return [self.__class__(_m) for _m in _type_names]
222
223    def smaller_types(self):
224        bits = c_names_dict[self.NAME].alignment
225        types = []
226        for name in _type_names:
227            if c_names_dict[name].alignment < bits:
228                types.append(Type(name))
229        return types
230
231    def equal_types(self):
232        bits = c_names_dict[self.NAME].alignment
233        types = []
234        for name in _type_names:
235            if name == self.NAME:
236                continue
237            if c_names_dict[name].alignment == bits:
238                types.append(Type(name))
239        return types
240
241    def larger_types(self):
242        bits = c_names_dict[self.NAME].alignment
243        types = []
244        for name in _type_names:
245            if c_names_dict[name].alignment > bits:
246                types.append(Type(name))
247        return types
248
249
250class Array:
251
252    def __repr__(self):
253        return (f'Array({self.type}, {self.dims}, {self.intent},'
254                f' {self.obj})|arr={self.arr}')
255
256    def __init__(self, typ, dims, intent, obj):
257        self.type = typ
258        self.dims = dims
259        self.intent = intent
260        self.obj_copy = copy.deepcopy(obj)
261        self.obj = obj
262
263        # arr.dtypechar may be different from typ.dtypechar
264        self.arr = wrap.call(typ.type_num,
265                             typ.elsize,
266                             dims, intent.flags, obj)
267
268        assert isinstance(self.arr, np.ndarray)
269
270        self.arr_attr = wrap.array_attrs(self.arr)
271
272        if len(dims) > 1:
273            if self.intent.is_intent("c"):
274                assert (intent.flags & wrap.F2PY_INTENT_C)
275                assert not self.arr.flags["FORTRAN"]
276                assert self.arr.flags["CONTIGUOUS"]
277                assert (not self.arr_attr[6] & wrap.FORTRAN)
278            else:
279                assert (not intent.flags & wrap.F2PY_INTENT_C)
280                assert self.arr.flags["FORTRAN"]
281                assert not self.arr.flags["CONTIGUOUS"]
282                assert (self.arr_attr[6] & wrap.FORTRAN)
283
284        if obj is None:
285            self.pyarr = None
286            self.pyarr_attr = None
287            return
288
289        if intent.is_intent("cache"):
290            assert isinstance(obj, np.ndarray), repr(type(obj))
291            self.pyarr = np.array(obj).reshape(*dims).copy()
292        else:
293            self.pyarr = np.array(
294                np.array(obj, dtype=typ.dtypechar).reshape(*dims),
295                order=(self.intent.is_intent("c") and "C") or "F",
296            )
297            assert self.pyarr.dtype == typ
298        self.pyarr.setflags(write=self.arr.flags["WRITEABLE"])
299        assert self.pyarr.flags["OWNDATA"], (obj, intent)
300        self.pyarr_attr = wrap.array_attrs(self.pyarr)
301
302        if len(dims) > 1:
303            if self.intent.is_intent("c"):
304                assert not self.pyarr.flags["FORTRAN"]
305                assert self.pyarr.flags["CONTIGUOUS"]
306                assert (not self.pyarr_attr[6] & wrap.FORTRAN)
307            else:
308                assert self.pyarr.flags["FORTRAN"]
309                assert not self.pyarr.flags["CONTIGUOUS"]
310                assert (self.pyarr_attr[6] & wrap.FORTRAN)
311
312        assert self.arr_attr[1] == self.pyarr_attr[1]  # nd
313        assert self.arr_attr[2] == self.pyarr_attr[2]  # dimensions
314        if self.arr_attr[1] <= 1:
315            assert self.arr_attr[3] == self.pyarr_attr[3], repr((
316                self.arr_attr[3],
317                self.pyarr_attr[3],
318                self.arr.tobytes(),
319                self.pyarr.tobytes(),
320            ))  # strides
321        assert self.arr_attr[5][-2:] == self.pyarr_attr[5][-2:], repr((
322            self.arr_attr[5], self.pyarr_attr[5]
323            ))  # descr
324        assert self.arr_attr[6] == self.pyarr_attr[6], repr((
325            self.arr_attr[6],
326            self.pyarr_attr[6],
327            flags2names(0 * self.arr_attr[6] - self.pyarr_attr[6]),
328            flags2names(self.arr_attr[6]),
329            intent,
330        ))  # flags
331
332        if intent.is_intent("cache"):
333            assert self.arr_attr[5][3] >= self.type.elsize
334        else:
335            assert self.arr_attr[5][3] == self.type.elsize
336            assert (self.arr_equal(self.pyarr, self.arr))
337
338        if isinstance(self.obj, np.ndarray):
339            if typ.elsize == Type(obj.dtype).elsize:
340                if not intent.is_intent("copy") and self.arr_attr[1] <= 1:
341                    assert self.has_shared_memory()
342
343    def arr_equal(self, arr1, arr2):
344        if arr1.shape != arr2.shape:
345            return False
346        return (arr1 == arr2).all()
347
348    def __str__(self):
349        return str(self.arr)
350
351    def has_shared_memory(self):
352        """Check that created array shares data with input array."""
353        if self.obj is self.arr:
354            return True
355        if not isinstance(self.obj, np.ndarray):
356            return False
357        obj_attr = wrap.array_attrs(self.obj)
358        return obj_attr[0] == self.arr_attr[0]
359
360
361class TestIntent:
362    def test_in_out(self):
363        assert str(intent.in_.out) == "intent(in,out)"
364        assert intent.in_.c.is_intent("c")
365        assert not intent.in_.c.is_intent_exact("c")
366        assert intent.in_.c.is_intent_exact("c", "in")
367        assert intent.in_.c.is_intent_exact("in", "c")
368        assert not intent.in_.is_intent("c")
369
370
371class TestSharedMemory:
372
373    @pytest.fixture(autouse=True, scope="class", params=_type_names)
374    def setup_type(self, request):
375        request.cls.type = Type(request.param)
376        request.cls.array = lambda self, dims, intent, obj: Array(
377            Type(request.param), dims, intent, obj)
378
379    @property
380    def num2seq(self):
381        if self.type.NAME.startswith('STRING'):
382            elsize = self.type.elsize
383            return ['1' * elsize, '2' * elsize]
384        return [1, 2]
385
386    @property
387    def num23seq(self):
388        if self.type.NAME.startswith('STRING'):
389            elsize = self.type.elsize
390            return [['1' * elsize, '2' * elsize, '3' * elsize],
391                    ['4' * elsize, '5' * elsize, '6' * elsize]]
392        return [[1, 2, 3], [4, 5, 6]]
393
394    def test_in_from_2seq(self):
395        a = self.array([2], intent.in_, self.num2seq)
396        assert not a.has_shared_memory()
397
398    def test_in_from_2casttype(self):
399        for t in self.type.cast_types():
400            obj = np.array(self.num2seq, dtype=t.dtype)
401            a = self.array([len(self.num2seq)], intent.in_, obj)
402            if t.elsize == self.type.elsize:
403                assert a.has_shared_memory(), repr((self.type.dtype, t.dtype))
404            else:
405                assert not a.has_shared_memory()
406
407    @pytest.mark.parametrize("write", ["w", "ro"])
408    @pytest.mark.parametrize("order", ["C", "F"])
409    @pytest.mark.parametrize("inp", ["2seq", "23seq"])
410    def test_in_nocopy(self, write, order, inp):
411        """Test if intent(in) array can be passed without copies"""
412        seq = getattr(self, "num" + inp)
413        obj = np.array(seq, dtype=self.type.dtype, order=order)
414        obj.setflags(write=(write == 'w'))
415        a = self.array(obj.shape,
416                       ((order == 'C' and intent.in_.c) or intent.in_), obj)
417        assert a.has_shared_memory()
418
419    def test_inout_2seq(self):
420        obj = np.array(self.num2seq, dtype=self.type.dtype)
421        a = self.array([len(self.num2seq)], intent.inout, obj)
422        assert a.has_shared_memory()
423
424        try:
425            a = self.array([2], intent.in_.inout, self.num2seq)
426        except TypeError as msg:
427            if not str(msg).startswith(
428                    "failed to initialize intent(inout|inplace|cache) array"):
429                raise
430        else:
431            raise SystemError("intent(inout) should have failed on sequence")
432
433    def test_f_inout_23seq(self):
434        obj = np.array(self.num23seq, dtype=self.type.dtype, order="F")
435        shape = (len(self.num23seq), len(self.num23seq[0]))
436        a = self.array(shape, intent.in_.inout, obj)
437        assert a.has_shared_memory()
438
439        obj = np.array(self.num23seq, dtype=self.type.dtype, order="C")
440        shape = (len(self.num23seq), len(self.num23seq[0]))
441        try:
442            a = self.array(shape, intent.in_.inout, obj)
443        except ValueError as msg:
444            if not str(msg).startswith(
445                    "failed to initialize intent(inout) array"):
446                raise
447        else:
448            raise SystemError(
449                "intent(inout) should have failed on improper array")
450
451    def test_c_inout_23seq(self):
452        obj = np.array(self.num23seq, dtype=self.type.dtype)
453        shape = (len(self.num23seq), len(self.num23seq[0]))
454        a = self.array(shape, intent.in_.c.inout, obj)
455        assert a.has_shared_memory()
456
457    def test_in_copy_from_2casttype(self):
458        for t in self.type.cast_types():
459            obj = np.array(self.num2seq, dtype=t.dtype)
460            a = self.array([len(self.num2seq)], intent.in_.copy, obj)
461            assert not a.has_shared_memory()
462
463    def test_c_in_from_23seq(self):
464        a = self.array(
465            [len(self.num23seq), len(self.num23seq[0])], intent.in_,
466            self.num23seq)
467        assert not a.has_shared_memory()
468
469    def test_in_from_23casttype(self):
470        for t in self.type.cast_types():
471            obj = np.array(self.num23seq, dtype=t.dtype)
472            a = self.array(
473                [len(self.num23seq), len(self.num23seq[0])], intent.in_, obj)
474            assert not a.has_shared_memory()
475
476    def test_f_in_from_23casttype(self):
477        for t in self.type.cast_types():
478            obj = np.array(self.num23seq, dtype=t.dtype, order="F")
479            a = self.array(
480                [len(self.num23seq), len(self.num23seq[0])], intent.in_, obj)
481            if t.elsize == self.type.elsize:
482                assert a.has_shared_memory()
483            else:
484                assert not a.has_shared_memory()
485
486    def test_c_in_from_23casttype(self):
487        for t in self.type.cast_types():
488            obj = np.array(self.num23seq, dtype=t.dtype)
489            a = self.array(
490                [len(self.num23seq), len(self.num23seq[0])], intent.in_.c, obj)
491            if t.elsize == self.type.elsize:
492                assert a.has_shared_memory()
493            else:
494                assert not a.has_shared_memory()
495
496    def test_f_copy_in_from_23casttype(self):
497        for t in self.type.cast_types():
498            obj = np.array(self.num23seq, dtype=t.dtype, order="F")
499            a = self.array(
500                [len(self.num23seq), len(self.num23seq[0])], intent.in_.copy,
501                obj)
502            assert not a.has_shared_memory()
503
504    def test_c_copy_in_from_23casttype(self):
505        for t in self.type.cast_types():
506            obj = np.array(self.num23seq, dtype=t.dtype)
507            a = self.array(
508                [len(self.num23seq), len(self.num23seq[0])], intent.in_.c.copy,
509                obj)
510            assert not a.has_shared_memory()
511
512    def test_in_cache_from_2casttype(self):
513        for t in self.type.all_types():
514            if t.elsize != self.type.elsize:
515                continue
516            obj = np.array(self.num2seq, dtype=t.dtype)
517            shape = (len(self.num2seq), )
518            a = self.array(shape, intent.in_.c.cache, obj)
519            assert a.has_shared_memory()
520
521            a = self.array(shape, intent.in_.cache, obj)
522            assert a.has_shared_memory()
523
524            obj = np.array(self.num2seq, dtype=t.dtype, order="F")
525            a = self.array(shape, intent.in_.c.cache, obj)
526            assert a.has_shared_memory()
527
528            a = self.array(shape, intent.in_.cache, obj)
529            assert a.has_shared_memory(), repr(t.dtype)
530
531            try:
532                a = self.array(shape, intent.in_.cache, obj[::-1])
533            except ValueError as msg:
534                if not str(msg).startswith(
535                        "failed to initialize intent(cache) array"):
536                    raise
537            else:
538                raise SystemError(
539                    "intent(cache) should have failed on multisegmented array")
540
541    def test_in_cache_from_2casttype_failure(self):
542        for t in self.type.all_types():
543            if t.NAME == 'STRING':
544                # string elsize is 0, so skipping the test
545                continue
546            if t.elsize >= self.type.elsize:
547                continue
548            is_int = np.issubdtype(t.dtype, np.integer)
549            if is_int and int(self.num2seq[0]) > np.iinfo(t.dtype).max:
550                # skip test if num2seq would trigger an overflow error
551                continue
552            obj = np.array(self.num2seq, dtype=t.dtype)
553            shape = (len(self.num2seq), )
554            try:
555                self.array(shape, intent.in_.cache, obj)  # Should succeed
556            except ValueError as msg:
557                if not str(msg).startswith(
558                        "failed to initialize intent(cache) array"):
559                    raise
560            else:
561                raise SystemError(
562                    "intent(cache) should have failed on smaller array")
563
564    def test_cache_hidden(self):
565        shape = (2, )
566        a = self.array(shape, intent.cache.hide, None)
567        assert a.arr.shape == shape
568
569        shape = (2, 3)
570        a = self.array(shape, intent.cache.hide, None)
571        assert a.arr.shape == shape
572
573        shape = (-1, 3)
574        try:
575            a = self.array(shape, intent.cache.hide, None)
576        except ValueError as msg:
577            if not str(msg).startswith(
578                    "failed to create intent(cache|hide)|optional array"):
579                raise
580        else:
581            raise SystemError(
582                "intent(cache) should have failed on undefined dimensions")
583
584    def test_hidden(self):
585        shape = (2, )
586        a = self.array(shape, intent.hide, None)
587        assert a.arr.shape == shape
588        assert a.arr_equal(a.arr, np.zeros(shape, dtype=self.type.dtype))
589
590        shape = (2, 3)
591        a = self.array(shape, intent.hide, None)
592        assert a.arr.shape == shape
593        assert a.arr_equal(a.arr, np.zeros(shape, dtype=self.type.dtype))
594        assert a.arr.flags["FORTRAN"] and not a.arr.flags["CONTIGUOUS"]
595
596        shape = (2, 3)
597        a = self.array(shape, intent.c.hide, None)
598        assert a.arr.shape == shape
599        assert a.arr_equal(a.arr, np.zeros(shape, dtype=self.type.dtype))
600        assert not a.arr.flags["FORTRAN"] and a.arr.flags["CONTIGUOUS"]
601
602        shape = (-1, 3)
603        try:
604            a = self.array(shape, intent.hide, None)
605        except ValueError as msg:
606            if not str(msg).startswith(
607                    "failed to create intent(cache|hide)|optional array"):
608                raise
609        else:
610            raise SystemError(
611                "intent(hide) should have failed on undefined dimensions")
612
613    def test_optional_none(self):
614        shape = (2, )
615        a = self.array(shape, intent.optional, None)
616        assert a.arr.shape == shape
617        assert a.arr_equal(a.arr, np.zeros(shape, dtype=self.type.dtype))
618
619        shape = (2, 3)
620        a = self.array(shape, intent.optional, None)
621        assert a.arr.shape == shape
622        assert a.arr_equal(a.arr, np.zeros(shape, dtype=self.type.dtype))
623        assert a.arr.flags["FORTRAN"] and not a.arr.flags["CONTIGUOUS"]
624
625        shape = (2, 3)
626        a = self.array(shape, intent.c.optional, None)
627        assert a.arr.shape == shape
628        assert a.arr_equal(a.arr, np.zeros(shape, dtype=self.type.dtype))
629        assert not a.arr.flags["FORTRAN"] and a.arr.flags["CONTIGUOUS"]
630
631    def test_optional_from_2seq(self):
632        obj = self.num2seq
633        shape = (len(obj), )
634        a = self.array(shape, intent.optional, obj)
635        assert a.arr.shape == shape
636        assert not a.has_shared_memory()
637
638    def test_optional_from_23seq(self):
639        obj = self.num23seq
640        shape = (len(obj), len(obj[0]))
641        a = self.array(shape, intent.optional, obj)
642        assert a.arr.shape == shape
643        assert not a.has_shared_memory()
644
645        a = self.array(shape, intent.optional.c, obj)
646        assert a.arr.shape == shape
647        assert not a.has_shared_memory()
648
649    def test_inplace(self):
650        obj = np.array(self.num23seq, dtype=self.type.dtype)
651        assert not obj.flags["FORTRAN"] and obj.flags["CONTIGUOUS"]
652        shape = obj.shape
653        a = self.array(shape, intent.inplace, obj)
654        assert obj[1][2] == a.arr[1][2], repr((obj, a.arr))
655        a.arr[1][2] = 54
656        assert obj[1][2] == a.arr[1][2] == np.array(54, dtype=self.type.dtype)
657        assert a.arr is obj
658        assert obj.flags["FORTRAN"]  # obj attributes are changed inplace!
659        assert not obj.flags["CONTIGUOUS"]
660
661    def test_inplace_from_casttype(self):
662        for t in self.type.cast_types():
663            if t is self.type:
664                continue
665            obj = np.array(self.num23seq, dtype=t.dtype)
666            assert obj.dtype.type == t.type
667            assert obj.dtype.type is not self.type.type
668            assert not obj.flags["FORTRAN"] and obj.flags["CONTIGUOUS"]
669            shape = obj.shape
670            a = self.array(shape, intent.inplace, obj)
671            assert obj[1][2] == a.arr[1][2], repr((obj, a.arr))
672            a.arr[1][2] = 54
673            assert obj[1][2] == a.arr[1][2] == np.array(54,
674                                                        dtype=self.type.dtype)
675            assert a.arr is obj
676            assert obj.flags["FORTRAN"]  # obj attributes changed inplace!
677            assert not obj.flags["CONTIGUOUS"]
678            assert obj.dtype.type is self.type.type  # obj changed inplace!
679 
codekingpro/portable-devtools · Team Ai