diff options
author | Eric Jones <eric@enthought.com> | 2002-01-13 22:04:09 +0000 |
---|---|---|
committer | Eric Jones <eric@enthought.com> | 2002-01-13 22:04:09 +0000 |
commit | e6c3b438b2e9897b9f23d1784f15f898525d6617 (patch) | |
tree | 9be46572f6663326b6b3eae7e6b7b03c8a29a764 | |
parent | 79501722383e037a4e4a10d009c5ed338eb91e93 (diff) | |
download | numpy-e6c3b438b2e9897b9f23d1784f15f898525d6617.tar.gz |
consolidating much of the C++ code for converting variables into a single file, conversion_code.py. It contains a couple of CXX specific lines, but most everything that is CXX specific is still in the cxx_info file.
The code that was divided between common_info and scalar_info is pretty much consolidated together.
-rw-r--r-- | weave/common_info.py | 145 | ||||
-rwxr-xr-x | weave/conversion_code.py | 409 | ||||
-rwxr-xr-x | weave/scalar_info.py | 98 |
3 files changed, 428 insertions, 224 deletions
diff --git a/weave/common_info.py b/weave/common_info.py index da2278845..914134aea 100644 --- a/weave/common_info.py +++ b/weave/common_info.py @@ -7,148 +7,37 @@ import base_info # Basic module support code ############################################################# -module_support_code = \ -""" - -char* find_type(PyObject* py_obj) -{ - if(py_obj == NULL) return "C NULL value"; - if(PyCallable_Check(py_obj)) return "callable"; - if(PyString_Check(py_obj)) return "string"; - if(PyInt_Check(py_obj)) return "int"; - if(PyFloat_Check(py_obj)) return "float"; - if(PyDict_Check(py_obj)) return "dict"; - if(PyList_Check(py_obj)) return "list"; - if(PyTuple_Check(py_obj)) return "tuple"; - if(PyFile_Check(py_obj)) return "file"; - if(PyModule_Check(py_obj)) return "module"; - - //should probably do more intergation (and thinking) on these. - if(PyCallable_Check(py_obj) && PyInstance_Check(py_obj)) return "callable"; - if(PyInstance_Check(py_obj)) return "instance"; - if(PyCallable_Check(py_obj)) return "callable"; - return "unkown type"; -} - -void handle_bad_type(PyObject* py_obj, char* good_type, char* var_name) -{ - char msg[500]; - sprintf(msg,"received '%s' type instead of '%s' for variable '%s'", - find_type(py_obj),good_type,var_name); - throw Py::TypeError(msg); -} -""" +from conversion_code import module_support_code +from conversion_code import file_convert_code +from conversion_code import instance_convert_code +from conversion_code import callable_convert_code +from conversion_code import module_convert_code +from conversion_code import scalar_support_code +from conversion_code import non_template_scalar_support_code class basic_module_info(base_info.base_info): _headers = ['"Python.h"'] _support_code = [module_support_code] -############################################################# -# File conversion support code -############################################################# - -file_convert_code = \ -""" -FILE* py_to_file(PyObject* py_obj, char* name) -{ - if (!py_obj || !PyFile_Check(py_obj)) - handle_bad_type(py_obj,"file", name); - - // Cleanup code should call DECREF - Py_INCREF(py_obj); - return PyFile_AsFile(py_obj); -} - -PyObject* file_to_py(FILE* file, char* name, char* mode) -{ - PyObject* py_obj = NULL; - //extern int fclose(FILE *); - return (PyObject*) PyFile_FromFile(file, name, mode, fclose); -} - -""" - class file_info(base_info.base_info): _headers = ['<stdio.h>'] _support_code = [file_convert_code] -############################################################# -# Instance info code -############################################################# - -instance_convert_code = \ -""" -PyObject* py_to_instance(PyObject* py_obj, char* name) -{ - if (!py_obj || !PyFile_Check(py_obj)) - handle_bad_type(py_obj,"instance", name); - - // Should I INCREF??? - // Py_INCREF(py_obj); - // just return the raw python pointer. - return py_obj; -} - -PyObject* instance_to_py(PyObject* instance) -{ - // Don't think I need to do anything... - return (PyObject*) instance; -} - -""" class instance_info(base_info.base_info): _support_code = [instance_convert_code] -############################################################# -# Callable info code -############################################################# - -callable_convert_code = \ -""" -PyObject* py_to_callable(PyObject* py_obj, char* name) -{ - if (!py_obj || !PyCallable_Check(py_obj)) - handle_bad_type(py_obj,"callable", name); - - // Should I INCREF??? - // Py_INCREF(py_obj); - // just return the raw python pointer. - return py_obj; -} - -PyObject* callable_to_py(PyObject* callable) -{ - // Don't think I need to do anything... - return (PyObject*) callable; -} - -""" class callable_info(base_info.base_info): _support_code = [callable_convert_code] -############################################################# -# Module info code -############################################################# - -module_convert_code = \ -""" -PyObject* py_to_module(PyObject* py_obj, char* name) -{ - if (!py_obj || !PyModule_Check(py_obj)) - handle_bad_type(py_obj,"module", name); - - // Should I INCREF??? - // Py_INCREF(py_obj); - // just return the raw python pointer. - return py_obj; -} - -PyObject* module_to_py(PyObject* module) -{ - // Don't think I need to do anything... - return (PyObject*) module; -} - -""" class module_info(base_info.base_info): _support_code = [module_convert_code] + +class scalar_info(base_info.base_info): + _warnings = ['disable: 4275', 'disable: 4101'] + _headers = ['<complex>','<math.h>'] + def support_code(self): + if self.compiler != 'msvc': + # maybe this should only be for gcc... + return [scalar_support_code,non_template_scalar_support_code] + else: + return [non_template_scalar_support_code] diff --git a/weave/conversion_code.py b/weave/conversion_code.py new file mode 100755 index 000000000..91e0d2353 --- /dev/null +++ b/weave/conversion_code.py @@ -0,0 +1,409 @@ +""" C/C++ code strings needed for converting most non-sequence + Python variables: + module_support_code -- several routines used by most other code + conversion methods. It holds the only + CXX dependent code in this file. The CXX + stuff is used for exceptions + file_convert_code + instance_convert_code + callable_convert_code + module_convert_code + + scalar_convert_code + non_template_scalar_support_code + Scalar conversion covers int, float, double, complex, + and double complex. While Python doesn't support all these, + Numeric does and so all of them are made available. + Python longs are currently converted to C ints. Any + better way to handle this? +""" + +import base_info + +############################################################# +# Basic module support code +############################################################# + +module_support_code = \ +""" + +char* find_type(PyObject* py_obj) +{ + if(py_obj == NULL) return "C NULL value"; + if(PyCallable_Check(py_obj)) return "callable"; + if(PyString_Check(py_obj)) return "string"; + if(PyInt_Check(py_obj)) return "int"; + if(PyFloat_Check(py_obj)) return "float"; + if(PyDict_Check(py_obj)) return "dict"; + if(PyList_Check(py_obj)) return "list"; + if(PyTuple_Check(py_obj)) return "tuple"; + if(PyFile_Check(py_obj)) return "file"; + if(PyModule_Check(py_obj)) return "module"; + + //should probably do more intergation (and thinking) on these. + if(PyCallable_Check(py_obj) && PyInstance_Check(py_obj)) return "callable"; + if(PyInstance_Check(py_obj)) return "instance"; + if(PyCallable_Check(py_obj)) return "callable"; + return "unkown type"; +} + +void handle_bad_type(PyObject* py_obj, char* good_type, char* var_name) +{ + char msg[500]; + sprintf(msg,"received '%s' type instead of '%s' for variable '%s'", + find_type(py_obj),good_type,var_name); + throw Py::TypeError(msg); +} + +void handle_conversion_error(PyObject* py_obj, char* good_type, char* var_name) +{ + char msg[500]; + sprintf(msg,"Conversion Error:, received '%s' type instead of '%s' for variable '%s'", + find_type(py_obj),good_type,var_name); + throw Py::TypeError(msg); +} + +""" + +############################################################# +# File conversion support code +############################################################# + +file_convert_code = \ +""" + +FILE* convert_to_file(PyObject* py_obj, char* name) +{ + if (!py_obj || !PyFile_Check(py_obj)) + handle_conversion_error_type(py_obj,"file", name); + + // Cleanup code should call DECREF + Py_INCREF(py_obj); + return PyFile_AsFile(py_obj); +} + +FILE* py_to_file(PyObject* py_obj, char* name) +{ + if (!py_obj || !PyFile_Check(py_obj)) + handle_bad_type(py_obj,"file", name); + + // Cleanup code should call DECREF + Py_INCREF(py_obj); + return PyFile_AsFile(py_obj); +} + +PyObject* file_to_py(FILE* file, char* name, char* mode) +{ + PyObject* py_obj = NULL; + //extern int fclose(FILE *); + return (PyObject*) PyFile_FromFile(file, name, mode, fclose); +} + +""" + +############################################################# +# Instance conversion code +############################################################# + +instance_convert_code = \ +""" + +PyObject* convert_to_instance(PyObject* py_obj, char* name) +{ + if (!py_obj || !PyFile_Check(py_obj)) + handle_conversion_error(py_obj,"instance", name); + + // Should I INCREF??? + // Py_INCREF(py_obj); + // just return the raw python pointer. + return py_obj; +} + +PyObject* py_to_instance(PyObject* py_obj, char* name) +{ + if (!py_obj || !PyFile_Check(py_obj)) + handle_bad_type(py_obj,"instance", name); + + // Should I INCREF??? + // Py_INCREF(py_obj); + // just return the raw python pointer. + return py_obj; +} + +PyObject* instance_to_py(PyObject* instance) +{ + // Don't think I need to do anything... + return (PyObject*) instance; +} + +""" + +############################################################# +# Callable conversion code +############################################################# + +callable_convert_code = \ +""" + +PyObject* convert_to_callable(PyObject* py_obj, char* name) +{ + if (!py_obj || !PyCallable_Check(py_obj)) + handle_conversion_error(py_obj,"callable", name); + + // Should I INCREF??? + // Py_INCREF(py_obj); + // just return the raw python pointer. + return py_obj; +} + +PyObject* py_to_callable(PyObject* py_obj, char* name) +{ + if (!py_obj || !PyCallable_Check(py_obj)) + handle_bad_type(py_obj,"callable", name); + + // Should I INCREF??? + // Py_INCREF(py_obj); + // just return the raw python pointer. + return py_obj; +} + +PyObject* callable_to_py(PyObject* callable) +{ + // Don't think I need to do anything... + return (PyObject*) callable; +} + +""" + +############################################################# +# Module conversion code +############################################################# + +module_convert_code = \ +""" +PyObject* convert_to_module(PyObject* py_obj, char* name) +{ + if (!py_obj || !PyModule_Check(py_obj)) + handle_conversion_error(py_obj,"module", name); + + // Should I INCREF??? + // Py_INCREF(py_obj); + // just return the raw python pointer. + return py_obj; +} + +PyObject* py_to_module(PyObject* py_obj, char* name) +{ + if (!py_obj || !PyModule_Check(py_obj)) + handle_bad_type(py_obj,"module", name); + + // Should I INCREF??? + // Py_INCREF(py_obj); + // just return the raw python pointer. + return py_obj; +} + +PyObject* module_to_py(PyObject* module) +{ + // Don't think I need to do anything... + return (PyObject*) module; +} + +""" + +############################################################# +# Scalar conversion code +############################################################# + +import base_info + +# this code will not build with msvc... +scalar_support_code = \ +""" +// conversion routines + +template<class T> +static T convert_to_scalar(PyObject* py_obj,char* name) +{ + //never used. + return (T) 0; +} +template<> +static int convert_to_scalar<int>(PyObject* py_obj,char* name) +{ + if (!py_obj || !PyInt_Check(py_obj)) + handle_conversion_error(py_obj,"int", name); + return (int) PyInt_AsLong(py_obj); +} + +template<> +static long convert_to_scalar<long>(PyObject* py_obj,char* name) +{ + if (!py_obj || !PyLong_Check(py_obj)) + handle_conversion_error(py_obj,"long", name); + return (long) PyLong_AsLong(py_obj); +} + +template<> +static double convert_to_scalar<double>(PyObject* py_obj,char* name) +{ + if (!py_obj || !PyFloat_Check(py_obj)) + handle_conversion_error(py_obj,"float", name); + return PyFloat_AsDouble(py_obj); +} + +template<> +static float convert_to_scalar<float>(PyObject* py_obj,char* name) +{ + return (float) convert_to_scalar<double>(py_obj,name); +} + +// complex not checked. +template<> +static std::complex<float> convert_to_scalar<std::complex<float> >(PyObject* py_obj, + char* name) +{ + if (!py_obj || !PyComplex_Check(py_obj)) + handle_conversion_error(py_obj,"complex", name); + return std::complex<float>((float) PyComplex_RealAsDouble(py_obj), + (float) PyComplex_ImagAsDouble(py_obj)); +} +template<> +static std::complex<double> convert_to_scalar<std::complex<double> >( + PyObject* py_obj,char* name) +{ + if (!py_obj || !PyComplex_Check(py_obj)) + handle_conversion_error(py_obj,"complex", name); + return std::complex<double>(PyComplex_RealAsDouble(py_obj), + PyComplex_ImagAsDouble(py_obj)); +} + +///////////////////////////////// +// standard translation routines + +template<class T> +static T py_to_scalar(PyObject* py_obj,char* name) +{ + //never used. + return (T) 0; +} +template<> +static int py_to_scalar<int>(PyObject* py_obj,char* name) +{ + if (!py_obj || !PyInt_Check(py_obj)) + handle_bad_type(py_obj,"int", name); + return (int) PyInt_AsLong(py_obj); +} + +template<> +static long py_to_scalar<long>(PyObject* py_obj,char* name) +{ + if (!py_obj || !PyLong_Check(py_obj)) + handle_bad_type(py_obj,"long", name); + return (long) PyLong_AsLong(py_obj); +} + +template<> +static double py_to_scalar<double>(PyObject* py_obj,char* name) +{ + if (!py_obj || !PyFloat_Check(py_obj)) + handle_bad_type(py_obj,"float", name); + return PyFloat_AsDouble(py_obj); +} + +template<> +static float py_to_scalar<float>(PyObject* py_obj,char* name) +{ + return (float) py_to_scalar<double>(py_obj,name); +} + +// complex not checked. +template<> +static std::complex<float> py_to_scalar<std::complex<float> >(PyObject* py_obj, + char* name) +{ + if (!py_obj || !PyComplex_Check(py_obj)) + handle_bad_type(py_obj,"complex", name); + return std::complex<float>((float) PyComplex_RealAsDouble(py_obj), + (float) PyComplex_ImagAsDouble(py_obj)); +} +template<> +static std::complex<double> py_to_scalar<std::complex<double> >( + PyObject* py_obj,char* name) +{ + if (!py_obj || !PyComplex_Check(py_obj)) + handle_bad_type(py_obj,"complex", name); + return std::complex<double>(PyComplex_RealAsDouble(py_obj), + PyComplex_ImagAsDouble(py_obj)); +} +""" + +non_template_scalar_support_code = \ +""" + +// Conversion Errors + +static int convert_to_int(PyObject* py_obj,char* name) +{ + if (!py_obj || !PyInt_Check(py_obj)) + handle_conversion_error(py_obj,"int", name); + return (int) PyInt_AsLong(py_obj); +} + +static long convert_to_long(PyObject* py_obj,char* name) +{ + if (!py_obj || !PyLong_Check(py_obj)) + handle_conversion_error(py_obj,"long", name); + return (long) PyLong_AsLong(py_obj); +} + +static double convert_to_float(PyObject* py_obj,char* name) +{ + if (!py_obj || !PyFloat_Check(py_obj)) + handle_conversion_error(py_obj,"float", name); + return PyFloat_AsDouble(py_obj); +} + +// complex not checked. +static std::complex<double> convert_to_complex(PyObject* py_obj,char* name) +{ + if (!py_obj || !PyComplex_Check(py_obj)) + handle_conversion_error(py_obj,"complex", name); + return std::complex<double>(PyComplex_RealAsDouble(py_obj), + PyComplex_ImagAsDouble(py_obj)); +} + +///////////////////////////////////// +// The following functions are used for scalar conversions in msvc +// because it doesn't handle templates as well. + +static int py_to_int(PyObject* py_obj,char* name) +{ + if (!py_obj || !PyInt_Check(py_obj)) + handle_bad_type(py_obj,"int", name); + return (int) PyInt_AsLong(py_obj); +} + +static long py_to_long(PyObject* py_obj,char* name) +{ + if (!py_obj || !PyLong_Check(py_obj)) + handle_bad_type(py_obj,"long", name); + return (long) PyLong_AsLong(py_obj); +} + +static double py_to_float(PyObject* py_obj,char* name) +{ + if (!py_obj || !PyFloat_Check(py_obj)) + handle_bad_type(py_obj,"float", name); + return PyFloat_AsDouble(py_obj); +} + +// complex not checked. +static std::complex<double> py_to_complex(PyObject* py_obj,char* name) +{ + if (!py_obj || !PyComplex_Check(py_obj)) + handle_bad_type(py_obj,"complex", name); + return std::complex<double>(PyComplex_RealAsDouble(py_obj), + PyComplex_ImagAsDouble(py_obj)); +} +""" diff --git a/weave/scalar_info.py b/weave/scalar_info.py index eb2e4fa00..c87427d48 100755 --- a/weave/scalar_info.py +++ b/weave/scalar_info.py @@ -10,102 +10,8 @@ import base_info -# this code will not build with msvc... -scalar_support_code = \ -""" -template<class T> -static T py_to_scalar(PyObject* py_obj,char* name) -{ - //never used. - return (T) 0; -} -template<> -static int py_to_scalar<int>(PyObject* py_obj,char* name) -{ - if (!py_obj || !PyInt_Check(py_obj)) - handle_bad_type(py_obj,"int", name); - return (int) PyInt_AsLong(py_obj); -} - -template<> -static long py_to_scalar<long>(PyObject* py_obj,char* name) -{ - if (!py_obj || !PyLong_Check(py_obj)) - handle_bad_type(py_obj,"long", name); - return (long) PyLong_AsLong(py_obj); -} - -template<> -static double py_to_scalar<double>(PyObject* py_obj,char* name) -{ - if (!py_obj || !PyFloat_Check(py_obj)) - handle_bad_type(py_obj,"float", name); - return PyFloat_AsDouble(py_obj); -} - -template<> -static float py_to_scalar<float>(PyObject* py_obj,char* name) -{ - return (float) py_to_scalar<double>(py_obj,name); -} - -// complex not checked. -template<> -static std::complex<float> py_to_scalar<std::complex<float> >(PyObject* py_obj, - char* name) -{ - if (!py_obj || !PyComplex_Check(py_obj)) - handle_bad_type(py_obj,"complex", name); - return std::complex<float>((float) PyComplex_RealAsDouble(py_obj), - (float) PyComplex_ImagAsDouble(py_obj)); -} -template<> -static std::complex<double> py_to_scalar<std::complex<double> >( - PyObject* py_obj,char* name) -{ - if (!py_obj || !PyComplex_Check(py_obj)) - handle_bad_type(py_obj,"complex", name); - return std::complex<double>(PyComplex_RealAsDouble(py_obj), - PyComplex_ImagAsDouble(py_obj)); -} -""" - -# this code will not build with msvc... -non_template_scalar_support_code = \ -""" -// The following functions are used for scalar conversions in msvc -// because it doesn't handle templates as well. - -static int py_to_int(PyObject* py_obj,char* name) -{ - if (!py_obj || !PyInt_Check(py_obj)) - handle_bad_type(py_obj,"int", name); - return (int) PyInt_AsLong(py_obj); -} - -static long py_to_long(PyObject* py_obj,char* name) -{ - if (!py_obj || !PyLong_Check(py_obj)) - handle_bad_type(py_obj,"long", name); - return (long) PyLong_AsLong(py_obj); -} - -static double py_to_float(PyObject* py_obj,char* name) -{ - if (!py_obj || !PyFloat_Check(py_obj)) - handle_bad_type(py_obj,"float", name); - return PyFloat_AsDouble(py_obj); -} - -// complex not checked. -static std::complex<double> py_to_complex(PyObject* py_obj,char* name) -{ - if (!py_obj || !PyComplex_Check(py_obj)) - handle_bad_type(py_obj,"complex", name); - return std::complex<double>(PyComplex_RealAsDouble(py_obj), - PyComplex_ImagAsDouble(py_obj)); -} -""" +from conversion_code import scalar_support_code +from conversion_code import non_template_scalar_support_code class scalar_info(base_info.base_info): _warnings = ['disable: 4275', 'disable: 4101'] |