Commit f4e6da2a authored by SVN-Git Migration's avatar SVN-Git Migration

Imported Upstream version 2.2.0.1

parent bad794d4
*.pyc
*.c
zmq/*/*.c
build
dist
conf
bundled
*.egg-info
*.so
*.pyd
*.dll
*.dylib
docs/source/api/generated
docs/gh-pages
setup.cfg
MANIFEST
.tox
language: python
python:
- 2.6
- 2.7
- 3.2
before_install:
- pip install -q --use-mirrors cython
install:
- python setup.py build_ext --inplace
script: python setup.py test
......@@ -7,12 +7,23 @@ include setup.cfg.template
include setup.py
include setupegg.py
include zmqversion.py
include buildutils.py
include tox.ini
include .travis.yml
graft docs
prune docs/build
prune docs/gh-pages
graft bundled/uuid
exclude bundled/uuid/Makefile*
include bundled/zeromq/COPYING
graft bundled/zeromq/include
graft bundled/zeromq/src
include bundled/zeromq/builds/msvc/platform.hpp
exclude bundled/zeromq/src/Makefile*
exclude bundled/zeromq/src/platform.hpp
graft buildutils
graft examples
graft zmq
graft perf
......
......@@ -5,6 +5,8 @@ PyZMQ: Python bindings for ØMQ
This package contains Python bindings for `ØMQ <http://www.zeromq.org>`_.
ØMQ is a lightweight and fast messaging implementation.
PyZMQ should work with libzmq 2.1.4 (including libzmq 3.2.x), and Python 2.6 (including Python 3).
Versioning
==========
......@@ -51,6 +53,23 @@ or later.
Building and installation
=========================
pip
---
We build eggs for OS X and Windows, so we recommend that those platforms use ``easy_install pyzmq``.
But many users prefer pip, which unfortunately still ignores eggs.
In an effort to make pyzmq easier to install,
pyzmq will try to build libzmq as a Python extension if it cannot find a libzmq to link against.
This is thanks to work done in `pyzmq_static <https://github.com/brandon-rhodes/pyzmq-static>`_.
Linking against system libzmq is still the preferred mechanism,
so pyzmq will try pretty hard to find it.
You can skip the searching by explicitly specifying that pyzmq build its own libzmq::
$> pip install pyzmq --install-option="--zmq=bundled"
Eggs and MSIs
-------------
......@@ -240,9 +259,9 @@ is the primary developer of pyzmq at this time.
The following people have contributed to the project:
* 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)
* Brandon Craig Rhodes (brandon AT rhodesmill DOT org)
* 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)
......@@ -252,17 +271,24 @@ The following people have contributed to the project:
* Erik Tollerud (erik DOT tollerud AT gmail DOT com)
* 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)
* 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)
* 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))
* spez (steve AT hipmunk DOT com)
......@@ -276,6 +302,7 @@ with some adjustments.
Not in git log
--------------
* Brandon Craig-Rhodes (brandon AT rhodesmill DOT org)
* Eugene Chernyshov (chernyshov DOT eugene AT gmail DOT com)
* Douglas Creager (dcreager AT dcreager DOT net)
* Craig Austin (craig DOT austin AT gmail DOT com)
......
"""utilities for building pyzmq.
Largely adapted from h5py
"""
from .msg import *
from .config import *
from .detect import *
from .bundle import *
"""utilities for fetching build dependencies."""
#-----------------------------------------------------------------------------
# Copyright (c) 2012 Min Ragan-Kelley
#
# This file is part of pyzmq
#
# Distributed under the terms of the New BSD License. The full license is in
# the file COPYING.BSD, distributed as part of this software.
#
# This bundling code is largely adapted from pyzmq-static's get.sh by
# Brandon Craig-Rhodes, which is itself BSD licensed.
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------
import os
import shutil
import sys
import tarfile
from subprocess import Popen, PIPE
try:
# py2
from urllib2 import urlopen
except ImportError:
# py3
from urllib.request import urlopen
from .msg import fatal, debug, info, warn
pjoin = os.path.join
#-----------------------------------------------------------------------------
# Constants
#-----------------------------------------------------------------------------
bundled_version = (2,2,0)
libzmq = "zeromq-%i.%i.%i.tar.gz" % (bundled_version)
libzmq_url = "http://download.zeromq.org/" + libzmq
util = "util-linux-2.21.tar.gz"
util_url = "http://www.kernel.org/pub/linux/utils/util-linux/v2.21/" + util
HERE = os.path.dirname(__file__)
ROOT = os.path.dirname(HERE)
#-----------------------------------------------------------------------------
# functions
#-----------------------------------------------------------------------------
def untgz(archive):
return archive.replace('.tar.gz', '')
def localpath(*args):
"""construct an absolute path from a list relative to the root pyzmq directory"""
plist = [ROOT] + list(args)
return os.path.abspath(pjoin(*plist))
def fetch_archive(savedir, url, fname, force=False):
"""download an archive to a specific location"""
dest = pjoin(savedir, fname)
if os.path.exists(dest) and not force:
info("already have %s" % fname)
return dest
info("fetching %s into %s" % (url, savedir))
if not os.path.exists(savedir):
os.makedirs(savedir)
req = urlopen(url)
with open(dest, 'wb') as f:
f.write(req.read())
return dest
def fetch_libzmq(savedir):
"""download and extract libzmq"""
dest = pjoin(savedir, 'zeromq')
if os.path.exists(dest):
info("already have %s" % dest)
return
fname = fetch_archive(savedir, libzmq_url, libzmq)
tf = tarfile.open(fname)
with_version = pjoin(savedir, tf.firstmember.path)
tf.extractall(savedir)
tf.close()
# remove version suffix:
shutil.move(with_version, dest)
def stage_platform_hpp(zmqroot):
"""stage platform.hpp into libzmq sources
Tries ./configure first (except on Windows),
then falls back on included platform.hpp previously generated.
"""
platform_hpp = pjoin(zmqroot, 'src', 'platform.hpp')
if os.path.exists(platform_hpp):
info("already have platform.hpp")
return
if os.name == 'nt':
# stage msvc platform header
platform_dir = pjoin(zmqroot, 'builds', 'msvc')
else:
info("attempting ./configure to generate platform.hpp")
p = Popen('./configure', cwd=zmqroot, shell=True,
stdout=PIPE, stderr=PIPE,
)
o,e = p.communicate()
if p.returncode:
warn("failed to configure libzmq:\n%s" % e)
if sys.platform == 'darwin':
platform_dir = pjoin(HERE, 'include_darwin')
elif sys.platform.startswith('freebsd'):
platform_dir = pjoin(HERE, 'include_freebsd')
else:
platform_dir = pjoin(HERE, 'include_linux')
else:
return
info("staging platform.hpp from: %s" % platform_dir)
shutil.copy(pjoin(platform_dir, 'platform.hpp'), platform_hpp)
def fetch_uuid(savedir):
"""download, extract, and patch libuuid sources"""
dest = pjoin(savedir, 'uuid')
if os.path.exists(dest):
info("already have %s" % dest)
return
fname = fetch_archive(savedir, util_url, util)
tf = tarfile.open(fname)
util_name = untgz(util)
uuid_path = util_name+'/libuuid/src'
uuid = filter(
lambda m: m.name.startswith(uuid_path) and not m.name.endswith("nt.c"),
tf.getmembers()
)
# uuid_members = map(tf.getmember, uuid_names)
tf.extractall(savedir, uuid)
if os.path.exists(dest):
shutil.rmtree(dest)
shutil.move(pjoin(savedir, util_name, 'libuuid', 'src'), dest)
shutil.rmtree(pjoin(savedir, util_name))
patch_uuid(dest)
def patch_uuid(uuid_dir):
"""patch uuid.h with a few defines
from pyzmq-static
"""
info("patching gen_uuid.c")
gen_uuid = pjoin(uuid_dir, "gen_uuid.c")
with open(gen_uuid) as f:
lines = f.readlines()
if 'pyzmq-patch' in lines[0]:
info("already patched")
return
else:
lines.insert(0, "// end pyzmq-patch\n")
for h in ('UNISTD', 'STDLIB', 'SYS_FILE'):
lines.insert(0, "#define HAVE_%s_H\n" % h)
lines.insert(0, "// begin pyzmq-patch\n")
with open(gen_uuid, 'w') as f:
f.writelines(lines)
def copy_and_patch_libzmq(ZMQ, libzmq):
"""copy libzmq into source dir, and patch it if necessary.
This command is necessary prior to running a bdist on Linux or OS X.
"""
if sys.platform.startswith('win'):
return
# copy libzmq into zmq for bdist
local = localpath('zmq',libzmq)
if ZMQ is None and not os.path.exists(local):
fatal("Please specify zmq prefix via `setup.py configure --zmq=/path/to/zmq` "
"or copy libzmq into zmq/ manually prior to running bdist.")
try:
# resolve real file through symlinks
lib = os.path.realpath(pjoin(ZMQ, 'lib', libzmq))
print ("copying %s -> %s"%(lib, local))
shutil.copy(lib, local)
except Exception:
if not os.path.exists(local):
fatal("Could not copy libzmq into zmq/, which is necessary for bdist. "
"Please specify zmq prefix via `setup.py configure --zmq=/path/to/zmq` "
"or copy libzmq into zmq/ manually.")
if sys.platform == 'darwin':
# patch install_name on darwin, instead of using rpath
cmd = ['install_name_tool', '-id', '@loader_path/../%s'%libzmq, local]
try:
p = Popen(cmd, stdout=PIPE,stderr=PIPE)
except OSError:
fatal("install_name_tool not found, cannot patch libzmq for bundling.")
out,err = p.communicate()
if p.returncode:
fatal("Could not patch bundled libzmq install_name: %s"%err, p.returncode)
"""Config functions"""
#-----------------------------------------------------------------------------
# Copyright (C) 2011 Brian Granger, Min Ragan-Kelley
#
# This file is part of pyzmq, copied and adapted from h5py.
# h5py source used under the New BSD license
#
# h5py: <http://code.google.com/p/h5py/>
#
# Distributed under the terms of the New BSD License. The full license is in
# the file COPYING.BSD, distributed as part of this software.
#-----------------------------------------------------------------------------
import sys
import os
import json
try:
from configparser import ConfigParser
except:
from ConfigParser import ConfigParser
pjoin = os.path.join
from .msg import debug, fatal, warn
#-----------------------------------------------------------------------------
# Utility functions (adapted from h5py: http://h5py.googlecode.com)
#-----------------------------------------------------------------------------
def load_config(name):
"""Load config dict from JSON"""
fname = pjoin('conf', name+'.json')
if not os.path.exists(fname):
return None
try:
with open(fname) as f:
cfg = json.load(f)
except Exception as e:
warn("Couldn't load %s: %s" % (fname, e))
cfg = None
return cfg
def save_config(name, data):
"""Save config dict to JSON"""
if not os.path.exists('conf'):
os.mkdir('conf')
fname = pjoin('conf', name+'.json')
with open(fname, 'w') as f:
json.dump(data, f, indent=2)
def v_str(v_tuple):
"""turn (2,0,1) into '2.0.1'."""
return ".".join(str(x) for x in v_tuple)
def get_eargs():
""" Look for options in environment vars """
settings = {}
zmq = os.environ.get("ZMQ_DIR", '')
if zmq != '':
debug("Found environ var ZMQ_DIR=%s" % zmq)
settings['zmq'] = zmq
return settings
def get_cfg_args():
""" Look for options in setup.cfg """
settings = {}
zmq = ''
if not os.path.exists('setup.cfg'):
return settings
cfg = ConfigParser()
cfg.read('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
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)
else:
settings['zmq'] = zmq
sys.argv.remove(arg)
save_config('buildconf', settings)
return settings
def discover_settings():
""" Discover custom settings for ZMQ path"""
settings = get_cfg_args() # lowest priority
settings.update(get_eargs())
settings.update(get_cargs()) # highest priority
return settings.get('zmq')
......@@ -15,36 +15,13 @@ import shutil
import sys
import os
import logging
import pickle
import platform
from distutils import ccompiler
from distutils.sysconfig import customize_compiler
from subprocess import Popen, PIPE
try:
from configparser import ConfigParser
except:
from ConfigParser import ConfigParser
pjoin = os.path.join
#-----------------------------------------------------------------------------
# Logging (adapted from h5py: http://h5py.googlecode.com)
#-----------------------------------------------------------------------------
logger = logging.getLogger()
logger.addHandler(logging.StreamHandler(sys.stderr))
def debug(what):
pass
def fatal(instring, code=1):
logger.error("Fatal: "+instring)
exit(code)
def warn(instring):
logger.error("Warning: "+instring)
#-----------------------------------------------------------------------------
# Utility functions (adapted from h5py: http://h5py.googlecode.com)
#-----------------------------------------------------------------------------
......@@ -69,7 +46,7 @@ def detect_zmq(basedir, **compiler_attrs):
vers : tuple
The ZMQ version as a tuple of ints, e.g. (2,2,0)
options : dict
settings : dict
The compiler options used to compile the test function, e.g. `include_dirs`,
`library_dirs`, `libs`, etc.
"""
......@@ -81,27 +58,12 @@ def detect_zmq(basedir, **compiler_attrs):
cfile = pjoin(basedir, 'vers.c')
efile = pjoin(basedir, 'vers')
f = open(cfile, 'w')
try:
f.write(
r"""
#include <stdio.h>
#include "zmq.h"
int main(void){
int major, minor, patch;
zmq_version(&major, &minor, &patch);
fprintf(stdout, "vers: %d.%d.%d\n", major, minor, patch);
return 0;
}
""")
finally:
f.close()
shutil.copy(pjoin(os.path.dirname(__file__), 'vers.c'), cfile)
cpreargs = lpreargs = None
if sys.platform == 'darwin':
# use appropriate arch for comiler
# use appropriate arch for compiler
if platform.architecture()[0]=='32bit':
cpreargs = ['-arch','i386']
lpreargs = ['-arch', 'i386', '-undefined', 'dynamic_lookup']
......@@ -122,140 +84,13 @@ int main(void){
logging.error(msg)
raise IOError(msg)
handlers = {'vers': lambda val: tuple(int(v) for v in val.split('.'))}
handlers = {'vers': lambda val: tuple(int(v) for v in val.split('.'))}
props = {}
for line in (x for x in so.split('\n') if x):
key, val = line.split(':')
props[key] = handlers[key](val)
props['options'] = compiler_attrs
props['settings'] = compiler_attrs
return props
def localpath(*args):
plist = [os.path.dirname(__file__)]+list(args)
return os.path.abspath(pjoin(*plist))
def loadpickle(name):
""" Load object from pickle file, or None if it can't be opened """
name = pjoin('conf', name)
try:
f = open(name,'rb')
except IOError:
# raise
return None
try:
return pickle.load(f)
except Exception:
# raise
return None
finally:
f.close()
def savepickle(name, data):
""" Save to pickle file, exiting if it can't be written """
if not os.path.exists('conf'):
os.mkdir('conf')
name = pjoin('conf', name)
try:
f = open(name, 'wb')
except IOError:
fatal("Can't open pickle file \"%s\" for writing" % name)
try:
pickle.dump(data, f, 0)
finally:
f.close()
def v_str(v_tuple):
"""turn (2,0,1) into '2.0.1'."""
return ".".join(str(x) for x in v_tuple)
def get_eargs():
""" Look for options in environment vars """
settings = {}
zmq = os.environ.get("ZMQ_DIR", '')
if zmq != '':
debug("Found environ var ZMQ_DIR=%s" % zmq)
settings['zmq'] = zmq
return settings
def get_cfg_args():
""" Look for options in setup.cfg """
settings = {}
zmq = ''
if not os.path.exists('setup.cfg'):
return settings
cfg = ConfigParser()
cfg.read('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
return settings
def get_cargs():
""" Look for global options in the command line """
settings = loadpickle('buildconf.pickle')
if settings is None: settings = {}
for arg in sys.argv[:]:
if arg.find('--zmq=') == 0:
zmq = arg.split('=')[-1]
if zmq.lower() == 'default':
settings.pop('zmq', None)
else:
settings['zmq'] = zmq
sys.argv.remove(arg)
savepickle('buildconf.pickle', settings)
return settings
def discover_settings():
""" Discover custom settings for ZMQ path"""
settings = get_cfg_args() # lowest priority
settings.update(get_eargs())
settings.update(get_cargs()) # highest priority
return settings.get('zmq')
def copy_and_patch_libzmq(ZMQ, libzmq):
"""copy libzmq into source dir, and patch it if necessary.
This command is necessary prior to running a bdist on Linux or OS X.
"""
if sys.platform.startswith('win'):
return
# copy libzmq into zmq for bdist
local = localpath('zmq',libzmq)
if ZMQ is None and not os.path.exists(local):
fatal("Please specify zmq prefix via `setup.py configure --zmq=/path/to/zmq` "
"or copy libzmq into zmq/ manually prior to running bdist.")
try:
# resolve real file through symlinks
lib = os.path.realpath(pjoin(ZMQ, 'lib', libzmq))
print ("copying %s -> %s"%(lib, local))
shutil.copy(lib, local)
except Exception:
if not os.path.exists(local):
fatal("Could not copy libzmq into zmq/, which is necessary for bdist. "
"Please specify zmq prefix via `setup.py configure --zmq=/path/to/zmq` "
"or copy libzmq into zmq/ manually.")
if sys.platform == 'darwin':
# patch install_name on darwin, instead of using rpath
cmd = ['install_name_tool', '-id', '@loader_path/../%s'%libzmq, local]
try:
p = Popen(cmd, stdout=PIPE,stderr=PIPE)
except OSError:
fatal("install_name_tool not found, cannot patch libzmq for bundling.")
out,err = p.communicate()
if p.returncode:
fatal("Could not patch bundled libzmq install_name: %s"%err, p.returncode)
/* src/platform.hpp. Generated from platform.hpp.in by configure. */
/* src/platform.hpp.in. Generated from configure.in by autoheader. */
/* Define to 1 if you have the <alloca.h> header file. */
#define HAVE_ALLOCA_H 1
/* 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 <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* Define to 1 if you have the <errno.h> header file. */
#define HAVE_ERRNO_H 1
/* Define to 1 if you have the `freeifaddrs' function. */
#define HAVE_FREEIFADDRS 1
/* Define to 1 if you have the `getifaddrs' function. */
#define HAVE_GETIFADDRS 1
/* Define to 1 if you have the `gettimeofday' function. */
#define HAVE_GETTIMEOFDAY 1
/* Define to 1 if you have the <ifaddrs.h> header file. */
#define HAVE_IFADDRS_H 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the `crypto' library (-lcrypto). */
/* #undef HAVE_LIBCRYPTO */
/* Define to 1 if you have the `iphlpapi' library (-liphlpapi). */
/* #undef HAVE_LIBIPHLPAPI */
/* Define to 1 if you have the `nsl' library (-lnsl). */
/* #undef HAVE_LIBNSL */
/* Define to 1 if you have the `pthread' library (-lpthread). */
#define HAVE_LIBPTHREAD 1
/* Define to 1 if you have the `rpcrt4' library (-lrpcrt4). */