[PyQt] sip: Can I map a C++ namespace to another name in the python bindings?

Jakob Simon-Gaarde sip at skolesys.dk
Wed Jul 1 10:31:21 BST 2009


I have a large C++ library where all classes are implemented under one 
namespace called CAPA. I ask sip to generate bindings for these classes under 
a single module called pycapa. So when I generate my bindings the resulting 
classes will be defined under pycapa.CAPA.SomeClass.

I would like to split the C++ namespace up into several python namespaces. so 
that I can group the classes and in the same module with multiple python 
namespaces. ie.

    C++ class              | python mapped class
    ------------------------------------------------
    CAPA::Session          | pycapa.session.Session
    CAPA::LoginParam       | pycapa.session.LoginParam
    CAPA::LoginResult      | pycapa.session.LoginResult
    ... etc

    C++ class              | python mapped class
    ------------------------------------------------
    CAPA::UserService      | pycapa.userservice.UserService
    CAPA::CreateUserParam  | pycapa.userservice.CreateUserParam
    CAPA::CreateUserResult | pycapa.userservice.CreateUserResult
	... etc

There are some problems with this approach, cause python namespaces resolve to 
python classes, so I can't write: from pycapa.session import *, or like it is 
now with no namespace mapping:

>>> from pycapa.CAPA import *
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named CAPA

Alternatively I'd like to remove the namespace in the resulting python 
bindings and then make several modules like, pycapa_session pycapa_userservice 
etc.

Best regards Jakob Simon-Gaarde

PS. here is my sip definition experiment which works:
------------------------------------------------
%Module pycapa 0

%Include ../common/mapped_types.sip
%Include ../common/param.sip
%Include ../common/result.sip
%Include param/loginparam.sip
%Include result/loginresult.sip
%Include param/logoffparam.sip
%Include result/logoffresult.sip

namespace CAPA {

	class Param {
%TypeHeaderCode
#include "param.h"
%End
	public:
        Param();
	};

	class Result {
%TypeHeaderCode
#include <api/session.h>
%End
	public:
        Result();
        int resCode() const;   //get metode, return m_resCode
        const std::string& resMsg() const;   //get metode, return m_resMsg
        const std::string& details() const;   //get metode, return m_details
        const std::string& context() const;   //get metode, return m_context
        bool isClientSoapFault() const;   //get metode, return 
m_isClientSoapFault
	};
	
	class LoginParam : CAPA::Param {
%TypeHeaderCode
#include <api/session.h>
%End
	public:
        LoginParam(const std::string &domain,
                   const std::string &username, 
                   const std::string &passwd,
                   const std::string &appName,
                   const std::string &appVersion);
                   
        void setAppBuild(const std::string &appBuild);
        void setOfflineLogin(bool enable=true);

        const std::string& userName() const;
        const std::string& appName() const;
        const std::string& appVersion() const;
        const std::string& appBuild() const;
        const std::string& passWd() const;
        const std::string& domain() const;
        bool offlineLogin() const;

	};

	class LoginResult {
%TypeHeaderCode
#include <api/session.h>
%End
	public:
        LoginResult();

        bool    bindOk() const;
        void    setBindOk(bool bindOk);
	};
	
	class Session {
%TypeHeaderCode
#include <api/session.h>
%End
	public:
        Session(const std::string &schema,
                const std::string &host,
                int port);
        const std::string& sessionId() const;
        const std::string& schema() const;
        const std::string& host() const;
        int port() const;

		bool login(const CAPA::LoginParam& param, CAPA::LoginResult& result);
	};
};


%MappedType std::string
{
%TypeHeaderCode
#include <string>
%End

%ConvertFromTypeCode
    // convert an std::string to a Python (unicode) string
    PyObject* newstring;
    newstring = PyUnicode_DecodeUTF8(sipCpp->c_str(), sipCpp->length(), NULL);
    if(newstring == NULL) {
        PyErr_Clear();
        newstring = PyString_FromString(sipCpp->c_str());
    }
    return newstring;
%End

%ConvertToTypeCode
	// Allow a Python string (or a unicode string) whenever a string is
	// expected.
    // If argument is a Unicode string, just decode it to UTF-8
    // If argument is a Python string, assume it's UTF-8
	if (sipIsErr == NULL)
		return (PyString_Check(sipPy) || PyUnicode_Check(sipPy));
	if (sipPy == Py_None) {
		*sipCppPtr = new std::string;
		return 1;
	}
	if (PyUnicode_Check(sipPy))	{
        PyObject* s = PyUnicode_AsEncodedString(sipPy, "UTF-8", "");
        *sipCppPtr = new std::string(PyString_AS_STRING(s));
        Py_DECREF(s);
        return 1;
	}
	if (PyString_Check(sipPy)) {
        *sipCppPtr = new std::string(PyString_AS_STRING(sipPy));
    	return 1;
	}
    return 0;
%End
};
---------------------------------------------------------------------------
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: This is a digitally signed message part.
Url : http://www.riverbankcomputing.com/pipermail/pyqt/attachments/20090701/7c0723cf/attachment.bin


More information about the PyQt mailing list