Python 3.6, embedded C++, add module path, TypeError: a bytes-like object is required, not 'str'

Viewed 429

I am trying to expand the module search path when embedding Python 3.6 in a C++ application. The code to insert the current working directory into the system module search path is:

PyObject *sysPath = PySys_GetObject("path");
PyObject *path = PyBytes_FromString(".");
int result = PyList_Insert(sysPath, 0, path);

This works fine (no errors), but Python is not happy when I try to run a module:

PyObject *pModule = PyImport_ImportModule("python_demo_x");

The error reported by Python is:

Could not load module python_demo_x
Traceback (most recent call last):
  File "<frozen importlib._bootstrap>", line 961, in _find_and_load
  File "<frozen importlib._bootstrap>", line 946, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 885, in _find_spec
  File "<frozen importlib._bootstrap_external>", line 1157, in find_spec
  File "<frozen importlib._bootstrap_external>", line 1129, in _get_spec
  File "<frozen importlib._bootstrap_external>", line 1245, in find_spec
  File "<frozen importlib._bootstrap_external>", line 1302, in _fill_cache
TypeError: a bytes-like object is required, not 'str'

Through trial and error, I found that wrapping the path in double quotes solves the problem:

PyObject *path = PyBytes_FromString("\".\"");

I cannot find any documentation that indicates wrapping the path is a requirement. Is this required, or is there something else wrong?

1 Answers

Python 3 changed the way strings are represented. I encountered this when using Popen to exec other apps and code externally.

Try changing all your strings from "some-string" to b"some-string" which encodes it as a byte-string. You may need to decode resulting byte-object to a string if you need a string return value. You would do that like this: .decode('utf-8')

From the Python 3.6 docs: "In Python 3.x, those implicit conversions are gone - conversions between 8-bit binary data and Unicode text must be explicit, and bytes and string objects will always compare unequal. "

More information is available here: https://docs.python.org/3/library/stdtypes.html

Related