def _side_effect(self, *args): """ Check args of gwyfile_object_graphmodel_get func and write self.curves_array in 'curves' field """ # first arg is GwyDatafield returned by get_gwyitem_object self.assertEqual(args[0], self.gwygraphmodel) # second arg is GwyfileError** assert ffi.typeof(args[1]) == ffi.typeof(ffi.new("GwyfileError**")) # last arg in Null self.assertEqual(args[-1], ffi.NULL) # combine fields names and fields pointers in one dictionary arg_keys = [ffi.string(key).decode('utf-8') for key in args[2:-1:2]] arg_pointers = [pointer for pointer in args[3:-1:2]] arg_dict = dict(zip(arg_keys, arg_pointers)) arg_dict['curves'][0] = self.curves_array # C func returns true if the graphmodel object loock acceptable truep = ffi.new("bool*", True) return truep[0]
def __init__(self, c_gwyfile): """ Args: c_gwyfile (cdata GwyfileOjbect*): gwyfile object from Libgwyfile C library The top-level object of the c_gwyfile must be 'GwyContainer' """ if not c_gwyfile: raise GwyfileError("c_gwyfile object is empty") c_toplevel_object_name = lib.gwyfile_object_name(c_gwyfile) if c_toplevel_object_name: toplevel_object_name = ffi.string(c_toplevel_object_name) else: error_msg = 'The top-level object of c_gwyfile is empty' raise GwyfileError(error_msg) if not toplevel_object_name == b'GwyContainer': error_msg = 'The top-level object of c_gwyfile is not ' \ ' a GwyContainer' raise GwyfileError(error_msg) self.c_gwyfile = c_gwyfile
def _get_meta(gwycurve): """ Get metadata from <GwyGraphCurveModel*> object Args: curve (GwyfileObject*): GwyGraphCurveModel object Returns: metadata (dict): GwyGraphCurveModel metadaat """ error = ffi.new("GwyfileError*") errorp = ffi.new("GwyfileError**", error) ndatap = ffi.new("int32_t*") descriptionp = ffi.new("char**") typep = ffi.new("int32_t*") point_typep = ffi.new("int32_t*") line_stylep = ffi.new("int32_t*") point_sizep = ffi.new("int32_t*") line_sizep = ffi.new("int32_t*") color_redp = ffi.new("double*") color_greenp = ffi.new("double*") color_bluep = ffi.new("double*") metadata = {} if not lib.gwyfile_object_graphcurvemodel_get( gwycurve, errorp, ffi.new('char[]', b'ndata'), ndatap, ffi.new('char[]', b'description'), descriptionp, ffi.new('char[]', b'type'), typep, ffi.new('char[]', b'point_type'), point_typep, ffi.new('char[]', b'line_style'), line_stylep, ffi.new('char[]', b'point_size'), point_sizep, ffi.new('char[]', b'line_size'), line_sizep, ffi.new('char[]', b'color.red'), color_redp, ffi.new('char[]', b'color.green'), color_greenp, ffi.new('char[]', b'color.blue'), color_bluep, ffi.NULL): raise GwyfileErrorCMsg(errorp[0].message) else: metadata['ndata'] = ndatap[0] if descriptionp[0]: description = ffi.string(descriptionp[0]).decode('utf-8') metadata['description'] = description else: metadata['description'] = '' metadata['type'] = typep[0] metadata['point_type'] = point_typep[0] metadata['line_style'] = line_stylep[0] metadata['point_size'] = point_sizep[0] metadata['line_size'] = line_sizep[0] metadata['color.red'] = color_redp[0] metadata['color.green'] = color_greenp[0] metadata['color.blue'] = color_bluep[0] return metadata
def _get_points_side_effect(self, *args): """ Write self.cpoints in 'data' field and return True """ # combine fields names and fields pointers in one dictionary arg_keys = [ffi.string(key).decode('utf-8') for key in args[2:-1:2]] arg_pointers = [pointer for pointer in args[3:-1:2]] arg_dict = dict(zip(arg_keys, arg_pointers)) arg_dict['data'][0] = self.cpoints # Function should return True if object looks acceptable truep = ffi.new("bool*", True) return truep[0]
def _test_returned_value(self, *args): """Write self.nsel in 'nsel' and return True """ # combine fields names and fields pointers in one dictionary arg_keys = [ffi.string(key).decode('utf-8') for key in args[2:-1:2]] arg_pointers = [pointer for pointer in args[3:-1:2]] arg_dict = dict(zip(arg_keys, arg_pointers)) arg_dict['nsel'][0] = self.nsel # Function should return True if object looks acceptable truep = ffi.new("bool*", True) return truep[0]
def _side_effect_return_metadata(self, *args): arg_keys = [ffi.string(key).decode('utf-8') for key in args[2:-1:2]] arg_pointers = [pointer for pointer in args[3:-1:2]] arg_dict = dict(zip(arg_keys, arg_pointers)) for key in arg_dict: if key not in ['si_unit_xy', 'si_unit_z']: arg_dict[key][0] = self.test_metadata_dict[key] else: metadata_value = self.test_metadata_dict[key].encode('utf-8') metadata_c_str = ffi.new("char[]", metadata_value) arg_dict[key][0] = metadata_c_str return self.truep[0]
def _label_position(self, *args): """ Write self.label_position in 'label.position' field """ # combine fields names and fields pointers in one dictionary arg_keys = [ffi.string(key).decode('utf-8') for key in args[2:-1:2]] arg_pointers = [pointer for pointer in args[3:-1:2]] arg_dict = dict(zip(arg_keys, arg_pointers)) arg_dict['label.position'][0] = self.label_position # C func returns true if the graphmodel object loock acceptable truep = ffi.new("bool*", True) return truep[0]
def _getting_line_size_side_effect(self, *args): """ Write self.line_size in 'line_size' field and return True """ # combine fields names and fields pointers in one dictionary arg_keys = [ffi.string(key).decode('utf-8') for key in args[2:-1:2]] arg_pointers = [pointer for pointer in args[3:-1:2]] arg_dict = dict(zip(arg_keys, arg_pointers)) arg_dict['line_size'][0] = self.line_size # C func returns true if the graphcurvemodel object loock acceptable truep = ffi.new("bool*", True) return truep[0]
def _getting_null_description_of_curve(self, *args): """ Write Null in 'description' field and return True """ # combine fields names and fields pointers in one dictionary arg_keys = [ffi.string(key).decode('utf-8') for key in args[2:-1:2]] arg_pointers = [pointer for pointer in args[3:-1:2]] arg_dict = dict(zip(arg_keys, arg_pointers)) arg_dict['description'][0] = ffi.NULL # C func returns true if the graphcurvemodel object loock acceptable truep = ffi.new("bool*", True) return truep[0]
def _y_unit_is_empty(self, *args): """ Write NULL to y_unit field """ # combine fields names and fields pointers in one dictionary arg_keys = [ffi.string(key).decode('utf-8') for key in args[2:-1:2]] arg_pointers = [pointer for pointer in args[3:-1:2]] arg_dict = dict(zip(arg_keys, arg_pointers)) arg_dict['y_unit'][0] = ffi.NULL # C func returns true if the graphmodel object loock acceptable truep = ffi.new("bool*", True) return truep[0]
def _get_number_of_curves(self, *args): """ Return 3 as a number of curves in graphmodel object """ # combine fields names and fields pointers in one dictionary arg_keys = [ffi.string(key).decode('utf-8') for key in args[2:-1:2]] arg_pointers = [pointer for pointer in args[3:-1:2]] arg_dict = dict(zip(arg_keys, arg_pointers)) arg_dict['ncurves'][0] = 3 # C func returns true if the graphmodel object loock acceptable truep = ffi.new("bool*", True) return truep[0]
def _returned_value_side_effect(self, *args): """ Write self.xdata and self.ydata as C arrays to 'xdata' and 'ydata' and return True """ # combine fields names and fields pointers in one dictionary arg_keys = [ffi.string(key).decode('utf-8') for key in args[2:-1:2]] arg_pointers = [pointer for pointer in args[3:-1:2]] arg_dict = dict(zip(arg_keys, arg_pointers)) arg_dict['xdata'][0] = ffi.cast("double*", self.xdata.ctypes.data) arg_dict['ydata'][0] = ffi.cast("double*", self.ydata.ctypes.data) # C func returns true if the graphcurvemodel object loock acceptable truep = ffi.new("bool*", True) return truep[0]
def get_gwyitem_string(self, item_key): """Get string value contained in Gwy data item Args: item_key (string): Name of the Gwy data item Returns: string: The string contained in Gwy data item or None if item is not found """ cfunc = lib.gwyfile_item_get_string cvalue = self._get_gwyitem_value(item_key, cfunc) if cvalue: return ffi.string(cvalue).decode('utf-8') else: return None
def _y_max_set_is_true(self, *args): """ Write True in 'y_max_set' field and 0. in 'y_max' field """ # combine fields names and fields pointers in one dictionary arg_keys = [ffi.string(key).decode('utf-8') for key in args[2:-1:2]] arg_pointers = [pointer for pointer in args[3:-1:2]] arg_dict = dict(zip(arg_keys, arg_pointers)) truep = ffi.new("bool*", True) arg_dict['y_max_set'][0] = truep[0] arg_dict['y_max'][0] = 0. # C func returns true if the graphmodel object loock acceptable return truep[0]
def _x_unit_is_not_empty(self, *args): """ Write "m" C string to 'x_unit' field """ x_unit = ffi.new("char[]", b"m") # combine fields names and fields pointers in one dictionary arg_keys = [ffi.string(key).decode('utf-8') for key in args[2:-1:2]] arg_pointers = [pointer for pointer in args[3:-1:2]] arg_dict = dict(zip(arg_keys, arg_pointers)) arg_dict['x_unit'][0] = x_unit # C func returns true if the graphmodel object loock acceptable truep = ffi.new("bool*", True) return truep[0]
def _label_has_frame(self, *args): """ Write self.label_has_frame in 'label.has_frame' field """ # combine fields names and fields pointers in one dictionary arg_keys = [ffi.string(key).decode('utf-8') for key in args[2:-1:2]] arg_pointers = [pointer for pointer in args[3:-1:2]] arg_dict = dict(zip(arg_keys, arg_pointers)) truep = ffi.new("bool*", True) falsep = ffi.new("bool*", False) if self.label_has_frame: arg_dict['label.has_frame'][0] = truep[0] else: arg_dict['label.has_frame'][0] = falsep[0] # C func returns true if the graphmodel object loock acceptable return truep[0]
def _side_effect(self, *args): # first arg is GwyDatafield object from Libgwyfile self.assertEqual(args[0], self.cgwydf) # second arg is GwyfileError** assert ffi.typeof(args[1]) == ffi.typeof(self.errorp) # last arg in NULL self.assertEqual(args[-1], ffi.NULL) # create dict from names and types of pointers in args arg_keys = [ffi.string(key).decode('utf-8') for key in args[2:-1:2]] arg_pointers = [pointer for pointer in args[3:-1:2]] arg_dict = dict(zip(arg_keys, arg_pointers)) datap = arg_dict['data'] datap[0] = ffi.cast("double*", self.data.ctypes.data) return self.truep[0]
def _side_effect(self, *args): self.assertEqual(int(args[0]), self.gwydatafield.meta['xres']) self.assertEqual(int(args[1]), self.gwydatafield.meta['yres']) self.assertEqual(float(args[2]), self.gwydatafield.meta['xreal']) self.assertEqual(float(args[3]), self.gwydatafield.meta['yreal']) self.assertEqual(ffi.string(args[4]), b'data(copy)') self.assertEqual( args[5], ffi.cast("double*", self.gwydatafield.data.ctypes.data)) self.assertEqual(ffi.string(args[6]), b"xoff") self.assertEqual(float(args[7]), self.gwydatafield.meta['xoff']) self.assertEqual(ffi.string(args[8]), b"yoff") self.assertEqual(float(args[9]), self.gwydatafield.meta['yoff']) self.assertEqual(ffi.string(args[10]), b"si_unit_xy") self.assertEqual(ffi.string(args[11]), self.gwydatafield.meta['si_unit_xy'].encode('utf-8')) self.assertEqual(ffi.string(args[12]), b"si_unit_z") self.assertEqual(ffi.string(args[13]), self.gwydatafield.meta['si_unit_z'].encode('utf-8')) self.assertEqual(args[-1], ffi.NULL) return self.expected_return
def _side_effect_check_args(self, *args): """ Check args passing to gwyfile_object_datafield_get C function """ # first arg is GwyDatafield object from Libgwyfile self.assertEqual(args[0], self.cgwydf) # second arg is GwyfileError** assert ffi.typeof(args[1]) == ffi.typeof(self.errorp) # last arg in NULL self.assertEqual(args[-1], ffi.NULL) # create dict from names and types of pointers in args arg_keys = [ffi.string(key).decode('utf-8') for key in args[2:-1:2]] arg_pointer_types = [ffi.typeof(pointer) for pointer in args[3:-1:2]] arg_dict = dict(zip(arg_keys, arg_pointer_types)) self.assertDictEqual(arg_dict, self.metadata_dict) return self.truep[0]
def _get_meta(gwydf): """Get metadata from the datafield Args: gwydf (GwyDataField*): GwyDataField object from Libgwyfile Returns: meta: Python dictionary with the data field metadata Keys of the metadata dictionary: 'xres' (int): Horizontal dimension in pixels 'yres' (int): Vertical dimension in pixels 'xreal' (float): Horizontal size in physical units 'yreal' (float): Vertical size in physical units 'xoff' (double): Horizontal offset of the top-left corner in physical units. 'yoff' (double): Vertical offset of the top-left corner in physical units. 'si_unit_xy' (str): Physical units of lateral dimensions, base SI units, e.g. "m" 'si_unit_z' (str): Physical unit of vertical dimension, base SI unit, e.g. "m" """ error = ffi.new("GwyfileError*") errorp = ffi.new("GwyfileError**", error) xresp = ffi.new("int32_t*") yresp = ffi.new("int32_t*") xrealp = ffi.new("double*") yrealp = ffi.new("double*") xoffp = ffi.new("double*") yoffp = ffi.new("double*") xyunitp = ffi.new("char**") zunitp = ffi.new("char**") meta = {} if lib.gwyfile_object_datafield_get(gwydf, errorp, ffi.new("char[]", b'xres'), xresp, ffi.new("char[]", b'yres'), yresp, ffi.new("char[]", b'xreal'), xrealp, ffi.new("char[]", b'yreal'), yrealp, ffi.new("char[]", b'xoff'), xoffp, ffi.new("char[]", b'yoff'), yoffp, ffi.new("char[]", b'si_unit_xy'), xyunitp, ffi.new("char[]", b'si_unit_z'), zunitp, ffi.NULL): meta['xres'] = xresp[0] meta['yres'] = yresp[0] meta['xreal'] = xrealp[0] meta['yreal'] = yrealp[0] meta['xoff'] = xoffp[0] meta['yoff'] = yoffp[0] if xyunitp[0]: meta['si_unit_xy'] = ffi.string(xyunitp[0]).decode('utf-8') else: meta['si_unit_xy'] = '' if zunitp[0]: meta['si_unit_z'] = ffi.string(zunitp[0]).decode('utf-8') else: meta['si_unit_z'] = '' return meta else: raise GwyfileErrorCMsg(errorp[0].message)
def __init__(self, c_error_msg): if c_error_msg: error_msg = ffi.string(c_error_msg).decode('utf-8') super().__init__(error_msg) else: super().__init__()
def _get_meta(gwygraphmodel): """Get metadata from a GwyGraphModel object (libgwyfile) Args: gwygraphmodel (GwyGraphModel*): GwyGraphModel object from Libgwyfile C library Returns: meta (dict): python dictionary with metadata from the GwyGraphModel """ error = ffi.new("GwyfileError*") errorp = ffi.new("GwyfileError**", error) ncurvesp = ffi.new("int32_t*") titlep = ffi.new("char**") top_labelp = ffi.new("char**") left_labelp = ffi.new("char**") right_labelp = ffi.new("char**") bottom_labelp = ffi.new("char**") x_unitp = ffi.new("char**") y_unitp = ffi.new("char**") x_minp = ffi.new("double*") x_min_setp = ffi.new("bool*") x_maxp = ffi.new("double*") x_max_setp = ffi.new("bool*") y_minp = ffi.new("double*") y_min_setp = ffi.new("bool*") y_maxp = ffi.new("double*") y_max_setp = ffi.new("bool*") x_is_logarithmicp = ffi.new("bool*") y_is_logarithmicp = ffi.new("bool*") label_visiblep = ffi.new("bool*") label_has_framep = ffi.new("bool*") label_reversep = ffi.new("bool*") label_frame_thicknessp = ffi.new("int32_t*") label_positionp = ffi.new("int32_t*") grid_typep = ffi.new("int32_t*") meta = {} if lib.gwyfile_object_graphmodel_get( gwygraphmodel, errorp, ffi.new("char[]", b"ncurves"), ncurvesp, ffi.new("char[]", b"title"), titlep, ffi.new("char[]", b"top_label"), top_labelp, ffi.new("char[]", b"left_label"), left_labelp, ffi.new("char[]", b"right_label"), right_labelp, ffi.new("char[]", b"bottom_label"), bottom_labelp, ffi.new("char[]", b"x_unit"), x_unitp, ffi.new("char[]", b"y_unit"), y_unitp, ffi.new("char[]", b"x_min"), x_minp, ffi.new("char[]", b"x_min_set"), x_min_setp, ffi.new("char[]", b"x_max"), x_maxp, ffi.new("char[]", b"x_max_set"), x_max_setp, ffi.new("char[]", b"y_min"), y_minp, ffi.new("char[]", b"y_min_set"), y_min_setp, ffi.new("char[]", b"y_max"), y_maxp, ffi.new("char[]", b"y_max_set"), y_max_setp, ffi.new("char[]", b"x_is_logarithmic"), x_is_logarithmicp, ffi.new("char[]", b"y_is_logarithmic"), y_is_logarithmicp, ffi.new("char[]", b"label.visible"), label_visiblep, ffi.new("char[]", b"label.has_frame"), label_has_framep, ffi.new("char[]", b"label.reverse"), label_reversep, ffi.new("char[]", b"label.frame_thickness"), label_frame_thicknessp, ffi.new("char[]", b"label.position"), label_positionp, ffi.new("char[]", b"grid-type"), grid_typep, ffi.NULL): meta["ncurves"] = ncurvesp[0] if titlep[0]: title = ffi.string(titlep[0]).decode('utf-8') meta["title"] = title else: meta["title"] = '' if top_labelp[0]: top_label = ffi.string(top_labelp[0]).decode('utf-8') meta["top_label"] = top_label else: meta["top_label"] = '' if left_labelp[0]: left_label = ffi.string(left_labelp[0]).decode('utf-8') meta["left_label"] = left_label else: meta["left_label"] = '' if right_labelp[0]: right_label = ffi.string(right_labelp[0]).decode('utf-8') meta["right_label"] = right_label else: meta["right_label"] = '' if bottom_labelp[0]: bottom_label = ffi.string(bottom_labelp[0]).decode('utf-8') meta["bottom_label"] = bottom_label else: meta["bottom_label"] = '' if x_unitp[0]: x_unit = ffi.string(x_unitp[0]).decode('utf-8') meta["x_unit"] = x_unit else: meta["x_unit"] = '' if y_unitp[0]: y_unit = ffi.string(y_unitp[0]).decode('utf-8') meta["y_unit"] = y_unit else: meta["y_unit"] = '' if x_min_setp[0]: meta["x_min_set"] = True meta["x_min"] = x_minp[0] else: meta["x_min_set"] = False meta["x_min"] = None if x_max_setp[0]: meta["x_max_set"] = True meta["x_max"] = x_maxp[0] else: meta["x_max_set"] = False meta["x_max"] = None if y_min_setp[0]: meta["y_min_set"] = True meta["y_min"] = y_minp[0] else: meta["y_min_set"] = False meta["y_min"] = None if y_max_setp[0]: meta["y_max_set"] = True meta["y_max"] = y_maxp[0] else: meta["y_max_set"] = False meta["y_max"] = None if x_is_logarithmicp[0]: meta["x_is_logarithmic"] = True else: meta["x_is_logarithmic"] = False if y_is_logarithmicp[0]: meta["y_is_logarithmic"] = True else: meta["y_is_logarithmic"] = False if label_visiblep[0]: meta["label.visible"] = True else: meta["label.visible"] = False if label_has_framep[0]: meta["label.has_frame"] = True else: meta["label.has_frame"] = False if label_reversep[0]: meta["label.reverse"] = True else: meta["label.reverse"] = False meta["label.frame_thickness"] = label_frame_thicknessp[0] meta["label.position"] = label_positionp[0] meta["grid-type"] = grid_typep[0] return meta else: raise GwyfileErrorCMsg(errorp[0].message)
def _side_effect(self, *args): self.assertEqual(int(args[0]), self.ncurves) self.assertEqual(ffi.string(args[1]), b"curves") self.assertEqual(ffi.string(args[3]), b"title") self.assertEqual(ffi.string(args[4]), self.gwygraphmodel.meta['title'].encode('utf-8')) self.assertEqual(ffi.string(args[5]), b"top_label") self.assertEqual(ffi.string(args[6]), self.gwygraphmodel.meta['top_label'].encode('utf-8')) self.assertEqual(ffi.string(args[7]), b"left_label") self.assertEqual(ffi.string(args[8]), self.gwygraphmodel.meta['left_label'].encode('utf-8')) self.assertEqual(ffi.string(args[9]), b"right_label") self.assertEqual( ffi.string(args[10]), self.gwygraphmodel.meta['right_label'].encode('utf-8')) self.assertEqual(ffi.string(args[11]), b"bottom_label") self.assertEqual( ffi.string(args[12]), self.gwygraphmodel.meta['bottom_label'].encode('utf-8')) self.assertEqual(ffi.string(args[13]), b"x_unit") self.assertEqual(ffi.string(args[14]), self.gwygraphmodel.meta['x_unit'].encode('utf-8')) self.assertEqual(ffi.string(args[15]), b"y_unit") self.assertEqual(ffi.string(args[16]), self.gwygraphmodel.meta['y_unit'].encode('utf-8')) self.assertEqual(ffi.string(args[17]), b"x_min") self.assertEqual(float(args[18]), self.gwygraphmodel.meta['x_min']) self.assertEqual(ffi.string(args[19]), b"x_min_set") self.assertEqual(bool(args[20]), self.gwygraphmodel.meta['x_min_set']) self.assertEqual(ffi.string(args[21]), b"x_max") self.assertEqual(float(args[22]), self.gwygraphmodel.meta['x_max']) self.assertEqual(ffi.string(args[23]), b"x_max_set") self.assertEqual(bool(args[24]), self.gwygraphmodel.meta['x_max_set']) self.assertEqual(ffi.string(args[25]), b"x_is_logarithmic") self.assertEqual(bool(args[26]), self.gwygraphmodel.meta['x_is_logarithmic']) self.assertEqual(ffi.string(args[27]), b"y_is_logarithmic") self.assertEqual(bool(args[28]), self.gwygraphmodel.meta['y_is_logarithmic']) self.assertEqual(ffi.string(args[29]), b'label.visible') self.assertEqual(bool(args[30]), self.gwygraphmodel.meta['label.visible']) self.assertEqual(ffi.string(args[31]), b"label.has_frame") self.assertEqual(bool(args[32]), self.gwygraphmodel.meta['label.has_frame']) self.assertEqual(ffi.string(args[33]), b"label.reverse") self.assertEqual(bool(args[34]), self.gwygraphmodel.meta['label.reverse']) self.assertEqual(ffi.string(args[35]), b'label.frame_thickness') self.assertEqual(int(args[36]), self.gwygraphmodel.meta['label.frame_thickness']) self.assertEqual(ffi.string(args[37]), b'label.position') self.assertEqual(int(args[38]), self.gwygraphmodel.meta['label.position']) self.assertEqual(ffi.string(args[39]), b'grid-type') self.assertEqual(int(args[40]), self.gwygraphmodel.meta['grid-type']) self.assertEqual(args[-1], ffi.NULL) return self.expected_return
def _side_effect(self, *args): self.assertEqual(int(args[0]), self.ndata) self.assertEqual(ffi.string(args[1]), b"xdata") self.assertEqual(args[2], ffi.cast("double*", self.curve.data[0].ctypes.data)) self.assertEqual(ffi.string(args[3]), b"ydata") self.assertEqual(args[4], ffi.cast("double*", self.curve.data[1].ctypes.data)) self.assertEqual(ffi.string(args[5]), b"description") self.assertEqual(ffi.string(args[6]), self.description.encode('utf-8')) self.assertEqual(ffi.string(args[7]), b"type") self.assertEqual(int(args[8]), self.curve.meta['type']) self.assertEqual(ffi.string(args[9]), b"point_type") self.assertEqual(int(args[10]), self.curve.meta['point_type']) self.assertEqual(ffi.string(args[11]), b"line_style") self.assertEqual(int(args[12]), self.curve.meta['line_style']) self.assertEqual(ffi.string(args[13]), b"point_size") self.assertEqual(int(args[14]), self.curve.meta['point_size']) self.assertEqual(ffi.string(args[15]), b"line_size") self.assertEqual(int(args[16]), self.curve.meta['line_size']) self.assertEqual(ffi.string(args[17]), b"color.red") self.assertAlmostEqual(float(args[18]), self.curve.meta['color.red']) self.assertEqual(ffi.string(args[19]), b"color.green") self.assertAlmostEqual(float(args[20]), self.curve.meta['color.green']) self.assertEqual(ffi.string(args[21]), b"color.blue") self.assertAlmostEqual(float(args[22]), self.curve.meta['color.blue']) self.assertEqual(args[-1], ffi.NULL) return self.gwycurve