On 05/02/2017 05:59 PM, Jason Maldonis wrote:

@Steve they asked me to move it here because it was more fitting. I hope that's 
okay?

Yes, it's okay.  ;)

After some testing, it looks like I'm okay with how things work if the 
problem-object isn't a descriptor (although I do
still things it's a bit odd that an error gets squashed, but it's no big deal).

However, I use @property all the time, so that's likely why I'm running into 
this so often.  If you can help explain to
me what's going on in that case, that would be great!  I have two examples 
below for the sake of discussion.

Here's an example where the underlying error is completely hidden:

class A(object):
     def _some_complex_code_hidden_from_the_user(self):
         # Run a bunch of complex stuff that raises an attribute error 
internally
         # This could go layers deep into different modules
         return self.this_doesnt_exist

     @property
     def x(self):
         return self._some_complex_code_hidden_from_the_user()

     def __getattr__(self, attr):
         raise AttributeError("raised from A.__getattr__ to stop execution")

a = A()
print(a.x)


This results in the following output:

Traceback (most recent call last):
   File "test3.py", line 17, in <module>
     print(a.x)
   File "test3.py", line 14, in __getattr__
     raise AttributeError("raised from A.__getattr__ to stop execution")
AttributeError: raised from A.__getattr__ to stop execution


Here the real reason the code errors (`sys.this_doesnt_exist` throwing an 
AttributeError) is not in the traceback's stack.

The problem is that Python cannot tell the difference between `A.x` not existing (which would raise AttributeError), and some attribute inside `A.x` not existing (which also raises AttributeError).

There's an issue to fix this somewhere in the Python Bug Tracker (bugs.python.org) but I cannot find it at the moment (it's quite old).

My current opinion on this is that the error that triggered __getattr__ should 
be passed to __getattr__. This would
allow us to use the "raise from" syntax.

Hmm. Since the other issue isn't making any headway this might be the best we get -- you should open a thread for it over at Python Ideas. :)

Until then Chris' decorator is probably the easiest work around -- but you 
should only catch AttributeError, not everything.

--
~Ethan~
--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to