@@ -870,30 +870,33 @@ def _write_var_attrs(self, f: io.BufferedWriter, varNum: int, var_attrs: Dict[st
870870 if items == 2 :
871871 dataType = self ._datatype_token (entry [1 ])
872872
873+ # Handle user setting datatype
873874 if dataType > 0 :
874875 # CDF data type defined in entry
875876 data = entry [0 ]
876877 if self ._checklistofNums (data ):
877- # All are numbers
878+ # Data needs no pre-processing and is good to go
878879 if hasattr (data , "__len__" ) and not isinstance (data , str ):
879880 numElems = len (data )
880881 else :
881882 numElems = 1
882883 else :
883- # Then string(s) -- either in CDF_type or epoch in string(s)
884+ # Data needs some sort of pre-processing to proceed
884885 if dataType == self .CDF_CHAR or dataType == self .CDF_UCHAR :
885886 if hasattr (data , "__len__" ) and not isinstance (data , str ):
887+ # Reformat strings
886888 items = len (data )
887889 odata = data
888890 data = ""
889891 for x in range (0 , items ):
890892 if x > 0 :
891893 data += "\\ N "
892- data += odata [x ]
894+ data += str ( odata [x ])
893895 else :
894- data = odata [x ]
896+ data = str ( odata [x ])
895897 numElems = len (data )
896898 elif dataType == self .CDF_EPOCH or dataType == self .CDF_EPOCH16 or dataType == self .CDF_TIME_TT2000 :
899+ # Convert data to CDF time
897900 cvalue = []
898901 if hasattr (data , "__len__" ) and not isinstance (data , str ):
899902 numElems = len (data )
@@ -903,7 +906,22 @@ def _write_var_attrs(self, f: io.BufferedWriter, varNum: int, var_attrs: Dict[st
903906 else :
904907 data = cdfepoch .CDFepoch .parse (data )
905908 numElems = 1
906- else :
909+ elif isinstance (data , str ):
910+ # One possibility is that the user wants to convert a string to a number
911+ numElems = 1
912+ data = np .array (float (data ))
913+ else :
914+ # The final possibility I can think of is that the user wants to convert a list of strings to a list of numbers
915+ try :
916+ numElems = 1
917+ data = np .array ([float (item ) for item in data ])
918+ except :
919+ logger .warning (
920+ f"Cannot determine how to convert { str (data )} to specified type of { dataType } . Ignoring the specified datatype, and continuing."
921+ )
922+ dataType = 0
923+
924+ if dataType == 0 :
907925 # No data type defined...
908926 data = entry
909927 if hasattr (data , "__len__" ) and not isinstance (data , str ):
@@ -913,9 +931,9 @@ def _write_var_attrs(self, f: io.BufferedWriter, varNum: int, var_attrs: Dict[st
913931 for x in range (0 , len (entry )):
914932 if x > 0 :
915933 data += "\\ N "
916- data += entry [x ]
934+ data += str ( entry [x ])
917935 else :
918- data = entry [x ]
936+ data = str ( entry [x ])
919937 numElems = len (data )
920938 else :
921939 numElems , dataType = self ._datatype_define (entry )
@@ -1750,7 +1768,7 @@ def _write_aedr(
17501768 value_size = 1
17511769 cdata = "\x00 " .encode ()
17521770 else :
1753- value_size = len ( cdata )
1771+ value_size = recs * self . _datatype_size ( dataType , numElems )
17541772 block_size = value_size + 56
17551773 aedr = bytearray (block_size )
17561774 aedr [0 :8 ] = struct .pack (">q" , block_size )
@@ -2304,6 +2322,17 @@ def _convert_data(self, data_type: int, num_elems: int, num_values: int, indata:
23042322 odata += adata .ljust (num_elems , "\x00 " )
23052323 recs = int ((size * size2 ) / num_values )
23062324 return recs , odata .encode ()
2325+ elif all (isinstance (item , str ) for item in indata ):
2326+ # Attempt to convert to a numpy array of numbers
2327+ try :
2328+ return self ._numpy_to_bytes (data_type , num_values , num_elems , np .array ([float (item ) for item in indata ]))
2329+ except :
2330+ # Do the best we can, create bytes from the string.
2331+ # It will probably come out to be jibberish
2332+ outdata = ("" .join (indata )).ljust (num_elems , "\x00 " ).encode ()
2333+ recs = int (len (outdata ) / recSize )
2334+ return recs , outdata
2335+
23072336 else :
23082337 try :
23092338 return self ._numpy_to_bytes (data_type , num_values , num_elems , np .array (indata ))
@@ -2366,8 +2395,19 @@ def _convert_data(self, data_type: int, num_elems: int, num_values: int, indata:
23662395 return recs , odata .encode ()
23672396 else :
23682397 return self ._numpy_to_bytes (data_type , num_values , num_elems , indata )
2369- elif isinstance (indata , str ):
2398+ elif isinstance (indata , str ) and (data_type == self .CDF_CHAR or data_type == self .CDF_UCHAR ):
2399+ # Just convert the string directly to bytes
23702400 return 1 , indata .ljust (num_elems , "\x00 " ).encode ()
2401+ elif isinstance (indata , str ) and data_type != self .CDF_CHAR and data_type == self .CDF_UCHAR :
2402+ # Try to convert the single string to a numerical type.
2403+ try :
2404+ return self ._numpy_to_bytes (data_type , num_values , num_elems , np .array ([float (indata )]))
2405+ except :
2406+ # Do the best we can, create bytes from the string.
2407+ # It will probably come out to be jibberish
2408+ outdata = indata .ljust (num_elems , "\x00 " ).encode ()
2409+ recs = int (len (outdata ) / recSize )
2410+ return recs , outdata
23712411 else :
23722412 try :
23732413 # Try converting the data to numpy
@@ -2398,7 +2438,7 @@ def _convert_data(self, data_type: int, num_elems: int, num_values: int, indata:
23982438 else :
23992439 return recs , struct .pack (form , indata )
24002440 except struct .error :
2401- raise ValueError ("Unable to convert data to CDF format, data " " object cannot be of type string." )
2441+ raise ValueError ("Unable to convert data to CDF format, data object cannot be of type string." )
24022442
24032443 def _num_values (self , zVar : bool , varNum : int ) -> int :
24042444 """
0 commit comments