3

I have a small python module I have created with the Python C API which I call mycore.

I have also created some utility scripts in Python which are related.

How can I put both in the same module namespace? I know I can call Python code from my C code but surely there is an easier way to do that.

Thanks

3
  • Did you play around with boost python? Commented Jul 2, 2014 at 16:14
  • I'm quite happy with the C API Commented Jul 2, 2014 at 16:15
  • I have the same question. Commented Aug 9, 2018 at 20:55

2 Answers 2

3

The obvious way is by making mycore a package. Create a mycore/__init__.py that imports both the C part, typically named something like _mycore, and the Python part:

from _mycore import *
from _mycorepy import *

In the same directory you'd have a _mycore.so and _mycorepy.py.

Another way to mix Python and C code is by invoking PyRun_String on the embedded Python. This might be what you mean by I know I can call Python code from my C code..., but just in case, here is a simple example with the potentially tricky refcounting details:

PyObject *get_factory()
{
  PyObject *g, *runret, *factory;
  // prepare a dictionary for the module to run in
  g = Py_BuildValue("{s:O}", "__builtins__", PyEval_GetBuiltins());
  if (!g)
    return NULL;
  // run Python code in the dictionary -- the code may import modules, etc.
  runret = PyRun_String("\
def factory():\n\
    return 42\n", Py_file_input, g, NULL);
  Py_XDECREF(runret);
  if (!runret) {
    Py_DECREF(g);
    return NULL;
  }
  Py_DECREF(runret);
  // pick the stuff you care about from the dictionary and return it
  factory = PyDict_GetItemString(g, "factory");
  Py_INCREF(factory);
  Py_DECREF(g);
  return factory;
}
Sign up to request clarification or add additional context in comments.

3 Comments

Is this the best resource for learning about packages? guide.python-distribute.org/creation.html Also, why the underscore before the mycore* ?
@user3275885 The link appears to be about distributing on PyPI and others. The answer refers to Python packages, which are simply modules spread into several files, defined by a directory with __init__.py. The underscore in _mycore signifies that mycore._mycore is an implementation detail of the mycore package, and not something the user of the package should be importing themselves.
the PyRun_String() will surely work, but I was hoping to avoid any extra "glue" . Thank you @user4815162342
0

OK, this worked for me. My circumstances may be different. My C module was built internally and provided to my embedded Python with a call to PyImport_AppendInittab().

But I still had some accompanying Python code that I wanted associated with the same namespace.

So I got it working by naming my C code _mygadget and the Python file mygadget.py. For the first line of mygadget.py I wrote:

from _mygadget import *

This seems to work. I don't know what would happen if I had a Python method and C call with the same name. I am avoiding that at present.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.