# Local Python file in module?

**URL:** https://discourse.julialang.org/t/local-python-file-in-module/91080
**Category:** General Usage
**Tags:** question, pycall
**Created:** [December 1, 2022, 8:29am UTC](https://discourse.julialang.org/t/local-python-file-in-module/91080 "2022-12-01T08:29:05Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![polhager](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/polhager/32/37340_2.png) [@polhager](https://discourse.julialang.org/u/polhager)
#### Post date: [December 1, 2022, 8:29am UTC](https://discourse.julialang.org/t/local-python-file-in-module/91080/1 "2022-12-01T08:29:06Z")

</div>

Hi! I’m trying to create a Julia module which uses functions from a Python file in the same directory. The setup is this: In the same directory I have two files. A `mypythonfile.py`

```python
def myfunction():
	print("Hello!")

```

and `myjuliamodule.jl`

```julia
module myjuliamodule

using PyCall

pushfirst!(PyVector(pyimport("sys")."path"), "")

function testfun()
	pyimport("mypythonfile").myfunction()
end

export testfun

end

```

In the REPL, I then run

```julia
julia> push!(LOAD_PATH, "")
4-element Vector{String}:
 "@"
 "@v#.#"
 "@stdlib"
 ""

julia> using myjuliamodule

julia> testfun()
ERROR: PyError (PyImport_ImportModule

The Python package mypythonfile could not be imported by pyimport. Usually this means
that you did not install mypythonfile in the Python version being used by PyCall.

PyCall is currently configured to use the Python version at:

/usr/bin/python3

and you should use whatever mechanism you usually use (apt-get, pip, conda,
etcetera) to install the Python package containing the mypythonfile module.

One alternative is to re-configure PyCall to use a different Python
version on your system: set ENV["PYTHON"] to the path/name of the python
executable you want to use, run Pkg.build("PyCall"), and re-launch Julia.

Another alternative is to configure PyCall to use a Julia-specific Python
distribution via the Conda.jl package (which installs a private Anaconda
Python distribution), which has the advantage that packages can be installed
and kept up-to-date via Julia. As explained in the PyCall documentation,
set ENV["PYTHON"]="", run Pkg.build("PyCall"), and re-launch Julia. Then,
To install the mypythonfile module, you can use `pyimport_conda("mypythonfile", PKG)`,
where PKG is the Anaconda package that contains the module mypythonfile,
or alternatively you can use the Conda package directly (via
`using Conda` followed by `Conda.add` etcetera).

) <class 'ModuleNotFoundError'>
ModuleNotFoundError("No module named 'mypythonfile'")

Stacktrace:
 [1] pyimport(name::String)
   @ PyCall ~/.julia/packages/PyCall/ygXW2/src/PyCall.jl:558
 [2] testfun()
   @ myjuliamodule /media/VM_shared/dev/Estun Vibrations/module_issue/myjuliamodule.jl:8
 [3] top-level scope
   @ REPL[3]:1

```

The `pushfirst!` line clearly doesn’t allow the module to find the local Python file. However, if I run the same code outside of a module it does. Consider the file `myjuliafile.jl` in the same directory.

```julia
using PyCall

pushfirst!(PyVector(pyimport("sys")."path"), "")

function testfun2()
	pyimport("mypythonfile").myfunction()
end

```

In the REPL:

```julia
julia> include("myjuliafile.jl")
testfun2 (generic function with 1 method)

julia> testfun2()
Hello!

```

So my question is why is the behaviour different inside the module?

The reason I want to do this is we have some code that is implemented in Python and translating it to Julia would be a massive task. For convenience reasons, I would like to avoid putting the entire thing inside a `"""python """` block in a Julia file. Also, rather than having a user get the Python repo separately and pointing to it outside of the module, I would like to include the relevant files directly in the package.

---

<div class="post-metadata">

### Author: ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)
#### Post date: [December 1, 2022, 8:34am UTC](https://discourse.julialang.org/t/local-python-file-in-module/91080/2 "2022-12-01T08:34:08Z")

</div>

Try to place the `sys.path` manipulation in an ` __init__ ()` function, which is run during module initialization.

---

<div class="post-metadata">

### Author: ![polhager](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/polhager/32/37340_2.png) [@polhager](https://discourse.julialang.org/u/polhager)
#### Post date: [December 1, 2022, 8:45am UTC](https://discourse.julialang.org/t/local-python-file-in-module/91080/3 "2022-12-01T08:45:54Z")

</div>

That works! Thank you!

Why is this necessary though? I was under the impression that all code in the module would be run when I call `using myjuliamodule` regardless. I (clearly) don’t understand exactly how modules work.

---

<div class="post-metadata">

### Author: ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)
#### Post date: [December 1, 2022, 8:53am UTC](https://discourse.julialang.org/t/local-python-file-in-module/91080/4 "2022-12-01T08:53:27Z")

</div>

Some things are run once and cached, which doesn’t work so well with external state. See this [manual section](https://docs.julialang.org/en/v1/manual/modules/#Module-initialization-and-precompilation).
