Support using Python 3

Fixed the configure script to allow the user to specify using a python3
interpreter.  Had to change the the way to load the swig generated python modules.
Also had to change code dealing with python strings, oct, long, and
boolean operations.

refs #258
This commit is contained in:
Alex Lin 2016-06-28 13:44:21 -05:00
parent 268d3407df
commit 4ab584ed55
15 changed files with 150 additions and 30 deletions

View File

@ -192,7 +192,7 @@ AC_PATH_PROG(BISON, bison, nobison)
AS_IF([test "$ac_cv_path_BISON" = "nobison"],AC_MSG_ERROR([could not find bison]),[])
AC_PATH_PROG(PERL, perl, noperl)
AS_IF([test "$ac_cv_path_PERL" = "noperl"],AC_MSG_ERROR([could not find perl]),[])
AC_PATH_PROG(PYTHON, python, nopython)
AC_PATH_PROG(PYTHON, python${PYTHON_VERSION}, nopython)
AS_IF([test "$ac_cv_path_PYTHON" = "nopython"],AC_MSG_ERROR([could not find python]),[])
AC_PATH_PROG(SWIG, swig, noswig, "/bin:/usr/bin:/usr/local/bin:/sw/bin")
AS_IF([test "$ac_cv_path_SWIG" = "noswig"],AC_MSG_ERROR([could not find swig]),[])

4
configure vendored
View File

@ -4985,8 +4985,8 @@ fi
if test "$ac_cv_path_PERL" = "noperl"; then :
as_fn_error $? "could not find perl" "$LINENO" 5
fi
# Extract the first word of "python", so it can be a program name with args.
set dummy python; ac_word=$2
# Extract the first word of "python${PYTHON_VERSION}", so it can be a program name with args.
set dummy python${PYTHON_VERSION}; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_path_PYTHON+:} false; then :

View File

