KeyError: __array_interface__ not found when using PyCall

I’m using PyCall 1.7.1 in julia 0.4 to call out to a python 3.4 library, and there are cases when the library throws a PyCall.PyError. When I try to inspect the :__class__ of this error, I get an error:

# ex is an exception of type `PyCall.PyError`
julia> fieldnames(ex)
[:msg,:T,:val,:traceback]

julia> keys(ex.val)
[:__bytes__,:__cause__,:__class__,:__context__,:__delattr__,:__dict__,:__dir__,:__doc__,:__eq__,:__format__,:__ge__,:__getattribute__,:__gt__,:__hash__,:__init__,:__le__,:__lt__,:__module__,:__ne__,:__new__,:__reduce__,:__reduce_ex__,:__repr__,:__setattr__,:__setstate__,:__sizeof__,:__str__,:__subclasshook__,:__suppress_context__,:__traceback__,:__unicode__,:__weakref__,:args,:default_errorhandler,:errno,:errorhandler_wrapper,:logger,:msg,:sfqid,:sqlstate,:with_traceback]

julia> pyclass   = ex.val[:__class__]
ERROR: KeyError: __array_interface__ not found
 in getindex at /home/ubuntu/.julia/v0.4/PyCall/src/PyCall.jl:260
 in pysequence_query at /home/ubuntu/.julia/v0.4/PyCall/src/conversions.jl:729
 [inlined code] from /home/ubuntu/.julia/v0.4/PyCall/src/conversions.jl:745
 in pytype_query at /home/ubuntu/.julia/v0.4/PyCall/src/conversions.jl:774
 in convert at /home/ubuntu/.julia/v0.4/PyCall/src/conversions.jl:794
 in error_handler at /home/ubuntu/foo.jl:76

This doesn’t happen via the REPL, and only happens in code executing via a file, like my unit tests.

Does anyone know what the __array_interface__ not found error means?

Update: I have these two lines:

    println(ex.val[:__class__])
    pyclass   = ex.val[:__class__]

The first line works, the second line throws the error.

It means the PyCall auto-conversion machinery is trying to convert an object via the NumPy array interface, but that interface is not supported by the object.

I can’t reproduce this with the following simple attempt, so a reduced case might help (or at least specify what is the error type on the Python side, and the output of your println):

julia> global err

julia> try
         pyeval("1/0")
       catch err
       end

julia> typeof(err)
PyCall.PyError

julia> pyclass = err.val[:__class__]
PyObject <class 'ZeroDivisionError'>

(OSX, Julia 0.4.5, PyCall 1.7.2, Python 3.5),

Thanks, this makes sense since I do not have NumPy installed on this box.

The library I’m using is python-snowflake-connector, which is a DBI connector to the Snowflake database, and the specific error is snowflake.connector.ProgrammingError.

I was able to work around the issue by calling string() on the error itself, and parsing out the error class name from there.

This seems like a bug. PyCall shouldn’t attempt to convert via an
unsupported interface. If you can make a reduced case, please open an issue
on PyCall and ping me.

Thanks, I’ll try, but it seems you might need snowflake credentials to try this out.

Actually it seems to be fixed with PyCall 1.7.2.

I have filed a different bug though (#340) which is related and is still an issue in 1.7.2.

Thank you.