Skip to content
This repository has been archived by the owner on Sep 27, 2023. It is now read-only.

Add support for python properties #748

Merged
merged 1 commit into from
Sep 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions docs/GLM/Property/Python.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
[[/GLM/Property/Python]] -- Python property

# Synopsis

GLM:

~~~
class <class-name> {
python <property-name>;
}
object <class-name> {
<property-name> <type(<value>);
}
~~~

# Description

The `python` property type support general python objects. Although any type of object is supported, only those that implement the python `str` method as useful because GridLAB-D require the `str()` to generate the values for data exchange.

# Examples

~~~
class test
{
python py_object;
}
object test
{
py_object None;
}
object test
{
py_object int(1);
}
object test
{
py_object float(0.0);
}
object test
{
py_object float(1.23);
}
object test
{
py_object str('text');
}
object test
{
py_object list([1,2,3]);
}
object test
{
py_object dict(a=1,b=2,c=3);
}
~~~

56 changes: 56 additions & 0 deletions gldcore/autotest/test_python_property.glm
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@

#set savefile=gridlabd.json

class test
{
python py_object;
}

object test
{
name "test_none";
py_object None;
}

object test
{
name "test_0";
py_object int(0);
}

object test
{
name "test_1";
py_object int(1);
}

object test
{
name "test_0.0";
py_object float(0.0);
}

object test
{
name "test_1.23";
py_object float(1.23);
}

object test
{
name "test_str";
py_object str('text');
}

object test
{
name "test_list";
py_object list([1,2,3]);
}

object test
{
name "test_dict";
py_object dict(a=1,b=2,c=3);
}

1 change: 1 addition & 0 deletions gldcore/property.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ PROPERTYSPEC property_type[_PT_LAST] = {
{"randomvar", "string", NULL, sizeof(randomvar), 24, convert_from_randomvar, convert_to_randomvar, initial_from_randomvar,randomvar_create,NULL,convert_to_double,{TCOPS(double)},random_get_part,random_set_part},
{"method","string", NULL, 0, PSZ_DYNAMIC, convert_from_method,convert_to_method,initial_from_method},
{"string", "string", "", sizeof(STRING), PSZ_AUTO, convert_from_string, convert_to_string, NULL,string_create,NULL,convert_to_string,{TCOPS(string)},},
{"python", "string", "None", sizeof(PyObject**), PSZ_AUTO, convert_from_python, convert_to_python, initial_from_python, python_create,NULL,convert_to_python,{TCNONE},python_get_part,NULL},
};

PROPERTYTYPE property_getfirst_type(void)
Expand Down
1 change: 1 addition & 0 deletions gldcore/property.h
Original file line number Diff line number Diff line change
Expand Up @@ -1079,6 +1079,7 @@ enum e_propertytype {_PT_FIRST=-1,
PT_random,
PT_method,
PT_string,
PT_python,
/* add new property types here - don't forget to add them also to rt/gridlabd.h and property.c */
#ifdef USE_TRIPLETS
PT_triple,
Expand Down
48 changes: 48 additions & 0 deletions gldcore/python_embed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ void python_embed_init(int argc, const char *argv[])
PyInit_gridlabd();
}
gridlabd_module = this_module;
Py_INCREF(gridlabd_module);
Py_INCREF(main_module);
}

void *python_loader_init(int argc, const char **argv)
Expand All @@ -39,6 +41,8 @@ void *python_loader_init(int argc, const char **argv)

void python_embed_term()
{
Py_DECREF(gridlabd_module);
Py_DECREF(main_module);
if ( Py_FinalizeEx() )
{
output_warning("Py_FinalizeEx() failed");
Expand Down Expand Up @@ -369,9 +373,11 @@ bool python_parser(const char *line, void *context)
{
module = main_module;
}
Py_INCREF(module);

const char *command = input_buffer.c_str();
PyObject *result = PyRun_String(command,Py_file_input,module,module);
Py_DECREF(module);
if ( result == NULL )
{
output_error("python_parser(NULL,...): command '%s' failed",command);
Expand All @@ -386,3 +392,45 @@ bool python_parser(const char *line, void *context)
return true;
}
}

// Function: convert_from_double
DEPRECATED int convert_from_python(char *buffer, int size, void *data, PROPERTY *prop)
{
PyObject *raw = PyObject_Str(*(PyObject**)data);
PyObject *uni = PyUnicode_AsEncodedString(raw,"utf-8","~E~");
std::string bytes(PyBytes_AS_STRING(uni));
Py_XDECREF(raw);
Py_XDECREF(uni);
int len = bytes.length();
strncpy(buffer,bytes.c_str(),size-1);
return len < size-1 ? len : size-1;
}

// Function: convert_to_double
DEPRECATED int convert_to_python(const char *buffer, void *data, PROPERTY *prop)
{
PyObject **pObj = (PyObject **)data;
Py_DECREF(*pObj);
*pObj = PyRun_String(buffer,Py_eval_input,main_module,main_module);
return *pObj ? strlen(buffer) : -1;
}

DEPRECATED int initial_from_python(char *buffer, int size, void *data, PROPERTY *prop)
{
return convert_from_python(buffer,size,data,prop);
}

DEPRECATED int python_create(void *ptr)
{
PyObject **pObj = (PyObject**)ptr;
*pObj = Py_None;
Py_INCREF(Py_None);
return 1;
}

double python_get_part(void *c, const char *name)
{
return QNAN;
}


13 changes: 13 additions & 0 deletions gldcore/python_embed.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,17 @@ bool python_parser(const char *line=NULL, void *context = NULL);
// forward declarations to gldcore/link/python.c
MODULE *python_module_load(const char *, int, const char *[]);

// Function: convert_from_double
DEPRECATED int convert_from_python(char *buffer, int size, void *data, PROPERTY *prop);

// Function: convert_to_double
DEPRECATED int convert_to_python(const char *buffer, void *data, PROPERTY *prop);

DEPRECATED int initial_from_python(char *buffer, int size, void *data, PROPERTY *prop);

DEPRECATED int python_create(void *ptr);

double python_get_part(void *c, const char *name);


#endif
1 change: 1 addition & 0 deletions gldcore/rt/gridlabd.h
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,7 @@ typedef enum {_PT_FIRST=-1,
PT_random, /**< Randomized number */
PT_method, /**< Method interface */
PT_string,
PT_python,
#ifdef USE_TRIPLETS
PT_triple, /**< triplet of doubles (not supported) */
PT_triplex, /**< triplet of complexes (not supported) */
Expand Down