> On 16 Jun 2017, at 09:46, Nick Coghlan <ncogh...@gmail.com> wrote: > > On 16 June 2017 at 07:44, Barry Scott <ba...@barrys-emacs.org> wrote: >> But I need the result of __dir__ for my object not its base. Then I need to >> add in the list of member attributes that are missing because python >> itself has no knowledge of them they are accessed via getattr(). > > The C code: > > dir_result = PyObject_CallMethod(base_type, "__dir__", "O", self); > > is roughly equivalent to the Python code: > > dir_result = BaseType.__dir__(self) > > That is, it's calling the base type's __dir__ method, but it's still > using the subclass *instance*. > > It's the same pattern people use to call a base type's __getattr__ or > __getattribute__ for the subclass implementation of those methods, > just without multiple inheritance support (since calling super() from > C is painful).
Let me show you problem with an example. Here is an example run of the PyCXX Demo/Python3/simple.cxx code. : 19:01:15 ~/wc/svn/PyCXX : [1] barry@Expanse $ PYTHONPATH=obj python3.6 Python 3.6.0 (v3.6.0:41df79263a11, Dec 22 2016, 17:23:13) [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import simple sizeof(int) 4 sizeof(long) 8 sizeof(Py_hash_t) 8 sizeof(Py_ssize_t) 8 >>> dir(simple) ['SimpleError', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'decode_test', 'derived_class_test', 'encode_test', 'func', 'func_with_callback', 'func_with_callback_catch_simple_error', 'make_instance', 'new_style_class', 'old_style_class', 'var'] >>> n=simple.new_style_class() new_style_class c'tor Called with 0 normal arguments. and with 0 keyword arguments: >>> dir(n) ['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'func_keyword', 'func_noargs', 'func_noargs_raise_exception', 'func_varargs', 'func_varargs_call_member'] >>> n.value 'default value' Notice that 'value' is not in the list of string returned from dir(n). That omission is because python does not know about 'value'. The code does this: Py::Object getattro( const Py::String &name_ ) { std::string name( name_.as_std_string( "utf-8" ) ); if( name == "value" ) { return m_value; } else { return genericGetAttro( name_ ); } } Where getattro is called (indirectly) from tp_getattro. In the python 2 I can tell python that 'value' exists because I provide a value of __members__. What is the way to tell python about 'value' in the python3 world? Barry > > Cheers, > Nick. > > -- > Nick Coghlan | ncogh...@gmail.com | Brisbane, Australia > _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/