def test_roundtrip(self): # Write data to file fp = memmap(self.tmpfp, dtype=self.dtype, mode='w+', shape=self.shape) fp[:] = self.data[:] del fp # Test __del__ machinery, which handles cleanup # Read data back from file newfp = memmap(self.tmpfp, dtype=self.dtype, mode='r', shape=self.shape) assert_(allclose(self.data, newfp)) assert_array_equal(self.data, newfp) assert_equal(newfp.flags.writeable, False)
def test_getitem(self): fp = memmap(self.tmpfp, dtype=self.dtype, shape=self.shape) fp[:] = self.data assert_(fp[1:, :-1].__class__ is memmap) # Fancy indexing returns a copy that is not memmapped assert_(fp[[0, 1]].__class__ is ndarray)
def test_view(self): fp = memmap(self.tmpfp, dtype=self.dtype, shape=self.shape) new1 = fp.view() new2 = new1.view() assert_(new1.base is fp) assert_(new2.base is fp) new_array = asarray(fp) assert_(new_array.base is fp)
def test_filename(self): tmpname = mktemp('', 'mmap', dir=self.tempdir) fp = memmap(tmpname, dtype=self.dtype, mode='w+', shape=self.shape) abspath = os.path.abspath(tmpname) fp[:] = self.data[:] assert_equal(abspath, fp.filename) b = fp[:1] assert_equal(abspath, b.filename) del b del fp
def test_attributes(self): offset = 1 mode = "w+" fp = memmap(self.tmpfp, dtype=self.dtype, mode=mode, shape=self.shape, offset=offset) assert_equal(offset, fp.offset) assert_equal(mode, fp.mode) del fp
def test_del(self): # Make sure a view does not delete the underlying mmap fp_base = memmap(self.tmpfp, dtype=self.dtype, mode='w+', shape=self.shape) fp_base[0] = 5 fp_view = fp_base[0:1] assert_equal(fp_view[0], 5) del fp_view # Should still be able to access and assign values after # deleting the view assert_equal(fp_base[0], 5) fp_base[0] = 6 assert_equal(fp_base[0], 6)
def test_path(self): tmpname = mktemp('', 'mmap', dir=self.tempdir) fp = memmap(Path(tmpname), dtype=self.dtype, mode='w+', shape=self.shape) # os.path.realpath does not resolve symlinks on Windows # see: https://bugs.python.org/issue9949 # use Path.resolve, just as memmap class does internally abspath = str(Path(tmpname).resolve()) fp[:] = self.data[:] assert_equal(abspath, str(fp.filename.resolve())) b = fp[:1] assert_equal(abspath, str(b.filename.resolve())) del b del fp
def test_ufunc_return_ndarray(self): fp = memmap(self.tmpfp, dtype=self.dtype, shape=self.shape) fp[:] = self.data with suppress_warnings() as sup: sup.filter(FutureWarning, "np.average currently does not preserve") for unary_op in [sum, average, product]: result = unary_op(fp) assert_(isscalar(result)) assert_(result.__class__ is self.data[0, 0].__class__) assert_(unary_op(fp, axis=0).__class__ is ndarray) assert_(unary_op(fp, axis=1).__class__ is ndarray) for binary_op in [add, subtract, multiply]: assert_(binary_op(fp, self.data).__class__ is ndarray) assert_(binary_op(self.data, fp).__class__ is ndarray) assert_(binary_op(fp, fp).__class__ is ndarray) fp += 1 assert (fp.__class__ is memmap) add(fp, 1, out=fp) assert (fp.__class__ is memmap)
def test_unnamed_file(self): with TemporaryFile() as f: fp = memmap(f, dtype=self.dtype, shape=self.shape) del fp
def test_open_with_filename(self): tmpname = mktemp('', 'mmap', dir=self.tempdir) fp = memmap(tmpname, dtype=self.dtype, mode='w+', shape=self.shape) fp[:] = self.data[:] del fp
def test_mmap_offset_greater_than_allocation_granularity(self): size = 5 * mmap.ALLOCATIONGRANULARITY offset = mmap.ALLOCATIONGRANULARITY + 1 fp = memmap(self.tmpfp, shape=size, mode='w+', offset=offset) assert_(fp.offset == offset)
def test_slicing_keeps_references(self): fp = memmap(self.tmpfp, dtype=self.dtype, mode='w+', shape=self.shape) assert_(fp[:2, :2]._mmap is fp._mmap)
def test_indexing_drops_references(self): fp = memmap(self.tmpfp, dtype=self.dtype, mode='w+', shape=self.shape) tmp = fp[(1, 2), (2, 3)] if isinstance(tmp, memmap): assert_(tmp._mmap is not fp._mmap)
def test_arithmetic_drops_references(self): fp = memmap(self.tmpfp, dtype=self.dtype, mode='w+', shape=self.shape) tmp = (fp + 10) if isinstance(tmp, memmap): assert_(tmp._mmap is not fp._mmap)
def test_filename_fileobj(self): fp = memmap(self.tmpfp, dtype=self.dtype, mode="w+", shape=self.shape) assert_equal(fp.filename, self.tmpfp.name)
def test_no_shape(self): self.tmpfp.write(b'a' * 16) mm = memmap(self.tmpfp, dtype='float64') assert_equal(mm.shape, (2, ))
def open_memmap(filename, mode='r+', dtype=None, shape=None, fortran_order=False, version=None): """ Open a .npy file as a memory-mapped array. This may be used to read an existing file or create a new one. Parameters ---------- filename : str The name of the file on disk. This may *not* be a file-like object. mode : str, optional The mode in which to open the file; the default is 'r+'. In addition to the standard file modes, 'c' is also accepted to mean "copy on write." See `memmap` for the available mode strings. dtype : data-type, optional The data type of the array if we are creating a new file in "write" mode, if not, `dtype` is ignored. The default value is None, which results in a data-type of `float64`. shape : tuple of int The shape of the array if we are creating a new file in "write" mode, in which case this parameter is required. Otherwise, this parameter is ignored and is thus optional. fortran_order : bool, optional Whether the array should be Fortran-contiguous (True) or C-contiguous (False, the default) if we are creating a new file in "write" mode. version : tuple of int (major, minor) or None If the mode is a "write" mode, then this is the version of the file format used to create the file. None means use the oldest supported version that is able to store the data. Default: None Returns ------- marray : memmap The memory-mapped array. Raises ------ ValueError If the data or the mode is invalid. IOError If the file is not found or cannot be opened correctly. See Also -------- memmap """ if not isinstance(filename, basestring): raise ValueError("Filename must be a string. Memmap cannot use" " existing file handles.") if 'w' in mode: # We are creating the file, not reading it. # Check if we ought to create the file. _check_version(version) # Ensure that the given dtype is an authentic dtype object rather # than just something that can be interpreted as a dtype object. dtype = numpy1.dtype(dtype) if dtype.hasobject: msg = "Array can't be memory-mapped: Python objects in dtype." raise ValueError(msg) d = dict( descr=dtype_to_descr(dtype), fortran_order=fortran_order, shape=shape, ) # If we got here, then it should be safe to create the file. fp = open(filename, mode + 'b') try: used_ver = _write_array_header(fp, d, version) # this warning can be removed when 1.9 has aged enough if version != (2, 0) and used_ver == (2, 0): warnings.warn( "Stored array in format 2.0. It can only be" "read by NumPy >= 1.9", UserWarning, stacklevel=2) offset = fp.tell() finally: fp.close() else: # Read the header of the file first. fp = open(filename, 'rb') try: version = read_magic(fp) _check_version(version) shape, fortran_order, dtype = _read_array_header(fp, version) if dtype.hasobject: msg = "Array can't be memory-mapped: Python objects in dtype." raise ValueError(msg) offset = fp.tell() finally: fp.close() if fortran_order: order = 'F' else: order = 'C' # We need to change a write-only mode to a read-write mode since we've # already written data to the file. if mode == 'w+': mode = 'r+' marray = numpy1.memmap(filename, dtype=dtype, shape=shape, order=order, mode=mode, offset=offset) return marray
def test_flush(self): fp = memmap(self.tmpfp, dtype=self.dtype, mode='w+', shape=self.shape) fp[:] = self.data[:] assert_equal(fp[0], self.data[0]) fp.flush()