[Python-Dev] Issues about relative& absolute import way for Porting from python2.4 to python2.7

Brett Cannon brett at python.org
Wed Mar 19 15:35:45 CET 2014


This mailing list is for the development *of* Python, the the *use* of
Python. Your best option for getting an answer is to ask on python-list or
python-help.


On Tue, Mar 18, 2014 at 9:50 PM, 北冰洋 <wtz_wh at foxmail.com> wrote:

> Dear,
>
> I just wrote a sample like this:
> testPy/
>          __init__.py
>          client.py
>          SoamFactory.c
>          SoamFactory.so
>          soamapi.py
>          sample/testP.py
> export PYTHONPATH=$(TEST_LOCATION):$(TEST_LOCATION)/testPy
> Here's the source codes:
> *__init__.py:*
> import client
> *client.py*
> import soamapi
> class Client(soamapi.SessionCallback):
>
>   def __init__(self):
>     print "----class Client----"
>     super(Client, self).__init__()
>     soamapi.initialize()
>
>   def create_session(self):
>     sec_cb = soamapi.DefaultSecurityCallback()
>     self.connection = soamapi.connect(sec_cb)
> *soamapi.py*
> import SoamFactory
>
> class ConnectionSecurityCallback(object):
>   def __init__(self):
>     print "----class ConnectionSecurityCallback----"
>
>   def __del__(self):
>     pass
>
>   def test_P(self):
>     print "test_P in class ConnectionSecurityCallback"
>
> class DefaultSecurityCallback(ConnectionSecurityCallback):
>   def __init__(self):
>     super(DefaultSecurityCallback, self).__init__()
>     print "----class DefaultSecurityCallback----"
>
>   def __del__(self):
>     super(DefaultSecurityCallback, self).__del__()
>
>   def test(self):
>     print "test in class DefaultSecurityCallback"
>
> class SessionCallback(object):
>   def __init__(self):
>     pass
>
>   def __del__(self):
>     pass
>
> def connect(security_callback):
>   return SoamFactory.SoamFactory_connect(security_callback)
>
> def initialize():
>   SoamFactory.SoamFactory_initialize()
>
> print "call soamapi"
> *SoamFactory.c*
> #include "Python.h"
> #include "PythonLoop.c"
>
> PyObject* SOAM_API_MODULE = NULL;
> PyObject* pyModule = NULL;
>
> static PyObject* SoamFactory_initialize(PyObject* self, PyObject* args){
>     PyEval_InitThreads();
>     init();
>     Py_RETURN_NONE;
> }
>
> static PyObject* SoamFactory_connect(PyObject* self, PyObject* args){
>     PyObject* pySecCallback = NULL;
>     int ok = PyArg_ParseTuple(args, "O", &pySecCallback);
>     if (!ok){
>         printf("parse tuple error!\n");
>         Py_RETURN_NONE;
>     }
>     if (! PyObject_IsInstance(pySecCallback, connectSecCallback)){
>         printf("pySecCallback is not an instance of
> ConnectionSecurityCallback!\n");
>         Py_RETURN_NONE;
>     }
>     printf("Successful!\n");
>     Py_RETURN_NONE;
> }
>
> static PyMethodDef SoamFactory[] = {
>     {"SoamFactory_connect", SoamFactory_connect, METH_VARARGS, "connection
> function"},
>     {"SoamFactory_initialize", SoamFactory_initialize, METH_VARARGS,
> "SoamFactory_initialize"},
>     {NULL, NULL}
> };
>
> void initSoamFactory(){
>     PyEval_InitThreads();
>     Py_Initialize();
>     pyModule = Py_InitModule("SoamFactory", SoamFactory);
>     SOAM_API_MODULE = PyImport_ImportModule("soamapi");
> }
> *sample/testP.py*
> import testPy
>
> print "========================================"
> submitter = testPy.client.Client()
> submitter.create_session()
> print "========================================"
>
> When I ran it on python2.4, it worked well, and the result was
> *call soamapi*
> *after import soamapi------client.py*
> *========================================*
> *----class Client----*
> *----class ConnectionSecurityCallback----*
> *----class DefaultSecurityCallback----*
> *Successful!*
> *========================================*
>
> But when I ran it on python2.7, it worked beyond my expectation, the
> result was
> call soamapi
> call soamapi
> ========================================
> ----class Client----
> ----class ConnectionSecurityCallback----
> ----class DefaultSecurityCallback----
> pySecCallback is not an instance of ConnectionSecurityCallback!
> ========================================
>
> I found that soamapi was imported twice, and I investigated this is
> related to absolute&relative import way.  PyImport_ImportModule in
> python2.7 uses absolute import way, it will look up sys.path to get soamapi
> module, and when testP.py file import testPy module, it will find local
> module soamapi under testPy package, and binds module's name to package, as
> testPy.soamapi.
> There are two ways to correct it for python2.7, 1) Don't use import
> testPy, use import client directly to avoid using relative; 2) Use from
> __future__ import absolute_import to enable absolute import feature.
>
> But there are two Pre-conditions:
> 1) Should not modify testP.py;
> 2) Should be ran on both python2.4 and 2.7.
>
> I don't know how to fix it. Is there any official way about how to porting
> this scenario or better idea?
>
> Thanks,
> Vatel
>
> _______________________________________________
> Python-Dev mailing list
> Python-Dev at python.org
> https://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe:
> https://mail.python.org/mailman/options/python-dev/brett%40python.org
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20140319/0195ff99/attachment.html>


More information about the Python-Dev mailing list