2

Simple example of 'map_indexing_suite' usage is working fine:

class_<map<int, string> >("testMap")
        .def(map_indexing_suite<std::map<int, string>, true>())
    ;

and on python side it works as expected:

a = riversim.testMap()
a[1]='sdf'

But! If I try to use more complicated object BoundaryCondition instead of string in map, for example next one:

enum t_boundary 
{
    DIRICHLET = 0, 
    NEUMAN
}; 

struct BoundaryCondition
{
    t_boundary type = DIRICHLET;
    double value = 0;

    bool operator==(const BoundaryCondition& bc) const;
    friend ostream& operator <<(ostream& write, const BoundaryCondition & boundary_condition);
};

typedef map<t_boundary_id, BoundaryCondition> t_BoundaryConditions;

BOOST_PYTHON_MODULE(riversim)
{
    enum_<t_boundary>("t_boundary")
        .value("DIRICHLET", DIRICHLET)
        .value("NEUMAN", NEUMAN)
        .export_values()
        ;

    class_<BoundaryCondition>("BoundaryCondition")
        .def_readwrite("value", &BoundaryCondition::value)
        .def_readwrite("type", &BoundaryCondition::type)
        .def(self == self) 
    ;

    //and problematic class:
    class_<River::t_BoundaryConditions >("t_BoundaryConditions")
        .def(map_indexing_suite<t_BoundaryConditions, true>())
    ;

}

it compiles fine, and I can import riversim:

import riversim

bound = riversim.t_boundary
bc = riversim.BoundaryCondition
bcs = riversim.t_BoundaryConditions

and next command:

bcs[1] = bc

gives error:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
 in 
----> 1 bcs[1] = bc

TypeError: 'Boost.Python.class' object does not support item assignment

How to correctly port map to python?

ps: also triend this solution link and it didn't worked, got same error as above.

Oleg Kmechak
  • 165
  • 1
  • 14

1 Answers1

2

First off,

bcs = riversim.t_BoundaryConditions

Assings the class. It needs to be

bcs = riversim.t_BoundaryConditions()

Now

bcs[1] = bc

Results in

Traceback (most recent call last):
  File "./test.py", line 10, in <module>
    bcs[1] = bc
TypeError: Invalid assignment

That's because the same applied to bc, both the following work:

bcs[1] = bc()
bcs[2] = riversim.BoundaryCondition()
sehe
  • 374,641
  • 47
  • 450
  • 633
  • problem was so far away from place where I was looking for.. some note: cannot modify object from map using this `bcs[1].value = 1` only this is a way of modification: `a = bcs[1]; a.value = 1; bcs[1] = a` – Oleg Kmechak Jun 11 '20 at 20:42
  • 1
    Yeah, had me on the wrong foot as well. If you want to translate "reference semantics" so to speak, don't disable the value proxy (that's what the `no_proxy` argument on `map_indexing_suite` does). Just remove the second argument, or pass `false` instead of `true`. – sehe Jun 11 '20 at 21:10