Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom Serialization in Python Target #471

Merged
merged 5 commits into from
Jul 30, 2024
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
23 changes: 23 additions & 0 deletions python/include/pythontarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,29 @@ PyObject* convert_C_action_to_py(void* action);
*/
PyObject* get_python_function(string module, string class, int instance_id, string func);

/**
* Load the Serializer class from package name
* @param package_name Name of the python package to load
* @return Initialized Serializer class
*/
PyObject* load_serializer(string package_name);

/**
* Serialize Python object to a bytes object using external serializer
* @param obj The Python object to serialize
* @param custom_serializer The custom Serializer class
* @return Serialized Python bytes object
*/
PyObject* custom_serialize(PyObject* obj, PyObject* custom_serializer);

/**
* Deserialize Python object from a bytes object using external serializer
* @param serialized_pyobject The serialized bytes Python object
* @param custom_serializer The custom Serializer class
* @return Deserialized Python object
*/
PyObject* custom_deserialize(PyObject* serialized_pyobject, PyObject* custom_serializer);

/*
* The Python runtime will call this function to initialize the module.
* The name of this function is dynamically generated to follow
Expand Down
55 changes: 55 additions & 0 deletions python/lib/pythontarget.c
Original file line number Diff line number Diff line change
Expand Up @@ -695,3 +695,58 @@ PyObject* get_python_function(string module, string class, int instance_id, stri
PyGILState_Release(gstate);
return Py_None;
}

PyObject* load_serializer(string package_name) {
// import package_name
PyObject* pName = PyUnicode_DecodeFSDefault(package_name);
PyObject* pModule = PyImport_Import(pName);
Py_DECREF(pName);
if (PyErr_Occurred())
PyErr_Print();
if (pModule == NULL)
lf_print_error_and_exit("Could not load the custom serializer package '%s'.", package_name);
// Get the Serializer class
PyObject* SerializerClass = PyObject_GetAttrString(pModule, "Serializer");
if (PyErr_Occurred())
PyErr_Print();
if (SerializerClass == NULL)
lf_print_error_and_exit("Could not find class 'Serializer' in module '%s'.", package_name);
// Instanciate and initialize Serializer class
PyObject* custom_serializer = PyObject_CallObject(SerializerClass, NULL);
if (PyErr_Occurred())
PyErr_Print();
if (custom_serializer == NULL)
lf_print_error_and_exit("Could not instantiate class 'Serializer' in module '%s'.", package_name);
lf_print_log("Successfully loaded custom serializer package '%s'.\n", package_name);
return custom_serializer;
}

PyObject* custom_serialize(PyObject* obj, PyObject* custom_serializer) {
if (custom_serializer == NULL)
lf_print_error_and_exit("Serializer is null.");
PyObject* serializer_serialize = PyObject_GetAttrString(custom_serializer, "serialize");
PyObject* args = PyTuple_Pack(1, obj);
PyObject* serialized_pyobject = PyObject_CallObject(serializer_serialize, args);
Py_XDECREF(serializer_serialize);
Py_XDECREF(args);
if (PyErr_Occurred())
PyErr_Print();
if (serialized_pyobject == NULL)
lf_print_error_and_exit("Could not serialize object.");
return serialized_pyobject;
}

PyObject* custom_deserialize(PyObject* serialized_pyobject, PyObject* custom_serializer) {
if (custom_serializer == NULL)
lf_print_error_and_exit("Serializer is null.");
PyObject* serializer_deserialize = PyObject_GetAttrString(custom_serializer, "deserialize");
PyObject* args = PyTuple_Pack(1, serialized_pyobject);
PyObject* deserialized_obj = PyObject_CallObject(serializer_deserialize, args);
Py_XDECREF(serializer_deserialize);
Py_XDECREF(args);
if (PyErr_Occurred())
PyErr_Print();
if (deserialized_obj == NULL)
lf_print_error_and_exit("Could not deserialize deserialized_obj.");
return deserialized_obj;
}
Loading