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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.