Pycxx Simple2

I'm having a hard time trying to understand an example {c++ module / corresponding.py demo}. For a start, it appears to be broken. And fixing it requires digging in to the C++ module code to figure out what it is trying to do in the first place.

here is the .py (original broken version followed by fix):

import simple2
import sys

m = {
    simple2.xxx.first  : 1,
    simple2.xxx.second : 2,
    simple2.xxx.third  : 3
}

v = m[ simple2.xxx.second ]
# ^ was giving key error

- - -

import simple2
import sys

second = simple2.xxx.second

print (  id(second) )
print (  id(simple2.xxx.second) )
#^ different values!

m = {
    simple2.xxx.first  : 1,
    second : 2,
    simple2.xxx.third  : 3
}

print ( "---" )

v = m[ second ]
# ^ now it works

https://gist.github.com/p-i-/bc0f82c3c73e623f7b29 <— and this is the corresponding .cpp

Here is the relevant part, at the bottom:

typedef enum {
    xxx_first = 1,
    xxx_second,
    xxx_third
} xxx_t;

template <>
EnumString< xxx_t >::EnumString()
: m_type_name( "xxxw" )
{
    add( xxx_first, "first" );
    add( xxx_second, "second" );
    add( xxx_third, "third" );
    std::cout << std::endl << "foo" << std::endl;
}

template <>
void pysvn_enum< xxx_t >::init_type(void)
{
    behaviors().name("xxx");
    behaviors().doc("xxx enumeration");
    behaviors().supportGetattr();
}

template <>
void pysvn_enum_value< xxx_t >::init_type(void)
{
    behaviors().name("xxx");
    behaviors().doc("xxx value");
    behaviors().supportRepr();
    behaviors().supportStr();
    behaviors().supportHash();
}

class simple2_module : public Py::ExtensionModule<simple2_module>
{
public:
    simple2_module()
    : Py::ExtensionModule<simple2_module>( "simple2" ) // this must be name of the file on disk e.g. simple2.so or simple2.pyd
    {
        pysvn_enum      < xxx_t >::init_type();
        pysvn_enum_value< xxx_t >::init_type();

        // π populate method-map table

        // after initialize the moduleDictionary with exist
        // π populate moduleDictionary from method-map table
        initialize( "documentation for the simple2 module" );

        Py::Dict d( moduleDictionary() );
        d["xxx"] = Py::asObject( new pysvn_enum< xxx_t >() ); // import simple2; dir(simple2) shows this
    }

    ~simple2_module()
    { }

};

The .cpp loads two extension types when the module gets imported:

        pysvn_enum      < xxx_t >::init_type();
        pysvn_enum_value< xxx_t >::init_type();

And creates an instance of one of these, and loads it into the module's Dictionary:

        d["xxx"] = Py::asObject( new pysvn_enum< xxx_t >() );

So now 'simple2.xxx' in the Python console should be manipulating this pysvn_enum< xxx_t > object

>>>import simple2
>>> dir(simple2)
['__doc__', '__loader__', '__name__', '__package__', '__spec__', 'xxx']

What I don't get is that when both of these pysvn_enum and pysvn_enum_value objects get loaded…

template <>
void pysvn_enum< xxx_t >::init_type(void)
{
    behaviors().name("xxx");
    behaviors().doc("xxx enumeration");
    behaviors().supportGetattr();
}

template <>
void pysvn_enum_value< xxx_t >::init_type(void)
{
    behaviors().name("xxx");
    behaviors().doc("xxx value");
    behaviors().supportRepr();
    behaviors().supportStr();
    behaviors().supportHash();
}

… both of them have the same 'behaviors().name("xxx");' line

Does this value need to match up with the entry for this object in the module table?

in this case…

        Py::Dict d( moduleDictionary() );
        d["xxx"] = Py::asObject( new pysvn_enum< xxx_t >() );

What happens if I change the names so they are unique:

template <>
void pysvn_enum< xxx_t >::init_type(void)
{
    // https://docs.python.org/2/c-api/typeobj.html
    // For printing, in format "<module>.<name>"
    behaviors().name("xxx1");

    behaviors().doc("xxx enumeration");
    behaviors().supportGetattr();
}

template <>
void pysvn_enum_value< xxx_t >::init_type(void)
{
    behaviors().name("xxx2");
    behaviors().doc("xxx value");
    behaviors().supportRepr();
    behaviors().supportStr();
    behaviors().supportHash();
}
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License