Boost::python readonly access to nonconstant class members
Hi,
is it possible to have python have readonly access to class members
that are non constant?
typedef map
At Tue, 21 Dec 2010 15:47:38 +0100, Ralf Goertz wrote:
Hi,
is it possible to have python have readonly access to class members that are non constant?
typedef map
Links; class DataSet { Links links; }
BOOST_PYTHON_MODULE(_boosttest) { class_<Links>("Links") .def(map_indexing_suite<Links>());
class_<DataSet>("DataSet") .def_readonly("links",&DataSet::links); }
Although DataSet.links is defined readonly I can change it from within python.
If you mean that you can do d = DataSet() d.links = 1 that would be a Boost.Python bug. If instead you mean that you can do d = DataSet() d.links["foo"] = "bar" that would be unsurprising (to me), intended behavior; that's just how the Python object model works.
What can I do to prevent python from overwriting links?
You could always do the equivalent of del DataSet.__dict__["__setitem__"] to disable it. -- Dave Abrahams BoostPro Computing http://www.boostpro.com
Dave Abrahams wrote:
At Tue, 21 Dec 2010 15:47:38 +0100, Ralf Goertz wrote:
Hi,
is it possible to have python have readonly access to class members that are non constant?
typedef map
Links; class DataSet { Links links; }
BOOST_PYTHON_MODULE(_boosttest) { class_<Links>("Links") .def(map_indexing_suite<Links>());
class_<DataSet>("DataSet") .def_readonly("links",&DataSet::links); }
Although DataSet.links is defined readonly I can change it from within python.
If you mean that you can do
d = DataSet() d.links = 1
that would be a Boost.Python bug.
No I don't mean that and indeed that does not work: Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: can't set attribute
If instead you mean that you can do
d = DataSet() d.links["foo"] = "bar"
that would be unsurprising (to me), intended behavior; that's just how the Python object model works.
I know this would be intended if I had used def_readwrite("links",...) above. At least that's how I read http://www.boost.org/doc/libs/1_45_0/libs/python/doc/tutorial/doc/html/pytho... The only differences there to my case are that I can't have links to be a constant member of DataSet and that I am using map_indexing_suite. Is the latter the problem maybe?
What can I do to prevent python from overwriting links?
You could always do the equivalent of
del DataSet.__dict__["__setitem__"]
to disable it.
I have tried del Links.__dict__["__setitem__"] as I am concerned with the member variable of type Links but that gave the error TypeError: 'dictproxy' object does not support item deletion I guess map_indexing_suite creates this dictproxy which doesn't allow me to delete __setitem__. Maybe I can use some policy with map_indexing_suite? Sorry for my unqualified questions but I am only starting to learn python. Ralf
At Wed, 22 Dec 2010 09:42:42 +0100, Ralf Goertz wrote:
Dave Abrahams wrote:
If instead you mean that you can do
d = DataSet() d.links["foo"] = "bar"
that would be unsurprising (to me), intended behavior; that's just how the Python object model works.
I know this would be intended if I had used def_readwrite("links",...) above. At least that's how I read
http://www.boost.org/doc/libs/1_45_0/libs/python/doc/tutorial/doc/html/pytho...
Well, maybe the doc should be clearer, on this topic, but def_readonly makes the *attribute* read-only or read-write. Python has no distinction between const and non-const; it only has mutable and immutable objects. The map you've exposed is mutable.
The only differences there to my case are that I can't have links to be a constant member of DataSet and that I am using map_indexing_suite. Is the latter the problem maybe?
map_indexing_suite is indeed the thing that supplies the ability to do __setitem__ on Links. You could always wrap Links "manually" and expose the __getitem__ method yourself (but not __setitem__).
What can I do to prevent python from overwriting links?
You could always do the equivalent of
del DataSet.__dict__["__setitem__"]
to disable it.
I have tried
del Links.__dict__["__setitem__"]
as I am concerned with the member variable of type Links but that gave the error
TypeError: 'dictproxy' object does not support item deletion
I guess map_indexing_suite creates this dictproxy which doesn't allow me to delete __setitem__.
I'm sure there's a way around this, but I'm not tricky enough to figure it out right now ;-)
Maybe I can use some policy with map_indexing_suite? Sorry for my unqualified questions but I am only starting to learn python.
A mutability policy would be a good thing to add, for sure. But we don't have one today AFAIK. -- Dave Abrahams BoostPro Computing http://www.boostpro.com
participants (2)
-
Dave Abrahams
-
Ralf Goertz