I've appended this minimal example to the issue so hopefully it will get the maintainers' attention.
As for the __dir__ special method as far as I can see it's unsupported. I have my doubts whether it's likely to be supported: it may come under the "introspection" category mentioned here.
dir and __getattr__ weirdness
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: dir and __getattr__ weirdness
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.
Re: dir and __getattr__ weirdness
Thing is, with code like 'return 42' no matter what attribute is requested, basically it says 'yes, I do have all those attribute'. Seeing uPy uses that to populate dir(), which probably won't change anytime soon as I think it would require to either go back to the previous inferior behaviour or change the complete object model, maybe a solution here is to have __getattr__ do the 'right' thing (also per CPython: "This method should either return the (computed) attribute value or raise an AttributeError exception") and raise an exception for attributes which it doesn't handle, and have mp_builtin_dir() catch that.
Actually I started a patch which does that, but looking around there are multiple places where code comments basically say __getattr__ and it's behaviour with regards to catching AttributeError is a TODO (e.g. mp_builtin_hasattr, mp_obj_instance_load_attr). So it might be better to deal with all of that. Unfortunately I don't have enough time right now to check all that, and find a proper solution.
Actually I started a patch which does that, but looking around there are multiple places where code comments basically say __getattr__ and it's behaviour with regards to catching AttributeError is a TODO (e.g. mp_builtin_hasattr, mp_obj_instance_load_attr). So it might be better to deal with all of that. Unfortunately I don't have enough time right now to check all that, and find a proper solution.
I double checked, and it's not.s for the __dir__ special method as far as I can see it's unsupported
Re: dir and __getattr__ weirdness
Fair enough. However, I am under the, perhaps mistaken, impression that dir in CPython calsl the __dir__ method of the object if present and otherwise does its own magic. So in the C code quoted by dhylands one could be able to add that hook check. Basically, the current dir implementation is rather wasteful since it checks all the names: it's a bit like using a sledgehammer to kill a flypythoncoder wrote:As for the __dir__ special method as far as I can see it's unsupported. I have my doubts whether it's likely to be supported: it may come under the "introspection" category mentioned here.
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: dir and __getattr__ weirdness
The reasoning is discussed here.
I am not familiar with this code so I have no view on the ease or otherwise of implementing the special method.
I am not familiar with this code so I have no view on the ease or otherwise of implementing the special method.
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.
Re: dir and __getattr__ weirdness
Enlightening. I had not realised that about tab completion in REPL. I should have read the manual . Very nice. In the end I can live without dir working like in CPython. However, if one uses that example
then typing "f." then tab, then one gets this:
and micropython (unix) dies nastily: the terminal in Ubuntu it ran in looses its connection to the keyboard. I have to kill it by closing the window... In the end, one has to be very careful when using __getattr__ since it opens quite a can of worms.
Code: Select all
class Foo(object):
def __init__(self):
self.a = []
def __getattr__(self, name):
return getattr(self.a, name)
f = Foo()
Code: Select all
f.FATAL uncaught NLR xxxxxxxxx
Re: dir and __getattr__ weirdness
Not nice, looks like tab completion doesn't want you to raise exceptions from __getattr__, add this to the bug report or create a new one.