PyCall.jl
PyCall.jl copied to clipboard
Wrong error reported when accessing an attribute
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
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.