@ -37,8 +37,10 @@ extern "C" {
On = 1,
No = 0,
Yes = 1,
#ifndef SWIG
False = 0,
True = 1,
#endif
Disconnect = 0,
Connect = 1,
Inactive = 0,

View File

@ -83,6 +83,9 @@ class swig_int {
PyObject * __len__() ;
int __index__() ;
PyObject * __bool__() ;
} ;
#endif

View File

@ -62,12 +62,21 @@ template<typename T > static int typemap_in_scalar( T & output , PyObject *input
output = (T)PyFloat_AsDouble(input) ;
} else if ( PyInt_Check(input) ) {
output = (T)PyInt_AsLong(input) ;
#if PY_VERSION_HEX >= 0x03000000
} else if ( PyUnicode_Check(input) ) {
if ( PyUnicode_GET_SIZE(input) == 1 ) {
PyObject * temp = PyUnicode_AsEncodedString(input, "utf-8", "Error ~");
char * temp_str = PyBytes_AS_STRING(temp) ;
output = (T)temp_str[0] ;
}
#else
} else if ( PyString_Check(input) ) {
// scalar char as a string. Set the value of the output to the value of the first char.
if ( PyString_Size(input) == 1 ) {
char * temp_str = PyString_AsString(input) ;
output = (T)temp_str[0] ;
}
#endif
} else {
ret = -1 ;
}
@ -129,10 +138,16 @@ template<typename T > static T * typemap_in_1d( PyObject *input , unsigned int o
return NULL;
}
}
#if PY_VERSION_HEX >= 0x03000000
} else if ( PyUnicode_Check(input) ) {
unsigned int size = PyUnicode_GET_SIZE(input) ;
PyObject * temp = PyUnicode_AsEncodedString(input, "utf-8", "Error ~");
char * temp_str = PyBytes_AS_STRING(temp) ;
#else
} else if ( PyString_Check(input) ) {
unsigned int size = PyString_Size(input) ;
char * temp_str = PyString_AsString(input) ;
#endif
if ( size > out_size ) {
PyErr_SetString(PyExc_TypeError,"List too long to fit.");
return NULL ;
@ -218,8 +233,14 @@ template<typename T > static int typemap_in_1dp( PyObject *input , const char *
*output = reinterpret_cast< T * >(argp2) ;
} else {
if ( !strncmp( basetype , "char" , 4 )) {
#if PY_VERSION_HEX >= 0x03000000
if ( PyUnicode_Check(input) ) {
PyObject * temp = PyUnicode_AsEncodedString(input, "utf-8", "Error ~");
*output = (T *)TMM_strdup(PyBytes_AS_STRING(temp)) ;
#else
if ( PyString_Check(input) ) {
*output = (T *)TMM_strdup(PyString_AsString(input)) ;
#endif
} else {
PyErr_SetString(PyExc_TypeError,"swig_int (char): Input must be of type List, string, or a pointer type");
return -1;
@ -305,10 +326,16 @@ template<typename T, typename baseT > static void * typemap_in_2d( PyObject *inp
new_array[ii][jj] = (baseT)PyInt_AsLong(o2) ;
}
}
#if PY_VERSION_HEX >= 0x03000000
} else if ( PyUnicode_Check(o) ) {
unsigned int size = PyUnicode_GET_SIZE(o) ;
PyObject * temp = PyUnicode_AsEncodedString(o, "utf-8", "Error ~");
char * temp_str = PyBytes_AS_STRING(temp) ;
#else
} else if ( PyString_Check(o) ) {
unsigned int size = PyString_Size(o) ;
char * temp_str = PyString_AsString(o) ;
#endif
if ( size > out_dim1 ) {
PyErr_SetString(PyExc_TypeError,"String too long to fit.");
return NULL ;

View File

@ -327,6 +327,43 @@ LINK_OBJECTS += \$(SWIG_MODULE_OBJECTS)
close TOPFILE ;
open INITSWIGFILE , ">build/init_swig_modules.cpp" or return ;
print INITSWIGFILE "#include <Python.h>\n" ;
print INITSWIGFILE "#if PY_VERSION_HEX >= 0x03000000\n" ;
print INITSWIGFILE "extern \"C\" {\n\n" ;
foreach $f ( @files_to_process ) {
my $md5_sum = md5_hex($f) ;
print INITSWIGFILE "PyObject * PyInit__m${md5_sum}(void) ; /* $f */\n" ;
}
foreach $f ( @ext_lib_files ) {
my $md5_sum = md5_hex($f) ;
print INITSWIGFILE "PyObject * PyInit__m${md5_sum}(void) ; /* $f */\n" ;
}
print INITSWIGFILE "PyObject * PyInit__sim_services(void) ;\n" ;
print INITSWIGFILE "PyObject * PyInit__top(void) ;\n" ;
print INITSWIGFILE "PyObject * PyInit__swig_double(void) ;\n" ;
print INITSWIGFILE "PyObject * PyInit__swig_int(void) ;\n" ;
print INITSWIGFILE "PyObject * PyInit__swig_ref(void) ;\n" ;
print INITSWIGFILE "\nvoid init_swig_modules(void) {\n\n" ;
foreach $f ( @files_to_process ) {
next if ( $f =~ /S_source.hh/ ) ;
my $md5_sum = md5_hex($f) ;
print INITSWIGFILE " PyImport_AppendInittab(\"_m${md5_sum}\", PyInit__m${md5_sum}) ;\n" ;
}
foreach $f ( @ext_lib_files ) {
my $md5_sum = md5_hex($f) ;
print INITSWIGFILE " PyImport_AppendInittab(\"_m${md5_sum}\", PyInit__m${md5_sum}) ;\n" ;
}
print INITSWIGFILE " PyImport_AppendInittab(\"_m${s_source_md5}\", PyInit__m${s_source_md5}) ;\n" ;
print INITSWIGFILE " PyImport_AppendInittab(\"_sim_services\", PyInit__sim_services) ;\n" ;
print INITSWIGFILE " PyImport_AppendInittab(\"_top\", PyInit__top) ;\n" ;
print INITSWIGFILE " PyImport_AppendInittab(\"_swig_double\", PyInit__swig_double) ;\n" ;
print INITSWIGFILE " PyImport_AppendInittab(\"_swig_int\", PyInit__swig_int) ;\n" ;
print INITSWIGFILE " PyImport_AppendInittab(\"_swig_ref\", PyInit__swig_ref) ;\n" ;
print INITSWIGFILE " return ;\n}\n\n}\n" ;
print INITSWIGFILE "#else\n" ;
print INITSWIGFILE "extern \"C\" {\n\n" ;
foreach $f ( @files_to_process ) {
my $md5_sum = md5_hex($f) ;
@ -360,6 +397,7 @@ LINK_OBJECTS += \$(SWIG_MODULE_OBJECTS)
print INITSWIGFILE " init_swig_int() ;\n" ;
print INITSWIGFILE " init_swig_ref() ;\n" ;
print INITSWIGFILE " return ;\n}\n\n}\n" ;
print INITSWIGFILE "#endif\n" ;
close INITSWIGFILE ;
if ( ! -e "trick") {

View File

@ -82,9 +82,11 @@ if hasattr(top.cvar, 'trick_vs'):
def __init__(self, in_stream):
self.stream = in_stream
def write(self, text):
trick.var_write_stdio(self.stream , text)
sys.stdout = VarWriteStdio(1)
sys.stderr = VarWriteStdio(2)
trick.var_write_stdio(self.stream.fileno() , text)
def flush(self):
self.stream.flush()
sys.stdout = VarWriteStdio(sys.stdout)
sys.stderr = VarWriteStdio(sys.stderr)
# from real time injector
if hasattr(top.cvar, 'trick_inject'):

View File

@ -19,54 +19,54 @@ def TRICK_EXPECT_EQ( a , b, test_suite, test_case):
trick.add_test_result( test_suite , test_case , "") ;
else:
trick.add_test_result( test_suite , test_case , "TRICK_EXPECT_EQ failed") ;
print "a = " , a
print "b = " , b
print ("a = {}".format(a))
print ("b = {}".format(b))
def TRICK_EXPECT_NE( a , b, test_suite, test_case):
if a != b:
trick.add_test_result( test_suite , test_case , "") ;
else:
trick.add_test_result( test_suite , test_case , "TRICK_EXPECT_EQ failed") ;
print "a = " , a
print "b = " , b
print ("a = {}".format(a))
print ("b = {}".format(b))
def TRICK_EXPECT_LT( a , b, test_suite, test_case):
if a < b:
trick.add_test_result( test_suite , test_case , "") ;
else:
trick.add_test_result( test_suite , test_case , "TRICK_EXPECT_LT failed") ;
print "a = " , a
print "b = " , b
print ("a = {}".format(a))
print ("b = {}".format(b))
def TRICK_EXPECT_LE( a , b, test_suite, test_case):
if a <= b:
trick.add_test_result( test_suite , test_case , "") ;
else:
trick.add_test_result( test_suite , test_case , "TRICK_EXPECT_LE failed") ;
print "a = " , a
print "b = " , b
print ("a = {}".format(a))
print ("b = {}".format(b))
def TRICK_EXPECT_GT( a , b, test_suite, test_case):
if a > b:
trick.add_test_result( test_suite , test_case , "") ;
else:
trick.add_test_result( test_suite , test_case , "TRICK_EXPECT_GT failed") ;
print "a = " , a
print "b = " , b
print ("a = {}".format(a))
print ("b = {}".format(b))
def TRICK_EXPECT_GE( a , b, test_suite, test_case):
if a >= b:
trick.add_test_result( test_suite , test_case , "") ;
else:
trick.add_test_result( test_suite , test_case , "TRICK_EXPECT_GE failed") ;
print "a = " , a
print "b = " , b
print ("a = {}".format(a))
print ("b = {}".format(b))
def TRICK_EXPECT_NEAR( a , b, tol, test_suite, test_case):
if math.fabs(a - b) < tol:
trick.add_test_result( test_suite , test_case , "") ;
else:
trick.add_test_result( test_suite , test_case , "TRICK_EXPECT_NEAR failed") ;
print "a = " , a
print "b = " , b
print ("a = {}".format(a))
print ("b = {}".format(b))

View File

@ -1993,9 +1993,10 @@ def main():
test = int(test_so.obj.ikg)
TRICK_EXPECT_EQ( test , 20, test_suite , "int" )
test_so.obj.ikg = 20
test = long(test_so.obj.ikg)
TRICK_EXPECT_EQ( test , 20, test_suite , "long" )
if sys.version_info < (3,0):
test_so.obj.ikg = 20
test = long(test_so.obj.ikg)
TRICK_EXPECT_EQ( test , 20, test_suite , "long" )
test_so.obj.ikg = 20
test = float(test_so.obj.ikg)
@ -2003,7 +2004,10 @@ def main():
test_so.obj.ikg = 20
test = oct(test_so.obj.ikg)
TRICK_EXPECT_EQ( test , "024", test_suite , "oct" )
if sys.version_info >= (3,0):
TRICK_EXPECT_EQ( test , "0o24", test_suite , "oct" )
else:
TRICK_EXPECT_EQ( test , "024", test_suite , "oct" )
test_so.obj.ikg = 20
test = hex(test_so.obj.ikg)
@ -2493,9 +2497,10 @@ def main():
test = int(test_so.obj.dkg)
TRICK_EXPECT_NEAR( test , 20, 0.0001, test_suite , "int" )
test_so.obj.dkg = 20
test = long(test_so.obj.dkg)
TRICK_EXPECT_NEAR( test , 20, 0.0001, test_suite , "long" )
if sys.version_info < (3,0):
test_so.obj.dkg = 20
test = long(test_so.obj.dkg)
TRICK_EXPECT_NEAR( test , 20, 0.0001, test_suite , "long" )
test_so.obj.dkg = 20
test = float(test_so.obj.dkg)

View File

@ -83,11 +83,19 @@ int Trick::IPPython::init() {
pthread_mutexattr_settype(&m_attr, PTHREAD_MUTEX_RECURSIVE) ;
pthread_mutex_init(&ip_mutex , &m_attr) ;
// Run Py_Initialze first for python 2.x
#if PY_VERSION_HEX < 0x03000000
Py_Initialize();
#endif
/* Run the Swig generated routine in S_source_wrap.cpp. */
init_swig_modules() ;
// Run Py_Initialze after init_swig_modules for python 3.x
#if PY_VERSION_HEX >= 0x03000000
Py_Initialize();
#endif
/* Import simulation specific routines into interpreter. */
PyRun_SimpleString(
"import sys\n"

View File

@ -167,7 +167,7 @@ def traceit(frame, event, arg):
filename.endswith(".pyo")):
filename = filename[:-1]
line = linecache.getline(filename, lineno)
print "%s:%s: %s" % (filename, lineno, line.rstrip())
print (filename,":",lineno,": ",line.rstrip())
return traceit
%}

View File

@ -1227,3 +1227,14 @@ PyObject * swig_int::__len__() {
return PyInt_FromLong(1) ;
}
//**********************************************************************************************
// New for python 3
int swig_int::__index__() {
return value ;
}
PyObject * swig_int::__bool__() {
return __nonzero__() ;
}

View File

@ -80,5 +80,8 @@ class swig_int {
PyObject * __hex__() ;
PyObject * __len__() ;
int __index__() ;
PyObject * __bool__() ;
} ;

View File

@ -218,9 +218,16 @@ int swig_ref::__setitem__( int ii, PyObject * obj1 ) {
} else if (PyInt_Check(obj1)) {
v_tree.v_data->type = TRICK_LONG_LONG ;
v_tree.v_data->value.ll = PyInt_AsLong(obj1) ;
#if PY_VERSION_HEX >= 0x03000000
} else if ( PyUnicode_Check(obj1) ) {
v_tree.v_data->type = TRICK_STRING ;
PyObject * temp = PyUnicode_AsEncodedString(obj1, "utf-8", "Error ~");
v_tree.v_data->value.cp = strdup(PyBytes_AS_STRING(temp)) ;
#else
} else if (PyString_Check(obj1)) {
v_tree.v_data->type = TRICK_STRING ;
v_tree.v_data->value.cp = PyString_AsString(obj1) ;
#endif
} else if (SWIG_IsOK(SWIG_ConvertPtr(obj1, &argp2,SWIG_TypeQuery("_p_swig_double"), 0 ))) {
swig_double * temp_m = reinterpret_cast< swig_double * >(argp2) ;
ref_copy.units = (char *)temp_m->units.c_str() ;
@ -440,7 +447,11 @@ int swig_ref::__setitem__( PyObject * index , PyObject * obj1 ) {
// TODO: make sure obj1 is list or tuple. Handle singular values on RHS
// get the start, stop, and step value of the slice
#if PY_VERSION_HEX >= 0x03000000
status = PySlice_GetIndices( index , ref.attr->index[0].size , &start , &stop , &step ) ;
#else
status = PySlice_GetIndices( (PySliceObject *)index , ref.attr->index[0].size , &start , &stop , &step ) ;
#endif
if ( status == 0 ) {
V_TREE v_tree ;
@ -801,7 +812,11 @@ PyObject * swig_ref::__getitem__( PyObject * index ) {
Py_ssize_t ii , start , stop , step ;
// get the start, stop, and step value of the slice
#if PY_VERSION_HEX >= 0x03000000
status = PySlice_GetIndices( index , temp_ref.attr->index[0].size , &start , &stop , &step ) ;
#else
status = PySlice_GetIndices( (PySliceObject *)index , temp_ref.attr->index[0].size , &start , &stop , &step ) ;
#endif
if ( status == 0 ) {
// only work with final index of array... no pointer dims yet. (Alex)
if ( temp_ref.num_index_left == 1 ) {

View File

@ -20,8 +20,14 @@ PyObject * attach_units(PyObject * in_units_obj , PyObject * in_object) {
std::string in_units ;
void * my_argp ;
#if PY_VERSION_HEX >= 0x03000000
if ( PyUnicode_Check(in_units_obj) ) {
PyObject * temp = PyUnicode_AsEncodedString(in_units_obj, "utf-8", "Error ~");
in_units = PyBytes_AS_STRING(temp) ;
#else
if ( PyString_Check(in_units_obj) ) {
in_units = PyString_AsString(in_units_obj) ;
#endif
in_units.erase(remove_if(in_units.begin(), in_units.end(), isspace), in_units.end());
if ( ! in_units.compare("--")) {
in_units = "1" ;