diff --git a/python/python/cwrap/CMakeLists.txt b/python/python/cwrap/CMakeLists.txt index a6b98b1b08..71e5705908 100644 --- a/python/python/cwrap/CMakeLists.txt +++ b/python/python/cwrap/CMakeLists.txt @@ -4,6 +4,7 @@ set(PYTHON_SOURCES basecenum.py basecvalue.py cfile.py + stream.py clib.py metacwrap.py prototype.py diff --git a/python/python/cwrap/__init__.py b/python/python/cwrap/__init__.py index 027cab1f70..c63a461c4b 100644 --- a/python/python/cwrap/__init__.py +++ b/python/python/cwrap/__init__.py @@ -44,9 +44,10 @@ from .cfile import CFILE from .clib import load, lib_name +from .stream import Stream from .metacwrap import MetaCWrap from .prototype import REGISTERED_TYPES, Prototype, PrototypeError __all__ = ['BaseCClass', 'BaseCEnum', 'BaseCValue', 'CFILE', - 'MetaCWrap', 'Prototype', 'load', 'lib_name'] + 'MetaCWrap', 'Prototype', 'load', 'lib_name', 'Stream'] diff --git a/python/python/cwrap/stream.py b/python/python/cwrap/stream.py new file mode 100644 index 0000000000..b250a40e08 --- /dev/null +++ b/python/python/cwrap/stream.py @@ -0,0 +1,182 @@ +# Copyright (C) 2017 Statoil ASA, Norway. +# +# This file is part of ERT - Ensemble based Reservoir Tool. +# +# ERT is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# ERT is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. +# +# See the GNU General Public License at +# for more details. + +from os import linesep +from six import string_types + +import numpy +from .clib import load as cwrapload +from .prototype import Prototype +from .basecclass import BaseCClass + + +class LibcPrototype(Prototype): + lib = cwrapload('libc', '.6') + + def __init__(self, prototype, bind=False): + super(LibcPrototype, self).__init__(LibcPrototype.lib, prototype, bind=bind) + +class Stream(BaseCClass): + """ + Utility class to map a Python file handle <-> FILE* in C + """ + TYPE_NAME = "stream" + + _fopen = LibcPrototype("void* fopen(char*, char*)") + _fread = LibcPrototype("size_t fread(void*, size_t, size_t, stream)") + _fwrite = LibcPrototype("size_t fwrite(void*, size_t, size_t, stream)") + _fseek = LibcPrototype("size_t fseek(stream, size_t, size_t)", bind=True) + + _fclose = LibcPrototype("size_t fclose (stream)", bind=True) + _fflush = LibcPrototype("size_t fflush (stream)", bind=True) + + def __init__(self, fname, mode='r'): + c_ptr = self._fopen(fname, mode) + self._mode = mode + self._fname = fname + + self._closed = False # A closed file cannot be used for further I/O + # operations. close() may be called more than once + # without error. + + try: + super(Stream, self).__init__(c_ptr) + except ValueError as e: + self._closed = True + raise IOError('Could not load file "%s" in mode %s.' % (fname, mode)) + + @property + def closed(self): + return self._closed + + def _assert_open(self): + if self.closed: + raise IOError('Stream is closed: %s' % self) + + def _read_rest_of_file(self): + out = numpy.zeros(0, dtype=numpy.byte) + read = -1 + while read != 0: # num bytes read + bptr = numpy.zeros(1, dtype=numpy.byte) + read = self._fread(bptr.ctypes.data, 1, 1, self) + if read: + out = numpy.append(out, bptr) + return out + + def read(self, size=-1): + """Will read size bytes, or rest of file if size < 0. + + The return type will be iterable, but may be a string or a numpy bytes + array. + + If the file is open in textmode (no 'b'), it will return a string. + """ + self._assert_open() + ret_arr = None + if size < 0: + ret_arr = self._read_rest_of_file() + else: + byte_array = numpy.zeros(size, dtype=numpy.byte) + self._fread(byte_array.ctypes.data, 1, size, self) + ret_arr = byte_array + if self._textmode(): + return ret_arr.tostring() + return ret_arr + + def _is_newline_chr(self, c, sep=None): + if sep is None: + return c == ord(linesep) + return c == ord(sep) + + def readline(self, sep=None): + """ returns string. sep defaults to linesep=\n """ + self._assert_open() + if not self._textmode(): + raise IOError('Warning: reading line from %s in byte mode is nonsensical.' % self) + out = numpy.zeros(0, dtype=numpy.byte) + while True: + bptr = numpy.zeros(1, dtype=numpy.byte) + read = self._fread(bptr.ctypes.data, 1, 1, self) + if read == 0: + break # EOF + out = numpy.append(out, bptr) + if self._is_newline_chr(bptr[0], sep): + break + return out.tostring() + + def readlines(self, sep=None): + return [x for x in self.readline(sep=sep)] + + def __iter__(self): + self._assert_open() + prev = self.readline() + while len(prev) > 0: + yield prev + prev = self.readline() + + def seek(self, offset, whence): + """whence must be one of SEEK_SET, SEEK_CUR, or SEEK_END.""" + self._assert_open() + if self._fseek(offset, whence): + raise IOError("Unable to seek.") + + def _bytemode(self): + return 'b' in self._mode + + def _textmode(self): + return 'b' not in self._mode + + def _writable(self): + return any(m in self._mode for m in 'aw+') + + def write(self, np_arr): + """ @type np_arr: numpy.array """ + if not self._writable(): + raise IOError('Cannot write to file "%s" in mode %s.' % (self._fname, self._mode)) + if self.closed: + raise IOError('File is closed. Cannot write to file "%s".' % self._fname) + + if isinstance(np_arr, string_types): + arr = numpy.zeros(len(np_arr), dtype=numpy.character) + for i in range(len(np_arr)): + arr[i] = np_arr[i] + np_arr = arr + return self._fwrite(np_arr.ctypes.data, 1, len(np_arr), self) + + def close(self): + if not self.closed: + self._fflush() + cs = self._fclose() + self._closed = True + return cs + + def __repr__(self): + cl = ', closed' if self.closed else '' + fmt = 'fname=%s, mode=%s%s' + return self._create_repr(fmt % (self._fname, self._mode, cl)) + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.close() + return exc_type is None + + def free(self): + self.close() + + def __del__(self): + self.close() diff --git a/python/python/ert/ecl/ecl_file.py b/python/python/ert/ecl/ecl_file.py index b50cf38869..32f35fe9c6 100644 --- a/python/python/ert/ecl/ecl_file.py +++ b/python/python/ert/ecl/ecl_file.py @@ -202,7 +202,7 @@ def __init__( self , filename , flags = 0): FIPNUM from an INIT file. """ c_ptr = self._open( filename , flags ) - if c_ptr is None: + if not c_ptr: raise IOError('Failed to open file "%s"' % filename) else: super(EclFile , self).__init__(c_ptr) diff --git a/python/python/ert/ecl/ecl_grid.py b/python/python/ert/ecl/ecl_grid.py index efb0c76d65..0e3a651f6b 100644 --- a/python/python/ert/ecl/ecl_grid.py +++ b/python/python/ert/ecl/ecl_grid.py @@ -23,13 +23,16 @@ implemented in the EclGrid class. The ecl_grid module is a thin wrapper around the ecl_grid.c implementation from the libecl library. """ +from __future__ import absolute_import + import ctypes import numpy import sys import os.path import math -from cwrap import CFILE, BaseCClass +from cwrap import BaseCClass +from cwrap import Stream from ert.util import IntVector from ert.ecl import EclPrototype, EclDataType, EclKW, FortIO, EclUnitTypeEnum @@ -125,24 +128,25 @@ def loadFromGrdecl(cls , filename): faster. """ - if os.path.isfile(filename): - with open(filename) as f: - specgrid = EclKW.read_grdecl(f, "SPECGRID", ecl_type=EclDataType.ECL_INT, strict=False) - zcorn = EclKW.read_grdecl(f, "ZCORN") - coord = EclKW.read_grdecl(f, "COORD") - try: - actnum = EclKW.read_grdecl(f, "ACTNUM", ecl_type=EclDataType.ECL_INT) - except ValueError: - actnum = None - - try: - mapaxes = EclKW.read_grdecl(f, "MAPAXES") - except ValueError: - mapaxes = None - - return EclGrid.create( specgrid , zcorn , coord , actnum , mapaxes ) - else: - raise IOError("No such file:%s" % filename) + if not os.path.isfile(filename): + raise IOError('No such file "%s".' % filename) + + specgrid , zcorn , coord , actnum , mapaxes = None, None, None, None, None + with Stream(filename) as f: + specgrid = EclKW.read_grdecl(f, "SPECGRID", ecl_type=EclTypeEnum.ECL_INT_TYPE, strict=False) + zcorn = EclKW.read_grdecl(f, "ZCORN") + coord = EclKW.read_grdecl(f, "COORD") + try: + actnum = EclKW.read_grdecl(f, "ACTNUM", ecl_type=EclTypeEnum.ECL_INT_TYPE) + except ValueError: + actnum = None + try: + mapaxes = EclKW.read_grdecl(f, "MAPAXES") + except ValueError: + mapaxes = None + if None in (specgrid, zcorn, coord): + raise ValueError('None of (specgrid, zcorn, coord) can be None: was (%s, %s, %s).' % (specgrid,zcorn,coord)) + return EclGrid.create( specgrid , zcorn , coord , actnum , mapaxes ) @classmethod def loadFromFile(cls , filename): @@ -223,7 +227,6 @@ def __init__(self , filename , apply_mapaxes = True): super(EclGrid, self).__init__(c_ptr) else: raise IOError("Loading grid from:%s failed" % filename) - self.__str__ = self.__repr__ def free(self): self._free( ) diff --git a/python/python/ert/ecl/ecl_kw.py b/python/python/ert/ecl/ecl_kw.py index 7678e61dba..250a849d7c 100644 --- a/python/python/ert/ecl/ecl_kw.py +++ b/python/python/ert/ecl/ecl_kw.py @@ -43,8 +43,9 @@ import ctypes import warnings -import numpy -from cwrap import CFILE, BaseCClass +import numpy +from cwrap import BaseCClass +from cwrap import Stream from ert.ecl import EclDataType from ert.ecl import EclTypeEnum, EclUtil, EclPrototype @@ -274,10 +275,12 @@ def read_grdecl( cls , fileH , kw , strict = True , ecl_type = None): it finds in the file. """ - cfile = CFILE( fileH ) - if kw: - if len(kw) > 8: - raise TypeError("Sorry keyword:%s is too long, must be eight characters or less." % kw) + if not isinstance(fileH, Stream): + raise ValueError('Must be a Stream, fileH was a %s.' % type(fileH)) + if kw and len(kw) > 8: + raise TypeError('Sorry keyword "%s" is too long, ' + + 'must be eight characters or less, was %d.' + % (kw, len(kw))) if ecl_type is None: if cls.int_kw_set.__contains__( kw ): @@ -321,8 +324,8 @@ def fseek_grdecl( cls , fileH , kw , rewind = False): true the function rewind to the beginning of the file and search from there after the initial search. """ - cfile = CFILE( fileH ) - return cls._fseek_grdecl( kw , rewind , cfile) + # cfile = CFILE( fileH ) + return cls._fseek_grdecl( kw , rewind , fileH) @classmethod @@ -817,14 +820,18 @@ def equal(self , other): The check is based on the content of the keywords, and not pointer comparison. """ - if isinstance(other , EclKW): + if isinstance(other, EclKW): return self._equal( other ) else: raise TypeError("Can only compare with another EclKW") def __eq__(self , other): - return self.equal( other ) + if other is None: + return False + if isinstance(other, EclKW): + return self.equal(other) + return NotImplemented def __hash__(self): return hash(self._get_header( )) @@ -1049,7 +1056,7 @@ def numpyCopy(self): def fwrite( self , fortio ): self._fwrite( fortio ) - def write_grdecl( self , file ): + def write_grdecl( self , fileH ): """ Will write keyword in GRDECL format. @@ -1071,12 +1078,12 @@ def write_grdecl( self , file ): fileH.close() """ - cfile = CFILE( file ) - self._fprintf_grdecl( cfile ) + # cfile = CFILE( file ) + self._fprintf_grdecl( fileH ) - def fprintf_data( self , file , fmt = None): + def fprintf_data( self , fileH , fmt = None): """ Will print the keyword data formatted to file. @@ -1094,8 +1101,8 @@ def fprintf_data( self , file , fmt = None): """ if fmt is None: fmt = self.str_fmt + "\n" - cfile = CFILE( file ) - self._fprintf_data( fmt , cfile ) + #cfile = CFILE( file ) + self._fprintf_data( fmt , fileH ) def fixUninitialized(self , grid): diff --git a/python/python/ert/ecl/ecl_rft.py b/python/python/ert/ecl/ecl_rft.py index e337a86a59..33100aea0f 100644 --- a/python/python/ert/ecl/ecl_rft.py +++ b/python/python/ert/ecl/ecl_rft.py @@ -69,7 +69,10 @@ class EclRFT(BaseCClass): def __init__(self , name , type_string , date , days): c_ptr = self._alloc( name , type_string , CTime( date ) , days ) - super(EclRFT , self).__init__( c_ptr ) + if c_ptr: + super(EclRFT , self).__init__( c_ptr ) + else: + raise ValueError('Failed to construct EclRFT object from given input.') def free(self): diff --git a/python/python/ert/ecl/ecl_sum.py b/python/python/ert/ecl/ecl_sum.py index d4ad01a5fa..883722ede6 100644 --- a/python/python/ert/ecl/ecl_sum.py +++ b/python/python/ert/ecl/ecl_sum.py @@ -30,7 +30,7 @@ # regarding order of arguments: The C code generally takes the time # index as the first argument and the key/key_index as second # argument. In the python code this order has been reversed. -from cwrap import BaseCClass, CFILE +from cwrap import BaseCClass from ert.ecl import EclSumTStep from ert.ecl import EclSumVarType from ert.ecl.ecl_sum_vector import EclSumVector @@ -154,11 +154,11 @@ def __init__(self, load_case , join_string = ":" , include_restart = True): loader will, in the case of a restarted ECLIPSE simulation, try to load summary results also from the restarted case. """ - c_pointer = self._fread_alloc( load_case , join_string , include_restart) - if c_pointer is None: + c_ptr = self._fread_alloc( load_case , join_string , include_restart) + if not c_ptr: raise IOError("Failed to create summary instance from argument:%s" % load_case) else: - super(EclSum, self).__init__(c_pointer) + super(EclSum, self).__init__(c_ptr) self.__private_init( ) self._load_case = load_case @@ -1208,11 +1208,10 @@ def __repr__(self): def dumpCSVLine(self, time, keywords, pfile): """ Will dump a csv formatted line of the keywords in @keywords, - evaluated at the intertpolated time @time. @pfile should point to an open Python file handle. + evaluated at the intertpolated time @time. @pfile should point to an open Stream. """ - cfile = CFILE(pfile ) ctime = CTime( time ) - EclSum._dump_csv_line(self , ctime, keywords, cfile) + EclSum._dump_csv_line(self , ctime, keywords, pfile) def exportCSV(self , filename , keys = None , date_format = "%Y-%m-%d" , sep = ";"): diff --git a/python/python/ert/ecl/faults/fault_block.py b/python/python/ert/ecl/faults/fault_block.py index d21a94f303..96eb0f4068 100644 --- a/python/python/ert/ecl/faults/fault_block.py +++ b/python/python/ert/ecl/faults/fault_block.py @@ -79,14 +79,15 @@ def __getitem__(self , index): raise TypeError("Index:%s wrong type - integer expected") def __str__(self): - return "Block ID: %d" % self.getBlockID() - + b_id = 'block_id=%d' % self.getBlockID() + return self._create_repr(b_id) def __len__(self): return self._get_size( ) def free(self): - self._free( ) + # TODO no such method self._free( ) + pass def getCentroid(self): xc = self._get_xc( ) diff --git a/python/python/ert/ecl/faults/fault_collection.py b/python/python/ert/ecl/faults/fault_collection.py index 4d03a1d160..4e3eac640a 100644 --- a/python/python/ert/ecl/faults/fault_collection.py +++ b/python/python/ert/ecl/faults/fault_collection.py @@ -17,6 +17,7 @@ from .fault import Fault from ert.ecl import EclGrid +from cwrap import Stream comment_regexp = re.compile("--.*") @@ -62,12 +63,7 @@ def __getitem__(self , index): def __iter__(self): return iter(self.__fault_list) - - - def getGrid(self): - return self.__grid - def getFault(self , name): return self.__getitem__(name) @@ -121,7 +117,7 @@ def loadFaults(self , grid , fileH): def load(self , grid , file_name): - with open(file_name) as fileH: + with Stream(file_name) as fileH: for line in fileH: if line.startswith("FAULTS"): self.loadFaults(grid , fileH) diff --git a/python/python/ert/ecl/faults/layer.py b/python/python/ert/ecl/faults/layer.py index dc91705e43..43d570e850 100644 --- a/python/python/ert/ecl/faults/layer.py +++ b/python/python/ert/ecl/faults/layer.py @@ -23,7 +23,6 @@ class Layer(BaseCClass): TYPE_NAME = "layer" _alloc = EclPrototype("void* layer_alloc(int, int)", bind = False) - _copy = EclPrototype("void layer_memcpy(layer , layer)") _free = EclPrototype("void layer_free(layer)") _get_nx = EclPrototype("int layer_get_nx(layer)") _get_ny = EclPrototype("int layer_get_ny(layer)") @@ -51,13 +50,6 @@ def __init__(self , nx , ny): else: raise ValueError("Invalid input - no Layer object created") - @classmethod - def copy(cls , src): - layer = Layer( src.getNX() , src.getNY()) - self._copy( layer , src ) - return layer - - def __assertIJ(self , i,j): if i < 0 or i >= self.getNX(): raise ValueError("Invalid layer i:%d" % i) diff --git a/python/python/ert/ecl/fortio.py b/python/python/ert/ecl/fortio.py index 2c680f4a9d..352e76b9b7 100644 --- a/python/python/ert/ecl/fortio.py +++ b/python/python/ert/ecl/fortio.py @@ -155,6 +155,8 @@ def seek(self, position, whence=0): # SEEK_END = 2 self._seek(position, whence) + def __repr__(self): + return self._create_repr('filename=%s' % self.filename()) @classmethod def isFortranFile(cls, filename, endian_flip=True): diff --git a/python/python/ert/ecl/rft/well_trajectory.py b/python/python/ert/ecl/rft/well_trajectory.py index adaf2f299c..80e1b5381c 100644 --- a/python/python/ert/ecl/rft/well_trajectory.py +++ b/python/python/ert/ecl/rft/well_trajectory.py @@ -17,41 +17,42 @@ import sys import os from collections import namedtuple +from cwrap import Stream TrajectoryPoint = namedtuple("TrajectoryPoint", "utm_x utm_y measured_depth true_vertical_depth zone") -class WellTrajectory: +class WellTrajectory(object): def __init__(self , filename): - if os.path.isfile(filename): - self.points = [] - with open(filename) as fileH: - for line in fileH.readlines(): - line = line.partition("--")[0] - line = line.strip() - if line: - point = line.split() - if len(point) < 4 or len(point) > 5: - raise UserWarning("Trajectory data file not on correct format: \"utm_x utm_y md tvd [zone]\" - zone is optional") - - try: - utm_x = float(point[0]) - utm_y = float(point[1]) - md = float(point[2]) - tvd = float(point[3]) - if len(point) > 4: - zone = point[4] - else: - zone = None - except ValueError: - raise UserWarning("Error: Failed to extract data from line %s\n" % line) - - self.points.append(TrajectoryPoint(utm_x , utm_y , md , tvd , zone)) - - else: - raise IOError("File not found:%s" % filename) - - + if not os.path.isfile(filename): + raise IOError('No such file "%s".' % filename) + + self.points = [] + with open(filename) as fileH: + for line in fileH: + self._append(line) + + def _append(self, line): + """Appends a content of a TrajectoryPoint line to self.points.""" + line = line.split('--')[0].strip() + if not line: + return + point = line.split() + if len(point) not in (4, 5): + raise UserWarning("Trajectory data file not on correct format: \"utm_x utm_y md tvd [zone]\" - zone is optional") + try: + utm_x = float(point[0]) + utm_y = float(point[1]) + md = float(point[2]) + tvd = float(point[3]) + if len(point) > 4: + zone = point[4] + else: + zone = None + self.points.append(TrajectoryPoint(utm_x , utm_y , md , tvd , zone)) + except ValueError: + raise UserWarning("Warning: Failed to extract data from line %s\n" % line) + def __len__(self): return len(self.points) @@ -61,3 +62,9 @@ def __getitem__(self , index): index += len(self) return self.points[index] + + def __repr__(self): + return repr(self.points) + + def __str__(self): + return str(self.points) diff --git a/python/python/ert/enkf/data/gen_kw.py b/python/python/ert/enkf/data/gen_kw.py index 84bd4ef413..2d11b0dfe1 100644 --- a/python/python/ert/enkf/data/gen_kw.py +++ b/python/python/ert/enkf/data/gen_kw.py @@ -15,7 +15,8 @@ # for more details. import os.path -from cwrap import BaseCClass, CFILE +from cwrap import BaseCClass +from cwrap import Stream from ert.util import DoubleVector from ert.enkf import EnkfPrototype @@ -50,13 +51,12 @@ def __init__(self, gen_kw_config): self.__str__ = self.__repr__ else: raise ValueError('Cannot issue a GenKw from the given keyword config: %s.' % str(gen_kw_config)) - + def exportParameters(self, file_name): """ @type: str """ - with open(file_name , "w") as py_file: - cfile = CFILE( py_file ) - self._export_parameters(cfile) + with Stream(file_name , "w") as stream: + self._export_parameters(stream) def exportTemplate(self, file_name): @@ -113,8 +113,8 @@ def eclWrite(self , path , filename , export_file = None): if not os.path.isdir(path): raise IOError("The directory:%s does not exist" % path) if export_file: - with open(export_file , "w") as fileH: - self._ecl_write(path , filename , CFILE( fileH )) + with Stream(export_file , "w") as fileH: + self._ecl_write(path , filename , fileH) else: self._ecl_write( path , filename , None ) diff --git a/python/python/ert/enkf/export/arg_loader.py b/python/python/ert/enkf/export/arg_loader.py index ffb57dc1c1..f3f64a4129 100644 --- a/python/python/ert/enkf/export/arg_loader.py +++ b/python/python/ert/enkf/export/arg_loader.py @@ -6,15 +6,15 @@ from ert.enkf.plot_data import EnsemblePlotGenData from ert.util import BoolVector - class ArgLoader(object): @staticmethod def load(filename , column_names = None): rows = 0 columns = 0 - with open(filename,"r") as fileH: + with open(filename, "r") as fileH: for line in fileH.readlines(): + print(line) rows += 1 columns = max(columns , len( line.split()) ) @@ -22,7 +22,8 @@ def load(filename , column_names = None): if len(column_names) <= columns: columns = len(column_names) else: - raise ValueError("To many coloumns in input") + raise ValueError("Too many columns (should be at most %d) in input for line '%s'." % + (columns, column_names)) data = numpy.empty(shape=(rows , columns) , dtype=numpy.float64) data.fill( numpy.nan ) diff --git a/python/python/ert/geo/xyz_io.py b/python/python/ert/geo/xyz_io.py index 9f349b339f..760c2c3f59 100644 --- a/python/python/ert/geo/xyz_io.py +++ b/python/python/ert/geo/xyz_io.py @@ -1,5 +1,6 @@ import os from .polyline import Polyline +from cwrap import Stream class XYZIo(object): @@ -14,7 +15,7 @@ def readXYZFile(path): polyline = Polyline(name=name) - with open(path, "r") as f: + with Stream(path, "r") as f: for line in f: line = line.strip() if line: @@ -41,7 +42,7 @@ def readXYFile(path): polyline = Polyline(name=name) - with open(path, "r") as f: + with Stream(path, "r") as f: for line in f: x, y= map(float, line.split()) polyline.addPoint(x, y) @@ -54,7 +55,7 @@ def saveXYFile(polyline , filename): """ @type polyline: Polyline or list of tuple of (float, float) """ - with open(filename , "w") as fileH: + with Stream(filename , "w") as fileH: for p in polyline: fileH.write("%g %g\n" % (p[0] , p[1])) diff --git a/python/python/ert/test/source_enumerator.py b/python/python/ert/test/source_enumerator.py index e0c76300f1..41a3fe3a60 100644 --- a/python/python/ert/test/source_enumerator.py +++ b/python/python/ert/test/source_enumerator.py @@ -1,5 +1,6 @@ import os import re +from cwrap import Stream class SourceEnumerator(object): @@ -12,7 +13,7 @@ def removeComments(cls, code_string): @classmethod def findEnum(cls, enum_name, full_source_file_path): - with open(full_source_file_path, "r") as f: + with Stream(full_source_file_path, "r") as f: text = f.read() text = SourceEnumerator.removeComments(text) diff --git a/python/python/ert/util/matrix.py b/python/python/ert/util/matrix.py index e4ddafea31..06b9cb8629 100644 --- a/python/python/ert/util/matrix.py +++ b/python/python/ert/util/matrix.py @@ -28,7 +28,7 @@ # choice. -from cwrap import BaseCClass,CFILE +from cwrap import BaseCClass from ert.util import UtilPrototype @@ -212,9 +212,9 @@ def fprint(self , fileH , fmt = "%g "): 6 7 8 """ - self._fprint( fmt , CFILE( fileH)) + self._fprint(fmt, fileH) + - def randomInit(self, rng): self._random_init(rng) diff --git a/python/tests/core/ecl/test_ecl_kw.py b/python/tests/core/ecl/test_ecl_kw.py index 4634bf78e4..7ee06a17c0 100644 --- a/python/tests/core/ecl/test_ecl_kw.py +++ b/python/tests/core/ecl/test_ecl_kw.py @@ -22,7 +22,7 @@ from ert.ecl import EclKW, EclDataType, EclTypeEnum, EclFile, FortIO, EclFileFlagEnum , openFortIO from ert.test import ExtendedTestCase , TestAreaContext - +from cwrap import Stream def copy_long(): src = EclKW("NAME", 100, EclDataType.ECL_FLOAT) @@ -73,11 +73,11 @@ def kw_test( self, data_type, data, fmt ): kw[i] = d i += 1 - file1 = open(name1, "w") + file1 = Stream(name1, "w") kw.fprintf_data(file1, fmt) file1.close() - file2 = open(name2, "w") + file2 = Stream(name2, "w") for d in data: file2.write(fmt % d) file2.close() @@ -183,11 +183,11 @@ def test_fprintf_data(self): for i in range(len(kw)): kw[i] = i - fileH = open("test" , "w") + fileH = Stream("test" , "w") kw.fprintf_data( fileH ) fileH.close() - fileH = open("test" , "r") + fileH = Stream("test" , "r") data = [] for line in fileH.readlines(): tmp = line.split() diff --git a/python/tests/core/ecl/test_ecl_sum.py b/python/tests/core/ecl/test_ecl_sum.py index 8e9baf2c76..a0cd4e502f 100644 --- a/python/tests/core/ecl/test_ecl_sum.py +++ b/python/tests/core/ecl/test_ecl_sum.py @@ -16,9 +16,10 @@ # for more details. import datetime import os.path -from cwrap import CFILE -from ert.ecl import EclSum, EclSumKeyWordVector, EclFile,FortIO, openFortIO,openEclFile,EclKW -from ert.test import ExtendedTestCase , TestAreaContext +from cwrap import Stream +from ert.ecl import (EclSum, EclSumKeyWordVector, EclFile,FortIO, openFortIO, + openEclFile, EclKW) +from ert.test import ExtendedTestCase, TestAreaContext class EclSumTest(ExtendedTestCase): @@ -51,7 +52,7 @@ def test_dump_csv_line(self): dtime = datetime.datetime( 2002 , 1 , 1 , 0 , 0 , 0 ) with TestAreaContext("EclSum/csv_dump"): test_file_name = self.createTestPath("dump.csv") - outputH = open(test_file_name , "w") + outputH = Stream(test_file_name , "w") self.ecl_sum.dumpCSVLine( dtime, ecl_sum_vector, outputH) assert os.path.isfile(test_file_name) diff --git a/python/tests/core/ecl/test_fault_blocks.py b/python/tests/core/ecl/test_fault_blocks.py index 1f46ca524f..1995296fb9 100644 --- a/python/tests/core/ecl/test_fault_blocks.py +++ b/python/tests/core/ecl/test_fault_blocks.py @@ -23,6 +23,7 @@ from ert.geo import Polyline , CPolylineCollection from ert.test import ExtendedTestCase , TestAreaContext +from cwrap import Stream class FaultBlockTest(ExtendedTestCase): def setUp(self): @@ -59,7 +60,7 @@ def test_fault_block(self): def test_get_ijk(self): with TestAreaContext("python/fault_block_layer/neighbour") as work_area: - with open("kw.grdecl","w") as fileH: + with Stream("kw.grdecl","w") as fileH: fileH.write("FAULTBLK \n") fileH.write("1 1 1 0 0\n") fileH.write("1 2 2 0 3\n") @@ -68,7 +69,7 @@ def test_get_ijk(self): fileH.write("4 4 4 0 5\n") fileH.write("/\n") - kw = EclKW.read_grdecl(open("kw.grdecl") , "FAULTBLK" , ecl_type = EclDataType.ECL_INT) + kw = EclKW.read_grdecl(Stream("kw.grdecl") , "FAULTBLK" , ecl_type = EclDataType.ECL_INT) grid = EclGrid.createRectangular( (5,5,1) , (1,1,1) ) layer = FaultBlockLayer( grid , 0 ) @@ -91,7 +92,7 @@ def test_get_ijk(self): def test_neighbours(self): with TestAreaContext("python/fault_block_layer/neighbour") as work_area: - with open("kw.grdecl","w") as fileH: + with Stream("kw.grdecl","w") as fileH: fileH.write("FAULTBLK \n") fileH.write("1 1 1 0 0\n") fileH.write("1 2 2 0 3\n") @@ -100,7 +101,7 @@ def test_neighbours(self): fileH.write("4 4 4 0 5\n") fileH.write("/\n") - kw = EclKW.read_grdecl(open("kw.grdecl") , "FAULTBLK" , ecl_type = EclDataType.ECL_INT) + kw = EclKW.read_grdecl(Stream("kw.grdecl") , "FAULTBLK" , ecl_type = EclDataType.ECL_INT) grid = EclGrid.createRectangular( (5,5,1) , (1,1,1) ) layer = FaultBlockLayer( grid , 0 ) @@ -148,7 +149,7 @@ def test_neighbours2(self): grid = EclGrid.createRectangular( (nx , ny , nz) , (1,1,1) ) layer = FaultBlockLayer( grid , 0 ) with TestAreaContext("python/FaultBlocks/neighbours"): - with open("faultblock.grdecl","w") as fileH: + with Stream("faultblock.grdecl","w") as fileH: fileH.write("FAULTBLK \n") fileH.write("1 1 1 1 2 2 2 2 \n") fileH.write("1 1 1 1 2 2 2 2 \n") @@ -160,8 +161,8 @@ def test_neighbours2(self): fileH.write("3 3 3 3 2 2 2 2 \n") fileH.write("/\n") - kw = EclKW.read_grdecl(open("faultblock.grdecl") , "FAULTBLK" , ecl_type = EclDataType.ECL_INT) - with open("faults.grdecl" , "w") as f: + kw = EclKW.read_grdecl(Stream("faultblock.grdecl") , "FAULTBLK" , ecl_type = EclDataType.ECL_INT) + with Stream("faults.grdecl" , "w") as f: f.write("FAULTS\n") f.write("\'FY\' 1 4 4 4 1 1 'Y' /\n") f.write("\'FX\' 4 4 1 8 1 1 'X' /\n") @@ -214,7 +215,7 @@ def test_neighbours3(self): grid = EclGrid.createRectangular( (nx , ny , nz) , (1,1,1) ) layer = FaultBlockLayer( grid , 0 ) with TestAreaContext("python/FaultBlocks/neighbours"): - with open("faultblock.grdecl","w") as fileH: + with Stream("faultblock.grdecl","w") as fileH: fileH.write("FAULTBLK \n") fileH.write("1 1 1 1 2 2 2 2 \n") fileH.write("1 1 1 1 2 2 2 2 \n") @@ -226,8 +227,8 @@ def test_neighbours3(self): fileH.write("1 1 1 1 1 2 2 2 \n") fileH.write("/\n") - kw = EclKW.read_grdecl(open("faultblock.grdecl") , "FAULTBLK" , ecl_type = EclDataType.ECL_INT) - with open("faults.grdecl" , "w") as f: + kw = EclKW.read_grdecl(Stream("faultblock.grdecl") , "FAULTBLK" , ecl_type = EclDataType.ECL_INT) + with Stream("faults.grdecl" , "w") as f: f.write("FAULTS\n") f.write("\'FX\' 4 4 1 4 1 1 'X' /\n") f.write("\'FX\' 5 5 5 8 1 1 'X' /\n") @@ -423,7 +424,7 @@ def test_internal_blocks(self): grid = EclGrid.createRectangular( (nx , ny , nz) , (1,1,1) ) layer = FaultBlockLayer( grid , 0 ) with TestAreaContext("python/FaultBlocks/internal_blocks"): - with open("faultblock.grdecl","w") as fileH: + with Stream("faultblock.grdecl","w") as fileH: fileH.write("FAULTBLK \n") fileH.write("1 1 1 1 2 2 2 2 \n") fileH.write("1 4 4 1 2 5 5 2 \n") @@ -436,8 +437,8 @@ def test_internal_blocks(self): fileH.write("/\n") - kw = EclKW.read_grdecl(open("faultblock.grdecl") , "FAULTBLK" , ecl_type = EclDataType.ECL_INT) - with open("faults.grdecl" , "w") as f: + kw = EclKW.read_grdecl(Stream("faultblock.grdecl") , "FAULTBLK" , ecl_type = EclDataType.ECL_INT) + with Stream("faults.grdecl" , "w") as f: f.write("FAULTS\n") f.write("\'FX\' 4 4 1 4 1 1 'X' /\n") f.write("\'FX\' 5 5 4 4 1 1 'Y' /\n") diff --git a/python/tests/core/ecl/test_fault_blocks_statoil.py b/python/tests/core/ecl/test_fault_blocks_statoil.py index 9c7d88f7f8..e2875fb8f0 100644 --- a/python/tests/core/ecl/test_fault_blocks_statoil.py +++ b/python/tests/core/ecl/test_fault_blocks_statoil.py @@ -23,11 +23,13 @@ from ert.test import ExtendedTestCase from ert.ecl.faults import FaultBlock, FaultBlockLayer +from cwrap import Stream + class FaultBlockTest(ExtendedTestCase): def setUp(self): self.grid = EclGrid( self.createTestPath("Statoil/ECLIPSE/Mariner/MARINER.EGRID")) - fileH = open( self.createTestPath("Statoil/ECLIPSE/Mariner/faultblock.grdecl") ) - self.kw = EclKW.read_grdecl( fileH , "FAULTBLK" , ecl_type = EclDataType.ECL_INT ) + fileH = Stream( self.createTestPath("Statoil/ECLIPSE/Mariner/faultblock.grdecl") ) + self.kw = EclKW.read_grdecl( fileH , "FAULTBLK" , ecl_type = EclDataType.ECL_INT) diff --git a/python/tests/core/ecl/test_faults.py b/python/tests/core/ecl/test_faults.py index 0a2f1873a7..42e20e1425 100644 --- a/python/tests/core/ecl/test_faults.py +++ b/python/tests/core/ecl/test_faults.py @@ -23,7 +23,7 @@ from ert.ecl import EclGrid, EclKW, EclDataType from ert.test import ExtendedTestCase, TestAreaContext from ert.geo import Polyline , CPolyline - +from cwrap import Stream class FaultTest(ExtendedTestCase): @classmethod @@ -502,7 +502,7 @@ def test_fault_line_order(self): nz = 43 grid = EclGrid.createRectangular( (nx , ny , nz) , (1,1,1) ) with TestAreaContext("python/faults/line_order"): - with open("faults.grdecl" , "w") as f: + with Stream("faults.grdecl" , "w") as f: f.write("""FAULTS \'F\' 105 107 50 50 1 43 \'Y\' / \'F\' 108 108 50 50 1 43 \'X\' / @@ -644,7 +644,7 @@ def test_num_linesegment(self): nz = 1 grid = EclGrid.createRectangular( (nx , ny , nz) , (1,1,1) ) with TestAreaContext("python/faults/line_order"): - with open("faults.grdecl" , "w") as f: + with Stream("faults.grdecl" , "w") as f: f.write("""FAULTS \'F1\' 1 4 2 2 1 1 \'Y\' / \'F1\' 6 8 2 2 1 1 \'Y\' / diff --git a/python/tests/core/ecl/test_fortio.py b/python/tests/core/ecl/test_fortio.py index 9ef02be191..2a6071810c 100755 --- a/python/tests/core/ecl/test_fortio.py +++ b/python/tests/core/ecl/test_fortio.py @@ -19,7 +19,7 @@ from ert.ecl import FortIO, EclDataType, EclKW , openFortIO, EclFile from ert.test import ExtendedTestCase, TestAreaContext - +from cwrap import Stream class FortIOTest(ExtendedTestCase): @@ -132,7 +132,7 @@ def test_is_fortran_file(self): with openFortIO("fortran_file" , mode = FortIO.WRITE_MODE) as f: kw1.fwrite( f ) - with open("text_file" , "w") as f: + with Stream("text_file" , "w") as f: kw1.write_grdecl( f ) self.assertTrue( FortIO.isFortranFile( "fortran_file" )) diff --git a/python/tests/core/ecl/test_grdecl.py b/python/tests/core/ecl/test_grdecl.py index 3ff4f63b01..57a419ebb9 100755 --- a/python/tests/core/ecl/test_grdecl.py +++ b/python/tests/core/ecl/test_grdecl.py @@ -19,7 +19,7 @@ from ert.ecl import EclKW,EclGrid,Ecl3DKW from ert.test import ExtendedTestCase - +from cwrap import Stream @@ -38,29 +38,29 @@ def tearDown(self): def test_Load( self ): - kw = EclKW.read_grdecl(open(self.src_file, "r"), "PERMX") + kw = EclKW.read_grdecl(Stream(self.src_file, "r"), "PERMX") self.assertTrue(kw) grid = EclGrid( self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE" )) - kw = Ecl3DKW.read_grdecl(grid , open(self.src_file, "r"), "PERMX") + kw = Ecl3DKW.read_grdecl(grid , Stream(self.src_file, "r"), "PERMX") self.assertTrue( isinstance( kw , Ecl3DKW )) def test_reload( self ): - kw = EclKW.read_grdecl(open(self.src_file, "r"), "PERMX") + kw = EclKW.read_grdecl(Stream(self.src_file, "r"), "PERMX") tmp_file1 = "/tmp/permx1.grdecl" tmp_file2 = "/tmp/permx2.grdecl" self.addFile(tmp_file1) self.addFile(tmp_file2) - fileH = open(tmp_file1, "w") + fileH = Stream(tmp_file1, "w") kw.write_grdecl(fileH) fileH.close() - kw1 = EclKW.read_grdecl(open(tmp_file1, "r"), "PERMX") + kw1 = EclKW.read_grdecl(Stream(tmp_file1, "r"), "PERMX") - fileH = open(tmp_file2, "w") + fileH = Stream(tmp_file2, "w") kw1.write_grdecl(fileH) fileH.close() @@ -68,12 +68,12 @@ def test_reload( self ): def test_fseek( self ): - file = open(self.src_file, "r") + file = Stream(self.src_file, "r") self.assertTrue(EclKW.fseek_grdecl(file, "PERMX")) self.assertFalse(EclKW.fseek_grdecl(file, "PERMY")) file.close() - file = open(self.src_file, "r") + file = Stream(self.src_file, "r") kw1 = EclKW.read_grdecl(file, "PERMX") self.assertFalse(EclKW.fseek_grdecl(file, "PERMX")) self.assertTrue(EclKW.fseek_grdecl(file, "PERMX", rewind=True)) @@ -83,7 +83,7 @@ def test_fseek( self ): def test_fseek2(self): test_src = self.createTestPath("local/ECLIPSE/grdecl-test/test.grdecl") # Test kw at the the very start - file = open(test_src, "r") + file = Stream(test_src, "r") self.assertTrue(EclKW.fseek_grdecl(file, "PERMX")) # Test commented out kw: @@ -105,7 +105,7 @@ def test_fseek2(self): def test_fseek_dos(self): test_src = self.createTestPath("local/ECLIPSE/grdecl-test/test.grdecl_dos") # File formatted with \r\n line endings. # Test kw at the the very start - file = open(test_src, "r") + file = Stream(test_src, "r") self.assertTrue(EclKW.fseek_grdecl(file, "PERMX")) # Test commented out kw: diff --git a/python/tests/core/ecl/test_grid_statoil.py b/python/tests/core/ecl/test_grid_statoil.py index 920cdaa95b..dbf2ca99cc 100755 --- a/python/tests/core/ecl/test_grid_statoil.py +++ b/python/tests/core/ecl/test_grid_statoil.py @@ -25,7 +25,7 @@ from ert.ecl import EclDataType, EclKW, EclGrid, EclFile, openEclFile from ert.util import DoubleVector, IntVector from ert.test import ExtendedTestCase , TestAreaContext - +from cwrap import Stream class GridTest(ExtendedTestCase): def egrid_file(self): @@ -115,7 +115,7 @@ def test_EGRID( self ): def create(self, filename, load_actnum=True): - fileH = open(filename, "r") + fileH = Stream(filename, "r") specgrid = EclKW.read_grdecl(fileH, "SPECGRID", ecl_type=EclDataType.ECL_INT, strict=False) zcorn = EclKW.read_grdecl(fileH, "ZCORN") coord = EclKW.read_grdecl(fileH, "COORD") @@ -170,7 +170,7 @@ def test_grdecl_load(self): grid = EclGrid.loadFromGrdecl("/file/does/not/exists") with TestAreaContext("python/grid-test/grdeclLoad"): - with open("grid.grdecl","w") as f: + with Stream("grid.grdecl","w") as f: f.write("Hei ...") with self.assertRaises(ValueError): @@ -183,7 +183,7 @@ def test_grdecl_load(self): g1.save_EGRID("G.EGRID") with openEclFile("G.EGRID") as f: - with open("grid.grdecl" , "w") as f2: + with Stream("grid.grdecl" , "w") as f2: f2.write("SPECGRID\n") f2.write(" 10 10 10 \'F\' /\n") @@ -227,7 +227,7 @@ def test_save(self): g2 = EclGrid("test.GRID") self.assertTrue(g1.equal(g2)) - fileH = open("test.grdecl", "w") + fileH = Stream("test.grdecl", "w") g1.save_grdecl(fileH) fileH.close() g2 = self.create("test.grdecl") diff --git a/python/tests/core/ecl/test_statoil_faults.py b/python/tests/core/ecl/test_statoil_faults.py index 0804a9e41a..53397f0ba7 100644 --- a/python/tests/core/ecl/test_statoil_faults.py +++ b/python/tests/core/ecl/test_statoil_faults.py @@ -23,13 +23,13 @@ from ert.ecl.faults import FaultCollection, Fault, FaultLine, FaultSegment from ert.ecl import EclGrid, EclKW, EclDataType from ert.test import ExtendedTestCase - +from cwrap import Stream class StatoilFaultTest(ExtendedTestCase): def loadGrid(self): grid_file = self.createTestPath("Statoil/ECLIPSE/Faults/grid.grdecl") - fileH = open(grid_file, "r") + fileH = Stream(grid_file, "r") specgrid = EclKW.read_grdecl(fileH, "SPECGRID", ecl_type=EclDataType.ECL_INT, strict=False) zcorn = EclKW.read_grdecl(fileH, "ZCORN") coord = EclKW.read_grdecl(fileH, "COORD") diff --git a/python/tests/core/util/test_matrix.py b/python/tests/core/util/test_matrix.py index d5b6a626d1..cfb27443ac 100644 --- a/python/tests/core/util/test_matrix.py +++ b/python/tests/core/util/test_matrix.py @@ -1,3 +1,5 @@ +from cwrap import Stream + from ert.util import Matrix , RandomNumberGenerator from ert.util.enums import RngAlgTypeEnum, RngInitModeEnum from ert.test import ExtendedTestCase, TestAreaContext @@ -108,14 +110,16 @@ def test_str(self): m[0,1] = 1 m[1,0] = 2 m[1,1] = 3 - - with TestAreaContext("matrix_fprint"): - with open("matrix.txt", "w") as f: - m.fprint( f ) - with open("matrix.txt") as f: - l1 = [ float(x) for x in f.readline().split()] - l2 = [ float(x) for x in f.readline().split()] + with TestAreaContext("matrix_fprint"): + fout = Stream("matrix.txt", "w") + m.fprint(fout) + fout.close() + + fin = Stream("matrix.txt") + l1 = [ float(x) for x in fin.readline().split()] + l2 = [ float(x) for x in fin.readline().split()] + fin.close() self.assertEqual( l1[0] , m[0,0]) self.assertEqual( l1[1] , m[0,1]) diff --git a/python/tests/cwrap/CMakeLists.txt b/python/tests/cwrap/CMakeLists.txt index 0f9355a5c4..acd658b17a 100644 --- a/python/tests/cwrap/CMakeLists.txt +++ b/python/tests/cwrap/CMakeLists.txt @@ -5,6 +5,7 @@ set(TEST_SOURCES test_basecvalue.py test_metawrap.py test_cfile.py + test_stream.py ) add_python_package("python.tests.core.cwrap" ${PYTHON_INSTALL_PREFIX}/tests/core/cwrap "${TEST_SOURCES}" False) @@ -14,4 +15,4 @@ addPythonTest(core.cwrap.basecenum tests.core.cwrap.test_basecenum.BaseCEnumTest addPythonTest(core.cwrap.basecvalue tests.core.cwrap.test_basecvalue.BaseCValueTest) addPythonTest(core.cwrap.metacwrap tests.core.cwrap.test_metawrap.MetaWrapTest) addPythonTest(core.cwrap.cfile tests.core.cwrap.test_cfile.CFILETest) - +addPythonTest(core.cwrap.stream tests.core.cwrap.test_stream.StreamTest) diff --git a/python/tests/cwrap/test_stream.py b/python/tests/cwrap/test_stream.py new file mode 100644 index 0000000000..a625bb6d34 --- /dev/null +++ b/python/tests/cwrap/test_stream.py @@ -0,0 +1,135 @@ +from cwrap import Stream +from ert.test import ExtendedTestCase +from ert.test.test_area import TestAreaContext + +import numpy as np + + +class StreamTest(ExtendedTestCase): + + def test_init(self): + with TestAreaContext("stream_tests") as test_area: + with open('outintest', 'w') as f: + f.write('dag og tid\nnatt og dag\n') + s = Stream('outintest', 'r') + self.assertEqual('dag og tid\n', s.readline()) + + def test_write(self): + with TestAreaContext("stream_tests") as test_area: + out = Stream('writetest', 'w') + out.write('one two three') + out.close() + inp = Stream('writetest', 'r') + self.assertEqual('one tw', inp.read(6)) + + with self.assertRaises(IOError): + inp.write('stream is not writable') + + with self.assertRaises(IOError): + out.write('stream is closed!') + + def test_closed(self): + with TestAreaContext("stream_tests_closed1") as test_area: + out = Stream('closetest', 'w') + self.assertFalse(out.closed) + out.close() + self.assertTrue(out.closed) + out.close() + self.assertTrue(out.closed) + with TestAreaContext("stream_tests_closed2") as test_area: + with Stream('closetest2', 'w') as s: + self.assertFalse(s.closed) + self.assertTrue(s.closed) + + def test_nosuchfile(self): + with TestAreaContext("stream_tests_nsf") as test_area: + with self.assertRaises(IOError): + Stream('nosuchfile.abc', 'r') + + def test_readlines(self): + with TestAreaContext("stream_tests_rls") as test_area: + out = Stream('writelinetest', 'w') + out.write('myline1\nandline2\nfinalline3\n') + out.close() + inp = Stream('writelinetest', 'r') + self.assertEqual('myline1\n', inp.readline()) + self.assertEqual('andline2\n', inp.readline()) + self.assertEqual('finalline3\n', inp.readline()) + self.assertEqual('', inp.readline()) + self.assertEqual('', inp.readline()) + self.assertEqual('', inp.readline()) + + + def test_yield(self): + cnt = ['line 1\n', 'LINE 2\n', 'finalline\n'] + with TestAreaContext("stream_tests_yield") as test_area: + with open('writeyield', 'w') as f: + for x in cnt: + f.write('%s' % x) + + inp = Stream('writeyield', 'r') + c = 0 + for line in inp: + self.assertEqual(cnt[c], line) + c += 1 + self.assertFalse(inp.closed) + inp.close() + self.assertTrue(inp.closed) + + def test_with_file_stream(self): + with TestAreaContext("stream_tests_with_fs") as test_area: + with open('writewith', 'w') as s: + s.write('testing ```with``` syntax') + with Stream('writewith', 'r') as s: + l = s.readline() + self.assertEqual('testing ```with``` syntax', l) + + def test_with_stream_file(self): + with TestAreaContext("stream_tests_with_sf") as test_area: + with Stream('writewith', 'w') as s: + s.write('testing ```with``` syntax') + with open('writewith', 'r') as s: + l = s.readline() + self.assertEqual('testing ```with``` syntax', l) + l = s.readline() + self.assertEqual('', l) + + def test_bytes(self): + def generate_data(size = 100): + san = lambda x: max(0, min(127, abs(x))) + data = np.zeros(size, dtype=np.byte) + for i in range(size): + data[i] = san(127-i) + return data + + with TestAreaContext("stream_tests") as test_area: + data = generate_data() + read = None + + with Stream('writebytes', 'wb') as s_out: + w_ret = s_out.write(data) + self.assertEqual(w_ret, 100) + self.assertFalse(s_out.closed) + self.assertTrue(s_out.closed) + + with Stream('writebytes', 'rb') as s_in: + read = s_in.read() + + for i in range(100): + self.assertEqual(data[i], read[i]) + self.assertEqual(100, len(read)) + self.assertEqual(len(data), len(read)) + + def test_contextmanager_exception(self): + # testing that exceptions in with still closes the file + with TestAreaContext("test_contextmanager_exception") as test_area: + fname = 'expectexcept' + with self.assertRaises(IOError): + with Stream(fname, 'w') as s: + s.write('yes!\n') + raise IOError('bloody hell!') + self.assertTrue(s.closed) + content = '' + with Stream(fname, 'r') as inp: + content = inp.readline() + self.assertEquals('yes!\n', content) diff --git a/python/tests/ert/config/test_config.py b/python/tests/ert/config/test_config.py index a58507cd34..c697e25c20 100755 --- a/python/tests/ert/config/test_config.py +++ b/python/tests/ert/config/test_config.py @@ -16,9 +16,12 @@ # for more details. import os -import ert -from ert.config import ContentTypeEnum, UnrecognizedEnum, SchemaItem, ContentItem, ContentNode, ConfigParser, ConfigContent,ConfigSettings from cwrap import Prototype, clib +from cwrap import Stream +import ert +from ert.config import (ContentTypeEnum, UnrecognizedEnum, SchemaItem, + ContentItem, ContentNode, ConfigParser, ConfigContent, + ConfigSettings) from ert.test import ExtendedTestCase, TestAreaContext @@ -51,7 +54,7 @@ def test_enums(self): def test_item_types(self): with TestAreaContext("config/types") as test_area: - with open("config" , "w") as f: + with Stream("config" , "w") as f: f.write("TYPE_ITEM 10 3.14 TruE String file\n") conf = ConfigParser() @@ -127,7 +130,7 @@ def test_parse_invalid(self): conf = ConfigParser() conf.add("INT", value_type = ContentTypeEnum.CONFIG_INT ) with TestAreaContext("config/parse2"): - with open("config","w") as fileH: + with Stream("config","w") as fileH: fileH.write("INT xx\n") with self.assertRaises(ValueError): @@ -144,7 +147,7 @@ def test_parse_deprecated(self): msg = "ITEM INT IS DEPRECATED" item.setDeprecated( msg ) with TestAreaContext("config/parse2"): - with open("config","w") as fileH: + with Stream("config","w") as fileH: fileH.write("INT 100\n") content = conf.parse("config" ) @@ -165,10 +168,10 @@ def test_parse_dotdot_relative(self): os.makedirs("cwd/jobs") os.makedirs("eclipse/bin") script_path = os.path.join( os.getcwd() , "eclipse/bin/script.sh") - with open(script_path,"w") as f: + with Stream(script_path,"w") as f: f.write("This is a test script") - with open("cwd/jobs/JOB","w") as fileH: + with Stream("cwd/jobs/JOB","w") as fileH: fileH.write("EXECUTABLE ../../eclipse/bin/script.sh\n") os.makedirs("cwd/ert") @@ -194,7 +197,7 @@ def test_parser_content(self): with TestAreaContext("config/parse2"): - with open("config","w") as fileH: + with Stream("config","w") as fileH: fileH.write("KEY VALUE1 VALUE2 100 True 3.14 path/file.txt\n") cwd0 = os.getcwd( ) @@ -317,7 +320,7 @@ def test_settings(self): with TestAreaContext("config/parse3"): - with open("config","w") as fileH: + with Stream("config","w") as fileH: fileH.write("SETTINGS A 100\n") fileH.write("SETTINGS B 200\n") fileH.write("SETTINGS C 300\n") @@ -346,7 +349,7 @@ def test_settings(self): cs.initParser( parser ) with TestAreaContext("config/parse4"): - with open("config","w") as fileH: + with Stream("config","w") as fileH: fileH.write("SETTINGS A 100.1\n") fileH.write("SETTINGS B 200\n") fileH.write("SETTINGS C 300\n") diff --git a/python/tests/ert/enkf/data/test_gen_kw.py b/python/tests/ert/enkf/data/test_gen_kw.py index 63716dfffc..3665849556 100644 --- a/python/tests/ert/enkf/data/test_gen_kw.py +++ b/python/tests/ert/enkf/data/test_gen_kw.py @@ -1,4 +1,5 @@ import os.path +from cwrap import Stream from ert.enkf.data import GenKw from ert.enkf.config import GenKwConfig from ert.test import TestAreaContext, ExtendedTestCase @@ -7,12 +8,12 @@ def create_gen_kw(): parameter_file ="MULTFLT.txt" template_file ="MULTFLT.tmpl" - with open(parameter_file, "w") as f: + with Stream(parameter_file, "w") as f: f.write("MULTFLT1 NORMAL 0 1\n") f.write("MULTFLT2 RAW \n") f.write("MULTFLT3 NORMAL 0 1\n") - with open(template_file, "w") as f: + with Stream(template_file, "w") as f: f.write(" \n") f.write("/\n") diff --git a/python/tests/ert/enkf/export/test_arg_loader.py b/python/tests/ert/enkf/export/test_arg_loader.py index 58e510271c..cbfedf3bcd 100644 --- a/python/tests/ert/enkf/export/test_arg_loader.py +++ b/python/tests/ert/enkf/export/test_arg_loader.py @@ -12,13 +12,11 @@ def test_arg_loader(self): arg = ArgLoader.load("arg1X") arg_file = self.createTestPath("Statoil/config/with_GEN_DATA_RFT/wellpath/WI_1.txt") - + with self.assertRaises(ValueError): - arg = ArgLoader.load(arg_file , column_names = ["Col1" , "Col2" , "Col3" ,"COl5" , "Col6"]) + arg = ArgLoader.load(arg_file, column_names=["Col1", "Col2", "Col3", + "COl5", "Col6"]) - arg = ArgLoader.load(arg_file , column_names = ["utm_x" , "utm_y" , "md" , "tvd"]) - self.assertFloatEqual( arg["utm_x"][0] , 461317.620646) - - + arg = ArgLoader.load(arg_file, column_names=["utm_x", "utm_y", "md", "tvd"]) - + self.assertFloatEqual(arg["utm_x"][0], 461317.620646) diff --git a/python/tests/ert/job_queue/workflow_common.py b/python/tests/ert/job_queue/workflow_common.py index 564c934ebc..a10b7d03b0 100644 --- a/python/tests/ert/job_queue/workflow_common.py +++ b/python/tests/ert/job_queue/workflow_common.py @@ -1,11 +1,12 @@ import os import stat +from cwrap import Stream class WorkflowCommon(object): @staticmethod def createExternalDumpJob(): - with open("dump_job", "w") as f: + with Stream("dump_job", "w") as f: f.write("INTERNAL FALSE\n") f.write("EXECUTABLE dump.py\n") f.write("MIN_ARG 2\n") @@ -13,7 +14,7 @@ def createExternalDumpJob(): f.write("ARG_TYPE 0 STRING\n") - with open("dump.py", "w") as f: + with Stream("dump.py", "w") as f: f.write("#!/usr/bin/env python\n") f.write("import sys\n") f.write("f = open('%s' % sys.argv[1], 'w')\n") @@ -23,21 +24,21 @@ def createExternalDumpJob(): st = os.stat("dump.py") os.chmod("dump.py", st.st_mode | stat.S_IEXEC) # | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH - with open("dump_workflow", "w") as f: + with Stream("dump_workflow", "w") as f: f.write("DUMP dump1 dump_text_1\n") f.write("DUMP dump2 dump__2\n") @staticmethod def createInternalFunctionJob(): - with open("select_case_job", "w") as f: + with Stream("select_case_job", "w") as f: f.write("INTERNAL True\n") f.write("FUNCTION enkf_main_select_case_JOB\n") f.write("MIN_ARG 1\n") f.write("MAX_ARG 1\n") f.write("ARG_TYPE 0 STRING\n") - with open("printf_job", "w") as f: + with Stream("printf_job", "w") as f: f.write("INTERNAL True\n") f.write("FUNCTION printf\n") f.write("MIN_ARG 4\n") @@ -49,7 +50,7 @@ def createInternalFunctionJob(): f.write("ARG_TYPE 4 STRING\n") - with open("compare_job", "w") as f: + with Stream("compare_job", "w") as f: f.write("INTERNAL True\n") f.write("FUNCTION strcmp\n") f.write("MIN_ARG 2\n") @@ -60,7 +61,7 @@ def createInternalFunctionJob(): @staticmethod def createErtScriptsJob(): - with open("subtract_script.py", "w") as f: + with Stream("subtract_script.py", "w") as f: f.write("from ert.job_queue import ErtScript\n") f.write("\n") f.write("class SubtractScript(ErtScript):\n") @@ -68,7 +69,7 @@ def createErtScriptsJob(): f.write(" return arg1 - arg2\n") - with open("subtract_script_job", "w") as f: + with Stream("subtract_script_job", "w") as f: f.write("INTERNAL True\n") f.write("SCRIPT subtract_script.py\n") f.write("MIN_ARG 2\n") @@ -79,7 +80,7 @@ def createErtScriptsJob(): @staticmethod def createWaitJob(): - with open("wait_job.py", "w") as f: + with Stream("wait_job.py", "w") as f: f.write("from ert.job_queue import ErtScript\n") f.write("import time\n") f.write("\n") @@ -104,7 +105,7 @@ def createWaitJob(): f.write(" return None\n") - with open("external_wait_job.sh", "w") as f: + with Stream("external_wait_job.sh", "w") as f: f.write("#!/usr/bin/env bash\n") f.write("echo \"text\" > wait_started_$1\n") f.write("sleep $2\n") @@ -113,7 +114,7 @@ def createWaitJob(): st = os.stat("external_wait_job.sh") os.chmod("external_wait_job.sh", st.st_mode | stat.S_IEXEC) # | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH - with open("wait_job", "w") as f: + with Stream("wait_job", "w") as f: f.write("INTERNAL True\n") f.write("SCRIPT wait_job.py\n") f.write("MIN_ARG 2\n") @@ -121,7 +122,7 @@ def createWaitJob(): f.write("ARG_TYPE 0 INT\n") f.write("ARG_TYPE 1 INT\n") - with open("external_wait_job", "w") as f: + with Stream("external_wait_job", "w") as f: f.write("INTERNAL False\n") f.write("EXECUTABLE external_wait_job.sh\n") f.write("MIN_ARG 2\n") @@ -130,11 +131,11 @@ def createWaitJob(): f.write("ARG_TYPE 1 INT\n") - with open("wait_workflow", "w") as f: + with Stream("wait_workflow", "w") as f: f.write("WAIT 0 1\n") f.write("WAIT 1 10\n") f.write("WAIT 2 1\n") - with open("fast_wait_workflow", "w") as f: + with Stream("fast_wait_workflow", "w") as f: f.write("WAIT 0 1\n") f.write("EXTERNAL_WAIT 1 1\n")