PythonCall - from X import Y

When I want to import a module X, I can call

using PythonCall
pyimport("X")

I want to import Image from PIL, which in python is done by

from PIL import Image

However, I can not access Image from PIL directly:

>>> import PIL
>>> PIL.Image
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'PIL' has no attribute 'Image'

So I need to import them in one statement, or do something else than importing one at a time.

Below is a number of attempts:

julia> PIL = pyimport("PIL")
Python module: <module 'PIL' from '/usr/lib/python3/dist-packages/PIL/__init__.py'>

julia> PIL.Image
ERROR: Python: AttributeError: module 'PIL' has no attribute 'Image'
Python stacktrace: none
Stacktrace:
 [1] pythrow()
   @ PythonCall ~/.julia/packages/PythonCall/Td3SH/src/err.jl:94
 [2] errcheck
   @ ~/.julia/packages/PythonCall/Td3SH/src/err.jl:10 [inlined]
 [3] pygetattr(x::Py, k::String)
   @ PythonCall ~/.julia/packages/PythonCall/Td3SH/src/abstract/object.jl:60
 [4] getproperty(x::Py, k::Symbol)
   @ PythonCall ~/.julia/packages/PythonCall/Td3SH/src/Py.jl:272
 [5] top-level scope
   @ REPL[9]:1

julia> PIL = pyimport("from PIL import Image")
ERROR: Python: ModuleNotFoundError: No module named 'from PIL import Image'
Python stacktrace: none
Stacktrace:
 [1] pythrow()
   @ PythonCall ~/.julia/packages/PythonCall/Td3SH/src/err.jl:94
 [2] errcheck
   @ ~/.julia/packages/PythonCall/Td3SH/src/err.jl:10 [inlined]
 [3] pyimport(m::String)
   @ PythonCall ~/.julia/packages/PythonCall/Td3SH/src/concrete/import.jl:11
 [4] top-level scope
   @ REPL[10]:1

julia> PIL = pyimport("PIL"=>"Image")
ERROR: Python: AttributeError: module 'PIL' has no attribute 'Image'
Python stacktrace: none
Stacktrace:
 [1] pythrow()
   @ PythonCall ~/.julia/packages/PythonCall/Td3SH/src/err.jl:94
 [2] errcheck
   @ ~/.julia/packages/PythonCall/Td3SH/src/err.jl:10 [inlined]
 [3] pygetattr(x::Py, k::String)
   @ PythonCall ~/.julia/packages/PythonCall/Td3SH/src/abstract/object.jl:60
 [4] pyimport(::Pair{String, String})
   @ PythonCall ~/.julia/packages/PythonCall/Td3SH/src/concrete/import.jl:12
 [5] top-level scope
   @ REPL[11]:1

Anyone know how I can import Y from X using PythonCall?

PIL.Image is a module, so I would try importing it.

Nice, thanks:

julia> PILImage = pyimport("PIL.Image")
Python module: <module 'PIL.Image' from '/usr/lib/python3/dist-packages/PIL/Image.py'>

2 Likes

It’s a module in your case, but not always(?), so the general question hasn’t been answered. I’m still curious, and you may want to uncheck the solution box.

It’s probably the second option:

pyimport(m)
pyimport(m => k)
pyimport(m => (k1, k2, ...))
pyimport(m1, m2, ...)

In PyCall.jl you could do (while not recommended for import, for some reason I forget):

py"from PIL import Image"

The py macro is awesome, e.g. multi-line py"“” but I’m not sure it’s supported in PythonCall.jl. Is there similar (or a workaround)? Also as with RCall.jl a Python REPL mode would be awesome. It’ not there (yet), while there is a Pkg conda REPL mode…

1 Like