KeyError: __array_interface__ not found when using PyCall

pycall

#1

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.


#2

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),


#3

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.


#4

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.


#5

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


#6

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.