Use PEP383 to embed non-decodable bytes in argv
Users who need the original bytes can use `.encode('utf8', 'surrogateescape')` to get them back.
Without this change, passing non-decodable bytes would just cause cocotb to fail to startup.
This behavior is consistent with how `sys.argv` is handled on UNIX platforms by python itself.
@@ -302,10 +302,20 @@ int embed_sim_init(gpi_sim_info_t *info)
goto cleanup;
}
for (i = 0; i < info->argc; i++) {
- PyObject *argv_item = PyUnicode_FromString(info->argv[i]); // New reference
+ PyObject *argv_item_raw = PyBytes_FromString(info->argv[i]); // New reference
+ if (argv_item_raw == NULL) {
+ PyErr_Print();
+ LOG_ERROR("Unable to create argv item");
+ Py_DECREF(argv_list);
+ goto cleanup;
+ }
+ // Decode, embedding non-decodable bytes using PEP-383. This can only
+ // fail with MemoryError or similar.
+ PyObject *argv_item = PyUnicode_FromEncodedObject(argv_item_raw, NULL, "surrogateescape");
+ Py_DECREF(argv_item_raw);
if (argv_item == NULL) {
PyErr_Print();
- LOG_ERROR("Unable to create Python string from argv[%d] = \"%s\"", i, info->argv[i]);
+ LOG_ERROR("Unable to decode argv item");
Py_DECREF(argv_list);
goto cleanup;
}
