PyCall.jl icon indicating copy to clipboard operation
PyCall.jl copied to clipboard

Wrong error reported when accessing an attribute

Open aplavin opened this issue 6 years ago • 1 comments

Hi! I have a class that does some checking before setting an attribute value, like this (pure Python):

class A:
    def __setattr__(self, name, value):
        if value == 0:
            raise ValueError(value)
        # set value...

a = A()
a.a = 5  # OK
a.a = 0  # correct error message:
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-9-7600552ca637> in <module>()
----> 1 a.a = 0

<ipython-input-6-585623315894> in __setattr__(self, name, value)
      2     def __setattr__(self, name, value):
      3         if value == 0:
----> 4             raise ValueError(value)
      5         # set value...
      6

ValueError: 0

However, running the same code with PyCall.jl gives a very confusing error message:

py"""
class A:
    def __setattr__(self, name, value):
        if value == 0:
            raise ValueError(value)
        # set value...
"""
a = py"A"()
a.a = 5  # OK
a.a = 0  # completely wrong exception:
ERROR: KeyError: key :a not found
Stacktrace:
 [1] setproperty!(::PyObject, ::Symbol, ::Int64) at /users/aplavin/.julia/packages/PyCall/ttONZ/src/PyCall.jl:329
 [2] top-level scope at none:0

aplavin avatar Jun 12 '19 14:06 aplavin

Bump! In the meantime I noticed that the same KeyError is wrongly raised when getting an attribute as well, not only when setting. Traceback points to this line: https://github.com/JuliaPy/PyCall.jl/blob/5d227fc23fda631783a68c9ff1c6aff47200978e/src/PyCall.jl#L307. I don't know Python internals, but looks like this code doesn't check for raised exceptions at all and raises KeyError no matter what.

aplavin avatar Feb 19 '21 17:02 aplavin