[C++-sig] Re: pyste: current cvs/1_30_00 difference in treatment of overloaded members

Nicodemus nicodemus at globalite.com.br
Fri May 16 05:21:38 CEST 2003


David Abrahams wrote:

>Nicodemus <nicodemus at globalite.com.br> writes:
>  
>
>>... unless we also expose it in the class_ declaration:
>>
>>    .def("name", &A::name, &A_Wrapper::default_name)
>>    
>>
>
>Of course you do have to do that.
>
>  
>
>>Which, besides making the function public, can't be done because
>>A::name is protected. Or am I missing something?
>>    
>>
>
>You're certainly missing that A_Wrapper is derived from A and so can
>access A's protected members, including name().
>

That's what I meant by "making the function public" (sorry, I should 
have said "exported"):

    class_< A, A_Wrapper >("A", init<  >())
        .def(init< const A & >())
        .def("get_name", &A::get_name)
        .def("name", &A::name, &A_Wrapper::default_name)
    ;

This gives an error (obviously):

test.cpp(43): error #308: function "A::name" is inaccessible
          .def("name", &A::name, &A_Wrapper::default_name)
                           ^

>Anyway, let me get this straight.  In what context don't you want to
>make "the function" (which function?) public?
>
>Are you trying to prevent:
>
>    >>> x = A()
>    >>> x.name()
>
>??
>  
>

Yes. I think it would be nice to mimic the C++ classes on the Python 
side as much as possible, but I know that Python has different 
semantics. My first thoughts were that one couldn't access the protected 
function from outside the class, but could override it inside a derived 
class. But on second thought, that is not a very good option either, 
because then you can't call the parent's implementation from the derived 
class that way:

     class B(A):
         def name(self):
             return A.name(self) + 'B'  # wouldn't work, unless "name" 
were also exported

>If so, keep in mind that Python doesn't have any notion of
>"protected" interfaces.  
>

I'm aware of that.

>But anyway, back to your original problem.  I think you are saying you
>want instances of A created from Python not to have a Python "name"
>method, yet that Python classes derived from A can override A::name,
>and that from C++, python instances of A implement "name" using the
>C++ A::name by default.  Right?
>

Yes.

>I think trying to get Python A instances not to have a name method is
>sort of unpythonic, but be that as it may...
>  
>
>To get overridability, you need to implement A_Wrapper::name() so that
>it dispatches into Python.  If you don't want to expose a "name"
>attribute, you'd better implement A_Wrapper::name() something like
>this:
>
>        char const* name()
>        {
>            if (PyObject_HasAttrString(this->self, "name"))
>                return boost::python::call_method<char const*>(self, "name");
>            else
>                return A::name();
>        }
>  
>

That's what I thought...

>>>Private virtual functions are a bigger problem; the best you can do
>>>is to break the C++ rules by replicating the base class declaration
>>>with the private function declared protected.
>>> 
>>>      
>>>
>>I believe the problem persists: you still must tell Boost.Python about
>>the default implementation.
>>    
>>
>
>Still not sure what you perceive the problem to be...
>  
>

I wanted to know how to expose the default implementation of protected 
virtual methods, and also how should Pyste handle them. I saw two 
options: export them normaly, just like a public method; or override the 
function and inside it check if the python object has reimplemented it, 
otherwise call the default implementation. I wanted to discuss here in 
the list what would be the best method, that's all.






More information about the Cplusplus-sig mailing list