Commit 9b9c15ce authored by SVN-Git Migration's avatar SVN-Git Migration

Imported Upstream version 13.1.0

parent f4e6da2a
......@@ -2,5 +2,7 @@ Brian E. Granger <> Brian Granger <>
Daniel Lundin <> Daniel Lundin <>
Min Ragan-Kelley <> Min RK <>
Min Ragan-Kelley <> MinRK <>
Michel Pelletier <> Michel Pelletier <>
Nicholas Piël <> nicholas <>
Felipe Cruz <> felipecruz <>
Felipe Cruz <> Felipe cruz <>
......@@ -4,11 +4,24 @@ python:
- 2.6
- 2.7
- 3.2
- 3.3
- pypy
- ZMQ=
- ZMQ=bundled
- pip install -q --use-mirrors cython
- sudo apt-get install -qq libzmq3-dev
- if [[ $TRAVIS_PYTHON_VERSION == 'pypy' ]]; then pip install -q --use-mirrors cffi; fi
- if [[ $TRAVIS_PYTHON_VERSION != 'pypy' ]]; then pip install -q --use-mirrors cython; fi
- python build_ext --inplace
- python build_ext --inplace --zmq=$ZMQ
- python: pypy
env: ZMQ=bundled
- python: pypy
script: python test
## Authors
This project was started and continues to be led by Brian E. Granger
(ellisonbg AT gmail DOT com). Min Ragan-Kelley (benjaminrk AT gmail DOT
com) is the primary developer of pyzmq at this time.
The following people have contributed to the project:
- Alexander Else (alexander DOT else AT team DOT telstra DOT com)
- Andrea Crotti (andrea DOT crotti DOT 0 AT gmail DOT com)
- Andrew Gwozdziewycz (git AT apgwoz DOT com)
- Baptiste Lepilleur (baptiste DOT lepilleur AT gmail DOT com)
- Brandyn A. White (bwhite AT dappervision DOT com)
- Brian E. Granger (ellisonbg AT gmail DOT com)
- Carlos A. Rocha (carlos DOT rocha AT gmail DOT com)
- Christian Wyglendowski (christian AT bu DOT mp)
- Cyril Holweck (cyril DOT holweck AT free DOT fr)
- Dan Colish (dcolish AT gmail DOT com)
- Daniel Lundin (dln AT spotify DOT com)
- Daniel Truemper (truemped AT googlemail DOT com)
- Douglas Creager (douglas DOT creager AT redjack DOT com)
- Eduardo Stalinho (eduardooc DOT 86 AT gmail DOT com)
- Erick Tryzelaar (erick DOT tryzelaar AT gmail DOT com)
- Erik Tollerud (erik DOT tollerud AT gmail DOT com)
- FELD Boris (lothiraldan AT gmail DOT com)
- Felipe cruz (felipecruz AT loogica DOT net)
- Fernando Perez (Fernando DOT Perez AT berkeley DOT edu)
- Frank Wiles (frank AT revsys DOT com)
- Gavrie Philipson (gavriep AT il DOT ibm DOT com)
- Godefroid Chapelle (gotcha AT bubblenet DOT be)
- Ivo Danihelka (ivo AT danihelka DOT net)
- John Gallagher (johnkgallagher AT gmail DOT com)
- Justin Riley (justin DOT t DOT riley AT gmail DOT com)
- Marc Abramowitz (marc AT marc-abramowitz DOT com)
- Michel Pelletier (pelletier DOT michel AT gmail DOT com)
- Min Ragan-Kelley (benjaminrk AT gmail DOT com)
- Nicholas Piël (nicholas AT nichol DOT as)
- Nick Pellegrino (npellegrino AT mozilla DOT com)
- Ondrej Certik (ondrej AT certik DOT cz)
- Paul Colomiets (paul AT colomiets DOT name)
- Robert Jordens (jordens AT gmail DOT com)
- Ryan Cox (ryan DOT a DOT cox AT gmail DOT com)
- Scott Sadler (github AT mashi DOT org)
- Stefan Friesel (sf AT cloudcontrol DOT de)
- Stefan van der Walt (stefan AT sun DOT ac DOT za)
- Stephen Diehl (stephen DOT m DOT diehl AT gmail DOT com)
- Thomas Kluyver (takowl AT gmail DOT com)
- Thomas Spura (tomspur AT fedoraproject DOT org)
- Tigger Bear (Tigger AT Tiggers-Mac-mini DOT local)
- Zbigniew Jędrzejewski-Szmek (zbyszek AT in DOT waw DOT pl)
- hugo shi (hugoshi AT bleb2 DOT (none))
- jdgleeson (jdgleeson AT mac DOT com)
- kyledj (kyle AT bucebuce DOT com)
- spez (steve AT hipmunk DOT com)
as reported by:
git log --all --format='- %aN (%aE)' | sort -u | sed 's/@/ AT /1' | sed -e 's/\./ DOT /g'
with some adjustments.
### Not in git log
- Brandon Craig-Rhodes (brandon AT rhodesmill DOT org)
- Eugene Chernyshov (chernyshov DOT eugene AT gmail DOT com)
- Craig Austin (craig DOT austin AT gmail DOT com)
### gevent\_zeromq, now
- Travis Cline (travis DOT cline AT gmail DOT com)
- Ryan Kelly (ryan AT rfk DOT id DOT au)
- Zachary Voase (z AT zacharyvoase DOT com)
# Opening an Issue
For a good bug report:
1. [Search][] for existing Issues, both on GitHub and in general with Google/Stack Overflow before posting a duplicate question.
2. Update to pyzmq master, if possible, especially if you are already using git. It's
possible that the bug you are about to report has already been fixed.
Many things reported as pyzmq Issues are often just libzmq-related,
and don't have anything to do with pyzmq itself.
These are better directed to [zeromq-dev][].
When making a bug report, it is helpful to tell us as much as you can about your system
(such as pyzmq version, libzmq version, Python version, OS Version, how you built/installed pyzmq and libzmq, etc.)
The basics:
import sys
import zmq
print "libzmq-%s" % zmq.zmq_version()
print "pyzmq-%s" % zmq.pyzmq_version()
print "Python-%s" % sys.version
Which will give something like:
Python-2.7.2 (default, Jun 20 2012, 16:23:33)
[GCC 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-418.0.60)]
# Licensing and contributing to PyZMQ
PyZMQ uses different licenses for different parts of the code.
The 'core' of PyZMQ (located in zmq/core) is licensed under LGPLv3. This just
means that if you make any changes to how that code works, you must release
those changes under the LGPL. If you just *use* pyzmq, then you can use any
license you want for your own code.
The 'core' of PyZMQ (located in zmq/core) is licensed under LGPLv3.
This just means that if you make any changes to how that code works,
you must release those changes under the LGPL.
If you just *use* pyzmq, then you can use any license you want for your own code.
We don't feel that the restrictions imposed by the LGPL make sense for the
'non-core' functionality in pyzmq (derivative code must *also* be LGPL or GPL),
......@@ -16,14 +53,21 @@ your own apps without needing to license your own code with the LGPL or GPL.
## Your contributions
**Pull Requests are welcome!**
When you contribute to PyZMQ, your contributions are made under the same
license as the file you are working on. Any new original code should be BSD
license as the file you are working on. Any new, original code should be BSD
We don't enforce strict style, but when in doubt [PEP8][] is a good guideline.
The only thing we really don't like is mixing up 'cleanup' in real work.
Examples are copyright their respective authors, and BSD unless otherwise
specified by the author. You can LGPL (or GPL or MIT or Apache, etc.) your own new
examples if you like, but we strongly encourage using the default BSD license.
## Inherited licenses in pyzmq
Some code outside the core is taken from other open-source projects, and
......@@ -2,8 +2,10 @@ include COPYING.BSD
include README.rst
include setup.cfg.template
......@@ -33,6 +35,8 @@ exclude zmq/libzmq*
# exclude docs/_static
# exclude docs/_templates
global-exclude __pycache__/*
global-exclude .deps/*
global-exclude *.so
global-exclude *.pyd
global-exclude *.pyc
# PyZMQ: Python bindings for ØMQ
This package contains Python bindings for [ØMQ](
ØMQ is a lightweight and fast messaging implementation.
PyZMQ should work with any Python ≥ 2.6 (including Python 3), as well as PyPy.
The Cython backend used by CPython supports libzmq ≥ 2.1.4 (including 3.2.x),
but the CFFI backend used by PyPy only supports libzmq ≥ 3.2.2.
## Versioning
Current release of pyzmq is 13.1.0, and targets libzmq-3.2.2. For
libzmq 2.0.x, use pyzmq release or the 2.0.x development
branch. PyZMQ (on CPython via Cython) continues to support libzmq ≥ 2.1.4.
pyzmq-2.1.11 was the last version of pyzmq to support Python 2.5, and
pyzmq ≥ 2.2.0 requires Python ≥ 2.6.
pyzmq-13.0.0 introduces PyPy support via CFFI, which only supports libzmq-3.2.2 and newer.
PyZMQ releases ≤ 2.2.0 matched libzmq versioning, but this will no
longer be the case. To avoid confusion with the contemporary libzmq-3.2
major version release, PyZMQ is jumping to 13.0 (it will be the
thirteenth release, so why not?). PyZMQ ≥ 13.0 will follow semantic
versioning conventions accounting only for PyZMQ itself.
For a summary of changes to pyzmq, see our
### ØMQ 3.x
PyZMQ ≥ 2.2.0 fully supports the 3.x API of libzmq,
developed at [zeromq/libzmq](
No code to change, no flags to pass,
just build pyzmq against libzmq3 and it should work.
PyZMQ on PyPy *only* supports the 3.x API of libzmq.
## Documentation
See PyZMQ's Sphinx-generated
[documentation]( on GitHub for API
details, and some notes on Python and Cython development. If you want to
learn about using ØMQ in general, the excellent [ØMQ
Guide]( is the place to start, which has a
Python version of every example. We also have some information on our
## Downloading
Unless you specifically want to develop PyZMQ, we recommend downloading
the PyZMQ source code, eggs, or MSI installer from
You can also get the latest source code from our GitHub repository, but
building from the repository will require that you install Cython
version 0.16 or later.
## Building and installation
For more detail on building pyzmq, see [our Wiki](
We build eggs for OS X and Windows, so we generally recommend that those
platforms use `easy_install pyzmq`, but `pip install pyzmq` should work on
most platforms as well.
To build pyzmq from the git repo requires Cython.
This diff is collapsed.
......@@ -7,3 +7,4 @@ from .msg import *
from .config import *
from .detect import *
from .bundle import *
from .misc import *
......@@ -17,6 +17,7 @@
import os
import shutil
import stat
import sys
import tarfile
from subprocess import Popen, PIPE
......@@ -36,9 +37,10 @@ pjoin = os.path.join
# Constants
bundled_version = (2,2,0)
bundled_version = (3,2,2)
libzmq = "zeromq-%i.%i.%i.tar.gz" % (bundled_version)
libzmq_url = "" + libzmq
# util no longer used
util = "util-linux-2.21.tar.gz"
util_url = "" + util
......@@ -113,6 +115,8 @@ def stage_platform_hpp(zmqroot):
platform_dir = pjoin(HERE, 'include_darwin')
elif sys.platform.startswith('freebsd'):
platform_dir = pjoin(HERE, 'include_freebsd')
elif sys.platform.startswith('linux-armv'):
platform_dir = pjoin(HERE, 'include_linux-armv')
platform_dir = pjoin(HERE, 'include_linux')
......@@ -122,6 +126,9 @@ def stage_platform_hpp(zmqroot):
shutil.copy(pjoin(platform_dir, 'platform.hpp'), platform_hpp)
# fetch/patch_uuid no longer needed for libzmq >= 3
def fetch_uuid(savedir):
"""download, extract, and patch libuuid sources"""
dest = pjoin(savedir, 'uuid')
......@@ -180,7 +187,7 @@ def copy_and_patch_libzmq(ZMQ, libzmq):
# copy libzmq into zmq for bdist
local = localpath('zmq',libzmq)
if ZMQ is None and not os.path.exists(local):
if not ZMQ and not os.path.exists(local):
fatal("Please specify zmq prefix via ` configure --zmq=/path/to/zmq` "
"or copy libzmq into zmq/ manually prior to running bdist.")
......@@ -195,6 +202,10 @@ def copy_and_patch_libzmq(ZMQ, libzmq):
"or copy libzmq into zmq/ manually.")
if sys.platform == 'darwin':
# chmod u+w on the lib,
# which can be user-read-only for some reason
mode = os.stat(local).st_mode
os.chmod(local, mode | stat.S_IWUSR)
# patch install_name on darwin, instead of using rpath
cmd = ['install_name_tool', '-id', '@loader_path/../%s'%libzmq, local]
#include <stdio.h>
#include "sys/un.h"
int main(int argc, char **argv) {
struct sockaddr_un *dummy;
printf("%lu\n", sizeof(dummy->sun_path) - 1);
return 0;
......@@ -28,25 +28,25 @@ from .msg import debug, fatal, warn
def load_config(name):
def load_config(name, base='conf'):
"""Load config dict from JSON"""
fname = pjoin('conf', name+'.json')
fname = pjoin(base, name + '.json')
if not os.path.exists(fname):
return None
return {}
with open(fname) as f:
cfg = json.load(f)
except Exception as e:
warn("Couldn't load %s: %s" % (fname, e))
cfg = None
cfg = {}
return cfg
def save_config(name, data):
def save_config(name, data, base='conf'):
"""Save config dict to JSON"""
if not os.path.exists('conf'):
fname = pjoin('conf', name+'.json')
if not os.path.exists(base):
fname = pjoin(base, name+'.json')
with open(fname, 'w') as f:
json.dump(data, f, indent=2)
......@@ -60,52 +60,98 @@ def get_eargs():
settings = {}
zmq = os.environ.get("ZMQ_DIR", '')
if zmq != '':
debug("Found environ var ZMQ_DIR=%s" % zmq)
settings['zmq'] = zmq
zmq = os.environ.get("ZMQ_PREFIX", None)
if zmq is not None:
debug("Found environ var ZMQ_PREFIX=%s" % zmq)
settings['zmq_prefix'] = zmq
return settings
def cfg2dict(cfg):
"""turn a ConfigParser into a nested dict
because ConfigParser objects are dumb.
d = {}
for section in cfg.sections():
d[section] = dict(cfg.items(section))
return d
def get_cfg_args():
""" Look for options in setup.cfg """
settings = {}
zmq = ''
if not os.path.exists('setup.cfg'):
return settings
return {}
cfg = ConfigParser()'setup.cfg')
if 'build_ext' in cfg.sections() and \
cfg.has_option('build_ext', 'include_dirs'):
includes = cfg.get('build_ext', 'include_dirs')
include = includes.split(os.pathsep)[0]
if include.endswith('include') and os.path.isdir(include):
zmq = include[:-8]
if zmq != '':
debug("Found ZMQ=%s in setup.cfg" % zmq)
settings['zmq'] = zmq
cfg = cfg2dict(cfg)
g = cfg.setdefault('global', {})
# boolean keys:
for key in ['libzmq_extension',
if key in g:
g[key] = eval(g[key])
# globals go to top level
return cfg
def config_from_prefix(prefix):
"""Get config from zmq prefix"""
settings = {}
if prefix.lower() in ('default', 'auto', ''):
settings['zmq_prefix'] = ''
settings['libzmq_extension'] = False
settings['no_libzmq_extension'] = False
elif prefix.lower() in ('bundled', 'extension'):
settings['zmq_prefix'] = ''
settings['libzmq_extension'] = True
settings['no_libzmq_extension'] = False
settings['zmq_prefix'] = prefix
settings['libzmq_extension'] = False
settings['no_libzmq_extension'] = True
return settings
def get_cargs():
""" Look for global options in the command line """
settings = load_config('buildconf')
if settings is None: settings = {}
for arg in sys.argv[:]:
if arg.find('--zmq=') == 0:
zmq = arg.split('=')[-1]
if zmq.lower() in ('default', 'auto', ''):
settings.pop('zmq', None)
def merge(into, d):
"""merge two containers
into is updated, d has priority
if isinstance(into, dict):
for key in d.keys():
if key not in into:
into[key] = d[key]
settings['zmq'] = zmq
save_config('buildconf', settings)
return settings
def discover_settings():
into[key] = merge(into[key], d[key])
return into
elif isinstance(into, list):
return into + d
return d
def discover_settings(conf_base=None):
""" Discover custom settings for ZMQ path"""
settings = get_cfg_args() # lowest priority
settings.update(get_cargs()) # highest priority
return settings.get('zmq')
settings = {
'zmq_prefix': '',
'libzmq_extension': False,
'no_libzmq_extension': False,
'skip_check_zmq': False,
'build_ext': {},
'bdist_egg': {},
if sys.platform.startswith('win'):
settings['have_sys_un_h'] = False
if conf_base:
# lowest priority
merge(settings, load_config('config', conf_base))
merge(settings, get_cfg_args())
merge(settings, get_eargs())
return settings
......@@ -20,13 +20,67 @@ from distutils import ccompiler
from distutils.sysconfig import customize_compiler
from subprocess import Popen, PIPE
from .misc import customize_mingw
pjoin = os.path.join
# Utility functions (adapted from h5py:
def detect_zmq(basedir, **compiler_attrs):
def test_compilation(cfile, compiler=None, **compiler_attrs):
"""Test simple compilation with given settings"""
if compiler is None or isinstance(compiler, str):
cc = ccompiler.new_compiler(compiler=compiler)
if cc.compiler_type == 'mingw32':
cc = compiler
for name, val in compiler_attrs.items():
setattr(cc, name, val)
efile, ext = os.path.splitext(cfile)
cpreargs = lpreargs = None
if sys.platform == 'darwin':
# use appropriate arch for compiler
if platform.architecture()[0]=='32bit':
if platform.processor() == 'powerpc':
cpu = 'ppc'
cpu = 'i386'
cpreargs = ['-arch', cpu]
lpreargs = ['-arch', cpu, '-undefined', 'dynamic_lookup']
# allow for missing UB arch, since it will still work:
lpreargs = ['-undefined', 'dynamic_lookup']
extra = compiler_attrs.get('extra_compile_args', None)
objs = cc.compile([cfile],extra_preargs=cpreargs, extra_postargs=extra)
cc.link_executable(objs, efile, extra_preargs=lpreargs)
return efile
def compile_and_run(basedir, src, compiler=None, **compiler_attrs):
if not os.path.exists(basedir):
cfile = pjoin(basedir, os.path.basename(src))
shutil.copy(src, cfile)
efile = test_compilation(cfile, compiler=compiler, **compiler_attrs)
result = Popen(efile, stdout=PIPE, stderr=PIPE)
so, se = result.communicate()
# for py3k:
so = so.decode()
se = se.decode()
return result.returncode, so, se
def detect_zmq(basedir, compiler=None, **compiler_attrs):
"""Compile, link & execute a test program, in empty directory `basedir`.
The C compiler will be updated with any keywords given via setattr.
......@@ -36,6 +90,8 @@ def detect_zmq(basedir, **compiler_attrs):
basedir : path
The location where the test program will be compiled and run
compiler : str
The distutils compiler key (e.g. 'unix', 'msvc', or 'mingw32')
**compiler_attrs : dict
Any extra compiler attributes, which will be set via ``setattr(cc)``.
......@@ -50,30 +106,19 @@ def detect_zmq(basedir, **compiler_attrs):
The compiler options used to compile the test function, e.g. `include_dirs`,
`library_dirs`, `libs`, etc.
cc = ccompiler.new_compiler()
for name, val in compiler_attrs.items():
setattr(cc, name, val)
cfile = pjoin(basedir, 'vers.c')
efile = pjoin(basedir, 'vers')
cfile = pjoin(basedir, 'vers.c')
shutil.copy(pjoin(os.path.dirname(__file__), 'vers.c'), cfile)
cpreargs = lpreargs = None
if sys.platform == 'darwin':
# use appropriate arch for compiler
if platform.architecture()[0]=='32bit':
cpreargs = ['-arch','i386']
lpreargs = ['-arch', 'i386', '-undefined', 'dynamic_lookup']
# allow for missing UB arch, since it will still work:
lpreargs = ['-undefined', 'dynamic_lookup']
objs = cc.compile([cfile],extra_preargs=cpreargs)
cc.link_executable(objs, efile, extra_preargs=lpreargs)
# check if we need to link against Realtime Extensions library
if sys.platform.startswith('linux'):
cc = ccompiler.new_compiler(compiler=compiler)
cc.output_dir = basedir
if not cc.has_function('timer_create'):
efile = test_compilation(cfile, compiler=compiler, **compiler_attrs)
result = Popen(efile, stdout=PIPE, stderr=PIPE)
so, se = result.communicate()
# for py3k:
......@@ -91,6 +136,5 @@ def detect_zmq(basedir, **compiler_attrs):
key, val = line.split(':')
props[key] = handlers[key](val)
props['settings'] = compiler_attrs
return props
// empty file, just to test compilation
int main(int argc, char **argv){
return 0;
......@@ -7,6 +7,9 @@
/* Define to 1 if you have the <arpa/inet.h> header file. */
#define HAVE_ARPA_INET_H 1
/* Define to 1 if you have the `clock_gettime' function. */
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
......@@ -16,6 +19,9 @@
/* Define to 1 if you have the `freeifaddrs' function. */
/* Define to 1 if you have the `gethrtime' function. */
/* #undef HAVE_GETHRTIME */
/* Define to 1 if you have the `getifaddrs' function. */
......@@ -28,9 +34,6 @@
/* Define to 1 if you have the <inttypes.h> header file. */
/* Define to 1 if you have the `crypto' library (-lcrypto). */
/* #undef HAVE_LIBCRYPTO */
/* Define to 1 if you have the `iphlpapi' library (-liphlpapi). */
......@@ -49,9 +52,6 @@
/* Define to 1 if you have the `socket' library (-lsocket). */
/* #undef HAVE_LIBSOCKET */
/* Define to 1 if you have the `uuid' library (-luuid). */
/* #undef HAVE_LIBUUID */
/* Define to 1 if you have the `ws2_32' library (-lws2_32). */
/* #undef HAVE_LIBWS2_32 */
......@@ -94,6 +94,9 @@
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1