Changes in PyZMQ#
This is a coarse summary of changes in pyzmq versions. For a full changelog, consult the git log.
all zmq constants are now available as Python enums (e.g.
zmq.SocketOption.IDENTITY), generated statically from zmq.h instead of at compile-time. This means that checks for the presence of a constant (
hasattr(zmq, 'RADIO')) is not a valid check for the presence of a feature. This practice has never been robust, but it may have worked sometimes. Use direct checks via e.g.
A bit more type coverage of Context.term and Context.socket
Remove all use of deprecated stdlib distutils
Update to Cython 0.29.30 (required for Python 3.11 compatibility)
Compatibility with Python 3.11.0b1
Switch to myst for docs
zmq.utils.strtypes, now unused
Updates to autoformatting, linting
New wheels for PyPy 3.9
Manylinux wheels for CPython 3.10 are based on manylinux2014
strlcpycompilation issues on alpine, freebsd. Adds new build-time dependency on
In event-loop integration: warn instead of raise when triggering callback on a socket whose context has been closed.
Bundled libzmq in wheels backport a patch to avoid crashes due to inappropriate closing of libsodium’s random generator when using CurveZMQ.
New ResourceWarnings when contexts and sockets are closed by garbage collection, which can be a source of hangs and leaks (matches open files)
Fix bundling of wepoll on Windows.
IPC support on Windows: where available (64bit Windows wheels and bundled libzmq when compiling from source, via wepoll), IPC should work on appropriate Windows versions.
Nicer reprs of contexts and sockets
Memory allocated by
recv(copy=False)is no longer read-only
asyncio: Always reference current loop instead of attaching to the current loop at instantiation time. This fixes e.g. contexts and/or sockets instantiated prior to a call to
$PYZMQ_PARAMIKO_HOST_KEY_POLICYcan be used to set the missing host key policy, e.g.
Fix memory corruption in gevent integration
memoryview(zmq.Frame)with cffi backend
Fix threadsafety issue when closing sockets
pypy Windows wheels are 64b-only, following an update in cibuildwheel 2.0
zmq.utils.jsonapiand remove support for non-stdlib json implementations in
send/recv_json. Custom serialization methods should be used instead.
asyncio: experimental support for Proactor eventloop if tornado 6.1 is available by running a selector in a background thread.
Windows: fix type of
socket.FDoption in win-amd64
asyncio: Cancel timers when using HWM with async Sockets
Windows: update bundled libzmq dll URLs for Windows. Windows wheels no longer include concrt140.dll.
adopt pre-commit for formatting, linting
Fix fork-safety bug in garbage collection thread (regression in 20.0) when using subprocesses.
Start uploading universal wheels for ARM Macs.
Add workaround for bug in DLL loading for Windows wheels with conda Python >= 3.8
Fix type of
Frame.bytesfor non-copying recvs with CFFI backend (regression in 21.0)
Add manylinux wheels for pypy
This is a major release due to changes in wheels and building on Windows. Code changes from 21.0 are minimal.
Some typing fixes
Bump bundled libzmq to 4.3.4
Strip unused symbols in manylinux wheels, resulting in dramatically smaller binaries. This matches behavior in v20 and earlier.
Windows CPython wheels bundle public libzmq binary builds, instead of building libzmq as a Python Extension. This means they include libsodium for the first time.
Our own implementation of bundling libzmq into pyzmq on Windows is removed, instead relying on delvewheel (or installations putting dlls on %PATH%) to bundle dependency dlls.
The (new in 21.0) Windows wheels for PyPy likely require the Windows vcredist package. This may have always been the case, but the delvewheel approach doesn’t seem to work.
Windows + PyPy is now the only remaining case where a wheel has libzmq built as an Extension. All other builds ship libzmq built using its own tooling, which should result in better, more stable builds.
Fix wheels on macOS older than 10.15 (sets MACOSX_DEPLOYMENT_TARGET to 10.9, matching wheel ABI tag).
pyzmq-21.0.1 only changes CI configuration for Windows wheels (built with VS2017 instead of VS2019), fixing compatibility with some older Windows on all Pythons and removing requirement of VC++ redistributable package on latest Windows and Python < 3.8.
There still appears to be a compatibility issue with Windows 7 that will be fixed ASAP.
Until then, you can pin
pip install pyzmq<21.
There are no changes from 21.0.0 for other platforms.
pyzmq 21 is a major version bump because of dropped support for old Pythons and some changes in packaging. CPython users should not face major compatibility issues if installation works at all :) PyPy users may see issues with the new implementation of send/recv. If you do, please report them!
The big changes are:
drop support for Python 3.5. Python >= 3.6 is required
mypy type stubs, which should improve static analysis of pyzmq, especially for dynamically defined attributes such as zmq constants. These are new! Let us know if you find any issues.
support for zero-copy and sending bufferables with cffi backend. This is experimental! Please report issues.
linux-aarch64 on Python 3.7-3.9
wheels for pypy36, 37 on Linux and Windows (previously just mac)
We’ve totally redone the wheel-building setup, so let us know if you start seeing instalation issues!
Require Python >= 3.6, required for good type annotation support
Wheels for macOS no longer build libzmq as a Python Extension, instead ‘real’ libzmq is built and linked to libsodium, bundled with delocate. This matches the longstanding behavior of Linux wheels, and should result in better performance.
Add manylinux wheels for linux-aarch64. These bundle an older version of libzmq than the rest.
Build wheels for python3.8, 3.9 with manylinux2010 instead of manylinux1. Wheels for older Pythons will still be built on manylinux1.
rework cffi backend in setup.py
All wheels are built on GitHub Actions (most with cibuildwheel) instead of Min’s laptop (finally!).
zero-copy support in CFFI backend (
send(copy=False)now does something).
Support sending any buffer-interface-providing objects in CFFI backend.
Errors during teardown of asyncio Sockets
Missing MSVCP140.dll in Python 3.9 wheels on Windows, causing vcruntime-redist package to be required to use the Python 3.9 wheels for pyzmq 20.0
20.0 is a major version bump because of dropped support for old Pythons and some changes in packaging, but there are only small changes for users with relatively recent versions of Python.
Update bundled libzmq to 4.3.3
Drop support for Python < 3.5 (all versions of Python < 3.6 are EOL at time of release)
Require setuptools to build from source
Require Cython 0.29 to build from version control (sdists still ship .c files, so will never need Cython)
Respect $PKG_CONFIG env for finding libzmq when building from source
Better error when libzmq is bundled and fails to be loaded.
Hold GIL while calling
zmq_curve_functions, which may fix apparent threadsafety issues.
Regenerate Cython sources with 0.29.21 in sdists for compatibility with Python 3.9
Handle underlying socket being closed in ZMQStream with warning instead of error
Improvements to socket cleanup during process teardown
Fix debug-builds on Windows
Avoid importing ctypes during startup on Windows
ZMQError(EINVAL)on attempts to read write-only attributes, for compatibility with mocking
Fix TypeError during garbage collection
Fix compilation with some C++ compilers
Fixes in tests and examples
Cython backend: Build Cython extensions with language level “3str” (requires Cython 0.29)
Cython backend: You can now
Asyncio: Fix memory leak in Poller
Log: Much improved logging in
zmq.log(see Asynchronous Logging via PyZMQ)
python -m zmq.logentrypoint
Sources generated with Cython 0.29.15
Fix race condition when shutting down ZAP thread while events are still processing (only affects tests)
Publish wheels for Python 3.8 on all platforms
Stop publishing wheels for Python 3.4 on Windows
Sources generated with Cython 0.29.14
Compatibility with Python 3.8 prerelease by regenerating Cython sources with Cython 0.29.10.
Fix language_level=2 in Cython sources, for compatibility with Cython 0.30
Show missing path for ENOENT errors on ipc connections.
Fixes installation from source on non-unicode locales with Python 3. There are no code changes in this release.
Fix compatibility with tornado 6 (removal of stack_context)
Fix possible hang when working with asyncio
Remove some outdated workarounds for old Cython versions
Fix some compilation with custom compilers
Remove unneeded link of libstdc++ on PyPy
Bump bundled libzmq to 4.2.5
Add support for
Remove delayed import of json in
Various build fixes
sdist sources generated with Cython 0.28.3
Stop building wheels for Python 3.4, start building wheels for Python 3.7
zmq.COPY_THRESHOLD. Messages smaller than this are always copied, regardless of
copy=False, to avoid overhead of zero-copy bookkeeping on small messages.
Added visible deprecation warnings to bundled tornado IOLoop. Tornado eventloop integration shouldn’t be used without a proper tornado install since pyzmq 14.
Allow pyzmq asyncio/tornado integration to run without installing
zmq_poll()implementation. The following methods and classes are deprecated and no longer required:
Set RPATH correctly when building on macOS.
Compatibility fixes with tornado 5.0.dev (may not be quite enough for 5.0 final, which is not yet released as of pyzmq 17).
Draft support for CLIENT-SERVER
Regenerate Cython sources in sdists with Cython 0.27.3, fixing builds on CPython 3.7.
Add warning when using bundled tornado, which was deprecated too quietly in 14.x.
Regenerate Cython sources in sdists with Cython 0.27.2, fixing builds on CPython 3.7.
Workaround bug in libzmq-4.2.0 causing EINVAL on poll.
Fix erroneous EAGAIN that could happen on async sockets
Bundle libzmq 4.1.6
Support for Python 2.6 and Python 3.2 is dropped. For old Pythons, use pip install "pyzmq<16" to get the last version of pyzmq that supports these versions.
zmq.Stopwatch. Native Python timing tools can be used instead.
Better support for using pyzmq as a Cython library - bundle zmq.h when pyzmq bundles libzmq as an extension - add
zmq.get_library_dirs()to find bundled libzmq
Updates to setup.py for Cython 0.25 compatibility
Various asyncio/future fixes: - support raw sockets in pollers - allow cancelling async sends
Load bundled libzmq extension with import rather than CDLL, which should fix some manifest issues in certain cases on Windows.
Avoid installing asyncio sources on Python 2, which confuses some tools that run
python -m compileall, which reports errors on the Python 3-only files.
Bundle msvcp.dll in Windows wheels on CPython 3.5, which should fix wheel compatibility systems without Visual C++ 2015 redistributable.
zmq.Context.instance()is now threadsafe.
FIX: sync some behavior in zmq_poll and setting LINGER on close/destroy with the CFFI backend.
PERF: resolve send/recv immediately if events are available in async Sockets
Async Sockets (asyncio, tornado) now support
add preliminary support for
zmq.DRAFT_APIreflecting ZMQ_BUILD_DRAFT_API, which indicates whether new APIs in prereleases are available.
Bump bundled libzmq to 4.1.5, using tweetnacl for bundled curve support instead of libsodium
FIX: include .pxi includes in installation for consumers of Cython API
FIX: various fixes in new async sockets
zmq.decoratorsAPI for decorating functions to create sockets or contexts
zmq.Socket.unsubscribe()methods to sockets, so that assignment is no longer needed for subscribing. Verbs should be methods! Assignment is still supported for backward-compatibility.
Accept text (unicode) input to z85 encoding, not just bytes
zmq.Context.socket()forwards keyword arguments to the
FIX: handle multiple events in a single register call in
FIX: unicode/bytes bug in password prompt in
zmq.sshon Python 3
FIX: workaround gevent monkeypatches in garbage collection thread
update bundled minitornado from tornado-4.3.
improved inspection by setting
binding=Truein cython compile options
add asyncio Authenticator implementation in
workaround overflow bug in libzmq preventing receiving messages larger than
FIX: Remove inadvertant tornado dependency when using
FIX: 15.0 Python 3.5 wheels didn’t work on Windows
Add GSSAPI support to Authenticators
Support new constants defined in upcoming libzmq-4.2.dev
PyZMQ 15 adds Future-returning sockets and pollers for both
Update bundled libzmq to 4.1.2.
Following the lead of Python 3.5, interrupted system calls will be retried.
Fixes for CFFI backend on Python 3 + support for PyPy 3.
Verify types of all frames in
send_multipart()before sending, to avoid partial messages.
Fix build on Windows when both debug and release versions of libzmq are found.
Windows build fixes for Python 3.5.
zmq.Socket.bind_to_random_port(): : - use system to allocate ports by default
catch EACCES on Windows
include libsodium when building bundled libzmq on Windows (includes wheels on PyPI)
pyzmq no longer bundles external libzmq when making a bdist. You can use delocate to do this.
use pickle.DEFAULT_PROTOCOL by default in send_pickle
with the release of pip-6, OS X wheels are only marked as 10.6-intel, indicating that they should be installable on any newer or single-arch Python.
raise SSHException on failed check of host key
fix method name in utils.wi32.allow_interrupt
fork-related fixes in garbage collection thread
add missing import in
zmq.__init__, causing failure to import in some circumstances
Bugfixes for 14.4
SyntaxError on Python 2.6 in zmq.ssh
Handle possible bug in garbage collection after fork
Experimental support for libzmq-4.1.0 rc (new constants, plus
Update bundled libzmq to 4.0.5
Update bundled libsodium to 1.0.0
Fixes for SSH dialogs when using
zmq.sshto create tunnels
More build/link/load fixes on OS X and Solaris
Get Frame metadata via dict access (libzmq 4)
Contexts and Sockets are context managers (term/close on
zmq.utils.win32.allow_interruptcontext manager for catching SIGINT on Windows
Bundled libzmq should not trigger recompilation after install on PyPy
pyzmq-14.3.1 is the last version to include bdists for Python 3.3
Minor bugfixes to pyzmq 14.3:
Fixes to building bundled libzmq on OS X < 10.9
Fixes to import-failure warnings on Python 3.4
Fixes to tests
Pull upstream fixes to zmq.ssh for ssh multiplexing
ZMQStream.close()closes its socket immediately, rather than scheduling a timeout.
Raise the original ImportError when importing zmq fails. Should be more informative than
no module cffi....
Users of Python 3.4 should not use pyzmq < 14.3, due to changes in garbage collection.
Raise new ZMQVersionError when a requested method is not supported by the linked libzmq. For backward compatibility, this subclasses NotImplementedError.
Memory leak introduced in pyzmq-14.0 in zero copy.
OverflowError on 32 bit systems in zero copy.
The headline features for 14.1 are adding better support for libzmq’s security features.
When libzmq is bundled as a Python extension (e.g. wheels, eggs), libsodium is also bundled (excluding Windows), ensuring that libzmq security is available to users who install from wheels
Other New Stuff#
Add PYZMQ_BACKEND for enabling use of backends outside the pyzmq codebase.
Add TOS, ROUTER_HANDOVER, and IPC_FILTER constants from libzmq-4.1-dev.
Add Context option support in the CFFI backend.
Various small unicode and build fixes, as always.
Socket.socket_typeis deprecated, in favor of
Socket.type, which has been available since 2.1.
Update bundled libzmq to current (4.0.3).
Fix bug in
Context.destroy()with no open sockets.
Threadsafety fixes in the garbage collector.
Python 3 fixes in
Update bundled libzmq to current (4.0.1).
Backends are now implemented in
zmq.core. This has no effect on public APIs.
Various build improvements for Cython and CFFI backends (PyPy compiles at build time).
Various GIL-related performance improvements - the GIL is no longer touched from a zmq IO thread.
Adding a constant should now be a bit easier - only zmq/sugar/constant_names should need updating, all other constant-related files should be automatically updated by
add support for latest libzmq-4.0.1 (includes ZMQ_CURVE security and socket event monitoring).
The main new feature is improved tornado 3 compatibility. PyZMQ ships a ‘minitornado’ submodule, which contains a small subset of tornado 3.0.1, in order to get the IOLoop base class. zmq.eventloop.ioloop.IOLoop is now a simple subclass, and if the system tornado is ≥ 3.0, then the zmq IOLoop is a proper registered subclass of the tornado one itself, and minitornado is entirely unused.
A few things were broken in 13.0.0, so this is a quick bugfix release.
FIXED EAGAIN was unconditionally turned into KeyboardInterrupt
FIXED we used totally deprecated ctypes_configure to generate constants in CFFI backend
FIXED memory leak in CFFI backend for PyPy
FIXED typo prevented IPC_PATH_MAX_LEN from ever being defined
FIXED various build fixes - linking with librt, Cython compatibility, etc.
defunct bugfix. We do not speak of this…
PyZMQ now officially targets libzmq-3 (3.2.2), 0MQ ≥ 2.1.4 is still supported for the indefinite future, but 3.x is recommended. PyZMQ has detached from libzmq versioning, and will just follow its own regular versioning scheme from now on. PyZMQ bdists will include whatever is the latest stable libzmq release (3.2.2 for pyzmq-13.0).
set/get methods are exposed via get/setattr on all Context, Socket, and Frame classes. This means that subclasses of these classes that require extra attributes must declare these attributes at the class level.
The Threadsafe ZMQStream experiment in 184.108.40.206 was deemed inappropriate and not useful, and has been removed.
zmq.webexperiment has been removed, to be developed as a standalone project.
Support for PyPy via CFFI backend (requires py, ctypes-configure, and cffi).
Add support for new APIs in libzmq-3
Setting and getting
Socket.hwmsets or gets both SNDHWM/RCVHWM for libzmq-3.
Implementation splits core Cython bindings from pure-Python subclasses with sugar methods (send/recv_multipart). This should facilitate non-Cython backends and PyPy support [spoiler: it did!].
This is a tech-preview release, to try out some new features. It is expected to be short-lived, as there are likely to be issues to iron out, particularly with the new pip-install support.
Experimental New Stuff#
These features are marked ‘experimental’, which means that their APIs are not set in stone, and may be removed or changed in incompatible ways in later releases.
With the IOLoop inherited from tornado, there is exactly one method that is threadsafe:
IOLoop.add_callback(). With this release, we are trying an experimental option
to pass all IOLoop calls via this method, so that ZMQStreams can be used from one thread
while the IOLoop runs in another. To try out a threadsafe stream:
stream = ZMQStream(socket, threadsafe=True)
pip install pyzmq#
PyZMQ should now be pip installable, even on systems without libzmq. In these cases, when pyzmq fails to find an appropriate libzmq to link against, it will try to build libzmq as a Python extension. This work is derived from pyzmq_static.
To this end, PyZMQ source distributions include the sources for libzmq (2.2.0) and libuuid (2.21), both used under the LGPL.
TIMEO sockopts are properly included for libzmq-2.2.0
avoid garbage collection of sockets after fork (would cause
Some effort has gone into refining the pyzmq API in this release to make it a model for other language bindings. This is principally made in a few renames of objects and methods, all of which leave the old name for backwards compatibility.
As of this release, all code outside
zmq.core is BSD licensed (where
possible), to allow more permissive use of less-critical code and utilities.
Messageclass has been renamed to
Frame, to better match other zmq bindings. The old Message name remains for backwards-compatibility. Wherever pyzmq docs say “Message”, they should refer to a complete zmq atom of communication (one or more Frames, connected by ZMQ_SNDMORE). Please report any remaining instances of Message==MessagePart with an Issue (or better yet a Pull Request).
foo_unicodemethods are now called
_unicoderemains for backwards compatibility). This is not only for cross-language consistency, but it makes more sense in Python 3, where native strings are unicode, and the
_unicodesuffix was wedded too much to Python 2.
Other Changes and Removals#
prefixremoved as an unused keyword argument from
on_err()is deprecated, because it never did anything.
Python 2.5 compatibility has been dropped, and some code has been cleaned up to reflect no-longer-needed hacks.
Some Cython files in
zmq.corehave been split, to reduce the amount of Cython-compiled code. Much of the body of these files were pure Python, and thus did not benefit from the increased compile time. This change also aims to ease maintaining feature parity in other projects, such as pyzmq-ctypes.
Contextobjects can now set default options when they create a socket. These are set and accessed as attributes to the context. Socket options that do not apply to a socket (e.g. SUBSCRIBE on non-SUB sockets) will simply be ignored.
on_recv_stream()has been added, which adds the stream itself as a second argument to the callback, making it easier to use a single callback on multiple streams.
moreboolean attribute has been added to the
Frame(née Message) class, so that frames can be identified as terminal without extra queires of
Experimental New Stuff#
These features are marked ‘experimental’, which means that their APIs are not set in stone, and may be removed or changed in incompatible ways in later releases.
zmq.webadded for load-balancing requests in a tornado webapp with zeromq.
remove support for LABEL prefixes. A major feature of libzmq-3.0, the LABEL prefix, has been removed from libzmq, prior to the first stable libzmq 3.x release.
Socket.poll()method, for simple polling of events on a single socket.
no longer require monkeypatching tornado IOLoop. The
ioloop.ZMQPollerclass is a poller implementation that matches tornado’s expectations, and pyzmq sockets can be used with any tornado application just by specifying the use of this poller. The pyzmq IOLoop implementation now only trivially differs from tornado’s.
It is still recommended to use
ioloop.install(), which sets both the zmq and tornado global IOLoop instances to the same object, but it is no longer necessary.
The most important part of this change is that the
IOLoop.READ/WRITE/ERRORconstants now match tornado’s, rather than being mapped directly to the zmq
POLLIN/OUT/ERR. So applications that used the low-level
POLLIN/OUT/ERRdirectly (used to work, but was incorrect), rather than using the IOLoop class constants will no longer work. Fixing these to use the IOLoop constants should be insensitive to the actual value of the constants.
Add support for libzmq-3.0 LABEL prefixes:
This feature has been removed from libzmq, and thus removed from future pyzmq as well.
send a message with label-prefix with:
send_multipart([b"msg", b"parts"], prefix=[b"label", b"prefix"])
recv_multipart()returns a tuple of
(prefix,msg)if a label prefix is detected
ZMQStreams and devices also respect the LABEL prefix
add czmq-style close&term as
ctx.destroy(), so that
ctx.term()remains threadsafe and 1:1 with libzmq.
Socket.close()takes optional linger option, for setting linger prior to closing.
pyzmq_version_info()for getting libzmq and pyzmq versions as tuples of numbers. This helps with the fact that version string comparison breaks down once versions get into double-digits.
ioloop changes merged from upstream Tornado 2.1
added zmq.ssh tools for tunneling socket connections, copied from IPython
Expanded sockopt support to cover changes in libzmq-4.0 dev.
Fixed an issue that prevented
KeyboardInterruptsfrom being catchable.
Added attribute-access for set/getsockopt. Setting/Getting attributes of
Socketswith the names of socket options is mapped to calls of set/getsockopt.
s.hwm = 10 s.identity = b"whoda" s.linger # -1
Contextcloses the sockets it created, matching the behavior in czmq.
Context.instance()to create sockets, so they can use inproc connections to sockets in other threads.
fixed units error on
zmq.select(), where the poll timeout was 1000 times longer than expected.
DEALER/ROUTERsocket type names (currently aliases, to be replacements for
base libzmq dependency raised to 2.1.4 (first stable release) from 2.1.0.
bdist for 64b Windows only. This fixed a type mismatch on the
ZMQ_FDsockopt that only affected that platform.
Added experimental support for libzmq-3.0 API
zmq.eventloop.ioloop.install()for using pyzmq’s IOLoop in a tornado application.
First version with binary distribution support
instance()method for using a single Context throughout an application without passing references around.