Importing package modules from C-extension

Mark English Mark.English at liffe.com
Thu Mar 17 09:20:23 EST 2005


Basic problem:
If there is a C-extension module in a package and it tries to import
another python module in the same package without using the fully
qualified path, the import fails.

Config:
Python 2.4 on Windows 2000

For example:
mypackage contains:
  cextension_example.pyd
  to_be_imported.py
  does_an_import.py

Where:
  "mypackage" is a directory with an empty "__init__.py" file
  "cextension_example.pyd" is a c-extension module
  "to_be_imported.py" is a python module used by other python modules
  "does_an_import.py" is a python module which imports
"to_be_imported.py".

In other words "does_an_import.py" looks like this:
---Start code---
import to_be_imported
print to_be_imported
---End code---

and "to_be_imported.py" looks like this:
---Start code---
print 'Importing:', __file__
---End code---

The c-extension "cextension_example.pyd" contains a line in its
initialisation routine:
---Start code---
PyObject *pToBeImported = PyImport_Import("to_be_imported");
---End code---
Which returns NULL. I'd rather it imported the module from the local
package.

If at a python prompt I do this:
>>> import mypackage.does_an_import
it works fine as I would expect from reading the documentation.
It starts by looking in the package where it is currently placed before
searching the PYTHONPATH.

If at a python prompt I do this:
>>> import mypackage.cextension_example
it fails to import "to_be_imported.py" which I do not expect.
It does not look in the package where it is currently placed.

In the past I have used the solution of a fully qualified path:
E.g.
---Start code---
PyObject *pToBeImported = PyImport_Import("mypackage.to_be_imported");
---End code---

However this time my application is building library paths at runtime
and doesn't know exactly what's going to be where. I can guarantee the
directory structure will be like that above.

So, how do I get the behaviour of "import", rather than the behaviour of
what looks more like "__import__" ?

Guesswork and speculation:
>From looking at the python source, it seems that in my C extension I
need access to the module's dictionary (passed as globals and locals
parameters to import functions), so that the parent package's __name__
entry can be used later on.

Leading to more questions:
If this is the case, how do I get at the current module and its
dictionary from a c-extension function that takes no parameters ? Do I
have to stash it away internally in the C-code on initialisation, or is
there some thread local object I can get it from (either directly, or
from the current frame) ? Is it good programming practice to use
"PyThreadState_Get()->frame" ?

Thanks for any help,
Mark



-----------------------------------------------------------------------
The information contained in this e-mail is confidential and solely 
for the intended addressee(s). Unauthorised reproduction, disclosure, 
modification, and/or distribution of this email may be unlawful. If you 
have received this email in error, please notify the sender immediately 
and delete it from your system. The views expressed in this message 
do not necessarily reflect those of LIFFE Holdings Plc or any of its subsidiary companies.
-----------------------------------------------------------------------




More information about the Python-list mailing list