dir and __getattr__ weirdness

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: dir and __getattr__ weirdness

Post by pythoncoder » Thu Apr 19, 2018 8:20 am

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.
Peter Hinch
Index to my micropython libraries.

stijn
Posts: 735
Joined: Thu Apr 24, 2014 9:13 am

Re: dir and __getattr__ weirdness

Post by stijn » Thu Apr 19, 2018 8:38 am

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.
s for the __dir__ special method as far as I can see it's unsupported
I double checked, and it's not.

fstengel
Posts: 55
Joined: Tue Apr 17, 2018 4:37 pm

Re: dir and __getattr__ weirdness

Post by fstengel » Thu Apr 19, 2018 8:50 am

pythoncoder 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.
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 fly ;)

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: dir and __getattr__ weirdness

Post by pythoncoder » Thu Apr 19, 2018 9:53 am

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.
Peter Hinch
Index to my micropython libraries.

fstengel
Posts: 55
Joined: Tue Apr 17, 2018 4:37 pm

Re: dir and __getattr__ weirdness

Post by fstengel » Thu Apr 19, 2018 10:21 am

Enlightening. I had not realised that about tab completion in REPL. I should have read the manual :shock: . Very nice. In the end I can live without dir working like in CPython. However, if one uses that example

Code: Select all

class Foo(object):
    def __init__(self):
        self.a = []
    def __getattr__(self, name):
        return getattr(self.a, name)
 f = Foo()
then typing "f." then tab, then one gets this:

Code: Select all

f.FATAL uncaught NLR xxxxxxxxx
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.

stijn
Posts: 735
Joined: Thu Apr 24, 2014 9:13 am

Re: dir and __getattr__ weirdness

Post by stijn » Thu Apr 19, 2018 1:51 pm

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.

Post Reply