11from __future__ import absolute_import
22import numpy as np
3- import os
3+ import os , warnings
44
5- # The codec was changed to ASCII in version 0.10.0.
5+ # The codec was changed to ASCII in version 0.10.0.
66# A rewrite of DSS C-API is expected to return UTF8Strings in the future
77codec = 'ascii'
88
99interface_classes = set ()
1010
11- def use_com_compat (value = True ):
12- if value :
13- Base .__getattr__ = Base ._getattr
14- Base .__setattr__ = Base ._setattr
15- elif Base .__getattr__ == Base ._getattr :
11+ warn_wrong_case = False
12+
13+ def use_com_compat (use = True , warn = False ):
14+ if use :
15+ global warn_wrong_case
16+ warn_wrong_case = warn
17+ if warn_wrong_case :
18+ Base .__getattr__ = Base ._getattr_case_check
19+ Base .__setattr__ = Base ._setattr_case_check
20+ else :
21+ Base .__getattr__ = Base ._getattr
22+ Base .__setattr__ = Base ._setattr
23+
24+ elif Base .__getattr__ == Base ._getattr or Base .__getattr__ == Base ._getattr_case_check :
1625 del Base .__setattr__
17- del Base .__getattr__
26+ del Base .__getattr__
1827
1928class DssException (Exception ):
2029 pass
21-
30+
2231class Base (object ):
2332 __slots__ = [
2433 '_lib' ,
@@ -35,7 +44,7 @@ class Base(object):
3544 '_prepare_int32_array' ,
3645 '_prepare_string_array' ,
3746 ]
38-
47+
3948 def __init__ (self , api_util ):
4049 self ._lib = api_util .lib
4150 self ._api_util = api_util
@@ -50,7 +59,7 @@ def __init__(self, api_util):
5059 self ._prepare_float64_array = api_util .prepare_float64_array
5160 self ._prepare_int32_array = api_util .prepare_int32_array
5261 self ._prepare_string_array = api_util .prepare_string_array
53-
62+
5463 cls = type (self )
5564 if cls not in interface_classes :
5665 interface_classes .add (cls )
@@ -62,26 +71,45 @@ def CheckForError(self):
6271 error_num = self ._lib .Error_Get_Number ()
6372 if error_num :
6473 raise DssException (error_num , self ._get_string (self ._lib .Error_Get_Description ()))
65-
74+
6675 def _getattr (self , key ):
6776 if key .startswith ('_' ):
6877 return object .__getattribute__ (self , key )
6978
7079 key = self .__class__ ._dss_attributes .get (key .lower (), key )
7180 return object .__getattribute__ (self , key )
7281
82+ def _getattr_case_check (self , key ):
83+ if key .startswith ('_' ):
84+ return object .__getattribute__ (self , key )
85+
86+ correct_key = self .__class__ ._dss_attributes .get (key .lower (), key )
87+ if key != correct_key :
88+ warnings .warn ('Wrong case for getter {}.{}: {}' .format (self .__class__ .__name__ , correct_key , key ))
89+
90+ return object .__getattribute__ (self , correct_key )
91+
7392 def _setattr (self , key , value ):
7493 key = self .__class__ ._dss_attributes .get (key .lower (), key )
7594 object .__setattr__ (self , key , value )
76-
77-
95+
96+ def _setattr_case_check (self , key , value ):
97+ correct_key = self .__class__ ._dss_attributes .get (key .lower (), key )
98+ if key != correct_key :
99+ warnings .warn ('Wrong case for setter {}.{}: {}' .format (self .__class__ .__name__ , correct_key , key ))
100+
101+ key = self .__class__ ._dss_attributes .get (key .lower (), key )
102+ object .__setattr__ (self , key , value )
103+
104+
105+
78106class CffiApiUtil (object ):
79107 def __init__ (self , ffi , lib ):
80108 self .codec = codec #TODO: check which encoding FreePascal defaults to, on Linux
81109 self .ffi = ffi
82110 self .lib = lib
83111 self .init_buffers ()
84-
112+
85113 def init_buffers (self ):
86114 tmp_string_pointers = (self .ffi .new ('char****' ), self .ffi .new ('int32_t**' ))
87115 tmp_float64_pointers = (self .ffi .new ('double***' ), self .ffi .new ('int32_t**' ))
@@ -90,7 +118,7 @@ def init_buffers(self):
90118
91119 # reorder pointers so data pointers are first, count pointers last
92120 ptr_args = [
93- ptr
121+ ptr
94122 for ptrs in zip (tmp_string_pointers , tmp_float64_pointers , tmp_int32_pointers , tmp_int8_pointers )
95123 for ptr in ptrs
96124 ]
@@ -121,15 +149,15 @@ def get_float64_array(self, func, *args):
121149 def get_float64_gr_array (self ):
122150 ptr , cnt = self .gr_float64_pointers
123151 return np .fromstring (self .ffi .buffer (ptr [0 ], cnt [0 ] * 8 ), dtype = np .float )
124-
152+
125153 def get_int32_array (self , func , * args ):
126154 ptr = self .ffi .new ('int32_t**' )
127155 cnt = self .ffi .new ('int32_t[2]' )
128156 func (ptr , cnt , * args )
129157 res = np .fromstring (self .ffi .buffer (ptr [0 ], cnt [0 ] * 4 ), dtype = np .int32 )
130158 self .lib .DSS_Dispose_PInteger (ptr )
131159 return res
132-
160+
133161 def get_int32_gr_array (self ):
134162 ptr , cnt = self .gr_int32_pointers
135163 return np .fromstring (self .ffi .buffer (ptr [0 ], cnt [0 ] * 4 ), dtype = np .int32 )
@@ -145,7 +173,7 @@ def get_int8_array(self, func, *args):
145173 def get_int8_gr_array (self ):
146174 ptr , cnt = self .gr_int8_pointers
147175 return np .fromstring (self .ffi .buffer (ptr [0 ], cnt [0 ] * 1 ), dtype = np .int8 )
148-
176+
149177 def get_string_array (self , func , * args ):
150178 ptr = self .ffi .new ('char***' )
151179 cnt = self .ffi .new ('int32_t[2]' )
@@ -164,7 +192,7 @@ def get_string_array(self, func, *args):
164192
165193 self .lib .DSS_Dispose_PPAnsiChar (ptr , cnt [1 ])
166194 return res
167-
195+
168196 def get_string_array2 (self , func , * args ): # for compatibility with OpenDSSDirect.py
169197 ptr = self .ffi .new ('char***' )
170198 cnt = self .ffi .new ('int32_t[2]' )
@@ -205,7 +233,7 @@ def get_float64_array2(self, func, *args):
205233 def get_float64_gr_array2 (self ):
206234 ptr , cnt = self .gr_float64_pointers
207235 return self .ffi .unpack (ptr [0 ], cnt [0 ])
208-
236+
209237 def get_int32_array2 (self , func , * args ):
210238 ptr = self .ffi .new ('int32_t**' )
211239 cnt = self .ffi .new ('int32_t[2]' )
@@ -221,7 +249,7 @@ def get_int32_array2(self, func, *args):
221249 def get_int32_gr_array2 (self ):
222250 ptr , cnt = self .gr_int32_pointers
223251 return self .ffi .unpack (ptr [0 ], cnt [0 ])
224-
252+
225253 def get_int8_array2 (self , func , * args ):
226254 ptr = self .ffi .new ('int8_t**' )
227255 cnt = self .ffi .new ('int32_t[2]' )
@@ -233,12 +261,12 @@ def get_int8_array2(self, func, *args):
233261
234262 self .lib .DSS_Dispose_PByte (ptr )
235263 return res
236-
264+
237265 def get_int8_gr_array2 (self ):
238266 ptr , cnt = self .gr_int8_pointers
239267 return self .ffi .unpack (ptr [0 ], cnt [0 ])
240268
241-
269+
242270 def prepare_float64_array (self , value ):
243271 if type (value ) is not np .ndarray or value .dtype != np .float64 :
244272 value = np .array (value , dtype = np .float64 )
0 commit comments