Search code examples
pythonpython-importfailed-installationpyzmqpython-wheel

How to import pyzmq from wheel file?


I need to import zmq from the pyzmq.whl file, but I'm getting an ImportError. Due to constraints, I cannot do pip install.

I've downloaded the "pyzmq-18.1.0-cp37-cp37m-manylinux1_x86_64.whl" file from pypi.org (is it the right version for Python 3.7.4?) and renamed it to pyzmq.whl in my current directory.

import sys
sys.path.append("./pyzmq.whl")
import zmq

I'm getting this error message:

  File "import_zmq.py", line 3, in <module>
    import zmq
  File "pyzmq.whl/zmq/__init__.py", line 47, in <module>
  File "pyzmq.whl/zmq/backend/__init__.py", line 40, in <module>
  File "pyzmq.whl/zmq/utils/sixcerpt.py", line 34, in reraise
  File "pyzmq.whl/zmq/backend/__init__.py", line 27, in <module>
  File "pyzmq.whl/zmq/backend/select.py", line 28, in select_backend
  File "pyzmq.whl/zmq/backend/cython/__init__.py", line 6, in <module>
ImportError: cannot import name 'constants' from 'zmq.backend.cython' (pyzmq.whl/zmq/backend/cython/__init__.py)

This question points to it being a folder structure issue, but I have not extracted the wheel file, so I'm not sure how to fix this error.

EDIT:Nevermind, it may not be possible to import pyzmq as a wheel file because it depends on CPython. See https://www.python.org/dev/peps/pep-0427/#is-it-possible-to-import-python-code-directly-from-a-wheel-file

...importing C extensions from a zip archive is not supported by CPython (since doing so is not supported directly by the dynamic loading machinery on any platform)


Solution

  • It is not possible to import pyzmq as a wheel file because it depends on CPython.

    Importing C extensions from a zip archive is not supported by CPython (since doing so is not supported directly by the dynamic loading machinery on any platform https://www.python.org/dev/peps/pep-0427/#is-it-possible-to-import-python-code-directly-from-a-wheel-file

    Alright, here's how I'm doing it now. I'm basically using pip install programmatically. Also, changing the name of the whl file caused issues, so keep the original name.

    import subprocess, sys
    try:
     import zmq
    except ImportError:
     src_path = "path/to/folder/having/whl"
     pyzmq = "pyzmq-18.1.0-cp37-cp37m-manylinux1_x86_64.whl"
     target_path = "path/where/you/want/it/installed"
     install_cmd = sys.executable + " -m pip install --target=" + target_path + " " + src_path + pyzmq
     subprocess.call(install_cmd,shell=True) 
    finally:
     #Sometimes "import zmq" won't work here, so do this:
     import importlib
     zmq = importlib.import_module("zmq")
    

    The try block ensures that we don't redo this installation if zmq is already installed (supposing this code runs repeatedly). It works for my specific use case, hope this helps someone.