# Pyimport works from repl defined module but not in my package

**URL:** <https://discourse.julialang.org/t/pyimport-works-from-repl-defined-module-but-not-in-my-package/43539>\
**Category:** General Usage\
**Created:** [July 23, 2020, 5:15am UTC](https://discourse.julialang.org/t/pyimport-works-from-repl-defined-module-but-not-in-my-package/43539 "2020-07-23T05:15:32Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Pbellive](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pbellive/32/3604_2.png) [@Pbellive](https://discourse.julialang.org/u/Pbellive)\
**Post date:** [July 23, 2020, 5:15am UTC](https://discourse.julialang.org/t/pyimport-works-from-repl-defined-module-but-not-in-my-package/43539/1 "2020-07-23T05:15:32Z")

</div>

Hi,  
I’m trying to use PyCall to call the [hnswlib](https://github.com/nmslib/hnswlib) python bindings from julia. The following MWE with a module defined at the repl works as expected. And also a slightly expanded version of that module where the `find_ann` function actually does non-trivial work with hnswlib also works.

```julia
julia> module A
              using PyCall
              hnswlib = pyimport("hnswlib")
              function find_ann(X::AbstractArray{T,2};
                                metric = "l2") where T<:Real

                  n_elements,ndims = size(X)
                           
                  # Declaring index
                  p = hnswlib.Index(space=metric, dim=ndims) # possible options are l2, cosine or ip
              end
       end
Main.A

julia> using .A

julia> X = randn(100,10);

julia> A.find_ann(X)
PyObject <HNSW-lib index>

```

So then I start to develop a small package that I want the `find_ann` function to be a part of. I’m getting an error I don’t understand when I try to define my `find_ann` function inside the package. Right now my package consists of three files, MyPackage.jl, nn.jl, and Utils.jl. Utils.jl currently just has one simple function that only calls stuff from base julia. MyPackage.jl is:

```julia
module MyPackage

using LinearAlgebra, SparseArrays, Statistics
using PyCall

include("Utils.jl")
include("nn.jl")

end 

```

And then nn.jl is:

```julia
export find_ann
hnswlib = pyimport("hnswlib")

function find_ann(X::AbstractArray{T,2};
    metric = "l2") where T<:Real

    n_elements,ndims = size(X)

    # Declaring index
    p = hnswlib.Index(space=metric, dim=ndims) # possible options are l2, cosine or ip
end

```

This goes into the standard package folder structure:

- MyPackage/  
-Project.toml  
-src/  
-MyPackage.jl  
-nn.jl  
-Utils.jl

And I do `] dev /path/to/MyPackage/` to add the package to my julia environment.

The problem is that `find_ann` doesn’t work when it’s defined inside `MyPackage`, even though, as you can see, it’s literally been copy-pasted from the module I defined in the repl. When I try it I get:

```julia
julia> using MyPackage
[Info: Precompiling MyPackage [UUID-omitted for Discourse]

julia> X = randn(100,10);

julia> find_ann(X)
ERROR: ArgumentError: ref of NULL PyObject
Stacktrace:
 [1] getproperty(::PyCall.PyObject, ::String) at /home/patrick/.julia/packages/PyCall/zqDXB/src/PyCall.jl:296
 [2] getproperty(::PyCall.PyObject, ::Symbol) at /home/patrick/.julia/packages/PyCall/zqDXB/src/PyCall.jl:306
 [3] find_ann(::Array{Float64,2}; metric::String) at /home/patrick/julia-dev/SSLClustering/src/nn.jl:10
 [4] find_ann(::Array{Float64,2}) at /home/patrick/julia-dev/SSLClustering/src/nn.jl:7
 [5] top-level scope at REPL[4]:1

julia> 

```

Does anyone know why I get that `ref of NULL PyObject` error only when `find_ann` is defined in `MyPackage` and not in the repl defined module? Thanks!

P.S. This is on linux, julia 1.4.1, PyCall v1.91.4.

---

<div class="post-metadata">

**Author:** ![jishnub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jishnub/32/33620_2.png) [@jishnub](https://discourse.julialang.org/u/jishnub)\
**Post date:** [July 23, 2020, 5:30am UTC](https://discourse.julialang.org/t/pyimport-works-from-repl-defined-module-but-not-in-my-package/43539/2 "2020-07-23T05:30:46Z")

</div>

Could you verify that you don’t have multiple versions of python on your system, and the ones in the package’s environment is using the same python as the one in the default REPL environment?

---

<div class="post-metadata">

**Author:** ![tk3369](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tk3369/32/2824_2.png) [@tk3369](https://discourse.julialang.org/u/tk3369)\
**Post date:** [July 23, 2020, 3:15pm UTC](https://discourse.julialang.org/t/pyimport-works-from-repl-defined-module-but-not-in-my-package/43539/3 "2020-07-23T15:15:19Z")

</div>

My guess is that this line may not survive pre-compilation:

```julia
hnswlib = pyimport("hnswlib")

```

Can you try to define an object and then initialize it inside ` __init__ ` function, like this:

```julia
const hnswlib = PyNULL()

function __init__ ()
    copy!(hnswlib, pyimport("hnswlib"))
end

```

Ref: [https://github.com/JuliaPy/PyCall.jl#using-pycall-from-julia-modules](https://github.com/JuliaPy/PyCall.jl#using-pycall-from-julia-modules)

---

<div class="post-metadata">

**Author:** ![Pbellive](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pbellive/32/3604_2.png) [@Pbellive](https://discourse.julialang.org/u/Pbellive)\
**Post date:** [July 23, 2020, 4:03pm UTC](https://discourse.julialang.org/t/pyimport-works-from-repl-defined-module-but-not-in-my-package/43539/4 "2020-07-23T16:03:54Z")

</div>

Thanks for the suggestions @jishnub and @tk3369! @tk3369, you correctly identified the problem. Thank you. Not having the `pyimport` call in the module’s ` __init__ ` function was the issue. Failure to read the docs on my part. Glad it was a simple fix.
