From 741ff1b0132e849328dbf9cbfcc42bb3b964fe8b Mon Sep 17 00:00:00 2001 From: Sang Han Date: Wed, 25 Mar 2015 06:40:55 -0700 Subject: [PATCH 01/58] building messenger call now from root --- config.ini | 20 +++++++ messenger/__init__.py | 1 + messenger/__main__.py | 40 ++++++++++++++ messenger/make.py | 124 +++++++++++++++++++----------------------- messenger/settings.py | 51 +++++++++++++++++ 5 files changed, 168 insertions(+), 68 deletions(-) create mode 100644 config.ini create mode 100644 messenger/__main__.py mode change 100755 => 100644 messenger/make.py create mode 100644 messenger/settings.py diff --git a/config.ini b/config.ini new file mode 100644 index 0000000..9a1cdae --- /dev/null +++ b/config.ini @@ -0,0 +1,20 @@ +[Darwin] +; MATLAB_BIN=Applications/MATLAB_R2014a.app/bin +; OCTAVE_INC= +; OCTAVE_LIB= +ZMQ_INC=/usr/local/include +ZMQ_LIB=/usr/local/lib + +[Windows] +; MATLAB_BIN=C:\Program Files\MATLAB\R2014b\bin +; OCTAVE_INC=C:\Octave\Octave-3.8.2\include\octave-3.8.2\octave +; OCTAVE_LIB=C:\Octave\Octave-3.8.2\lib\octave\3.8.2 +ZMQ_INC=C:/Program Files/ZeroMQ 4.0.4/include +ZMQ_LIB=C:/Program Files/ZeroMQ 4.0.4/lib + +[Linux] +; MATLAB_BIN=/usr/local/bin +; OCTAVE_INC=/usr/include +; OCTAVE_LIB=/usr/lib/x86_64-linux-gnu/ +ZMQ_INC= +ZMQ_LIB= diff --git a/messenger/__init__.py b/messenger/__init__.py index e69de29..c70020d 100644 --- a/messenger/__init__.py +++ b/messenger/__init__.py @@ -0,0 +1 @@ +from .settings import * \ No newline at end of file diff --git a/messenger/__main__.py b/messenger/__main__.py new file mode 100644 index 0000000..ce3ef9c --- /dev/null +++ b/messenger/__main__.py @@ -0,0 +1,40 @@ +from argparse import ArgumentParser + +from .make import * + +def command_line(): + """ + Manages command line arguments. + + Returns + ======= + Namespace containing parsed arguments + """ + + parser = ArgumentParser() + parser.add_argument( + "target", + choices=["matlab", "octave"], + type=str.lower, + help="target to be built" + ) + parser.add_argument( + "--static", + action="store_true", + help="staticly link libzmq" + ) + return parser.parse_args() + + + +def main(): + args = command_line() + if args.target == "matlab": + build_matlab(static=args.static) + elif args.target == "octave": + build_octave() + else: + raise ValueError() + +if __name__ == '__main__': + main() diff --git a/messenger/make.py b/messenger/make.py old mode 100755 new mode 100644 index 7048aab..0a5f21d --- a/messenger/make.py +++ b/messenger/make.py @@ -1,62 +1,61 @@ -#!/usr/bin/python from __future__ import print_function + import os -import platform import sys import shlex import shutil import subprocess +import platform + +from glob import glob +try: + from ConfigParser import ConfigParser +except ImportError: + from configparser import ConfigParser + +from . import settings + +__all__ = [ + 'get_messenger_dir', + 'get_config', + 'do_build', + 'build_octave', + 'build_matlab' +] def get_messenger_dir(): - # Check the system platform first - splatform = sys.platform - - if splatform.startswith('linux'): - messenger_dir = 'mexa64' - elif splatform.startswith('darwin'): - messenger_dir = 'mexmaci64' - elif splatform.startswith('win32'): - if splatform == "win32": - # We have a win64 messenger, so we need to figure out if this is 32 - # or 64 bit Windows: - if not platform.machine().endswith('64'): - raise ValueError("pymatbridge does not work on win32") - - # We further need to differniate 32 from 64 bit: - maxint = sys.maxsize - if maxint == 9223372036854775807: - messenger_dir = 'mexw64' - elif maxint == 2147483647: - messenger_dir = 'mexw32' - return messenger_dir + host, is_64bit = platform.system(), sys.maxsize > 2**32 + ostype = { + 'Darwin': 'mexmaci64', + 'Linux': 'mexa64', + 'Windows': 'mexw64', + } + if not is_64bit and host == 'Windows': + raise ValueError("pymatbridge does not support 32-bit Windows") + + return ostype[host] if is_64bit else 'mexw32' def get_config(): - messenger_dir = get_messenger_dir() - with open(os.path.join(messenger_dir, 'local.cfg')) as fid: - lines = fid.readlines() - - cfg = {} - for line in lines: - if '=' not in line: - continue - name, path = line.split('=') - cfg[name.lower()] = path.strip() or '.' + config = os.path.join(os.path.realpath(__file__), 'config.ini') + print(config) + cfg = ConfigParser() + config.read(config) return cfg def do_build(make_cmd, messenger_exe): print('Building %s...' % messenger_exe) print(make_cmd) - messenger_dir = get_messenger_dir() - subprocess.check_output(shlex.split(make_cmd), shell=True) + messenger_dir = 'messenger' + '/' + get_messenger_dir() + subprocess.call(shlex.split(make_cmd), stderr=subprocess.STDOUT) messenger_loc = os.path.join(messenger_dir, messenger_exe) - shutil.move(messenger_exe, messenger_loc) + # shutil.move(messenger_exe, messenger_loc) - if os.path.exists('messenger.o'): + if os.path.isfile('messenger.o'): os.remove('messenger.o') @@ -68,45 +67,34 @@ def build_octave(): def build_matlab(static=False): - """build the messenger mex for MATLAB - + """ + Build the messenger mex for MATLAB + + Parameters + ============ static : bool Determines if the zmq library has been statically linked. If so, it will append the command line option -DZMQ_STATIC when compiling the mex so it matches libzmq. """ - cfg = get_config() - # To deal with spaces, remove quotes now, and add - # to the full commands themselves. - matlab_bin = cfg['matlab_bin'].strip('"') - # Get the extension - extcmd = '"' + os.path.join(matlab_bin, "mexext") + '"' - extension = subprocess.check_output(extcmd, shell=True) - extension = extension.decode('utf-8').rstrip('\r\n') + matlab_bin = settings.get_matlab_bin() + cfg, host = ConfigParser(), platform.system() + cfg.read('config.ini') + libzmq = { + 'zmq_lib': os.path.normpath(cfg.get(host, 'ZMQ_LIB')), + 'zmq_inc': os.path.normpath(cfg.get(host, 'ZMQ_INC')), + } + + extcmd = '%s' % os.path.join(matlab_bin, "mexext") + extension = subprocess.check_output(extcmd, shell=True) + extension = os.path.join('messenger', extension.decode('utf-8').rstrip()) # Build the mex file mex = '"' + os.path.join(matlab_bin, "mex") + '"' - paths = "-L%(zmq_lib)s -I%(zmq_inc)s" % cfg - make_cmd = '%s -O %s -lzmq ./src/messenger.c' % (mex, paths) + paths = "-L'%(zmq_lib)s' -I'%(zmq_inc)s'" % libzmq + make_cmd = '%s -O %s -lzmq messenger/src/messenger.c' % (mex, paths) + if static: make_cmd += ' -DZMQ_STATIC' - do_build(make_cmd, 'messenger.%s' % extension) - -if __name__ == '__main__': - import argparse - parser = argparse.ArgumentParser() - parser.add_argument( - "target", - choices=["matlab", "octave"], - type=str.lower, - help="target to be built") - parser.add_argument("--static", action="store_true", - help="staticly link libzmq") - args = parser.parse_args() - if args.target == "matlab": - build_matlab(static=args.static) - elif args.target == "octave": - build_octave() - else: - raise ValueError() + do_build(make_cmd, 'messenger.%s' % extension) diff --git a/messenger/settings.py b/messenger/settings.py new file mode 100644 index 0000000..c51e570 --- /dev/null +++ b/messenger/settings.py @@ -0,0 +1,51 @@ +import os +import platform + +from glob import glob + +try: + from configparser import ConfigParser +except ImportError: + from ConfigParser import ConfigParser + +__all__= ['get_matlab_bin'] + +def get_matlab_bin(config='config.ini'): + """ + Tries to find the MATLAB bin directory independent on host platform. + The operation of this function can be overridden by setting the MATLAB_BIN + variable within the configuration file specified. + + Parameters + -========= + config: + Relative path to configuration file + + Returns + ======= + matlab: + Absolute path to matlab bin directory + """ + cfg, host = ConfigParser(), platform.system() + cfg.read(os.path.join(__file__, config)) + + programs = { + 'Darwin' : r'/Applications', + 'Windows': r'C:/Program Files', + 'Linux' : r'/usr/local', + } + + if cfg.has_option(host, 'MATLAB_BIN'): + matlab = cfg.get(host, 'MATLAB_BIN') + else: + # Searches for Matlab bin if it's not set + _root = glob(r'%s/MATLAB*' % programs[host])[0] + _version = [p for p in os.listdir(_root) if p.startswith('R20')] + if any(_version): + _root = r'%s/%s' % (_root, _version.pop()) + matlab = r'%s/%s' % (_root, 'bin') + + assert os.path.isdir(matlab) + + return os.path.normpath(matlab) + From 0ab40340521e124a60f1a32eb4ba59cbec3ba1e6 Mon Sep 17 00:00:00 2001 From: Sang Han Date: Wed, 25 Mar 2015 06:55:45 -0700 Subject: [PATCH 02/58] deprecated local.cfg --- messenger/make.py | 6 +++--- messenger/mexa64/local.cfg | 6 ------ messenger/mexmaci64/local.cfg | 5 ----- messenger/mexmaci64/messenger.mexmaci64 | Bin 9792 -> 9768 bytes messenger/mexw32/local.cfg | 3 --- messenger/mexw64/local.cfg | 5 ----- 6 files changed, 3 insertions(+), 22 deletions(-) delete mode 100644 messenger/mexa64/local.cfg delete mode 100644 messenger/mexmaci64/local.cfg delete mode 100644 messenger/mexw32/local.cfg delete mode 100644 messenger/mexw64/local.cfg diff --git a/messenger/make.py b/messenger/make.py index 0a5f21d..e77105a 100644 --- a/messenger/make.py +++ b/messenger/make.py @@ -48,12 +48,12 @@ def get_config(): def do_build(make_cmd, messenger_exe): print('Building %s...' % messenger_exe) print(make_cmd) - messenger_dir = 'messenger' + '/' + get_messenger_dir() + messenger_dir = get_messenger_dir() subprocess.call(shlex.split(make_cmd), stderr=subprocess.STDOUT) messenger_loc = os.path.join(messenger_dir, messenger_exe) - # shutil.move(messenger_exe, messenger_loc) + shutil.move(messenger_exe, os.path.join('messenger', messenger_loc)) if os.path.isfile('messenger.o'): os.remove('messenger.o') @@ -87,7 +87,7 @@ def build_matlab(static=False): extcmd = '%s' % os.path.join(matlab_bin, "mexext") extension = subprocess.check_output(extcmd, shell=True) - extension = os.path.join('messenger', extension.decode('utf-8').rstrip()) + extension = extension.decode('utf-8').rstrip() # Build the mex file mex = '"' + os.path.join(matlab_bin, "mex") + '"' diff --git a/messenger/mexa64/local.cfg b/messenger/mexa64/local.cfg deleted file mode 100644 index 54ff2f8..0000000 --- a/messenger/mexa64/local.cfg +++ /dev/null @@ -1,6 +0,0 @@ -MATLAB_BIN=/home/silvester/matlab2014b/bin/ -OCTAVE_INC=/usr/include -OCTAVE_LIB=/usr/lib/x86_64-linux-gnu/ -ZMQ_INC= -ZMQ_LIB= - diff --git a/messenger/mexmaci64/local.cfg b/messenger/mexmaci64/local.cfg deleted file mode 100644 index 1de2d8b..0000000 --- a/messenger/mexmaci64/local.cfg +++ /dev/null @@ -1,5 +0,0 @@ -MATLAB_BIN=/Applications/MATLAB_R2012b.app/bin -ZMQ_INC=/usr/include -ZMQ_LIB=/usr/lib/x86_64-linux-gnu/ -OCTAVE_INC= -OCTAVE_LIB= diff --git a/messenger/mexmaci64/messenger.mexmaci64 b/messenger/mexmaci64/messenger.mexmaci64 index 3cc7b8da8bc4461123e832ea6b73474352cac894..71e946f4d2832908f43aa5680d20ba9ec0e2d9cc 100755 GIT binary patch delta 417 zcmX@$v%+Tq3!}zlMiy(u8H@}JI}{lhBp4VNn1C2WODHig$N}jUDhvz_lVe$|S$`-q zFz8Hv$S6E{0}F@1!eh_APpvWK-FTIApDB}^>gE$H5sZo#fTnN&b!h^z01)2*@SpJ1?YGN-b9#5Eurs0%Lo42}O4 zjn4yA3`A^TBY=bm8ea~=XPn%iEFowN<-im>OkSz1FPMNPnzi|-vJK;AdsRk8pfdo3 COibVa delta 441 zcmZ4CbHHZ-3!}qiMiy(u6^slFClnbNBp4VNn1C2WYbY@=$N}jcDhv!AlVe$|Svi0# zoyiXwg(q)d;Sf+&eD7=e&Z57^VVhOVhcxZYCs-mF6(0ai;Q;E=1Y!XoegWizfHn|= z`I{Zt-muxK0xf(Q_5c6>3@Z>T0L1bFvD`qc7!b<_#L5A&j6kd=5K9BZnz%WO_na_S zcxFk4e^ORza>-;1#YPs8C7ZV^3NjjY09ioA%pegEm zg9ktos0+^jfX4ri#uo!B1|l|~Fc`=|`I8%zB?OHi93Tk+wv$&X>np~giDsekOE$k$ OwqZo_=w?+_Mn(WPDOBVD diff --git a/messenger/mexw32/local.cfg b/messenger/mexw32/local.cfg deleted file mode 100644 index d8d9ff6..0000000 --- a/messenger/mexw32/local.cfg +++ /dev/null @@ -1,3 +0,0 @@ -MATLAB_BIN=/Applications/MATLAB_R2012a.app/bin -HEADER_PATH=/usr/include -LIB_PATH=/usr/local/lib diff --git a/messenger/mexw64/local.cfg b/messenger/mexw64/local.cfg deleted file mode 100644 index daf8ab6..0000000 --- a/messenger/mexw64/local.cfg +++ /dev/null @@ -1,5 +0,0 @@ -MATLAB_BIN="C:\Program Files\MATLAB\2014b\bin" -OCTAVE_INC="C:\Octave\Octave-3.8.2\include\octave-3.8.2\octave" -OCTAVE_LIB="C:\Octave\Octave-3.8.2\lib\octave\3.8.2" -ZMQ_INC="C:\zeromq-4.0.5\include" -ZMQ_LIB="C:\zeromq-4.0.5\lib" From b548443b3e1e18d55c04d727881cbdbaaf7c4502 Mon Sep 17 00:00:00 2001 From: Sang Han Date: Thu, 26 Mar 2015 01:56:14 -0700 Subject: [PATCH 03/58] added get_matlab_env function --- messenger/settings.py | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/messenger/settings.py b/messenger/settings.py index c51e570..9f4c396 100644 --- a/messenger/settings.py +++ b/messenger/settings.py @@ -1,5 +1,6 @@ import os import platform +import subprocess from glob import glob @@ -8,7 +9,7 @@ except ImportError: from ConfigParser import ConfigParser -__all__= ['get_matlab_bin'] +__all__= ['get_matlab_bin', 'matlab_env'] def get_matlab_bin(config='config.ini'): """ @@ -49,3 +50,25 @@ def get_matlab_bin(config='config.ini'): return os.path.normpath(matlab) +def get_matlab_env(matlab='matlab'): + """ + Get's the underlying enviornement variables set for a matlab installation. + + Parameters + ========== + matlab: string + Path to the matlab binary executable. + If matlab is in the users $PATH, just pass 'matlab' + + Returns + ======= + enviornment: dictionary + Mapping of enviornment variable[s] + """ + command = ' '.join([matlab, '-e']), + process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE) + + envs = (line.decode('utf-8').strip() for line in process.stdout) + mapping = (env.split('=', maxsplit=1) for env in envs) + + return {key:value for key, value in mapping} From ba6854a1fdcab4faa3389cd846380a2e6e6ce6c5 Mon Sep 17 00:00:00 2001 From: Sang Han Date: Thu, 26 Mar 2015 13:07:44 -0700 Subject: [PATCH 04/58] function for fetching zmq source --- messenger/settings.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/messenger/settings.py b/messenger/settings.py index 9f4c396..d43b1b6 100644 --- a/messenger/settings.py +++ b/messenger/settings.py @@ -1,16 +1,22 @@ import os import platform import subprocess +import logging from glob import glob try: + from urllib.request import urlopen from configparser import ConfigParser except ImportError: + from urllib2 import urlopen from ConfigParser import ConfigParser __all__= ['get_matlab_bin', 'matlab_env'] +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + def get_matlab_bin(config='config.ini'): """ Tries to find the MATLAB bin directory independent on host platform. @@ -72,3 +78,27 @@ def get_matlab_env(matlab='matlab'): mapping = (env.split('=', maxsplit=1) for env in envs) return {key:value for key, value in mapping} + +def fetch_zmq(prefix, version=(4,0,5)): + """ + Download and extract libzmq + + Parameters + ========== + save: str + File Save Location + version: tuple + ZMQ Version Number + """ + logging.info('Downloading ZMQ Version %i.%i.%i' % version) + + url = "http://download.zeromq.org/zeromq-%i.%i.%i.tar.gz" % version + + name, msg = urlretrieve(url, url.rsplit('/')[-1]) + + logging.info('Extracting into prefix %s' % prefix) + with tarfile.open(name) as tar: + tar.extractall(prefix) + + os.remove(name) + logging.info('Download Complete') From 4dfaae107d74840dbdaa00e02e41be7e624dcf93 Mon Sep 17 00:00:00 2001 From: Sang Han Date: Thu, 26 Mar 2015 14:27:50 -0700 Subject: [PATCH 05/58] Fixed windows path --- .idea/scopes/scope_settings.xml | 5 +++++ messenger/settings.py | 25 ++++++++++++------------- setup.py | 10 +++++----- 3 files changed, 22 insertions(+), 18 deletions(-) create mode 100644 .idea/scopes/scope_settings.xml diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml new file mode 100644 index 0000000..922003b --- /dev/null +++ b/.idea/scopes/scope_settings.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/messenger/settings.py b/messenger/settings.py index d43b1b6..9f473d8 100644 --- a/messenger/settings.py +++ b/messenger/settings.py @@ -2,17 +2,18 @@ import platform import subprocess import logging +import tarfile from glob import glob try: - from urllib.request import urlopen + from urllib.request import urlretrieve from configparser import ConfigParser except ImportError: - from urllib2 import urlopen + from urllib2 import urlretrieve from ConfigParser import ConfigParser -__all__= ['get_matlab_bin', 'matlab_env'] +__all__= ['get_matlab_bin', 'get_matlab_env', 'fetch_zmq'] logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) @@ -58,7 +59,7 @@ def get_matlab_bin(config='config.ini'): def get_matlab_env(matlab='matlab'): """ - Get's the underlying enviornement variables set for a matlab installation. + Get the underlying environment variables set for a matlab installation. Parameters ========== @@ -68,8 +69,8 @@ def get_matlab_env(matlab='matlab'): Returns ======= - enviornment: dictionary - Mapping of enviornment variable[s] + environment: dictionary + Mapping of environment variable[s] """ command = ' '.join([matlab, '-e']), process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE) @@ -90,15 +91,13 @@ def fetch_zmq(prefix, version=(4,0,5)): version: tuple ZMQ Version Number """ - logging.info('Downloading ZMQ Version %i.%i.%i' % version) + logger.info('Downloading ZMQ Source Version %i.%i.%i' % version) + url = ("http://download.zeromq.org/zeromq-%i.%i.%i.tar.gz" % version) + name = urlretrieve(url, url.rsplit('/')[-1])[0] - url = "http://download.zeromq.org/zeromq-%i.%i.%i.tar.gz" % version - - name, msg = urlretrieve(url, url.rsplit('/')[-1]) - - logging.info('Extracting into prefix %s' % prefix) + logger.info('Extracting into prefix %s' % prefix) with tarfile.open(name) as tar: tar.extractall(prefix) - os.remove(name) logging.info('Download Complete') + os.remove(name) \ No newline at end of file diff --git a/setup.py b/setup.py index ae9622a..62048cf 100755 --- a/setup.py +++ b/setup.py @@ -2,18 +2,18 @@ """Setup file for python-matlab-bridge""" import os -import sys import shutil import glob # BEFORE importing distutils, remove MANIFEST. distutils doesn't properly # update it when the contents of directories change. -if os.path.exists('MANIFEST'): - os.remove('MANIFEST') +if os.path.exists('MANIFEST'): os.remove('MANIFEST') - -from distutils.core import setup +try: + from setuptools import setup +except ImportError: + from distutils.core import setup # Find the messenger binary file(s) and copy it to /matlab folder. From cc4bfef54581833e745b760d8c41200f86efdd30 Mon Sep 17 00:00:00 2001 From: Sang Han Date: Thu, 26 Mar 2015 14:32:27 -0700 Subject: [PATCH 06/58] Fixed windows path --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 5bd58c1..4c79558 100644 --- a/.gitignore +++ b/.gitignore @@ -37,3 +37,5 @@ rebuildTags.sh # caused py setup.py develop pymatbridge.egg-info + +.idea/scopes/scope_settings.xml \ No newline at end of file From df419712ca111c84dcd18a2dedf37a675463d6a3 Mon Sep 17 00:00:00 2001 From: Sang Han Date: Thu, 26 Mar 2015 15:41:27 -0700 Subject: [PATCH 07/58] commit --- messenger/settings.py | 25 ++++++++++++------------- setup.py | 10 +++++----- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/messenger/settings.py b/messenger/settings.py index d43b1b6..9f473d8 100644 --- a/messenger/settings.py +++ b/messenger/settings.py @@ -2,17 +2,18 @@ import platform import subprocess import logging +import tarfile from glob import glob try: - from urllib.request import urlopen + from urllib.request import urlretrieve from configparser import ConfigParser except ImportError: - from urllib2 import urlopen + from urllib2 import urlretrieve from ConfigParser import ConfigParser -__all__= ['get_matlab_bin', 'matlab_env'] +__all__= ['get_matlab_bin', 'get_matlab_env', 'fetch_zmq'] logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) @@ -58,7 +59,7 @@ def get_matlab_bin(config='config.ini'): def get_matlab_env(matlab='matlab'): """ - Get's the underlying enviornement variables set for a matlab installation. + Get the underlying environment variables set for a matlab installation. Parameters ========== @@ -68,8 +69,8 @@ def get_matlab_env(matlab='matlab'): Returns ======= - enviornment: dictionary - Mapping of enviornment variable[s] + environment: dictionary + Mapping of environment variable[s] """ command = ' '.join([matlab, '-e']), process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE) @@ -90,15 +91,13 @@ def fetch_zmq(prefix, version=(4,0,5)): version: tuple ZMQ Version Number """ - logging.info('Downloading ZMQ Version %i.%i.%i' % version) + logger.info('Downloading ZMQ Source Version %i.%i.%i' % version) + url = ("http://download.zeromq.org/zeromq-%i.%i.%i.tar.gz" % version) + name = urlretrieve(url, url.rsplit('/')[-1])[0] - url = "http://download.zeromq.org/zeromq-%i.%i.%i.tar.gz" % version - - name, msg = urlretrieve(url, url.rsplit('/')[-1]) - - logging.info('Extracting into prefix %s' % prefix) + logger.info('Extracting into prefix %s' % prefix) with tarfile.open(name) as tar: tar.extractall(prefix) - os.remove(name) logging.info('Download Complete') + os.remove(name) \ No newline at end of file diff --git a/setup.py b/setup.py index ae9622a..62048cf 100755 --- a/setup.py +++ b/setup.py @@ -2,18 +2,18 @@ """Setup file for python-matlab-bridge""" import os -import sys import shutil import glob # BEFORE importing distutils, remove MANIFEST. distutils doesn't properly # update it when the contents of directories change. -if os.path.exists('MANIFEST'): - os.remove('MANIFEST') +if os.path.exists('MANIFEST'): os.remove('MANIFEST') - -from distutils.core import setup +try: + from setuptools import setup +except ImportError: + from distutils.core import setup # Find the messenger binary file(s) and copy it to /matlab folder. From 0266b48480f021a909c239cec36553a0a198119b Mon Sep 17 00:00:00 2001 From: Sang Han Date: Thu, 26 Mar 2015 19:34:31 -0700 Subject: [PATCH 08/58] fixed bug with zip-safe --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index 62048cf..8e7c896 100755 --- a/setup.py +++ b/setup.py @@ -43,6 +43,7 @@ version=VERSION, packages=PACKAGES, package_data=PACKAGE_DATA, + zip_safe=False, requires=REQUIRES, #extras_require=EXTRAS_REQUIRE, scripts=BIN From d7797ee31318f87081cf89499411bbdc6767647a Mon Sep 17 00:00:00 2001 From: Sang Han Date: Thu, 26 Mar 2015 19:40:01 -0700 Subject: [PATCH 09/58] cleanup --- .gitignore | 2 +- .idea/scopes/scope_settings.xml | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) delete mode 100644 .idea/scopes/scope_settings.xml diff --git a/.gitignore b/.gitignore index 4c79558..6f374ea 100644 --- a/.gitignore +++ b/.gitignore @@ -38,4 +38,4 @@ rebuildTags.sh # caused py setup.py develop pymatbridge.egg-info -.idea/scopes/scope_settings.xml \ No newline at end of file +.idea/** diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml deleted file mode 100644 index 922003b..0000000 --- a/.idea/scopes/scope_settings.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file From d4476c73b9e6ac5c6bed3e1d029e1ca0c5ac3da1 Mon Sep 17 00:00:00 2001 From: Sang Han Date: Thu, 26 Mar 2015 19:54:01 -0700 Subject: [PATCH 10/58] urllib can go die --- messenger/settings.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/messenger/settings.py b/messenger/settings.py index 9f473d8..0639f21 100644 --- a/messenger/settings.py +++ b/messenger/settings.py @@ -10,7 +10,7 @@ from urllib.request import urlretrieve from configparser import ConfigParser except ImportError: - from urllib2 import urlretrieve + from urllib import urlretrieve from ConfigParser import ConfigParser __all__= ['get_matlab_bin', 'get_matlab_env', 'fetch_zmq'] @@ -100,4 +100,4 @@ def fetch_zmq(prefix, version=(4,0,5)): tar.extractall(prefix) logging.info('Download Complete') - os.remove(name) \ No newline at end of file + os.remove(name) From 436ae0d0c0c8edf939199079643310c4949f0043 Mon Sep 17 00:00:00 2001 From: Sang Han Date: Thu, 26 Mar 2015 22:46:19 -0700 Subject: [PATCH 11/58] get_config() now actually returns a dict for the host platform --- messenger/__init__.py | 3 +- messenger/__main__.py | 25 ++++++++-------- messenger/make.py | 67 ++++++++++++++++++++++++++++++++----------- messenger/settings.py | 58 ++++--------------------------------- 4 files changed, 70 insertions(+), 83 deletions(-) diff --git a/messenger/__init__.py b/messenger/__init__.py index c70020d..da40056 100644 --- a/messenger/__init__.py +++ b/messenger/__init__.py @@ -1 +1,2 @@ -from .settings import * \ No newline at end of file +from .settings import * +from .make import * \ No newline at end of file diff --git a/messenger/__main__.py b/messenger/__main__.py index ce3ef9c..456f855 100644 --- a/messenger/__main__.py +++ b/messenger/__main__.py @@ -1,3 +1,5 @@ +import sys + from argparse import ArgumentParser from .make import * @@ -10,8 +12,8 @@ def command_line(): ======= Namespace containing parsed arguments """ + parser = ArgumentParser(prog='messenger') - parser = ArgumentParser() parser.add_argument( "target", choices=["matlab", "octave"], @@ -21,20 +23,19 @@ def command_line(): parser.add_argument( "--static", action="store_true", - help="staticly link libzmq" + help="statically link libzmq" ) return parser.parse_args() - - def main(): - args = command_line() - if args.target == "matlab": - build_matlab(static=args.static) - elif args.target == "octave": - build_octave() - else: - raise ValueError() + args = command_line() + build = { + 'matlab': build_matlab, + 'octave': build_octave, + } + target = build[args.target] + + return target(static=args.static) if __name__ == '__main__': - main() + sys.exit(main()) diff --git a/messenger/make.py b/messenger/make.py index e77105a..a430e1e 100644 --- a/messenger/make.py +++ b/messenger/make.py @@ -6,8 +6,7 @@ import shutil import subprocess import platform - -from glob import glob +import glob try: from ConfigParser import ConfigParser @@ -18,6 +17,7 @@ __all__ = [ 'get_messenger_dir', + 'get_matlab_bin' 'get_config', 'do_build', 'build_octave', @@ -37,12 +37,12 @@ def get_messenger_dir(): return ostype[host] if is_64bit else 'mexw32' -def get_config(): - config = os.path.join(os.path.realpath(__file__), 'config.ini') - print(config) +def get_config(host, config='config.ini'): + cfg = ConfigParser() - config.read(config) - return cfg + cfg.read(config) + + return dict(cfg.items(host)) def do_build(make_cmd, messenger_exe): @@ -59,9 +59,9 @@ def do_build(make_cmd, messenger_exe): os.remove('messenger.o') -def build_octave(): +def build_octave(static=False): paths = "-L%(octave_lib)s -I%(octave_inc)s -L%(zmq_lib)s -I%(zmq_inc)s" - paths = paths % get_config() + paths = paths % get_config(platform.system()) make_cmd = "mkoctfile --mex %s -lzmq ./src/messenger.c" % paths do_build(make_cmd, 'messenger.mex') @@ -77,13 +77,7 @@ def build_matlab(static=False): If so, it will append the command line option -DZMQ_STATIC when compiling the mex so it matches libzmq. """ - matlab_bin = settings.get_matlab_bin() - cfg, host = ConfigParser(), platform.system() - cfg.read('config.ini') - libzmq = { - 'zmq_lib': os.path.normpath(cfg.get(host, 'ZMQ_LIB')), - 'zmq_inc': os.path.normpath(cfg.get(host, 'ZMQ_INC')), - } + matlab_bin, cfg = settings.get_matlab_bin(), get_config(platform.system()) extcmd = '%s' % os.path.join(matlab_bin, "mexext") extension = subprocess.check_output(extcmd, shell=True) @@ -91,10 +85,49 @@ def build_matlab(static=False): # Build the mex file mex = '"' + os.path.join(matlab_bin, "mex") + '"' - paths = "-L'%(zmq_lib)s' -I'%(zmq_inc)s'" % libzmq + paths = "-L'%(zmq_lib)s' -I'%(zmq_inc)s'" % cfg make_cmd = '%s -O %s -lzmq messenger/src/messenger.c' % (mex, paths) if static: make_cmd += ' -DZMQ_STATIC' do_build(make_cmd, 'messenger.%s' % extension) + + +def get_matlab_bin(config='config.ini'): + """ + Tries to find the MATLAB bin directory independent on host platform. + The operation of this function can be overridden by setting the MATLAB_BIN + variable within the configuration file specified. + + Parameters + -========= + config: + Relative path to configuration file + + Returns + ======= + matlab: + Absolute path to matlab bin directory + """ + host = platform.system() + cfg = get_config(host) + programs = { + 'Darwin' : r'/Applications', + 'Windows': r'C:/Program Files', + 'Linux' : r'/usr/local', + } + + if cfg.get('MATLAB_BIN', None): + matlab = cfg['MATLAB_BIN'] + else: + # Searches for Matlab bin if it's not set + _root = glob.glob(r'%s/MATLAB*' % programs[host])[0] + _version = [p for p in os.listdir(_root) if p.startswith('R20')] + if _version: + _root = r'%s/%s' % (_root, _version.pop()) + matlab = r'%s/%s' % (_root, 'bin') + + assert os.path.isdir(matlab) + + return os.path.normpath(matlab) diff --git a/messenger/settings.py b/messenger/settings.py index 0639f21..a650350 100644 --- a/messenger/settings.py +++ b/messenger/settings.py @@ -1,61 +1,14 @@ import os -import platform import subprocess import logging import tarfile -from glob import glob - try: from urllib.request import urlretrieve - from configparser import ConfigParser except ImportError: from urllib import urlretrieve - from ConfigParser import ConfigParser - -__all__= ['get_matlab_bin', 'get_matlab_env', 'fetch_zmq'] - -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger(__name__) - -def get_matlab_bin(config='config.ini'): - """ - Tries to find the MATLAB bin directory independent on host platform. - The operation of this function can be overridden by setting the MATLAB_BIN - variable within the configuration file specified. - - Parameters - -========= - config: - Relative path to configuration file - - Returns - ======= - matlab: - Absolute path to matlab bin directory - """ - cfg, host = ConfigParser(), platform.system() - cfg.read(os.path.join(__file__, config)) - - programs = { - 'Darwin' : r'/Applications', - 'Windows': r'C:/Program Files', - 'Linux' : r'/usr/local', - } - - if cfg.has_option(host, 'MATLAB_BIN'): - matlab = cfg.get(host, 'MATLAB_BIN') - else: - # Searches for Matlab bin if it's not set - _root = glob(r'%s/MATLAB*' % programs[host])[0] - _version = [p for p in os.listdir(_root) if p.startswith('R20')] - if any(_version): - _root = r'%s/%s' % (_root, _version.pop()) - matlab = r'%s/%s' % (_root, 'bin') - - assert os.path.isdir(matlab) - return os.path.normpath(matlab) +__all__= ['get_matlab_env', 'fetch_zmq'] def get_matlab_env(matlab='matlab'): """ @@ -76,9 +29,8 @@ def get_matlab_env(matlab='matlab'): process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE) envs = (line.decode('utf-8').strip() for line in process.stdout) - mapping = (env.split('=', maxsplit=1) for env in envs) - return {key:value for key, value in mapping} + return dict(env.split('=', maxsplit=1) for env in envs) def fetch_zmq(prefix, version=(4,0,5)): """ @@ -91,13 +43,13 @@ def fetch_zmq(prefix, version=(4,0,5)): version: tuple ZMQ Version Number """ - logger.info('Downloading ZMQ Source Version %i.%i.%i' % version) + print('Downloading ZMQ Source Version %i.%i.%i' % version) url = ("http://download.zeromq.org/zeromq-%i.%i.%i.tar.gz" % version) name = urlretrieve(url, url.rsplit('/')[-1])[0] - logger.info('Extracting into prefix %s' % prefix) + print('Extracting into prefix %s' % prefix) with tarfile.open(name) as tar: tar.extractall(prefix) - logging.info('Download Complete') + print('Download Complete') os.remove(name) From 7eb892aa00b4828b4544cbbbd9f8a04d138ef8a1 Mon Sep 17 00:00:00 2001 From: Sang Han Date: Thu, 26 Mar 2015 22:52:47 -0700 Subject: [PATCH 12/58] oops forgot a comma --- messenger/make.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/messenger/make.py b/messenger/make.py index a430e1e..eab158c 100644 --- a/messenger/make.py +++ b/messenger/make.py @@ -17,7 +17,7 @@ __all__ = [ 'get_messenger_dir', - 'get_matlab_bin' + 'get_matlab_bin', 'get_config', 'do_build', 'build_octave', From f701877fc5a80a747bce210499bf34da00024a88 Mon Sep 17 00:00:00 2001 From: Sang Han Date: Thu, 26 Mar 2015 19:34:31 -0700 Subject: [PATCH 13/58] fixed bug with zip-safe --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index 62048cf..8e7c896 100755 --- a/setup.py +++ b/setup.py @@ -43,6 +43,7 @@ version=VERSION, packages=PACKAGES, package_data=PACKAGE_DATA, + zip_safe=False, requires=REQUIRES, #extras_require=EXTRAS_REQUIRE, scripts=BIN From a3735b4798821a5735bbe60f15e3db6ddad0edb0 Mon Sep 17 00:00:00 2001 From: Sang Han Date: Thu, 26 Mar 2015 14:32:27 -0700 Subject: [PATCH 14/58] Fixed windows path --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 5bd58c1..4c79558 100644 --- a/.gitignore +++ b/.gitignore @@ -37,3 +37,5 @@ rebuildTags.sh # caused py setup.py develop pymatbridge.egg-info + +.idea/scopes/scope_settings.xml \ No newline at end of file From 5fca4de2291c44479b34324a5b2dc1f7d1cbf585 Mon Sep 17 00:00:00 2001 From: Sang Han Date: Thu, 26 Mar 2015 22:46:19 -0700 Subject: [PATCH 15/58] get_config() now actually returns a dict for the host platform --- messenger/__init__.py | 3 +- messenger/__main__.py | 25 ++++++++-------- messenger/make.py | 67 ++++++++++++++++++++++++++++++++----------- messenger/settings.py | 20 +++++-------- 4 files changed, 72 insertions(+), 43 deletions(-) diff --git a/messenger/__init__.py b/messenger/__init__.py index c70020d..da40056 100644 --- a/messenger/__init__.py +++ b/messenger/__init__.py @@ -1 +1,2 @@ -from .settings import * \ No newline at end of file +from .settings import * +from .make import * \ No newline at end of file diff --git a/messenger/__main__.py b/messenger/__main__.py index ce3ef9c..456f855 100644 --- a/messenger/__main__.py +++ b/messenger/__main__.py @@ -1,3 +1,5 @@ +import sys + from argparse import ArgumentParser from .make import * @@ -10,8 +12,8 @@ def command_line(): ======= Namespace containing parsed arguments """ + parser = ArgumentParser(prog='messenger') - parser = ArgumentParser() parser.add_argument( "target", choices=["matlab", "octave"], @@ -21,20 +23,19 @@ def command_line(): parser.add_argument( "--static", action="store_true", - help="staticly link libzmq" + help="statically link libzmq" ) return parser.parse_args() - - def main(): - args = command_line() - if args.target == "matlab": - build_matlab(static=args.static) - elif args.target == "octave": - build_octave() - else: - raise ValueError() + args = command_line() + build = { + 'matlab': build_matlab, + 'octave': build_octave, + } + target = build[args.target] + + return target(static=args.static) if __name__ == '__main__': - main() + sys.exit(main()) diff --git a/messenger/make.py b/messenger/make.py index e77105a..eab158c 100644 --- a/messenger/make.py +++ b/messenger/make.py @@ -6,8 +6,7 @@ import shutil import subprocess import platform - -from glob import glob +import glob try: from ConfigParser import ConfigParser @@ -18,6 +17,7 @@ __all__ = [ 'get_messenger_dir', + 'get_matlab_bin', 'get_config', 'do_build', 'build_octave', @@ -37,12 +37,12 @@ def get_messenger_dir(): return ostype[host] if is_64bit else 'mexw32' -def get_config(): - config = os.path.join(os.path.realpath(__file__), 'config.ini') - print(config) +def get_config(host, config='config.ini'): + cfg = ConfigParser() - config.read(config) - return cfg + cfg.read(config) + + return dict(cfg.items(host)) def do_build(make_cmd, messenger_exe): @@ -59,9 +59,9 @@ def do_build(make_cmd, messenger_exe): os.remove('messenger.o') -def build_octave(): +def build_octave(static=False): paths = "-L%(octave_lib)s -I%(octave_inc)s -L%(zmq_lib)s -I%(zmq_inc)s" - paths = paths % get_config() + paths = paths % get_config(platform.system()) make_cmd = "mkoctfile --mex %s -lzmq ./src/messenger.c" % paths do_build(make_cmd, 'messenger.mex') @@ -77,13 +77,7 @@ def build_matlab(static=False): If so, it will append the command line option -DZMQ_STATIC when compiling the mex so it matches libzmq. """ - matlab_bin = settings.get_matlab_bin() - cfg, host = ConfigParser(), platform.system() - cfg.read('config.ini') - libzmq = { - 'zmq_lib': os.path.normpath(cfg.get(host, 'ZMQ_LIB')), - 'zmq_inc': os.path.normpath(cfg.get(host, 'ZMQ_INC')), - } + matlab_bin, cfg = settings.get_matlab_bin(), get_config(platform.system()) extcmd = '%s' % os.path.join(matlab_bin, "mexext") extension = subprocess.check_output(extcmd, shell=True) @@ -91,10 +85,49 @@ def build_matlab(static=False): # Build the mex file mex = '"' + os.path.join(matlab_bin, "mex") + '"' - paths = "-L'%(zmq_lib)s' -I'%(zmq_inc)s'" % libzmq + paths = "-L'%(zmq_lib)s' -I'%(zmq_inc)s'" % cfg make_cmd = '%s -O %s -lzmq messenger/src/messenger.c' % (mex, paths) if static: make_cmd += ' -DZMQ_STATIC' do_build(make_cmd, 'messenger.%s' % extension) + + +def get_matlab_bin(config='config.ini'): + """ + Tries to find the MATLAB bin directory independent on host platform. + The operation of this function can be overridden by setting the MATLAB_BIN + variable within the configuration file specified. + + Parameters + -========= + config: + Relative path to configuration file + + Returns + ======= + matlab: + Absolute path to matlab bin directory + """ + host = platform.system() + cfg = get_config(host) + programs = { + 'Darwin' : r'/Applications', + 'Windows': r'C:/Program Files', + 'Linux' : r'/usr/local', + } + + if cfg.get('MATLAB_BIN', None): + matlab = cfg['MATLAB_BIN'] + else: + # Searches for Matlab bin if it's not set + _root = glob.glob(r'%s/MATLAB*' % programs[host])[0] + _version = [p for p in os.listdir(_root) if p.startswith('R20')] + if _version: + _root = r'%s/%s' % (_root, _version.pop()) + matlab = r'%s/%s' % (_root, 'bin') + + assert os.path.isdir(matlab) + + return os.path.normpath(matlab) diff --git a/messenger/settings.py b/messenger/settings.py index 9f473d8..974709a 100644 --- a/messenger/settings.py +++ b/messenger/settings.py @@ -1,7 +1,5 @@ import os -import platform import subprocess -import logging import tarfile from glob import glob @@ -10,14 +8,11 @@ from urllib.request import urlretrieve from configparser import ConfigParser except ImportError: - from urllib2 import urlretrieve + from urllib import urlretrieve from ConfigParser import ConfigParser __all__= ['get_matlab_bin', 'get_matlab_env', 'fetch_zmq'] -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger(__name__) - def get_matlab_bin(config='config.ini'): """ Tries to find the MATLAB bin directory independent on host platform. @@ -55,7 +50,7 @@ def get_matlab_bin(config='config.ini'): assert os.path.isdir(matlab) - return os.path.normpath(matlab) +__all__= ['get_matlab_env', 'fetch_zmq'] def get_matlab_env(matlab='matlab'): """ @@ -76,9 +71,8 @@ def get_matlab_env(matlab='matlab'): process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE) envs = (line.decode('utf-8').strip() for line in process.stdout) - mapping = (env.split('=', maxsplit=1) for env in envs) - return {key:value for key, value in mapping} + return dict(env.split('=', maxsplit=1) for env in envs) def fetch_zmq(prefix, version=(4,0,5)): """ @@ -91,13 +85,13 @@ def fetch_zmq(prefix, version=(4,0,5)): version: tuple ZMQ Version Number """ - logger.info('Downloading ZMQ Source Version %i.%i.%i' % version) + print('Downloading ZMQ Source Version %i.%i.%i' % version) url = ("http://download.zeromq.org/zeromq-%i.%i.%i.tar.gz" % version) name = urlretrieve(url, url.rsplit('/')[-1])[0] - logger.info('Extracting into prefix %s' % prefix) + print('Extracting into prefix %s' % prefix) with tarfile.open(name) as tar: tar.extractall(prefix) - logging.info('Download Complete') - os.remove(name) \ No newline at end of file + print('Download Complete') + os.remove(name) From 3551b76711c1ecd4f7520fe2f7a4ead8ecabbf23 Mon Sep 17 00:00:00 2001 From: Sang Han Date: Mon, 30 Mar 2015 00:58:35 -0700 Subject: [PATCH 16/58] Use platform.machine().endswith(64) over sys.maxsize --- .gitignore | 3 ++- messenger/make.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 4c79558..9190128 100644 --- a/.gitignore +++ b/.gitignore @@ -38,4 +38,5 @@ rebuildTags.sh # caused py setup.py develop pymatbridge.egg-info -.idea/scopes/scope_settings.xml \ No newline at end of file +.idea/** + diff --git a/messenger/make.py b/messenger/make.py index eab158c..422702b 100644 --- a/messenger/make.py +++ b/messenger/make.py @@ -25,7 +25,7 @@ ] def get_messenger_dir(): - host, is_64bit = platform.system(), sys.maxsize > 2**32 + host, is_64bit = platform.system(), platform.machine().endswith('64') ostype = { 'Darwin': 'mexmaci64', 'Linux': 'mexa64', From 13166354e9b2687e2b41458f693e342398e9334e Mon Sep 17 00:00:00 2001 From: Sang Han Date: Mon, 30 Mar 2015 01:08:55 -0700 Subject: [PATCH 17/58] fixed docstring to fit scipy spec --- messenger/__main__.py | 2 +- messenger/make.py | 11 ++++---- messenger/settings.py | 61 +++++++------------------------------------ setup.py | 3 ++- 4 files changed, 19 insertions(+), 58 deletions(-) diff --git a/messenger/__main__.py b/messenger/__main__.py index 456f855..5820228 100644 --- a/messenger/__main__.py +++ b/messenger/__main__.py @@ -9,7 +9,7 @@ def command_line(): Manages command line arguments. Returns - ======= + ------- Namespace containing parsed arguments """ parser = ArgumentParser(prog='messenger') diff --git a/messenger/make.py b/messenger/make.py index 422702b..37d23f7 100644 --- a/messenger/make.py +++ b/messenger/make.py @@ -71,7 +71,7 @@ def build_matlab(static=False): Build the messenger mex for MATLAB Parameters - ============ + ---------- static : bool Determines if the zmq library has been statically linked. If so, it will append the command line option -DZMQ_STATIC @@ -101,13 +101,13 @@ def get_matlab_bin(config='config.ini'): variable within the configuration file specified. Parameters - -========= - config: + ---------- + config: str Relative path to configuration file Returns - ======= - matlab: + ------- + matlab: str Absolute path to matlab bin directory """ host = platform.system() @@ -131,3 +131,4 @@ def get_matlab_bin(config='config.ini'): assert os.path.isdir(matlab) return os.path.normpath(matlab) + diff --git a/messenger/settings.py b/messenger/settings.py index 974709a..477be1e 100644 --- a/messenger/settings.py +++ b/messenger/settings.py @@ -2,70 +2,28 @@ import subprocess import tarfile -from glob import glob - try: from urllib.request import urlretrieve - from configparser import ConfigParser except ImportError: from urllib import urlretrieve - from ConfigParser import ConfigParser __all__= ['get_matlab_bin', 'get_matlab_env', 'fetch_zmq'] -def get_matlab_bin(config='config.ini'): - """ - Tries to find the MATLAB bin directory independent on host platform. - The operation of this function can be overridden by setting the MATLAB_BIN - variable within the configuration file specified. - - Parameters - -========= - config: - Relative path to configuration file - - Returns - ======= - matlab: - Absolute path to matlab bin directory - """ - cfg, host = ConfigParser(), platform.system() - cfg.read(os.path.join(__file__, config)) - - programs = { - 'Darwin' : r'/Applications', - 'Windows': r'C:/Program Files', - 'Linux' : r'/usr/local', - } - - if cfg.has_option(host, 'MATLAB_BIN'): - matlab = cfg.get(host, 'MATLAB_BIN') - else: - # Searches for Matlab bin if it's not set - _root = glob(r'%s/MATLAB*' % programs[host])[0] - _version = [p for p in os.listdir(_root) if p.startswith('R20')] - if any(_version): - _root = r'%s/%s' % (_root, _version.pop()) - matlab = r'%s/%s' % (_root, 'bin') - - assert os.path.isdir(matlab) - -__all__= ['get_matlab_env', 'fetch_zmq'] def get_matlab_env(matlab='matlab'): """ Get the underlying environment variables set for a matlab installation. Parameters - ========== - matlab: string + ---------- + matlab: str Path to the matlab binary executable. If matlab is in the users $PATH, just pass 'matlab' Returns - ======= - environment: dictionary - Mapping of environment variable[s] + ------- + environment: dict + Mapping of environment variable """ command = ' '.join([matlab, '-e']), process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE) @@ -74,18 +32,19 @@ def get_matlab_env(matlab='matlab'): return dict(env.split('=', maxsplit=1) for env in envs) + def fetch_zmq(prefix, version=(4,0,5)): """ - Download and extract libzmq + Download and extract libzmq into `prefix` Parameters - ========== + ---------- save: str File Save Location - version: tuple + version: 3-tuple ZMQ Version Number """ - print('Downloading ZMQ Source Version %i.%i.%i' % version) + print('Downloading ZMQ Source Version %i.%i.%i' % version) url = ("http://download.zeromq.org/zeromq-%i.%i.%i.tar.gz" % version) name = urlretrieve(url, url.rsplit('/')[-1])[0] diff --git a/setup.py b/setup.py index 8e7c896..bd2cf6d 100755 --- a/setup.py +++ b/setup.py @@ -8,7 +8,8 @@ # BEFORE importing distutils, remove MANIFEST. distutils doesn't properly # update it when the contents of directories change. -if os.path.exists('MANIFEST'): os.remove('MANIFEST') +if os.path.exists('MANIFEST'): + os.remove('MANIFEST') try: from setuptools import setup From 5ebb8f67fc4f71bbc2538562bf11365616022846 Mon Sep 17 00:00:00 2001 From: Sang Han Date: Mon, 30 Mar 2015 02:08:33 -0700 Subject: [PATCH 18/58] added tests for messenger functions --- messenger/make.py | 2 +- messenger/tests/test_env.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 messenger/tests/test_env.py diff --git a/messenger/make.py b/messenger/make.py index cc4f4c9..66e70b0 100644 --- a/messenger/make.py +++ b/messenger/make.py @@ -111,7 +111,7 @@ def get_matlab_bin(config='config.ini'): Absolute path to matlab bin directory """ host = platform.system() - cfg = get_config(host) + cfg = get_config(host,config=config) programs = { 'Darwin' : r'/Applications', 'Windows': r'C:/Program Files', diff --git a/messenger/tests/test_env.py b/messenger/tests/test_env.py new file mode 100644 index 0000000..404e69a --- /dev/null +++ b/messenger/tests/test_env.py @@ -0,0 +1,31 @@ +import numpy.testing as npt +import sys +import os + +ROOT = os.path.join(os.path.dirname(__file__), '..', '..') + +# Necessary since messenger is not installed with pymatbridge +sys.path.append(ROOT) + +import messenger + +def test_matlab_bin(): + config = os.path.join(ROOT, 'config.ini') + npt.assert_equal(os.path.isfile(config), True) + bin = messenger.get_matlab_bin(config=config) + npt.assert_equal(os.path.isdir(bin), True) + + mexext = any(m for m in os.listdir(bin) if m == 'mexext' or m == 'mexext.exe') + mex = any(m for m in os.listdir(bin) if m == 'mex' or m == 'mex.exe') + + npt.assert_equal(mexext, True) + npt.assert_equal(mex, True) + +def test_matlab_env(): + config = os.path.join(ROOT, 'config.ini') + matlab = os.path.join(messenger.get_matlab_bin(config=config), 'matlab') + env = messenger.get_matlab_env(matlab=matlab) + arch = env['ARCH'] + + npt.assert_equal(arch.endswith(messenger.get_messenger_dir()[-2:]), True) + From 18cb0ccfcb69bf7196327a4ea9852a76d7133883 Mon Sep 17 00:00:00 2001 From: Sang Han Date: Mon, 30 Mar 2015 02:25:51 -0700 Subject: [PATCH 19/58] python 2 glob issue --- messenger/make.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/messenger/make.py b/messenger/make.py index 66e70b0..b13dd75 100644 --- a/messenger/make.py +++ b/messenger/make.py @@ -111,7 +111,7 @@ def get_matlab_bin(config='config.ini'): Absolute path to matlab bin directory """ host = platform.system() - cfg = get_config(host,config=config) + cfg = get_config(host, config=config) programs = { 'Darwin' : r'/Applications', 'Windows': r'C:/Program Files', @@ -122,7 +122,7 @@ def get_matlab_bin(config='config.ini'): matlab = cfg['MATLAB_BIN'] else: # Searches for Matlab bin if it's not set - _root = glob.glob(r'%s/MATLAB*' % programs[host])[0] + _root = [os.path.join(programs[host], p) for p in os.listdir(programs[host]) if p.startswith('MATLAB')][0] _version = [p for p in os.listdir(_root) if p.startswith('R20')] if _version: _root = r'%s/%s' % (_root, _version.pop()) From ce25c87967c14c44b1937d54e174ba5a9745d895 Mon Sep 17 00:00:00 2001 From: Sang Han Date: Mon, 30 Mar 2015 20:49:54 -0700 Subject: [PATCH 20/58] python 2 strings do not have maxsplit kwarg, use string module split --- messenger/settings.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/messenger/settings.py b/messenger/settings.py index 951e3a5..fcf97bc 100644 --- a/messenger/settings.py +++ b/messenger/settings.py @@ -1,6 +1,7 @@ import os import subprocess import tarfile +import string try: from urllib.request import urlretrieve @@ -30,7 +31,7 @@ def get_matlab_env(matlab='matlab'): envs = (line.decode('utf-8').strip() for line in process.stdout) - return dict(env.split('=', maxsplit=1) for env in envs) + return dict(string.split(env, '=', maxsplit=1) for env in envs) def fetch_zmq(prefix, version=(4,0,5)): From d3f605a4e195bbd3c70fbde49ac2ee320a2e6a29 Mon Sep 17 00:00:00 2001 From: Sang Han Date: Mon, 30 Mar 2015 21:29:04 -0700 Subject: [PATCH 21/58] tests validate that builds are possible rather than anticipate for all builds --- messenger/make.py | 19 ++++++++++++------- messenger/settings.py | 5 +++-- messenger/tests/test_env.py | 20 ++++++++++++-------- 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/messenger/make.py b/messenger/make.py index b13dd75..86296c2 100644 --- a/messenger/make.py +++ b/messenger/make.py @@ -107,8 +107,9 @@ def get_matlab_bin(config='config.ini'): Returns ------- - matlab: str - Absolute path to matlab bin directory + matlab: str or None + Absolute path to matlab bin directory. + Returns None if Matlab path could not be determined """ host = platform.system() cfg = get_config(host, config=config) @@ -122,12 +123,16 @@ def get_matlab_bin(config='config.ini'): matlab = cfg['MATLAB_BIN'] else: # Searches for Matlab bin if it's not set - _root = [os.path.join(programs[host], p) for p in os.listdir(programs[host]) if p.startswith('MATLAB')][0] - _version = [p for p in os.listdir(_root) if p.startswith('R20')] + matlab = [p for p in os.listdir(programs[host]) if p.startswith('MATLAB')] + + if not matlab: + return None + + _version = [p for p in os.listdir(os.path.join(programs[host], *matlab)) if p.startswith('R20')] + if _version: - _root = r'%s/%s' % (_root, _version.pop()) - matlab = r'%s/%s' % (_root, 'bin') + matlab = r'%s/%s' % (matlab, _version.pop()) - assert os.path.isdir(matlab) + matlab = r'%s/%s' % (matlab, 'bin') return os.path.normpath(matlab) diff --git a/messenger/settings.py b/messenger/settings.py index fcf97bc..a86087c 100644 --- a/messenger/settings.py +++ b/messenger/settings.py @@ -1,12 +1,13 @@ import os import subprocess import tarfile -import string -try: +try: # Python 3 Compat from urllib.request import urlretrieve + string = str except ImportError: from urllib import urlretrieve + import string __all__= ['get_matlab_env', 'fetch_zmq'] diff --git a/messenger/tests/test_env.py b/messenger/tests/test_env.py index 404e69a..d858e94 100644 --- a/messenger/tests/test_env.py +++ b/messenger/tests/test_env.py @@ -9,21 +9,25 @@ import messenger +CONFIG = os.path.join(ROOT, 'config.ini') +BIN = messenger.get_matlab_bin(config=CONFIG) + +def test_config(): + npt.assert_equal(os.path.isfile(CONFIG), True) + +@npt.decorators.skipif(BIN==None, 'No Matlab Installed') def test_matlab_bin(): - config = os.path.join(ROOT, 'config.ini') - npt.assert_equal(os.path.isfile(config), True) - bin = messenger.get_matlab_bin(config=config) - npt.assert_equal(os.path.isdir(bin), True) + npt.assert_equal(os.path.isdir(BIN), True) - mexext = any(m for m in os.listdir(bin) if m == 'mexext' or m == 'mexext.exe') - mex = any(m for m in os.listdir(bin) if m == 'mex' or m == 'mex.exe') + mexext = any(m for m in os.listdir(BIN) if m == 'mexext' or m == 'mexext.exe') + mex = any(m for m in os.listdir(BIN) if m == 'mex' or m == 'mex.exe') npt.assert_equal(mexext, True) npt.assert_equal(mex, True) +@npt.decorators.skipif(BIN==None, 'No Matlab Installed') def test_matlab_env(): - config = os.path.join(ROOT, 'config.ini') - matlab = os.path.join(messenger.get_matlab_bin(config=config), 'matlab') + matlab = os.path.join(messenger.get_matlab_bin(config=CONFIG), 'matlab') env = messenger.get_matlab_env(matlab=matlab) arch = env['ARCH'] From 95115f99ac17cdc40c8fc8fdb159dcfc5596a432 Mon Sep 17 00:00:00 2001 From: Sang Han Date: Tue, 31 Mar 2015 05:42:10 -0700 Subject: [PATCH 22/58] small bug in get_matlab_dir() --- messenger/make.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/messenger/make.py b/messenger/make.py index 86296c2..fb50987 100644 --- a/messenger/make.py +++ b/messenger/make.py @@ -7,6 +7,7 @@ import subprocess import platform import glob +import operator try: from ConfigParser import ConfigParser @@ -128,11 +129,10 @@ def get_matlab_bin(config='config.ini'): if not matlab: return None - _version = [p for p in os.listdir(os.path.join(programs[host], *matlab)) if p.startswith('R20')] + for p in os.listdir(os.path.join(programs[host], *matlab)): + if p.startswith('R20'): + matlab.append(p) - if _version: - matlab = r'%s/%s' % (matlab, _version.pop()) + matlab.append('bin') - matlab = r'%s/%s' % (matlab, 'bin') - - return os.path.normpath(matlab) + return os.path.normpath(os.path.join(programs[host], *matlab)) From 25175458a4da1656836ec2f5aca4514ec15a0174 Mon Sep 17 00:00:00 2001 From: Sang Han Date: Fri, 10 Apr 2015 19:44:32 -0700 Subject: [PATCH 23/58] octave build works --- config.ini | 4 +-- messenger/make.py | 88 +++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 80 insertions(+), 12 deletions(-) diff --git a/config.ini b/config.ini index 9a1cdae..26cb7fa 100644 --- a/config.ini +++ b/config.ini @@ -1,7 +1,7 @@ [Darwin] ; MATLAB_BIN=Applications/MATLAB_R2014a.app/bin -; OCTAVE_INC= -; OCTAVE_LIB= +OCTAVE_INC=/usr/local/Cellar/octave/3.8.2/include/octave-3.8.2/octave +OCTAVE_LIB=/usr/local/Cellar/octave/3.8.2/lib/octave/3.8.2 ZMQ_INC=/usr/local/include ZMQ_LIB=/usr/local/lib diff --git a/messenger/make.py b/messenger/make.py index fb50987..5bbd3cf 100644 --- a/messenger/make.py +++ b/messenger/make.py @@ -22,9 +22,70 @@ 'get_config', 'do_build', 'build_octave', - 'build_matlab' + 'build_matlab', + 'split_command_line', ] +def split_command_line(command_line): + + '''This splits a command line into a list of arguments. It splits arguments + on spaces, but handles embedded quotes, doublequotes, and escaped + characters. It's impossible to do this with a regular expression, so I + wrote a little state machine to parse the command line. ''' + + arg_list = [] + arg = '' + + # Constants to name the states we can be in. + state_basic = 0 + state_esc = 1 + state_singlequote = 2 + state_doublequote = 3 + # The state when consuming whitespace between commands. + state_whitespace = 4 + state = state_basic + + for c in command_line: + if state == state_basic or state == state_whitespace: + if c == '\\': + # Escape the next character + state = state_esc + elif c == r"'": + # Handle single quote + state = state_singlequote + elif c == r'"': + # Handle double quote + state = state_doublequote + elif c.isspace(): + # Add arg to arg_list if we aren't in the middle of whitespace. + if state == state_whitespace: + # Do nothing. + None + else: + arg_list.append(arg) + arg = '' + state = state_whitespace + else: + arg = arg + c + state = state_basic + elif state == state_esc: + arg = arg + c + state = state_basic + elif state == state_singlequote: + if c == r"'": + state = state_basic + else: + arg = arg + c + elif state == state_doublequote: + if c == r'"': + state = state_basic + else: + arg = arg + c + + if arg != '': + arg_list.append(arg) + return arg_list + def get_messenger_dir(): host, is_64bit = platform.system(), platform.machine().endswith('64') ostype = { @@ -47,10 +108,14 @@ def get_config(host, config='config.ini'): def do_build(make_cmd, messenger_exe): + + messenger_dir = get_messenger_dir() + use_shell = sys.platform.startswith('win32') + print('Building %s...' % messenger_exe) print(make_cmd) - messenger_dir = get_messenger_dir() - subprocess.call(shlex.split(make_cmd), stderr=subprocess.STDOUT) + + subprocess.check_output(make_cmd, shell=use_shell) messenger_loc = os.path.join(messenger_dir, messenger_exe) @@ -61,10 +126,12 @@ def do_build(make_cmd, messenger_exe): def build_octave(static=False): + paths = "-L%(octave_lib)s -I%(octave_inc)s -L%(zmq_lib)s -I%(zmq_inc)s" paths = paths % get_config(platform.system()) - make_cmd = "mkoctfile --mex %s -lzmq ./src/messenger.c" % paths - do_build(make_cmd, 'messenger.mex') + make_cmd = "mkoctfile --mex %s -lzmq messenger/src/messenger.c" % paths + + do_build(split_command_line(make_cmd), 'messenger.mex') def build_matlab(static=False): @@ -78,21 +145,22 @@ def build_matlab(static=False): If so, it will append the command line option -DZMQ_STATIC when compiling the mex so it matches libzmq. """ - matlab_bin, cfg = settings.get_matlab_bin(), get_config(platform.system()) + matlab_bin, cfg = get_matlab_bin(), get_config(platform.system()) - extcmd = '%s' % os.path.join(matlab_bin, "mexext") - extension = subprocess.check_output(extcmd, shell=True) + use_shell = sys.platform.startswith('win32') + extcmd = split_command_line(os.path.join(matlab_bin, "mexext")) + extension = subprocess.check_output(extcmd, shell=use_shell) extension = extension.decode('utf-8').rstrip() # Build the mex file - mex = '"' + os.path.join(matlab_bin, "mex") + '"' + mex = os.path.join(matlab_bin, "mex") paths = "-L'%(zmq_lib)s' -I'%(zmq_inc)s'" % cfg make_cmd = '%s -O %s -lzmq messenger/src/messenger.c' % (mex, paths) if static: make_cmd += ' -DZMQ_STATIC' - do_build(make_cmd, 'messenger.%s' % extension) + do_build(split_command_line(make_cmd), 'messenger.%s' % extension) def get_matlab_bin(config='config.ini'): From 0300ccc968a454ec6643c32faf0e445351c3e01a Mon Sep 17 00:00:00 2001 From: Sang Han Date: Sun, 12 Apr 2015 10:06:34 -0700 Subject: [PATCH 24/58] and the epic rebasing continues intensifies --- .gitignore | 77 +++++++++++++++++++++++++++++++++++------------ messenger/make.py | 10 +++--- 2 files changed, 62 insertions(+), 25 deletions(-) diff --git a/.gitignore b/.gitignore index 6f374ea..90eaacf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,28 +1,8 @@ - -.idea/workspace.xml - -.idea/vcs.xml - -.idea/python-matlab-bridge.iml - -.idea/modules.xml - -.idea/misc.xml - -.idea/encodings.xml - -.idea/.name - -.DS_Store - - ADME.markdown *.pyc *~ -build - # a nonce file to push this package to our local system. dpush.sh @@ -38,4 +18,61 @@ rebuildTags.sh # caused py setup.py develop pymatbridge.egg-info +# Compiled source {{{ +*.com +*.class +*.dll +*.exe +*.o +*.so +*.pyc +*.pyo +# }}} + +# Packages {{{ +# it's better to unpack these files and commit the raw source +# git has its own built in compression methods +*.7z +*.dmg +*.gz +*.iso +*.jar +*.rar +*.tar +*.tar.gz +*.zip +# }}} + +# Logs and databases # {{{ +*.log +*.sql +*.sqlite +*.key +benchmark/*.txt +# }}} + +# OS generated files/folders {{{ +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db +Icon* +# }}} + +# Distribution files/folders {{{ +docs/_build +.env +dist/** +build/** +*egg-info +*.whl +env/** +# }}} + +# Repository specific files {{{ +texts/** .idea/** +# }}} diff --git a/messenger/make.py b/messenger/make.py index 5bbd3cf..09064dc 100644 --- a/messenger/make.py +++ b/messenger/make.py @@ -27,12 +27,12 @@ ] def split_command_line(command_line): - - '''This splits a command line into a list of arguments. It splits arguments - on spaces, but handles embedded quotes, doublequotes, and escaped + """ + This splits a command line into a list of arguments. It splits arguments + on spaces, but handles embedded quotes, double quotes, and escaped characters. It's impossible to do this with a regular expression, so I - wrote a little state machine to parse the command line. ''' - + wrote a little state machine to parse the command line. + """ arg_list = [] arg = '' From deada064b3e61ed4c42663a4e9e186c6c2233d05 Mon Sep 17 00:00:00 2001 From: Sang Han Date: Fri, 27 Mar 2015 05:50:54 -0700 Subject: [PATCH 25/58] cherry-picking setuptools related commits Decided to start implementing the big merge with setuptools over current tools consolidated in the messenger module. Hooking into setuptools allows for automatic discovery of requirements and the ability to fine tune almost every aspects of the build process. --- .gitignore | 1 + LICENSE | 30 +++++++++++++ pymatbridge/__init__.py | 4 +- pymatbridge/__version__.py | 3 ++ pymatbridge/version.py | 90 -------------------------------------- setup.py | 80 +++++++++++++++++++-------------- version.py | 1 + 7 files changed, 84 insertions(+), 125 deletions(-) create mode 100644 pymatbridge/__version__.py delete mode 100644 pymatbridge/version.py create mode 120000 version.py diff --git a/.gitignore b/.gitignore index 90eaacf..d806133 100644 --- a/.gitignore +++ b/.gitignore @@ -75,4 +75,5 @@ env/** # Repository specific files {{{ texts/** .idea/** +dist/** # }}} diff --git a/LICENSE b/LICENSE index d3632fc..2759572 100644 --- a/LICENSE +++ b/LICENSE @@ -1,3 +1,33 @@ +Pymatbridge +=========== + +A python interface to call out to Matlab(R). + + +License information +=================== + +Copyright (c) 2012 -- , Max Jaderberg, Ariel Rokem, Haoxing Zhao +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +Redistributions in binary form must reproduce the above copyright notice, this +list of conditions and the following disclaimer in the documentation and/or +other materials provided with the distribution. + +Neither the name of the Oxford University, Stanford University nor the names of +its contributors may be used to endorse or promote products derived from this +software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Copyright (c) 2013. See "Contributors". MATLAB (R) is copyright of the Mathworks. All rights reserved. diff --git a/pymatbridge/__init__.py b/pymatbridge/__init__.py index 45d2145..bc6b244 100644 --- a/pymatbridge/__init__.py +++ b/pymatbridge/__init__.py @@ -1,5 +1,6 @@ from .pymatbridge import * -from .version import __version__ +from .__version__ import __version__ +from .__version__ import __build__ try: from .publish import * @@ -10,3 +11,4 @@ from .matlab_magic import * except ImportError: pass + diff --git a/pymatbridge/__version__.py b/pymatbridge/__version__.py new file mode 100644 index 0000000..ec2406a --- /dev/null +++ b/pymatbridge/__version__.py @@ -0,0 +1,3 @@ +__version__ = '0.5.0' +__build__ = 'dev' + diff --git a/pymatbridge/version.py b/pymatbridge/version.py deleted file mode 100644 index 0b9ef31..0000000 --- a/pymatbridge/version.py +++ /dev/null @@ -1,90 +0,0 @@ -"""pymatbridge version/release information""" - -# Format expected by setup.py and doc/source/conf.py: string of form "X.Y.Z" -_version_major = 0 -_version_minor = 5 -_version_micro = 0 #'' # use '' for first of series, number for 1 and above -_version_extra = 'dev' -#_version_extra = '' # Uncomment this for full releases - -# Construct full version string from these. -_ver = [_version_major, _version_minor] -if _version_micro: - _ver.append(_version_micro) -if _version_extra: - _ver.append(_version_extra) - -__version__ = '.'.join(map(str, _ver)) - -CLASSIFIERS = ["Development Status :: 3 - Alpha", - "Environment :: Console", - "Intended Audience :: Science/Research", - "License :: OSI Approved :: BSD License", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Topic :: Scientific/Engineering"] - -description = "pymatbridge is a set of python and matlab functions to allow these two systems to talk to each other" - -long_description = """ - -Pymatbridge -=========== - -A python interface to call out to Matlab(R). - - -License information -=================== - -Copyright (c) 2012 -- , Max Jaderberg, Ariel Rokem, Haoxing Zhao -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this -list of conditions and the following disclaimer. - -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. - -Neither the name of the Oxford University, Stanford University nor the names of -its contributors may be used to endorse or promote products derived from this -software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -""" - -NAME = "pymatbridge" -MAINTAINER = "Ariel Rokem" -MAINTAINER_EMAIL = "arokem@gmail.com" -DESCRIPTION = description -LONG_DESCRIPTION = long_description -URL = "https://github.com/arokem/python-matlab-bridge" -DOWNLOAD_URL = "https://github.com/arokem/python-matlab-bridge/archive/master.tar.gz" -LICENSE = "BSD" -AUTHOR = "https://github.com/arokem/python-matlab-bridge/contributors" -AUTHOR_EMAIL = "arokem@gmail.com" -PLATFORMS = "OS Independent" -MAJOR = _version_major -MINOR = _version_minor -MICRO = _version_micro -VERSION = __version__ -PACKAGES = ['pymatbridge'] -PACKAGE_DATA = {"pymatbridge": ["matlab/matlabserver.m", "matlab/messenger.*", - "matlab/usrprog/*", "matlab/util/*.m", - "matlab/util/json_v0.2.2/LICENSE", - "matlab/util/json_v0.2.2/README.md", - "matlab/util/json_v0.2.2/test/*", - "matlab/util/json_v0.2.2/json/*.m", - "matlab/util/json_v0.2.2/json/java/*", - "tests/*.py", "examples/*.ipynb"]} - -REQUIRES = ['pyzmq'] -#EXTRAS_REQUIRE = ['numpy', 'scipy', 'ipython'] - -BIN=['scripts/publish-notebook'] diff --git a/setup.py b/setup.py index bd2cf6d..efa1ee5 100755 --- a/setup.py +++ b/setup.py @@ -1,11 +1,12 @@ -#!/usr/bin/env python -"""Setup file for python-matlab-bridge""" +# -*- coding: utf-8 -*- +""" +Pymatbridge: A python interface to call out to Matlab(R) +""" import os import shutil import glob - # BEFORE importing distutils, remove MANIFEST. distutils doesn't properly # update it when the contents of directories change. if os.path.exists('MANIFEST'): @@ -16,41 +17,52 @@ except ImportError: from distutils.core import setup - # Find the messenger binary file(s) and copy it to /matlab folder. from messenger.make import get_messenger_dir -messenger_dir = get_messenger_dir() +from version import __version__, __build__ -for f in glob.glob("./messenger/%s/messenger.*" % messenger_dir): +for f in glob.glob("./messenger/%s/messenger.*" % get_messenger_dir()): shutil.copy(f, "./pymatbridge/matlab") - -# Get version and release info, which is all stored in pymatbridge/version.py -ver_file = os.path.join('pymatbridge', 'version.py') -exec(open(ver_file).read()) - -opts = dict(name=NAME, - maintainer=MAINTAINER, - maintainer_email=MAINTAINER_EMAIL, - description=DESCRIPTION, - long_description=LONG_DESCRIPTION, - url=URL, - download_url=DOWNLOAD_URL, - license=LICENSE, - classifiers=CLASSIFIERS, - author=AUTHOR, - author_email=AUTHOR_EMAIL, - platforms=PLATFORMS, - version=VERSION, - packages=PACKAGES, - package_data=PACKAGE_DATA, - zip_safe=False, - requires=REQUIRES, - #extras_require=EXTRAS_REQUIRE, - scripts=BIN - ) - - # Now call the actual setup function if __name__ == '__main__': - setup(**opts) + setup( + name="pymatbridge", + maintainer="Ariel Rokem", + maintainer_email="arokem@gmail.com", + description=__doc__, + long_description=open('LICENSE').read(), + url="https://github.com/arokem/python-matlab-bridge", + download_url="https://github.com/arokem/python-matlab-bridge/archive/master.tar.gz", + license='BSD', + author="https://github.com/arokem/python-matlab-bridge/contributors", + author_email="arokem@gmail.com", + platforms="OS Independent", + version='.'.join([__version__, __build__]), + packages=['pymatbridge'], + package_data={ + "pymatbridge": [ + "matlab/matlabserver.m", "matlab/messenger.*", + "matlab/usrprog/*", "matlab/util/*.m", + "matlab/util/json_v0.2.2/LICENSE", + "matlab/util/json_v0.2.2/README.md", + "matlab/util/json_v0.2.2/test/*", + "matlab/util/json_v0.2.2/json/*.m", + "matlab/util/json_v0.2.2/json/java/*", + "tests/*.py", "examples/*.ipynb" + ] + }, + zip_safe=False, + requires=['pyzmq'], + scripts=['scripts/publish-notebook'], + classifiers=[ + "Development Status :: 3 - Alpha", + "Environment :: Console", + "Intended Audience :: Science/Research", + "License :: OSI Approved :: BSD License", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Topic :: Scientific/Engineering", + ], + #extras_require=['numpy', 'scipy', 'ipython'] + ) diff --git a/version.py b/version.py new file mode 120000 index 0000000..c3709ac --- /dev/null +++ b/version.py @@ -0,0 +1 @@ +pymatbridge/__version__.py \ No newline at end of file From b57da428d61f081872adb78fbde6370f68ced6e4 Mon Sep 17 00:00:00 2001 From: Sang Han Date: Fri, 27 Mar 2015 09:21:18 -0700 Subject: [PATCH 26/58] import only bare minimum through exec --- setup.py | 14 +++++++++----- version.py | 1 - 2 files changed, 9 insertions(+), 6 deletions(-) delete mode 120000 version.py diff --git a/setup.py b/setup.py index efa1ee5..a99557d 100755 --- a/setup.py +++ b/setup.py @@ -2,7 +2,6 @@ """ Pymatbridge: A python interface to call out to Matlab(R) """ - import os import shutil import glob @@ -12,6 +11,9 @@ if os.path.exists('MANIFEST'): os.remove('MANIFEST') +# Set Version Info +exec(open('pymatbridge/__version__.py').read()) + try: from setuptools import setup except ImportError: @@ -19,10 +21,9 @@ # Find the messenger binary file(s) and copy it to /matlab folder. from messenger.make import get_messenger_dir -from version import __version__, __build__ -for f in glob.glob("./messenger/%s/messenger.*" % get_messenger_dir()): - shutil.copy(f, "./pymatbridge/matlab") +for f in glob.glob("messenger/%s/messenger.*" % get_messenger_dir()): + shutil.copy(f, 'pymatbridge/matlab/') # Now call the actual setup function if __name__ == '__main__': @@ -39,7 +40,10 @@ author_email="arokem@gmail.com", platforms="OS Independent", version='.'.join([__version__, __build__]), - packages=['pymatbridge'], + packages=['pymatbridge', 'messenger'], + data_files=[ + ('pymatbridge/matlab', ['messenger/mexmaci64/messenger.mex']) + ], package_data={ "pymatbridge": [ "matlab/matlabserver.m", "matlab/messenger.*", diff --git a/version.py b/version.py deleted file mode 120000 index c3709ac..0000000 --- a/version.py +++ /dev/null @@ -1 +0,0 @@ -pymatbridge/__version__.py \ No newline at end of file From 4f4fa3cfb4378f51196fd01b5dce6811a17295f1 Mon Sep 17 00:00:00 2001 From: Sang Han Date: Wed, 22 Apr 2015 07:04:04 -0700 Subject: [PATCH 27/58] working build on osx --- .travis.yml | 7 +- pymatbridge/__version__.py | 4 +- .../messenger}/__init__.py | 2 +- .../messenger}/__main__.py | 0 {messenger => pymatbridge/messenger}/make.py | 0 .../messenger}/mexa64/messenger.mex | Bin .../messenger}/mexa64/messenger.mex.zmq4 | Bin .../messenger}/mexa64/messenger.mexa64 | Bin .../messenger}/mexa64/messenger.mexa64.zmq4 | Bin .../messenger}/mexmaci64/messenger.mex | Bin .../messenger}/mexmaci64/messenger.mex.zmq3 | Bin .../messenger}/mexmaci64/messenger.mexmaci64 | Bin .../mexmaci64/messenger.mexmaci64.zmq3 | Bin .../messenger}/mexw64/README.md | 0 .../messenger}/mexw64/messenger.mex | Bin .../messenger}/mexw64/messenger.mexw64 | Bin .../messenger}/settings.py | 0 .../messenger}/src/messenger.c | 0 .../messenger}/tests/test_env.py | 12 +- pymatbridge/pymatbridge.py | 2 +- requirements.txt | 2 +- setup.py | 128 ++++++++++-------- version.py | 3 + 23 files changed, 82 insertions(+), 78 deletions(-) rename {messenger => pymatbridge/messenger}/__init__.py (54%) rename {messenger => pymatbridge/messenger}/__main__.py (100%) rename {messenger => pymatbridge/messenger}/make.py (100%) rename {messenger => pymatbridge/messenger}/mexa64/messenger.mex (100%) rename {messenger => pymatbridge/messenger}/mexa64/messenger.mex.zmq4 (100%) rename {messenger => pymatbridge/messenger}/mexa64/messenger.mexa64 (100%) rename {messenger => pymatbridge/messenger}/mexa64/messenger.mexa64.zmq4 (100%) rename {messenger => pymatbridge/messenger}/mexmaci64/messenger.mex (100%) rename {messenger => pymatbridge/messenger}/mexmaci64/messenger.mex.zmq3 (100%) rename {messenger => pymatbridge/messenger}/mexmaci64/messenger.mexmaci64 (100%) rename {messenger => pymatbridge/messenger}/mexmaci64/messenger.mexmaci64.zmq3 (100%) rename {messenger => pymatbridge/messenger}/mexw64/README.md (100%) rename {messenger => pymatbridge/messenger}/mexw64/messenger.mex (100%) rename {messenger => pymatbridge/messenger}/mexw64/messenger.mexw64 (100%) rename {messenger => pymatbridge/messenger}/settings.py (100%) rename {messenger => pymatbridge/messenger}/src/messenger.c (100%) rename {messenger => pymatbridge/messenger}/tests/test_env.py (80%) create mode 100644 version.py diff --git a/.travis.yml b/.travis.yml index dd6961b..e85b084 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,12 +33,7 @@ install: - python setup.py install script: - # run coverage on py2.7, regular on others - - if [[ $CONDA == python=2.7* ]]; then - nosetests --exe -v --with-cov --cover-package pymatbridge; - else - nosetests --exe -v pymatbridge; - fi + - python setup.py test after_success: - coveralls diff --git a/pymatbridge/__version__.py b/pymatbridge/__version__.py index ec2406a..8f0f77e 100644 --- a/pymatbridge/__version__.py +++ b/pymatbridge/__version__.py @@ -1,3 +1,3 @@ __version__ = '0.5.0' -__build__ = 'dev' - +__build__ = 'dev1' +__release__ = '.'.join([__version__, __build__]) diff --git a/messenger/__init__.py b/pymatbridge/messenger/__init__.py similarity index 54% rename from messenger/__init__.py rename to pymatbridge/messenger/__init__.py index da40056..8a14d96 100644 --- a/messenger/__init__.py +++ b/pymatbridge/messenger/__init__.py @@ -1,2 +1,2 @@ from .settings import * -from .make import * \ No newline at end of file +from .make import * diff --git a/messenger/__main__.py b/pymatbridge/messenger/__main__.py similarity index 100% rename from messenger/__main__.py rename to pymatbridge/messenger/__main__.py diff --git a/messenger/make.py b/pymatbridge/messenger/make.py similarity index 100% rename from messenger/make.py rename to pymatbridge/messenger/make.py diff --git a/messenger/mexa64/messenger.mex b/pymatbridge/messenger/mexa64/messenger.mex similarity index 100% rename from messenger/mexa64/messenger.mex rename to pymatbridge/messenger/mexa64/messenger.mex diff --git a/messenger/mexa64/messenger.mex.zmq4 b/pymatbridge/messenger/mexa64/messenger.mex.zmq4 similarity index 100% rename from messenger/mexa64/messenger.mex.zmq4 rename to pymatbridge/messenger/mexa64/messenger.mex.zmq4 diff --git a/messenger/mexa64/messenger.mexa64 b/pymatbridge/messenger/mexa64/messenger.mexa64 similarity index 100% rename from messenger/mexa64/messenger.mexa64 rename to pymatbridge/messenger/mexa64/messenger.mexa64 diff --git a/messenger/mexa64/messenger.mexa64.zmq4 b/pymatbridge/messenger/mexa64/messenger.mexa64.zmq4 similarity index 100% rename from messenger/mexa64/messenger.mexa64.zmq4 rename to pymatbridge/messenger/mexa64/messenger.mexa64.zmq4 diff --git a/messenger/mexmaci64/messenger.mex b/pymatbridge/messenger/mexmaci64/messenger.mex similarity index 100% rename from messenger/mexmaci64/messenger.mex rename to pymatbridge/messenger/mexmaci64/messenger.mex diff --git a/messenger/mexmaci64/messenger.mex.zmq3 b/pymatbridge/messenger/mexmaci64/messenger.mex.zmq3 similarity index 100% rename from messenger/mexmaci64/messenger.mex.zmq3 rename to pymatbridge/messenger/mexmaci64/messenger.mex.zmq3 diff --git a/messenger/mexmaci64/messenger.mexmaci64 b/pymatbridge/messenger/mexmaci64/messenger.mexmaci64 similarity index 100% rename from messenger/mexmaci64/messenger.mexmaci64 rename to pymatbridge/messenger/mexmaci64/messenger.mexmaci64 diff --git a/messenger/mexmaci64/messenger.mexmaci64.zmq3 b/pymatbridge/messenger/mexmaci64/messenger.mexmaci64.zmq3 similarity index 100% rename from messenger/mexmaci64/messenger.mexmaci64.zmq3 rename to pymatbridge/messenger/mexmaci64/messenger.mexmaci64.zmq3 diff --git a/messenger/mexw64/README.md b/pymatbridge/messenger/mexw64/README.md similarity index 100% rename from messenger/mexw64/README.md rename to pymatbridge/messenger/mexw64/README.md diff --git a/messenger/mexw64/messenger.mex b/pymatbridge/messenger/mexw64/messenger.mex similarity index 100% rename from messenger/mexw64/messenger.mex rename to pymatbridge/messenger/mexw64/messenger.mex diff --git a/messenger/mexw64/messenger.mexw64 b/pymatbridge/messenger/mexw64/messenger.mexw64 similarity index 100% rename from messenger/mexw64/messenger.mexw64 rename to pymatbridge/messenger/mexw64/messenger.mexw64 diff --git a/messenger/settings.py b/pymatbridge/messenger/settings.py similarity index 100% rename from messenger/settings.py rename to pymatbridge/messenger/settings.py diff --git a/messenger/src/messenger.c b/pymatbridge/messenger/src/messenger.c similarity index 100% rename from messenger/src/messenger.c rename to pymatbridge/messenger/src/messenger.c diff --git a/messenger/tests/test_env.py b/pymatbridge/messenger/tests/test_env.py similarity index 80% rename from messenger/tests/test_env.py rename to pymatbridge/messenger/tests/test_env.py index d858e94..e957735 100644 --- a/messenger/tests/test_env.py +++ b/pymatbridge/messenger/tests/test_env.py @@ -1,15 +1,13 @@ import numpy.testing as npt import sys import os +import pkg_resources -ROOT = os.path.join(os.path.dirname(__file__), '..', '..') +from pymatbridge import messenger -# Necessary since messenger is not installed with pymatbridge -sys.path.append(ROOT) - -import messenger - -CONFIG = os.path.join(ROOT, 'config.ini') +ROOT = __file__ +CONFIG = os.path.realpath(os.path.join(ROOT, '../../../../config.ini')) +print(CONFIG) BIN = messenger.get_matlab_bin(config=CONFIG) def test_config(): diff --git a/pymatbridge/pymatbridge.py b/pymatbridge/pymatbridge.py index 31855fa..8a94f96 100644 --- a/pymatbridge/pymatbridge.py +++ b/pymatbridge/pymatbridge.py @@ -41,7 +41,6 @@ class spmatrix: pass - def encode_ndarray(obj): """Write a numpy array and its shape to base64 buffers""" shape = obj.shape @@ -403,6 +402,7 @@ def _bind_method(self, name, unconditionally=False): class Matlab(_Session): + def __init__(self, executable='matlab', socket_addr=None, id='python-matlab-bridge', log=False, maxtime=60, platform=None, startup_options=None): diff --git a/requirements.txt b/requirements.txt index ae3bcc7..a77d8b4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,2 @@ pyzmq -numpy>=1.7 +numpy diff --git a/setup.py b/setup.py index a99557d..f5a0ccc 100755 --- a/setup.py +++ b/setup.py @@ -2,71 +2,79 @@ """ Pymatbridge: A python interface to call out to Matlab(R) """ -import os -import shutil -import glob - -# BEFORE importing distutils, remove MANIFEST. distutils doesn't properly -# update it when the contents of directories change. -if os.path.exists('MANIFEST'): - os.remove('MANIFEST') -# Set Version Info -exec(open('pymatbridge/__version__.py').read()) +import os +import sys +import filecmp +import itertools try: - from setuptools import setup + import pkg_resources except ImportError: - from distutils.core import setup + import ez_setup + ez_setup.use_setuptools() -# Find the messenger binary file(s) and copy it to /matlab folder. -from messenger.make import get_messenger_dir +from setuptools import setup, find_packages +from setuptools.command.test import test as TestCommand +from distutils import file_util +from distutils.extension import Extension +from pymatbridge.messenger import get_messenger_dir -for f in glob.glob("messenger/%s/messenger.*" % get_messenger_dir()): - shutil.copy(f, 'pymatbridge/matlab/') +from version import __version__, __build__, __release__ -# Now call the actual setup function -if __name__ == '__main__': - setup( - name="pymatbridge", - maintainer="Ariel Rokem", - maintainer_email="arokem@gmail.com", - description=__doc__, - long_description=open('LICENSE').read(), - url="https://github.com/arokem/python-matlab-bridge", - download_url="https://github.com/arokem/python-matlab-bridge/archive/master.tar.gz", - license='BSD', - author="https://github.com/arokem/python-matlab-bridge/contributors", - author_email="arokem@gmail.com", - platforms="OS Independent", - version='.'.join([__version__, __build__]), - packages=['pymatbridge', 'messenger'], - data_files=[ - ('pymatbridge/matlab', ['messenger/mexmaci64/messenger.mex']) - ], - package_data={ - "pymatbridge": [ - "matlab/matlabserver.m", "matlab/messenger.*", - "matlab/usrprog/*", "matlab/util/*.m", - "matlab/util/json_v0.2.2/LICENSE", - "matlab/util/json_v0.2.2/README.md", - "matlab/util/json_v0.2.2/test/*", - "matlab/util/json_v0.2.2/json/*.m", - "matlab/util/json_v0.2.2/json/java/*", - "tests/*.py", "examples/*.ipynb" - ] - }, - zip_safe=False, - requires=['pyzmq'], - scripts=['scripts/publish-notebook'], - classifiers=[ - "Development Status :: 3 - Alpha", - "Environment :: Console", - "Intended Audience :: Science/Research", - "License :: OSI Approved :: BSD License", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Topic :: Scientific/Engineering", +messenger = pkg_resources.resource_filename('pymatbridge.messenger', get_messenger_dir()) +matlab = pkg_resources.resource_filename('pymatbridge', 'matlab') +newfiles = filecmp.cmpfiles(messenger, matlab, os.listdir(messenger), shallow=False)[1:] + +for binary in itertools.chain(*newfiles): + cmd = (os.path.join(messenger, binary), os.path.join(matlab, binary)) + print('Copying %s' % binary) + file_util.copy_file(*cmd, update=True) + +extension = Extension( + name='messenger.mexmaci', + sources=['messenger/src/messenger.c'], + include_dirs=['/usr/local/include'], + library_dirs=['/usr/local/lib/'], + libraries=['zmq'], +) + +class NoseTestCommand(TestCommand): + + def finalize_options(self): + TestCommand.finalize_options(self) + self.test_args = [] + self.test_suite = True + + def run_tests(self): + import nose + args = 'nosetests -v --exe --with-cov ' + if sys.version_info == (2, 7): + args += '--cover-package pymatbridge' + nose.run_exit(argv=args.split()) + +setup( + name="pymatbridge", + maintainer="Ariel Rokem", + maintainer_email="arokem@gmail.com", + description=__doc__, + tests_require=['nose', 'coverage'], + setup_requires=['wheel'], + cmdclass={'test': NoseTestCommand}, + version=__release__, + packages=find_packages(exclude=['tests*']), + zip_safe = False, + requires=['numpy', 'pyzmq'], + package_data={ + "pymatbridge": [ + "matlab/matlabserver.m", "matlab/messenger.*", + "matlab/usrprog/*", "matlab/util/*.m", + "matlab/util/json_v0.2.2/LICENSE", + "matlab/util/json_v0.2.2/README.md", + "matlab/util/json_v0.2.2/test/*", + "matlab/util/json_v0.2.2/json/*.m", + "matlab/util/json_v0.2.2/json/java/*", + "tests/*.py", "examples/*.ipynb" ], - #extras_require=['numpy', 'scipy', 'ipython'] - ) + }, +) diff --git a/version.py b/version.py new file mode 100644 index 0000000..fcd9f36 --- /dev/null +++ b/version.py @@ -0,0 +1,3 @@ +# Set Version Info +exec(open('pymatbridge/__version__.py').read()) + From 9b9daa7deace660935594f6707955191f73231eb Mon Sep 17 00:00:00 2001 From: Sang Han Date: Wed, 22 Apr 2015 07:07:46 -0700 Subject: [PATCH 28/58] setup --- MANIFEST.in | 9 +++++++++ setup.cfg | 28 ++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 MANIFEST.in create mode 100644 setup.cfg diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..220eacf --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,9 @@ +recursive-include pymatbridge * + +include *.md +include *.py +include *.txt +include LICENSE +include config.ini +recursive-include pymatbridge *.py +recursive-include tools *.py diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..7de82dc --- /dev/null +++ b/setup.cfg @@ -0,0 +1,28 @@ +[global] +verbose=1 + +[build_ext] +inplace=1 + +[bdist_wheel] +universal = 1 + +[metadata] +summary = pymatbridge: A python interface to call out to Matlab(R) +license = BSD +scripts = scripts/publish-notebook +download_url = https://github.com/arokem/python-matlab-bridge/archive/master.tar.gz +long_description = + README.md + LICENSE +description-file = + README.md + LICENSE +classifiers = + Development Status :: 3 - Alpha + Environment :: Console + Intended Audience :: Science/Research + License :: OSI Approved :: BSD License + Operating System :: OS Independent + Programming Language :: Python + Topic :: Scientific/Engineering From 7f6cb89a9ae1bf9c5ea156c43555333fabed698f Mon Sep 17 00:00:00 2001 From: Sang Han Date: Wed, 22 Apr 2015 09:37:25 -0700 Subject: [PATCH 29/58] holy crap it works --- MANIFEST.in | 29 ++++++++++++++---- pymatbridge/messenger/make.py | 7 +++-- pymatbridge/messenger/mexw64/README.md | 41 -------------------------- pymatbridge/messenger/settings.py | 24 +-------------- setup.cfg | 20 +++++++++++-- setup.py | 38 ++++++++++-------------- 6 files changed, 60 insertions(+), 99 deletions(-) delete mode 100644 pymatbridge/messenger/mexw64/README.md diff --git a/MANIFEST.in b/MANIFEST.in index 220eacf..62719b8 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,9 +1,26 @@ -recursive-include pymatbridge * +exclude messenger.* -include *.md -include *.py -include *.txt include LICENSE include config.ini -recursive-include pymatbridge *.py -recursive-include tools *.py +include README.md +include requirements.txt +include setup.cfg +include scripts/publish-notebook + +include pymatbridge/messenger/src/messenger.c + +include pymatbridge/messenger/mexa64/ +include pymatbridge/messenger/mexmaci64/ +include pymatbridge/messenger/mexw64/ +include pymatbridge/messenger/mexa64/ + +include pymatbridge/matlab/messenger.mex +include pymatbridge/matlab/messenger.mex.zmq3 +include pymatbridge/matlab/messenger.mexmaci64 +include pymatbridge/matlab/messenger.mexmaci64.zmq3 +include pymatbridge/matlab/util/json_v0.2.2/json/java/json.jar +include pymatbridge/matlab/util/json_v0.2.2/LICENSE + +include *.ipynb +include *.m +include *.py diff --git a/pymatbridge/messenger/make.py b/pymatbridge/messenger/make.py index 09064dc..a4f8cde 100644 --- a/pymatbridge/messenger/make.py +++ b/pymatbridge/messenger/make.py @@ -134,7 +134,7 @@ def build_octave(static=False): do_build(split_command_line(make_cmd), 'messenger.mex') -def build_matlab(static=False): +def build_matlab(static=False, messenger='messenger.c'): """ Build the messenger mex for MATLAB @@ -155,12 +155,13 @@ def build_matlab(static=False): # Build the mex file mex = os.path.join(matlab_bin, "mex") paths = "-L'%(zmq_lib)s' -I'%(zmq_inc)s'" % cfg - make_cmd = '%s -O %s -lzmq messenger/src/messenger.c' % (mex, paths) + make_cmd = '%s -O %s -lzmq %s' % (mex, paths, messenger) if static: make_cmd += ' -DZMQ_STATIC' - do_build(split_command_line(make_cmd), 'messenger.%s' % extension) + print(make_cmd) + subprocess.check_output(split_command_line(make_cmd), shell=use_shell) def get_matlab_bin(config='config.ini'): diff --git a/pymatbridge/messenger/mexw64/README.md b/pymatbridge/messenger/mexw64/README.md deleted file mode 100644 index 47100e8..0000000 --- a/pymatbridge/messenger/mexw64/README.md +++ /dev/null @@ -1,41 +0,0 @@ -Dynamically linked building instructions ----------------------------------------- - -1) Install zeromq from the website: http://zeromq.org/distro:microsoft-windows - -2) Rename one of the lib/libzmq-*.lib files to libzmq.lib in the ZeroMQ - installation directory - -3) Add the ZeroMQ bin directory to your path. - -4) Edit the messenger/mexw64/local.cfg file in messenger to point to the - zeromq install directory (you will need to update both ZMQ_INC and ZMQ_LIB). - Also ensure the MATLAB directory is correct. - -5) Run ```make.py matlab``` in the messenger directory. This should build - messenger.mexw64 - -Statically linked building instructions ---------------------------------------- - -A statically linked library has the advantage of not requiring libzmq.dll to -be found in the path. For this reason, including it in the installer results -in a simpler and more robust installation process. While building a statically -linked mex is simple in practice, but because zeromq (as of 3/10/15) does not -provide a .lib for static linking with the windows installer, you will need to -compile this yourself. These directions are from zeromq 4.0.5. - -1) Download and unzip the zeromq zip file (listed as Windows sources) from - http://zeromq.org/intro:get-the-software - -2) In the builds/msvc directory open the msvc.sln file in Visual Studio. - -3) Create a new Platform for x64. In the Librarian section of properties, set - the target section to /Machine:X64 - -4) Build libzmq with the "StaticRelease" for x64. - -5) Edit the messenger/mexw64/local.cfg file to point to where you built ZeroMQ - and your MATLAB bin directory. - -6) Build messenger.mexw64 with ```make matlab --static``` diff --git a/pymatbridge/messenger/settings.py b/pymatbridge/messenger/settings.py index a86087c..5597983 100644 --- a/pymatbridge/messenger/settings.py +++ b/pymatbridge/messenger/settings.py @@ -9,7 +9,7 @@ from urllib import urlretrieve import string -__all__= ['get_matlab_env', 'fetch_zmq'] +__all__= ['get_matlab_env'] def get_matlab_env(matlab='matlab'): @@ -34,25 +34,3 @@ def get_matlab_env(matlab='matlab'): return dict(string.split(env, '=', maxsplit=1) for env in envs) - -def fetch_zmq(prefix, version=(4,0,5)): - """ - Download and extract libzmq into `prefix` - - Parameters - ---------- - save: str - File Save Location - version: 3-tuple - ZMQ Version Number - """ - print('Downloading ZMQ Source Version %i.%i.%i' % version) - url = ("http://download.zeromq.org/zeromq-%i.%i.%i.tar.gz" % version) - name = urlretrieve(url, url.rsplit('/')[-1])[0] - - print('Extracting into prefix %s' % prefix) - with tarfile.open(name) as tar: - tar.extractall(prefix) - - print('Download Complete') - os.remove(name) diff --git a/setup.cfg b/setup.cfg index 7de82dc..125b3a4 100644 --- a/setup.cfg +++ b/setup.cfg @@ -5,7 +5,7 @@ verbose=1 inplace=1 [bdist_wheel] -universal = 1 +universal = 0 [metadata] summary = pymatbridge: A python interface to call out to Matlab(R) @@ -23,6 +23,20 @@ classifiers = Environment :: Console Intended Audience :: Science/Research License :: OSI Approved :: BSD License - Operating System :: OS Independent - Programming Language :: Python Topic :: Scientific/Engineering + Topic :: Software Development :: Build Tools' + Intended Audience :: Developers' + Programming Language :: Python :: 2' + Programming Language :: Python :: 2.7' + Programming Language :: Python :: 3' + Programming Language :: Python :: 3.3' + Programming Language :: Python :: 3.4' + Programming Language :: Other Scripting Engines + Operating System :: Microsoft :: Windows + Operating System :: OS Independent + Intended Audience :: Developers + Intended Audience :: Education + Intended Audience :: Science/Research + +keywords = matlab python packaging + diff --git a/setup.py b/setup.py index f5a0ccc..9d48c64 100755 --- a/setup.py +++ b/setup.py @@ -7,6 +7,7 @@ import sys import filecmp import itertools +import platform try: import pkg_resources @@ -17,8 +18,9 @@ from setuptools import setup, find_packages from setuptools.command.test import test as TestCommand from distutils import file_util -from distutils.extension import Extension -from pymatbridge.messenger import get_messenger_dir +from setuptools.command.build_ext import build_ext + +from pymatbridge.messenger import build_matlab, get_messenger_dir from version import __version__, __build__, __release__ @@ -31,14 +33,6 @@ print('Copying %s' % binary) file_util.copy_file(*cmd, update=True) -extension = Extension( - name='messenger.mexmaci', - sources=['messenger/src/messenger.c'], - include_dirs=['/usr/local/include'], - library_dirs=['/usr/local/lib/'], - libraries=['zmq'], -) - class NoseTestCommand(TestCommand): def finalize_options(self): @@ -53,6 +47,13 @@ def run_tests(self): args += '--cover-package pymatbridge' nose.run_exit(argv=args.split()) +class CompileMEX(build_ext): + def run(self): + return build_matlab(messenger='pymatbridge/messenger/src/messenger.c') + + + + setup( name="pymatbridge", maintainer="Ariel Rokem", @@ -60,21 +61,12 @@ def run_tests(self): description=__doc__, tests_require=['nose', 'coverage'], setup_requires=['wheel'], - cmdclass={'test': NoseTestCommand}, + cmdclass={ + 'test': NoseTestCommand, + 'messenger': CompileMEX, + }, version=__release__, packages=find_packages(exclude=['tests*']), zip_safe = False, requires=['numpy', 'pyzmq'], - package_data={ - "pymatbridge": [ - "matlab/matlabserver.m", "matlab/messenger.*", - "matlab/usrprog/*", "matlab/util/*.m", - "matlab/util/json_v0.2.2/LICENSE", - "matlab/util/json_v0.2.2/README.md", - "matlab/util/json_v0.2.2/test/*", - "matlab/util/json_v0.2.2/json/*.m", - "matlab/util/json_v0.2.2/json/java/*", - "tests/*.py", "examples/*.ipynb" - ], - }, ) From fec95c939ab4213165ebbff02e687f8e084e6491 Mon Sep 17 00:00:00 2001 From: Sang Han Date: Wed, 25 Mar 2015 06:40:55 -0700 Subject: [PATCH 30/58] building messenger call now from root --- config.ini | 20 +++ messenger/__init__.py | 1 + messenger/__main__.py | 40 ++++++ messenger/make.py | 293 ++++++++---------------------------------- messenger/settings.py | 51 ++++++++ 5 files changed, 163 insertions(+), 242 deletions(-) create mode 100644 config.ini create mode 100644 messenger/__main__.py mode change 100755 => 100644 messenger/make.py create mode 100644 messenger/settings.py diff --git a/config.ini b/config.ini new file mode 100644 index 0000000..9a1cdae --- /dev/null +++ b/config.ini @@ -0,0 +1,20 @@ +[Darwin] +; MATLAB_BIN=Applications/MATLAB_R2014a.app/bin +; OCTAVE_INC= +; OCTAVE_LIB= +ZMQ_INC=/usr/local/include +ZMQ_LIB=/usr/local/lib + +[Windows] +; MATLAB_BIN=C:\Program Files\MATLAB\R2014b\bin +; OCTAVE_INC=C:\Octave\Octave-3.8.2\include\octave-3.8.2\octave +; OCTAVE_LIB=C:\Octave\Octave-3.8.2\lib\octave\3.8.2 +ZMQ_INC=C:/Program Files/ZeroMQ 4.0.4/include +ZMQ_LIB=C:/Program Files/ZeroMQ 4.0.4/lib + +[Linux] +; MATLAB_BIN=/usr/local/bin +; OCTAVE_INC=/usr/include +; OCTAVE_LIB=/usr/lib/x86_64-linux-gnu/ +ZMQ_INC= +ZMQ_LIB= diff --git a/messenger/__init__.py b/messenger/__init__.py index e69de29..c70020d 100644 --- a/messenger/__init__.py +++ b/messenger/__init__.py @@ -0,0 +1 @@ +from .settings import * \ No newline at end of file diff --git a/messenger/__main__.py b/messenger/__main__.py new file mode 100644 index 0000000..ce3ef9c --- /dev/null +++ b/messenger/__main__.py @@ -0,0 +1,40 @@ +from argparse import ArgumentParser + +from .make import * + +def command_line(): + """ + Manages command line arguments. + + Returns + ======= + Namespace containing parsed arguments + """ + + parser = ArgumentParser() + parser.add_argument( + "target", + choices=["matlab", "octave"], + type=str.lower, + help="target to be built" + ) + parser.add_argument( + "--static", + action="store_true", + help="staticly link libzmq" + ) + return parser.parse_args() + + + +def main(): + args = command_line() + if args.target == "matlab": + build_matlab(static=args.static) + elif args.target == "octave": + build_octave() + else: + raise ValueError() + +if __name__ == '__main__': + main() diff --git a/messenger/make.py b/messenger/make.py old mode 100755 new mode 100644 index 3419422..0a5f21d --- a/messenger/make.py +++ b/messenger/make.py @@ -1,187 +1,61 @@ -#!/usr/bin/python - -""" -Make : building messenger mex file. - -Some functions have been taken from the pexpect module (https://pexpect.readthedocs.org/en/latest/) - -The license for pexpect is below: - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -""" - from __future__ import print_function + import os -import platform import sys import shlex import shutil import subprocess -import stat +import platform + +from glob import glob try: - import pty + from ConfigParser import ConfigParser except ImportError: - pty = None - -def is_executable_file(path): - """Checks that path is an executable regular file (or a symlink to a file). - - This is roughly ``os.path isfile(path) and os.access(path, os.X_OK)``, but - on some platforms :func:`os.access` gives us the wrong answer, so this - checks permission bits directly. - - Note - ---- - This function is taken from the pexpect module, see module doc-string for - license. - """ - # follow symlinks, - fpath = os.path.realpath(path) - - # return False for non-files (directories, fifo, etc.) - if not os.path.isfile(fpath): - return False - - # On Solaris, etc., "If the process has appropriate privileges, an - # implementation may indicate success for X_OK even if none of the - # execute file permission bits are set." - # - # For this reason, it is necessary to explicitly check st_mode - - # get file mode using os.stat, and check if `other', - # that is anybody, may read and execute. - mode = os.stat(fpath).st_mode - if mode & stat.S_IROTH and mode & stat.S_IXOTH: - return True - - # get current user's group ids, and check if `group', - # when matching ours, may read and execute. - user_gids = os.getgroups() + [os.getgid()] - if (os.stat(fpath).st_gid in user_gids and - mode & stat.S_IRGRP and mode & stat.S_IXGRP): - return True - - # finally, if file owner matches our effective userid, - # check if `user', may read and execute. - user_gids = os.getgroups() + [os.getgid()] - if (os.stat(fpath).st_uid == os.geteuid() and - mode & stat.S_IRUSR and mode & stat.S_IXUSR): - return True - - return False + from configparser import ConfigParser +from . import settings -def which(filename): - '''This takes a given filename; tries to find it in the environment path; - then checks if it is executable. This returns the full path to the filename - if found and executable. Otherwise this returns None. - - Note - ---- - This function is taken from the pexpect module, see module doc-string for - license. - ''' - - # Special case where filename contains an explicit path. - if os.path.dirname(filename) != '' and is_executable_file(filename): - return filename - if 'PATH' not in os.environ or os.environ['PATH'] == '': - p = os.defpath - else: - p = os.environ['PATH'] - pathlist = p.split(os.pathsep) - for path in pathlist: - ff = os.path.join(path, filename) - if pty: - if is_executable_file(ff): - return ff - else: - pathext = os.environ.get('Pathext', '.exe;.com;.bat;.cmd') - pathext = pathext.split(os.pathsep) + [''] - for ext in pathext: - if os.access(ff + ext, os.X_OK): - return ff + ext - return None - - -use_shell = True if sys.platform.startswith("win32") else False - - -def make_str(byte_or_str): - return byte_or_str if isinstance(byte_or_str, str) \ - else str(byte_or_str.decode("UTF-8")) - - -def esc(path): - if ' ' in path: - return '"' + path + '"' - else: - return path - +__all__ = [ + 'get_messenger_dir', + 'get_config', + 'do_build', + 'build_octave', + 'build_matlab' +] def get_messenger_dir(): - # Check the system platform first - splatform = sys.platform - - if splatform.startswith('linux'): - messenger_dir = 'mexa64' - elif splatform.startswith('darwin'): - messenger_dir = 'mexmaci64' - elif splatform.startswith('win32'): - if splatform == "win32": - # We have a win64 messenger, so we need to figure out if this is 32 - # or 64 bit Windows: - if not platform.machine().endswith('64'): - raise ValueError("pymatbridge does not work on win32") + host, is_64bit = platform.system(), sys.maxsize > 2**32 + ostype = { + 'Darwin': 'mexmaci64', + 'Linux': 'mexa64', + 'Windows': 'mexw64', + } + if not is_64bit and host == 'Windows': + raise ValueError("pymatbridge does not support 32-bit Windows") - # We further need to differniate 32 from 64 bit: - maxint = sys.maxsize - if maxint == 9223372036854775807: - messenger_dir = 'mexw64' - elif maxint == 2147483647: - messenger_dir = 'mexw32' - return messenger_dir + return ostype[host] if is_64bit else 'mexw32' def get_config(): - messenger_dir = get_messenger_dir() - with open(os.path.join(messenger_dir, 'local.cfg')) as fid: - lines = fid.readlines() - - cfg = {} - for line in lines: - if '=' not in line: - continue - name, path = line.split('=') - cfg[name.lower()] = path.strip() or '.' + config = os.path.join(os.path.realpath(__file__), 'config.ini') + print(config) + cfg = ConfigParser() + config.read(config) return cfg def do_build(make_cmd, messenger_exe): print('Building %s...' % messenger_exe) print(make_cmd) - messenger_dir = get_messenger_dir() - subprocess.check_output(shlex.split(make_cmd), shell=use_shell) + messenger_dir = 'messenger' + '/' + get_messenger_dir() + subprocess.call(shlex.split(make_cmd), stderr=subprocess.STDOUT) messenger_loc = os.path.join(messenger_dir, messenger_exe) - shutil.move(messenger_exe, messenger_loc) + # shutil.move(messenger_exe, messenger_loc) - if os.path.exists('messenger.o'): + if os.path.isfile('messenger.o'): os.remove('messenger.o') @@ -192,100 +66,35 @@ def build_octave(): do_build(make_cmd, 'messenger.mex') -def which_matlab(): - try: - matlab_path = which('matlab').strip() - matlab_path = make_str(matlab_path) - return os.path.dirname(os.path.realpath(matlab_path)) - except (OSError, subprocess.CalledProcessError): - def ensure_path(path, extension=''): - return os.path.isdir(path) and \ - os.path.isfile(os.path.join(path, "matlab" + extension)) - - # need to guess the location of MATLAB - if sys.platform.startswith("darwin"): - MATLABs = [os.path.join("/Applications", i, "bin") - for i in os.listdir("/Applications") - if i.startswith("MATLAB_R")] - # only want ones with MATLAB executables - # sort so we can get the latest - MATLABs = list(sorted(filter(ensure_path, MATLABs))) - return MATLABs[-1] if len(MATLABs) > 0 else None - elif sys.platform.startswith("win32"): - MATLAB_loc = "C:\\Program Files\\MATLAB" - print(MATLAB_loc) - if not os.path.isdir(MATLAB_loc): - return None - MATLABs = [os.path.join(MATLAB_loc, i, "bin") - for i in os.listdir(MATLAB_loc)] - print(MATLABs) - print(i) - # only want ones with MATLAB executables - # sort so we can get the latest - MATLABs = list(sorted(filter(lambda x: ensure_path(x, ".exe"), - MATLABs))) - print(MATLABs) - return MATLABs[-1] if len(MATLABs) > 0 else None - elif sys.platform.startswith("linux"): - MATLAB_loc = "/usr/local/MATLAB/" - if not os.path.isdir(MATLAB_loc): - return None - MATLABs = [os.path.join(MATLAB_loc, i, "bin") - for i in os.listdir(MATLAB_loc) - if i.startswith("R")] - # only want ones with MATLAB executables - # sort so we can get the latest - MATLABs = list(sorted(filter(ensure_path, MATLABs))) - return MATLABs[-1] if len(MATLABs) > 0 else None - - def build_matlab(static=False): - """build the messenger mex for MATLAB + """ + Build the messenger mex for MATLAB + Parameters + ============ static : bool Determines if the zmq library has been statically linked. If so, it will append the command line option -DZMQ_STATIC when compiling the mex so it matches libzmq. """ - cfg = get_config() - # To deal with spaces, remove quotes now, and add - # to the full commands themselves. - if 'matlab_bin' in cfg and cfg['matlab_bin'] != '.': - matlab_bin = cfg['matlab_bin'].strip('"') - else: # attempt to autodetect MATLAB filepath - matlab_bin = which_matlab() - if matlab_bin is None: - raise ValueError("specify 'matlab_bin' in cfg file") - # Get the extension - extcmd = esc(os.path.join(matlab_bin, "mexext")) - extension = subprocess.check_output(extcmd, shell=use_shell) - extension = extension.decode('utf-8').rstrip('\r\n') + matlab_bin = settings.get_matlab_bin() + cfg, host = ConfigParser(), platform.system() + cfg.read('config.ini') + libzmq = { + 'zmq_lib': os.path.normpath(cfg.get(host, 'ZMQ_LIB')), + 'zmq_inc': os.path.normpath(cfg.get(host, 'ZMQ_INC')), + } + + extcmd = '%s' % os.path.join(matlab_bin, "mexext") + extension = subprocess.check_output(extcmd, shell=True) + extension = os.path.join('messenger', extension.decode('utf-8').rstrip()) # Build the mex file - mex = esc(os.path.join(matlab_bin, "mex")) - paths = "-L%(zmq_lib)s -I%(zmq_inc)s" % cfg - make_cmd = '%s -O %s -lzmq ./src/messenger.c' % (mex, paths) + mex = '"' + os.path.join(matlab_bin, "mex") + '"' + paths = "-L'%(zmq_lib)s' -I'%(zmq_inc)s'" % libzmq + make_cmd = '%s -O %s -lzmq messenger/src/messenger.c' % (mex, paths) + if static: make_cmd += ' -DZMQ_STATIC' - do_build(make_cmd, 'messenger.%s' % extension) - -if __name__ == '__main__': - import argparse - parser = argparse.ArgumentParser() - parser.add_argument( - "target", - choices=["matlab", "octave"], - type=str.lower, - help="target to be built") - parser.add_argument("--static", action="store_true", - help="staticly link libzmq") - args = parser.parse_args() - if args.target == "matlab": - build_matlab(static=args.static) - elif args.target == "octave": - if args.static: - raise ValueError("static building not yet supported for octave") - build_octave() - else: - raise ValueError() + do_build(make_cmd, 'messenger.%s' % extension) diff --git a/messenger/settings.py b/messenger/settings.py new file mode 100644 index 0000000..c51e570 --- /dev/null +++ b/messenger/settings.py @@ -0,0 +1,51 @@ +import os +import platform + +from glob import glob + +try: + from configparser import ConfigParser +except ImportError: + from ConfigParser import ConfigParser + +__all__= ['get_matlab_bin'] + +def get_matlab_bin(config='config.ini'): + """ + Tries to find the MATLAB bin directory independent on host platform. + The operation of this function can be overridden by setting the MATLAB_BIN + variable within the configuration file specified. + + Parameters + -========= + config: + Relative path to configuration file + + Returns + ======= + matlab: + Absolute path to matlab bin directory + """ + cfg, host = ConfigParser(), platform.system() + cfg.read(os.path.join(__file__, config)) + + programs = { + 'Darwin' : r'/Applications', + 'Windows': r'C:/Program Files', + 'Linux' : r'/usr/local', + } + + if cfg.has_option(host, 'MATLAB_BIN'): + matlab = cfg.get(host, 'MATLAB_BIN') + else: + # Searches for Matlab bin if it's not set + _root = glob(r'%s/MATLAB*' % programs[host])[0] + _version = [p for p in os.listdir(_root) if p.startswith('R20')] + if any(_version): + _root = r'%s/%s' % (_root, _version.pop()) + matlab = r'%s/%s' % (_root, 'bin') + + assert os.path.isdir(matlab) + + return os.path.normpath(matlab) + From 8157edabff85c8e784ac09bcf631b8d177b0cb48 Mon Sep 17 00:00:00 2001 From: Sang Han Date: Wed, 25 Mar 2015 06:55:45 -0700 Subject: [PATCH 31/58] deprecated local.cfg --- messenger/make.py | 6 +++--- messenger/mexa64/local.cfg | 6 ------ messenger/mexmaci64/local.cfg | 5 ----- messenger/mexw64/local.cfg | 2 +- 4 files changed, 4 insertions(+), 15 deletions(-) delete mode 100644 messenger/mexa64/local.cfg delete mode 100644 messenger/mexmaci64/local.cfg diff --git a/messenger/make.py b/messenger/make.py index 0a5f21d..e77105a 100644 --- a/messenger/make.py +++ b/messenger/make.py @@ -48,12 +48,12 @@ def get_config(): def do_build(make_cmd, messenger_exe): print('Building %s...' % messenger_exe) print(make_cmd) - messenger_dir = 'messenger' + '/' + get_messenger_dir() + messenger_dir = get_messenger_dir() subprocess.call(shlex.split(make_cmd), stderr=subprocess.STDOUT) messenger_loc = os.path.join(messenger_dir, messenger_exe) - # shutil.move(messenger_exe, messenger_loc) + shutil.move(messenger_exe, os.path.join('messenger', messenger_loc)) if os.path.isfile('messenger.o'): os.remove('messenger.o') @@ -87,7 +87,7 @@ def build_matlab(static=False): extcmd = '%s' % os.path.join(matlab_bin, "mexext") extension = subprocess.check_output(extcmd, shell=True) - extension = os.path.join('messenger', extension.decode('utf-8').rstrip()) + extension = extension.decode('utf-8').rstrip() # Build the mex file mex = '"' + os.path.join(matlab_bin, "mex") + '"' diff --git a/messenger/mexa64/local.cfg b/messenger/mexa64/local.cfg deleted file mode 100644 index a9a742c..0000000 --- a/messenger/mexa64/local.cfg +++ /dev/null @@ -1,6 +0,0 @@ -MATLAB_BIN= -OCTAVE_INC=/usr/include -OCTAVE_LIB=/usr/lib/x86_64-linux-gnu/ -ZMQ_INC= -ZMQ_LIB= - diff --git a/messenger/mexmaci64/local.cfg b/messenger/mexmaci64/local.cfg deleted file mode 100644 index 138795a..0000000 --- a/messenger/mexmaci64/local.cfg +++ /dev/null @@ -1,5 +0,0 @@ -MATLAB_BIN= -ZMQ_INC= -ZMQ_LIB= -OCTAVE_INC= -OCTAVE_LIB= diff --git a/messenger/mexw64/local.cfg b/messenger/mexw64/local.cfg index ab61682..daf8ab6 100644 --- a/messenger/mexw64/local.cfg +++ b/messenger/mexw64/local.cfg @@ -1,4 +1,4 @@ -MATLAB_BIN="C:\Program Files\MATLAB\2013a\bin" +MATLAB_BIN="C:\Program Files\MATLAB\2014b\bin" OCTAVE_INC="C:\Octave\Octave-3.8.2\include\octave-3.8.2\octave" OCTAVE_LIB="C:\Octave\Octave-3.8.2\lib\octave\3.8.2" ZMQ_INC="C:\zeromq-4.0.5\include" From 388f95ad2f4e590580d52ce48765261251ecf9dc Mon Sep 17 00:00:00 2001 From: Sang Han Date: Thu, 26 Mar 2015 01:56:14 -0700 Subject: [PATCH 32/58] added get_matlab_env function --- messenger/settings.py | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/messenger/settings.py b/messenger/settings.py index c51e570..9f4c396 100644 --- a/messenger/settings.py +++ b/messenger/settings.py @@ -1,5 +1,6 @@ import os import platform +import subprocess from glob import glob @@ -8,7 +9,7 @@ except ImportError: from ConfigParser import ConfigParser -__all__= ['get_matlab_bin'] +__all__= ['get_matlab_bin', 'matlab_env'] def get_matlab_bin(config='config.ini'): """ @@ -49,3 +50,25 @@ def get_matlab_bin(config='config.ini'): return os.path.normpath(matlab) +def get_matlab_env(matlab='matlab'): + """ + Get's the underlying enviornement variables set for a matlab installation. + + Parameters + ========== + matlab: string + Path to the matlab binary executable. + If matlab is in the users $PATH, just pass 'matlab' + + Returns + ======= + enviornment: dictionary + Mapping of enviornment variable[s] + """ + command = ' '.join([matlab, '-e']), + process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE) + + envs = (line.decode('utf-8').strip() for line in process.stdout) + mapping = (env.split('=', maxsplit=1) for env in envs) + + return {key:value for key, value in mapping} From 6216fb598d79f807e1603b170081e3c838453696 Mon Sep 17 00:00:00 2001 From: Sang Han Date: Thu, 26 Mar 2015 13:07:44 -0700 Subject: [PATCH 33/58] function for fetching zmq source --- messenger/settings.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/messenger/settings.py b/messenger/settings.py index 9f4c396..d43b1b6 100644 --- a/messenger/settings.py +++ b/messenger/settings.py @@ -1,16 +1,22 @@ import os import platform import subprocess +import logging from glob import glob try: + from urllib.request import urlopen from configparser import ConfigParser except ImportError: + from urllib2 import urlopen from ConfigParser import ConfigParser __all__= ['get_matlab_bin', 'matlab_env'] +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + def get_matlab_bin(config='config.ini'): """ Tries to find the MATLAB bin directory independent on host platform. @@ -72,3 +78,27 @@ def get_matlab_env(matlab='matlab'): mapping = (env.split('=', maxsplit=1) for env in envs) return {key:value for key, value in mapping} + +def fetch_zmq(prefix, version=(4,0,5)): + """ + Download and extract libzmq + + Parameters + ========== + save: str + File Save Location + version: tuple + ZMQ Version Number + """ + logging.info('Downloading ZMQ Version %i.%i.%i' % version) + + url = "http://download.zeromq.org/zeromq-%i.%i.%i.tar.gz" % version + + name, msg = urlretrieve(url, url.rsplit('/')[-1]) + + logging.info('Extracting into prefix %s' % prefix) + with tarfile.open(name) as tar: + tar.extractall(prefix) + + os.remove(name) + logging.info('Download Complete') From f9eefb782c55d7722ea9a54c62e2267ca66be22f Mon Sep 17 00:00:00 2001 From: Sang Han Date: Thu, 26 Mar 2015 14:32:27 -0700 Subject: [PATCH 34/58] Fixed windows path --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 5bd58c1..4c79558 100644 --- a/.gitignore +++ b/.gitignore @@ -37,3 +37,5 @@ rebuildTags.sh # caused py setup.py develop pymatbridge.egg-info + +.idea/scopes/scope_settings.xml \ No newline at end of file From 5ea7faf8b6df1b11768bdf8fb238cfe00504dea9 Mon Sep 17 00:00:00 2001 From: Sang Han Date: Thu, 26 Mar 2015 15:41:27 -0700 Subject: [PATCH 35/58] commit --- messenger/settings.py | 25 ++++++++++++------------- setup.py | 10 +++++----- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/messenger/settings.py b/messenger/settings.py index d43b1b6..9f473d8 100644 --- a/messenger/settings.py +++ b/messenger/settings.py @@ -2,17 +2,18 @@ import platform import subprocess import logging +import tarfile from glob import glob try: - from urllib.request import urlopen + from urllib.request import urlretrieve from configparser import ConfigParser except ImportError: - from urllib2 import urlopen + from urllib2 import urlretrieve from ConfigParser import ConfigParser -__all__= ['get_matlab_bin', 'matlab_env'] +__all__= ['get_matlab_bin', 'get_matlab_env', 'fetch_zmq'] logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) @@ -58,7 +59,7 @@ def get_matlab_bin(config='config.ini'): def get_matlab_env(matlab='matlab'): """ - Get's the underlying enviornement variables set for a matlab installation. + Get the underlying environment variables set for a matlab installation. Parameters ========== @@ -68,8 +69,8 @@ def get_matlab_env(matlab='matlab'): Returns ======= - enviornment: dictionary - Mapping of enviornment variable[s] + environment: dictionary + Mapping of environment variable[s] """ command = ' '.join([matlab, '-e']), process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE) @@ -90,15 +91,13 @@ def fetch_zmq(prefix, version=(4,0,5)): version: tuple ZMQ Version Number """ - logging.info('Downloading ZMQ Version %i.%i.%i' % version) + logger.info('Downloading ZMQ Source Version %i.%i.%i' % version) + url = ("http://download.zeromq.org/zeromq-%i.%i.%i.tar.gz" % version) + name = urlretrieve(url, url.rsplit('/')[-1])[0] - url = "http://download.zeromq.org/zeromq-%i.%i.%i.tar.gz" % version - - name, msg = urlretrieve(url, url.rsplit('/')[-1]) - - logging.info('Extracting into prefix %s' % prefix) + logger.info('Extracting into prefix %s' % prefix) with tarfile.open(name) as tar: tar.extractall(prefix) - os.remove(name) logging.info('Download Complete') + os.remove(name) \ No newline at end of file diff --git a/setup.py b/setup.py index ae9622a..62048cf 100755 --- a/setup.py +++ b/setup.py @@ -2,18 +2,18 @@ """Setup file for python-matlab-bridge""" import os -import sys import shutil import glob # BEFORE importing distutils, remove MANIFEST. distutils doesn't properly # update it when the contents of directories change. -if os.path.exists('MANIFEST'): - os.remove('MANIFEST') +if os.path.exists('MANIFEST'): os.remove('MANIFEST') - -from distutils.core import setup +try: + from setuptools import setup +except ImportError: + from distutils.core import setup # Find the messenger binary file(s) and copy it to /matlab folder. From 3790ca32b99a5f546f1a7944024c5c99a3874da7 Mon Sep 17 00:00:00 2001 From: Sang Han Date: Thu, 26 Mar 2015 19:34:31 -0700 Subject: [PATCH 36/58] fixed bug with zip-safe --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index 62048cf..8e7c896 100755 --- a/setup.py +++ b/setup.py @@ -43,6 +43,7 @@ version=VERSION, packages=PACKAGES, package_data=PACKAGE_DATA, + zip_safe=False, requires=REQUIRES, #extras_require=EXTRAS_REQUIRE, scripts=BIN From b0a0de4d63197649ff223c19e2015e0491f42ddd Mon Sep 17 00:00:00 2001 From: Sang Han Date: Thu, 26 Mar 2015 19:40:01 -0700 Subject: [PATCH 37/58] cleanup --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 4c79558..6f374ea 100644 --- a/.gitignore +++ b/.gitignore @@ -38,4 +38,4 @@ rebuildTags.sh # caused py setup.py develop pymatbridge.egg-info -.idea/scopes/scope_settings.xml \ No newline at end of file +.idea/** From 7658bb4284bcc0c5b7f113d2ff68d52f2d085241 Mon Sep 17 00:00:00 2001 From: Sang Han Date: Thu, 26 Mar 2015 19:54:01 -0700 Subject: [PATCH 38/58] urllib can go die --- messenger/settings.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/messenger/settings.py b/messenger/settings.py index 9f473d8..0639f21 100644 --- a/messenger/settings.py +++ b/messenger/settings.py @@ -10,7 +10,7 @@ from urllib.request import urlretrieve from configparser import ConfigParser except ImportError: - from urllib2 import urlretrieve + from urllib import urlretrieve from ConfigParser import ConfigParser __all__= ['get_matlab_bin', 'get_matlab_env', 'fetch_zmq'] @@ -100,4 +100,4 @@ def fetch_zmq(prefix, version=(4,0,5)): tar.extractall(prefix) logging.info('Download Complete') - os.remove(name) \ No newline at end of file + os.remove(name) From 92ce4bb0a4a7e18f86441fd3642e4438fc2ddb8d Mon Sep 17 00:00:00 2001 From: Sang Han Date: Thu, 26 Mar 2015 22:46:19 -0700 Subject: [PATCH 39/58] get_config() now actually returns a dict for the host platform --- messenger/__init__.py | 3 +- messenger/__main__.py | 25 ++++++++-------- messenger/make.py | 67 ++++++++++++++++++++++++++++++++----------- messenger/settings.py | 58 ++++--------------------------------- 4 files changed, 70 insertions(+), 83 deletions(-) diff --git a/messenger/__init__.py b/messenger/__init__.py index c70020d..da40056 100644 --- a/messenger/__init__.py +++ b/messenger/__init__.py @@ -1 +1,2 @@ -from .settings import * \ No newline at end of file +from .settings import * +from .make import * \ No newline at end of file diff --git a/messenger/__main__.py b/messenger/__main__.py index ce3ef9c..456f855 100644 --- a/messenger/__main__.py +++ b/messenger/__main__.py @@ -1,3 +1,5 @@ +import sys + from argparse import ArgumentParser from .make import * @@ -10,8 +12,8 @@ def command_line(): ======= Namespace containing parsed arguments """ + parser = ArgumentParser(prog='messenger') - parser = ArgumentParser() parser.add_argument( "target", choices=["matlab", "octave"], @@ -21,20 +23,19 @@ def command_line(): parser.add_argument( "--static", action="store_true", - help="staticly link libzmq" + help="statically link libzmq" ) return parser.parse_args() - - def main(): - args = command_line() - if args.target == "matlab": - build_matlab(static=args.static) - elif args.target == "octave": - build_octave() - else: - raise ValueError() + args = command_line() + build = { + 'matlab': build_matlab, + 'octave': build_octave, + } + target = build[args.target] + + return target(static=args.static) if __name__ == '__main__': - main() + sys.exit(main()) diff --git a/messenger/make.py b/messenger/make.py index e77105a..a430e1e 100644 --- a/messenger/make.py +++ b/messenger/make.py @@ -6,8 +6,7 @@ import shutil import subprocess import platform - -from glob import glob +import glob try: from ConfigParser import ConfigParser @@ -18,6 +17,7 @@ __all__ = [ 'get_messenger_dir', + 'get_matlab_bin' 'get_config', 'do_build', 'build_octave', @@ -37,12 +37,12 @@ def get_messenger_dir(): return ostype[host] if is_64bit else 'mexw32' -def get_config(): - config = os.path.join(os.path.realpath(__file__), 'config.ini') - print(config) +def get_config(host, config='config.ini'): + cfg = ConfigParser() - config.read(config) - return cfg + cfg.read(config) + + return dict(cfg.items(host)) def do_build(make_cmd, messenger_exe): @@ -59,9 +59,9 @@ def do_build(make_cmd, messenger_exe): os.remove('messenger.o') -def build_octave(): +def build_octave(static=False): paths = "-L%(octave_lib)s -I%(octave_inc)s -L%(zmq_lib)s -I%(zmq_inc)s" - paths = paths % get_config() + paths = paths % get_config(platform.system()) make_cmd = "mkoctfile --mex %s -lzmq ./src/messenger.c" % paths do_build(make_cmd, 'messenger.mex') @@ -77,13 +77,7 @@ def build_matlab(static=False): If so, it will append the command line option -DZMQ_STATIC when compiling the mex so it matches libzmq. """ - matlab_bin = settings.get_matlab_bin() - cfg, host = ConfigParser(), platform.system() - cfg.read('config.ini') - libzmq = { - 'zmq_lib': os.path.normpath(cfg.get(host, 'ZMQ_LIB')), - 'zmq_inc': os.path.normpath(cfg.get(host, 'ZMQ_INC')), - } + matlab_bin, cfg = settings.get_matlab_bin(), get_config(platform.system()) extcmd = '%s' % os.path.join(matlab_bin, "mexext") extension = subprocess.check_output(extcmd, shell=True) @@ -91,10 +85,49 @@ def build_matlab(static=False): # Build the mex file mex = '"' + os.path.join(matlab_bin, "mex") + '"' - paths = "-L'%(zmq_lib)s' -I'%(zmq_inc)s'" % libzmq + paths = "-L'%(zmq_lib)s' -I'%(zmq_inc)s'" % cfg make_cmd = '%s -O %s -lzmq messenger/src/messenger.c' % (mex, paths) if static: make_cmd += ' -DZMQ_STATIC' do_build(make_cmd, 'messenger.%s' % extension) + + +def get_matlab_bin(config='config.ini'): + """ + Tries to find the MATLAB bin directory independent on host platform. + The operation of this function can be overridden by setting the MATLAB_BIN + variable within the configuration file specified. + + Parameters + -========= + config: + Relative path to configuration file + + Returns + ======= + matlab: + Absolute path to matlab bin directory + """ + host = platform.system() + cfg = get_config(host) + programs = { + 'Darwin' : r'/Applications', + 'Windows': r'C:/Program Files', + 'Linux' : r'/usr/local', + } + + if cfg.get('MATLAB_BIN', None): + matlab = cfg['MATLAB_BIN'] + else: + # Searches for Matlab bin if it's not set + _root = glob.glob(r'%s/MATLAB*' % programs[host])[0] + _version = [p for p in os.listdir(_root) if p.startswith('R20')] + if _version: + _root = r'%s/%s' % (_root, _version.pop()) + matlab = r'%s/%s' % (_root, 'bin') + + assert os.path.isdir(matlab) + + return os.path.normpath(matlab) diff --git a/messenger/settings.py b/messenger/settings.py index 0639f21..a650350 100644 --- a/messenger/settings.py +++ b/messenger/settings.py @@ -1,61 +1,14 @@ import os -import platform import subprocess import logging import tarfile -from glob import glob - try: from urllib.request import urlretrieve - from configparser import ConfigParser except ImportError: from urllib import urlretrieve - from ConfigParser import ConfigParser - -__all__= ['get_matlab_bin', 'get_matlab_env', 'fetch_zmq'] - -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger(__name__) - -def get_matlab_bin(config='config.ini'): - """ - Tries to find the MATLAB bin directory independent on host platform. - The operation of this function can be overridden by setting the MATLAB_BIN - variable within the configuration file specified. - - Parameters - -========= - config: - Relative path to configuration file - - Returns - ======= - matlab: - Absolute path to matlab bin directory - """ - cfg, host = ConfigParser(), platform.system() - cfg.read(os.path.join(__file__, config)) - - programs = { - 'Darwin' : r'/Applications', - 'Windows': r'C:/Program Files', - 'Linux' : r'/usr/local', - } - - if cfg.has_option(host, 'MATLAB_BIN'): - matlab = cfg.get(host, 'MATLAB_BIN') - else: - # Searches for Matlab bin if it's not set - _root = glob(r'%s/MATLAB*' % programs[host])[0] - _version = [p for p in os.listdir(_root) if p.startswith('R20')] - if any(_version): - _root = r'%s/%s' % (_root, _version.pop()) - matlab = r'%s/%s' % (_root, 'bin') - - assert os.path.isdir(matlab) - return os.path.normpath(matlab) +__all__= ['get_matlab_env', 'fetch_zmq'] def get_matlab_env(matlab='matlab'): """ @@ -76,9 +29,8 @@ def get_matlab_env(matlab='matlab'): process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE) envs = (line.decode('utf-8').strip() for line in process.stdout) - mapping = (env.split('=', maxsplit=1) for env in envs) - return {key:value for key, value in mapping} + return dict(env.split('=', maxsplit=1) for env in envs) def fetch_zmq(prefix, version=(4,0,5)): """ @@ -91,13 +43,13 @@ def fetch_zmq(prefix, version=(4,0,5)): version: tuple ZMQ Version Number """ - logger.info('Downloading ZMQ Source Version %i.%i.%i' % version) + print('Downloading ZMQ Source Version %i.%i.%i' % version) url = ("http://download.zeromq.org/zeromq-%i.%i.%i.tar.gz" % version) name = urlretrieve(url, url.rsplit('/')[-1])[0] - logger.info('Extracting into prefix %s' % prefix) + print('Extracting into prefix %s' % prefix) with tarfile.open(name) as tar: tar.extractall(prefix) - logging.info('Download Complete') + print('Download Complete') os.remove(name) From 84a40fe55cd70776d4089a90ef9067d9ae08c38f Mon Sep 17 00:00:00 2001 From: Sang Han Date: Thu, 26 Mar 2015 22:52:47 -0700 Subject: [PATCH 40/58] oops forgot a comma --- messenger/make.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/messenger/make.py b/messenger/make.py index a430e1e..eab158c 100644 --- a/messenger/make.py +++ b/messenger/make.py @@ -17,7 +17,7 @@ __all__ = [ 'get_messenger_dir', - 'get_matlab_bin' + 'get_matlab_bin', 'get_config', 'do_build', 'build_octave', From a2f65e769b5f02b9f4b1a3a82ba3782323481825 Mon Sep 17 00:00:00 2001 From: Sang Han Date: Thu, 26 Mar 2015 22:46:19 -0700 Subject: [PATCH 41/58] get_config() now actually returns a dict for the host platform --- messenger/settings.py | 46 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/messenger/settings.py b/messenger/settings.py index a650350..974709a 100644 --- a/messenger/settings.py +++ b/messenger/settings.py @@ -1,12 +1,54 @@ import os import subprocess -import logging import tarfile +from glob import glob + try: from urllib.request import urlretrieve + from configparser import ConfigParser except ImportError: from urllib import urlretrieve + from ConfigParser import ConfigParser + +__all__= ['get_matlab_bin', 'get_matlab_env', 'fetch_zmq'] + +def get_matlab_bin(config='config.ini'): + """ + Tries to find the MATLAB bin directory independent on host platform. + The operation of this function can be overridden by setting the MATLAB_BIN + variable within the configuration file specified. + + Parameters + -========= + config: + Relative path to configuration file + + Returns + ======= + matlab: + Absolute path to matlab bin directory + """ + cfg, host = ConfigParser(), platform.system() + cfg.read(os.path.join(__file__, config)) + + programs = { + 'Darwin' : r'/Applications', + 'Windows': r'C:/Program Files', + 'Linux' : r'/usr/local', + } + + if cfg.has_option(host, 'MATLAB_BIN'): + matlab = cfg.get(host, 'MATLAB_BIN') + else: + # Searches for Matlab bin if it's not set + _root = glob(r'%s/MATLAB*' % programs[host])[0] + _version = [p for p in os.listdir(_root) if p.startswith('R20')] + if any(_version): + _root = r'%s/%s' % (_root, _version.pop()) + matlab = r'%s/%s' % (_root, 'bin') + + assert os.path.isdir(matlab) __all__= ['get_matlab_env', 'fetch_zmq'] @@ -43,7 +85,7 @@ def fetch_zmq(prefix, version=(4,0,5)): version: tuple ZMQ Version Number """ - print('Downloading ZMQ Source Version %i.%i.%i' % version) + print('Downloading ZMQ Source Version %i.%i.%i' % version) url = ("http://download.zeromq.org/zeromq-%i.%i.%i.tar.gz" % version) name = urlretrieve(url, url.rsplit('/')[-1])[0] From f8798660f8f23f97522f8d36fefb668153680904 Mon Sep 17 00:00:00 2001 From: Sang Han Date: Mon, 30 Mar 2015 00:58:35 -0700 Subject: [PATCH 42/58] Use platform.machine().endswith(64) over sys.maxsize --- .gitignore | 2 +- messenger/make.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 6f374ea..4c79558 100644 --- a/.gitignore +++ b/.gitignore @@ -38,4 +38,4 @@ rebuildTags.sh # caused py setup.py develop pymatbridge.egg-info -.idea/** +.idea/scopes/scope_settings.xml \ No newline at end of file diff --git a/messenger/make.py b/messenger/make.py index eab158c..422702b 100644 --- a/messenger/make.py +++ b/messenger/make.py @@ -25,7 +25,7 @@ ] def get_messenger_dir(): - host, is_64bit = platform.system(), sys.maxsize > 2**32 + host, is_64bit = platform.system(), platform.machine().endswith('64') ostype = { 'Darwin': 'mexmaci64', 'Linux': 'mexa64', From 5bb4fef40d6d164c3e43dbabfccdf6d5ce79696d Mon Sep 17 00:00:00 2001 From: Sang Han Date: Mon, 30 Mar 2015 01:08:55 -0700 Subject: [PATCH 43/58] fixed docstring to fit scipy spec --- messenger/__main__.py | 2 +- messenger/make.py | 11 ++++---- messenger/settings.py | 61 +++++++------------------------------------ setup.py | 3 ++- 4 files changed, 19 insertions(+), 58 deletions(-) diff --git a/messenger/__main__.py b/messenger/__main__.py index 456f855..5820228 100644 --- a/messenger/__main__.py +++ b/messenger/__main__.py @@ -9,7 +9,7 @@ def command_line(): Manages command line arguments. Returns - ======= + ------- Namespace containing parsed arguments """ parser = ArgumentParser(prog='messenger') diff --git a/messenger/make.py b/messenger/make.py index 422702b..37d23f7 100644 --- a/messenger/make.py +++ b/messenger/make.py @@ -71,7 +71,7 @@ def build_matlab(static=False): Build the messenger mex for MATLAB Parameters - ============ + ---------- static : bool Determines if the zmq library has been statically linked. If so, it will append the command line option -DZMQ_STATIC @@ -101,13 +101,13 @@ def get_matlab_bin(config='config.ini'): variable within the configuration file specified. Parameters - -========= - config: + ---------- + config: str Relative path to configuration file Returns - ======= - matlab: + ------- + matlab: str Absolute path to matlab bin directory """ host = platform.system() @@ -131,3 +131,4 @@ def get_matlab_bin(config='config.ini'): assert os.path.isdir(matlab) return os.path.normpath(matlab) + diff --git a/messenger/settings.py b/messenger/settings.py index 974709a..477be1e 100644 --- a/messenger/settings.py +++ b/messenger/settings.py @@ -2,70 +2,28 @@ import subprocess import tarfile -from glob import glob - try: from urllib.request import urlretrieve - from configparser import ConfigParser except ImportError: from urllib import urlretrieve - from ConfigParser import ConfigParser __all__= ['get_matlab_bin', 'get_matlab_env', 'fetch_zmq'] -def get_matlab_bin(config='config.ini'): - """ - Tries to find the MATLAB bin directory independent on host platform. - The operation of this function can be overridden by setting the MATLAB_BIN - variable within the configuration file specified. - - Parameters - -========= - config: - Relative path to configuration file - - Returns - ======= - matlab: - Absolute path to matlab bin directory - """ - cfg, host = ConfigParser(), platform.system() - cfg.read(os.path.join(__file__, config)) - - programs = { - 'Darwin' : r'/Applications', - 'Windows': r'C:/Program Files', - 'Linux' : r'/usr/local', - } - - if cfg.has_option(host, 'MATLAB_BIN'): - matlab = cfg.get(host, 'MATLAB_BIN') - else: - # Searches for Matlab bin if it's not set - _root = glob(r'%s/MATLAB*' % programs[host])[0] - _version = [p for p in os.listdir(_root) if p.startswith('R20')] - if any(_version): - _root = r'%s/%s' % (_root, _version.pop()) - matlab = r'%s/%s' % (_root, 'bin') - - assert os.path.isdir(matlab) - -__all__= ['get_matlab_env', 'fetch_zmq'] def get_matlab_env(matlab='matlab'): """ Get the underlying environment variables set for a matlab installation. Parameters - ========== - matlab: string + ---------- + matlab: str Path to the matlab binary executable. If matlab is in the users $PATH, just pass 'matlab' Returns - ======= - environment: dictionary - Mapping of environment variable[s] + ------- + environment: dict + Mapping of environment variable """ command = ' '.join([matlab, '-e']), process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE) @@ -74,18 +32,19 @@ def get_matlab_env(matlab='matlab'): return dict(env.split('=', maxsplit=1) for env in envs) + def fetch_zmq(prefix, version=(4,0,5)): """ - Download and extract libzmq + Download and extract libzmq into `prefix` Parameters - ========== + ---------- save: str File Save Location - version: tuple + version: 3-tuple ZMQ Version Number """ - print('Downloading ZMQ Source Version %i.%i.%i' % version) + print('Downloading ZMQ Source Version %i.%i.%i' % version) url = ("http://download.zeromq.org/zeromq-%i.%i.%i.tar.gz" % version) name = urlretrieve(url, url.rsplit('/')[-1])[0] diff --git a/setup.py b/setup.py index 8e7c896..bd2cf6d 100755 --- a/setup.py +++ b/setup.py @@ -8,7 +8,8 @@ # BEFORE importing distutils, remove MANIFEST. distutils doesn't properly # update it when the contents of directories change. -if os.path.exists('MANIFEST'): os.remove('MANIFEST') +if os.path.exists('MANIFEST'): + os.remove('MANIFEST') try: from setuptools import setup From 9627cceb8bbc5da1f00692313bf49626b7365808 Mon Sep 17 00:00:00 2001 From: Sang Han Date: Mon, 30 Mar 2015 02:08:33 -0700 Subject: [PATCH 44/58] added tests for messenger functions --- messenger/make.py | 2 +- messenger/tests/test_env.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 messenger/tests/test_env.py diff --git a/messenger/make.py b/messenger/make.py index 37d23f7..485262c 100644 --- a/messenger/make.py +++ b/messenger/make.py @@ -111,7 +111,7 @@ def get_matlab_bin(config='config.ini'): Absolute path to matlab bin directory """ host = platform.system() - cfg = get_config(host) + cfg = get_config(host,config=config) programs = { 'Darwin' : r'/Applications', 'Windows': r'C:/Program Files', diff --git a/messenger/tests/test_env.py b/messenger/tests/test_env.py new file mode 100644 index 0000000..404e69a --- /dev/null +++ b/messenger/tests/test_env.py @@ -0,0 +1,31 @@ +import numpy.testing as npt +import sys +import os + +ROOT = os.path.join(os.path.dirname(__file__), '..', '..') + +# Necessary since messenger is not installed with pymatbridge +sys.path.append(ROOT) + +import messenger + +def test_matlab_bin(): + config = os.path.join(ROOT, 'config.ini') + npt.assert_equal(os.path.isfile(config), True) + bin = messenger.get_matlab_bin(config=config) + npt.assert_equal(os.path.isdir(bin), True) + + mexext = any(m for m in os.listdir(bin) if m == 'mexext' or m == 'mexext.exe') + mex = any(m for m in os.listdir(bin) if m == 'mex' or m == 'mex.exe') + + npt.assert_equal(mexext, True) + npt.assert_equal(mex, True) + +def test_matlab_env(): + config = os.path.join(ROOT, 'config.ini') + matlab = os.path.join(messenger.get_matlab_bin(config=config), 'matlab') + env = messenger.get_matlab_env(matlab=matlab) + arch = env['ARCH'] + + npt.assert_equal(arch.endswith(messenger.get_messenger_dir()[-2:]), True) + From 901fe1f521ca89496235c6290f28b16f00eba6bb Mon Sep 17 00:00:00 2001 From: Sang Han Date: Mon, 30 Mar 2015 02:25:51 -0700 Subject: [PATCH 45/58] python 2 glob issue --- messenger/make.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/messenger/make.py b/messenger/make.py index 485262c..3ba68c3 100644 --- a/messenger/make.py +++ b/messenger/make.py @@ -111,7 +111,7 @@ def get_matlab_bin(config='config.ini'): Absolute path to matlab bin directory """ host = platform.system() - cfg = get_config(host,config=config) + cfg = get_config(host, config=config) programs = { 'Darwin' : r'/Applications', 'Windows': r'C:/Program Files', @@ -122,7 +122,7 @@ def get_matlab_bin(config='config.ini'): matlab = cfg['MATLAB_BIN'] else: # Searches for Matlab bin if it's not set - _root = glob.glob(r'%s/MATLAB*' % programs[host])[0] + _root = [os.path.join(programs[host], p) for p in os.listdir(programs[host]) if p.startswith('MATLAB')][0] _version = [p for p in os.listdir(_root) if p.startswith('R20')] if _version: _root = r'%s/%s' % (_root, _version.pop()) From 7f329b854e3c75d18e311bef36cc472f9a700372 Mon Sep 17 00:00:00 2001 From: Sang Han Date: Mon, 30 Mar 2015 20:49:54 -0700 Subject: [PATCH 46/58] python 2 strings do not have maxsplit kwarg, use string module split --- messenger/settings.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/messenger/settings.py b/messenger/settings.py index 477be1e..9b4969c 100644 --- a/messenger/settings.py +++ b/messenger/settings.py @@ -1,6 +1,7 @@ import os import subprocess import tarfile +import string try: from urllib.request import urlretrieve @@ -30,7 +31,7 @@ def get_matlab_env(matlab='matlab'): envs = (line.decode('utf-8').strip() for line in process.stdout) - return dict(env.split('=', maxsplit=1) for env in envs) + return dict(string.split(env, '=', maxsplit=1) for env in envs) def fetch_zmq(prefix, version=(4,0,5)): From b0b02051fbb2faed969fc9004f68c7a1f881ffbf Mon Sep 17 00:00:00 2001 From: Sang Han Date: Mon, 30 Mar 2015 21:29:04 -0700 Subject: [PATCH 47/58] tests validate that builds are possible rather than anticipate for all builds --- messenger/make.py | 19 ++++++++++++------- messenger/settings.py | 5 +++-- messenger/tests/test_env.py | 20 ++++++++++++-------- 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/messenger/make.py b/messenger/make.py index 3ba68c3..6361070 100644 --- a/messenger/make.py +++ b/messenger/make.py @@ -107,8 +107,9 @@ def get_matlab_bin(config='config.ini'): Returns ------- - matlab: str - Absolute path to matlab bin directory + matlab: str or None + Absolute path to matlab bin directory. + Returns None if Matlab path could not be determined """ host = platform.system() cfg = get_config(host, config=config) @@ -122,13 +123,17 @@ def get_matlab_bin(config='config.ini'): matlab = cfg['MATLAB_BIN'] else: # Searches for Matlab bin if it's not set - _root = [os.path.join(programs[host], p) for p in os.listdir(programs[host]) if p.startswith('MATLAB')][0] - _version = [p for p in os.listdir(_root) if p.startswith('R20')] + matlab = [p for p in os.listdir(programs[host]) if p.startswith('MATLAB')] + + if not matlab: + return None + + _version = [p for p in os.listdir(os.path.join(programs[host], *matlab)) if p.startswith('R20')] + if _version: - _root = r'%s/%s' % (_root, _version.pop()) - matlab = r'%s/%s' % (_root, 'bin') + matlab = r'%s/%s' % (matlab, _version.pop()) - assert os.path.isdir(matlab) + matlab = r'%s/%s' % (matlab, 'bin') return os.path.normpath(matlab) diff --git a/messenger/settings.py b/messenger/settings.py index 9b4969c..81b60b7 100644 --- a/messenger/settings.py +++ b/messenger/settings.py @@ -1,12 +1,13 @@ import os import subprocess import tarfile -import string -try: +try: # Python 3 Compat from urllib.request import urlretrieve + string = str except ImportError: from urllib import urlretrieve + import string __all__= ['get_matlab_bin', 'get_matlab_env', 'fetch_zmq'] diff --git a/messenger/tests/test_env.py b/messenger/tests/test_env.py index 404e69a..d858e94 100644 --- a/messenger/tests/test_env.py +++ b/messenger/tests/test_env.py @@ -9,21 +9,25 @@ import messenger +CONFIG = os.path.join(ROOT, 'config.ini') +BIN = messenger.get_matlab_bin(config=CONFIG) + +def test_config(): + npt.assert_equal(os.path.isfile(CONFIG), True) + +@npt.decorators.skipif(BIN==None, 'No Matlab Installed') def test_matlab_bin(): - config = os.path.join(ROOT, 'config.ini') - npt.assert_equal(os.path.isfile(config), True) - bin = messenger.get_matlab_bin(config=config) - npt.assert_equal(os.path.isdir(bin), True) + npt.assert_equal(os.path.isdir(BIN), True) - mexext = any(m for m in os.listdir(bin) if m == 'mexext' or m == 'mexext.exe') - mex = any(m for m in os.listdir(bin) if m == 'mex' or m == 'mex.exe') + mexext = any(m for m in os.listdir(BIN) if m == 'mexext' or m == 'mexext.exe') + mex = any(m for m in os.listdir(BIN) if m == 'mex' or m == 'mex.exe') npt.assert_equal(mexext, True) npt.assert_equal(mex, True) +@npt.decorators.skipif(BIN==None, 'No Matlab Installed') def test_matlab_env(): - config = os.path.join(ROOT, 'config.ini') - matlab = os.path.join(messenger.get_matlab_bin(config=config), 'matlab') + matlab = os.path.join(messenger.get_matlab_bin(config=CONFIG), 'matlab') env = messenger.get_matlab_env(matlab=matlab) arch = env['ARCH'] From 45a4274f26d351375b54ed01af00932f65ecd823 Mon Sep 17 00:00:00 2001 From: Sang Han Date: Tue, 31 Mar 2015 05:42:10 -0700 Subject: [PATCH 48/58] small bug in get_matlab_dir() --- messenger/make.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/messenger/make.py b/messenger/make.py index 6361070..fb50987 100644 --- a/messenger/make.py +++ b/messenger/make.py @@ -7,6 +7,7 @@ import subprocess import platform import glob +import operator try: from ConfigParser import ConfigParser @@ -128,12 +129,10 @@ def get_matlab_bin(config='config.ini'): if not matlab: return None - _version = [p for p in os.listdir(os.path.join(programs[host], *matlab)) if p.startswith('R20')] + for p in os.listdir(os.path.join(programs[host], *matlab)): + if p.startswith('R20'): + matlab.append(p) - if _version: - matlab = r'%s/%s' % (matlab, _version.pop()) - - matlab = r'%s/%s' % (matlab, 'bin') - - return os.path.normpath(matlab) + matlab.append('bin') + return os.path.normpath(os.path.join(programs[host], *matlab)) From 8c560f0de3fbd02637702610b2c2308fcbadb2db Mon Sep 17 00:00:00 2001 From: Sang Han Date: Fri, 10 Apr 2015 19:44:32 -0700 Subject: [PATCH 49/58] octave build works --- config.ini | 4 +-- messenger/make.py | 88 +++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 80 insertions(+), 12 deletions(-) diff --git a/config.ini b/config.ini index 9a1cdae..26cb7fa 100644 --- a/config.ini +++ b/config.ini @@ -1,7 +1,7 @@ [Darwin] ; MATLAB_BIN=Applications/MATLAB_R2014a.app/bin -; OCTAVE_INC= -; OCTAVE_LIB= +OCTAVE_INC=/usr/local/Cellar/octave/3.8.2/include/octave-3.8.2/octave +OCTAVE_LIB=/usr/local/Cellar/octave/3.8.2/lib/octave/3.8.2 ZMQ_INC=/usr/local/include ZMQ_LIB=/usr/local/lib diff --git a/messenger/make.py b/messenger/make.py index fb50987..5bbd3cf 100644 --- a/messenger/make.py +++ b/messenger/make.py @@ -22,9 +22,70 @@ 'get_config', 'do_build', 'build_octave', - 'build_matlab' + 'build_matlab', + 'split_command_line', ] +def split_command_line(command_line): + + '''This splits a command line into a list of arguments. It splits arguments + on spaces, but handles embedded quotes, doublequotes, and escaped + characters. It's impossible to do this with a regular expression, so I + wrote a little state machine to parse the command line. ''' + + arg_list = [] + arg = '' + + # Constants to name the states we can be in. + state_basic = 0 + state_esc = 1 + state_singlequote = 2 + state_doublequote = 3 + # The state when consuming whitespace between commands. + state_whitespace = 4 + state = state_basic + + for c in command_line: + if state == state_basic or state == state_whitespace: + if c == '\\': + # Escape the next character + state = state_esc + elif c == r"'": + # Handle single quote + state = state_singlequote + elif c == r'"': + # Handle double quote + state = state_doublequote + elif c.isspace(): + # Add arg to arg_list if we aren't in the middle of whitespace. + if state == state_whitespace: + # Do nothing. + None + else: + arg_list.append(arg) + arg = '' + state = state_whitespace + else: + arg = arg + c + state = state_basic + elif state == state_esc: + arg = arg + c + state = state_basic + elif state == state_singlequote: + if c == r"'": + state = state_basic + else: + arg = arg + c + elif state == state_doublequote: + if c == r'"': + state = state_basic + else: + arg = arg + c + + if arg != '': + arg_list.append(arg) + return arg_list + def get_messenger_dir(): host, is_64bit = platform.system(), platform.machine().endswith('64') ostype = { @@ -47,10 +108,14 @@ def get_config(host, config='config.ini'): def do_build(make_cmd, messenger_exe): + + messenger_dir = get_messenger_dir() + use_shell = sys.platform.startswith('win32') + print('Building %s...' % messenger_exe) print(make_cmd) - messenger_dir = get_messenger_dir() - subprocess.call(shlex.split(make_cmd), stderr=subprocess.STDOUT) + + subprocess.check_output(make_cmd, shell=use_shell) messenger_loc = os.path.join(messenger_dir, messenger_exe) @@ -61,10 +126,12 @@ def do_build(make_cmd, messenger_exe): def build_octave(static=False): + paths = "-L%(octave_lib)s -I%(octave_inc)s -L%(zmq_lib)s -I%(zmq_inc)s" paths = paths % get_config(platform.system()) - make_cmd = "mkoctfile --mex %s -lzmq ./src/messenger.c" % paths - do_build(make_cmd, 'messenger.mex') + make_cmd = "mkoctfile --mex %s -lzmq messenger/src/messenger.c" % paths + + do_build(split_command_line(make_cmd), 'messenger.mex') def build_matlab(static=False): @@ -78,21 +145,22 @@ def build_matlab(static=False): If so, it will append the command line option -DZMQ_STATIC when compiling the mex so it matches libzmq. """ - matlab_bin, cfg = settings.get_matlab_bin(), get_config(platform.system()) + matlab_bin, cfg = get_matlab_bin(), get_config(platform.system()) - extcmd = '%s' % os.path.join(matlab_bin, "mexext") - extension = subprocess.check_output(extcmd, shell=True) + use_shell = sys.platform.startswith('win32') + extcmd = split_command_line(os.path.join(matlab_bin, "mexext")) + extension = subprocess.check_output(extcmd, shell=use_shell) extension = extension.decode('utf-8').rstrip() # Build the mex file - mex = '"' + os.path.join(matlab_bin, "mex") + '"' + mex = os.path.join(matlab_bin, "mex") paths = "-L'%(zmq_lib)s' -I'%(zmq_inc)s'" % cfg make_cmd = '%s -O %s -lzmq messenger/src/messenger.c' % (mex, paths) if static: make_cmd += ' -DZMQ_STATIC' - do_build(make_cmd, 'messenger.%s' % extension) + do_build(split_command_line(make_cmd), 'messenger.%s' % extension) def get_matlab_bin(config='config.ini'): From 83ffc35924f1902bb9a7191979be39f9f4527814 Mon Sep 17 00:00:00 2001 From: Sang Han Date: Sun, 12 Apr 2015 10:06:34 -0700 Subject: [PATCH 50/58] and the epic rebasing continues intensifies --- messenger/make.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/messenger/make.py b/messenger/make.py index 5bbd3cf..09064dc 100644 --- a/messenger/make.py +++ b/messenger/make.py @@ -27,12 +27,12 @@ ] def split_command_line(command_line): - - '''This splits a command line into a list of arguments. It splits arguments - on spaces, but handles embedded quotes, doublequotes, and escaped + """ + This splits a command line into a list of arguments. It splits arguments + on spaces, but handles embedded quotes, double quotes, and escaped characters. It's impossible to do this with a regular expression, so I - wrote a little state machine to parse the command line. ''' - + wrote a little state machine to parse the command line. + """ arg_list = [] arg = '' From b8448173783c7cd4434c42c7797a6f87368df160 Mon Sep 17 00:00:00 2001 From: Sang Han Date: Fri, 27 Mar 2015 05:50:54 -0700 Subject: [PATCH 51/58] cherry-picking setuptools related commits Decided to start implementing the big merge with setuptools over current tools consolidated in the messenger module. Hooking into setuptools allows for automatic discovery of requirements and the ability to fine tune almost every aspects of the build process. --- LICENSE | 30 +++++++++++++ pymatbridge/__init__.py | 4 +- pymatbridge/__version__.py | 3 ++ pymatbridge/version.py | 90 -------------------------------------- setup.py | 80 +++++++++++++++++++-------------- version.py | 1 + 6 files changed, 83 insertions(+), 125 deletions(-) create mode 100644 pymatbridge/__version__.py delete mode 100644 pymatbridge/version.py create mode 120000 version.py diff --git a/LICENSE b/LICENSE index d3632fc..2759572 100644 --- a/LICENSE +++ b/LICENSE @@ -1,3 +1,33 @@ +Pymatbridge +=========== + +A python interface to call out to Matlab(R). + + +License information +=================== + +Copyright (c) 2012 -- , Max Jaderberg, Ariel Rokem, Haoxing Zhao +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +Redistributions in binary form must reproduce the above copyright notice, this +list of conditions and the following disclaimer in the documentation and/or +other materials provided with the distribution. + +Neither the name of the Oxford University, Stanford University nor the names of +its contributors may be used to endorse or promote products derived from this +software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Copyright (c) 2013. See "Contributors". MATLAB (R) is copyright of the Mathworks. All rights reserved. diff --git a/pymatbridge/__init__.py b/pymatbridge/__init__.py index 45d2145..bc6b244 100644 --- a/pymatbridge/__init__.py +++ b/pymatbridge/__init__.py @@ -1,5 +1,6 @@ from .pymatbridge import * -from .version import __version__ +from .__version__ import __version__ +from .__version__ import __build__ try: from .publish import * @@ -10,3 +11,4 @@ from .matlab_magic import * except ImportError: pass + diff --git a/pymatbridge/__version__.py b/pymatbridge/__version__.py new file mode 100644 index 0000000..ec2406a --- /dev/null +++ b/pymatbridge/__version__.py @@ -0,0 +1,3 @@ +__version__ = '0.5.0' +__build__ = 'dev' + diff --git a/pymatbridge/version.py b/pymatbridge/version.py deleted file mode 100644 index 0b9ef31..0000000 --- a/pymatbridge/version.py +++ /dev/null @@ -1,90 +0,0 @@ -"""pymatbridge version/release information""" - -# Format expected by setup.py and doc/source/conf.py: string of form "X.Y.Z" -_version_major = 0 -_version_minor = 5 -_version_micro = 0 #'' # use '' for first of series, number for 1 and above -_version_extra = 'dev' -#_version_extra = '' # Uncomment this for full releases - -# Construct full version string from these. -_ver = [_version_major, _version_minor] -if _version_micro: - _ver.append(_version_micro) -if _version_extra: - _ver.append(_version_extra) - -__version__ = '.'.join(map(str, _ver)) - -CLASSIFIERS = ["Development Status :: 3 - Alpha", - "Environment :: Console", - "Intended Audience :: Science/Research", - "License :: OSI Approved :: BSD License", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Topic :: Scientific/Engineering"] - -description = "pymatbridge is a set of python and matlab functions to allow these two systems to talk to each other" - -long_description = """ - -Pymatbridge -=========== - -A python interface to call out to Matlab(R). - - -License information -=================== - -Copyright (c) 2012 -- , Max Jaderberg, Ariel Rokem, Haoxing Zhao -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this -list of conditions and the following disclaimer. - -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. - -Neither the name of the Oxford University, Stanford University nor the names of -its contributors may be used to endorse or promote products derived from this -software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -""" - -NAME = "pymatbridge" -MAINTAINER = "Ariel Rokem" -MAINTAINER_EMAIL = "arokem@gmail.com" -DESCRIPTION = description -LONG_DESCRIPTION = long_description -URL = "https://github.com/arokem/python-matlab-bridge" -DOWNLOAD_URL = "https://github.com/arokem/python-matlab-bridge/archive/master.tar.gz" -LICENSE = "BSD" -AUTHOR = "https://github.com/arokem/python-matlab-bridge/contributors" -AUTHOR_EMAIL = "arokem@gmail.com" -PLATFORMS = "OS Independent" -MAJOR = _version_major -MINOR = _version_minor -MICRO = _version_micro -VERSION = __version__ -PACKAGES = ['pymatbridge'] -PACKAGE_DATA = {"pymatbridge": ["matlab/matlabserver.m", "matlab/messenger.*", - "matlab/usrprog/*", "matlab/util/*.m", - "matlab/util/json_v0.2.2/LICENSE", - "matlab/util/json_v0.2.2/README.md", - "matlab/util/json_v0.2.2/test/*", - "matlab/util/json_v0.2.2/json/*.m", - "matlab/util/json_v0.2.2/json/java/*", - "tests/*.py", "examples/*.ipynb"]} - -REQUIRES = ['pyzmq'] -#EXTRAS_REQUIRE = ['numpy', 'scipy', 'ipython'] - -BIN=['scripts/publish-notebook'] diff --git a/setup.py b/setup.py index bd2cf6d..efa1ee5 100755 --- a/setup.py +++ b/setup.py @@ -1,11 +1,12 @@ -#!/usr/bin/env python -"""Setup file for python-matlab-bridge""" +# -*- coding: utf-8 -*- +""" +Pymatbridge: A python interface to call out to Matlab(R) +""" import os import shutil import glob - # BEFORE importing distutils, remove MANIFEST. distutils doesn't properly # update it when the contents of directories change. if os.path.exists('MANIFEST'): @@ -16,41 +17,52 @@ except ImportError: from distutils.core import setup - # Find the messenger binary file(s) and copy it to /matlab folder. from messenger.make import get_messenger_dir -messenger_dir = get_messenger_dir() +from version import __version__, __build__ -for f in glob.glob("./messenger/%s/messenger.*" % messenger_dir): +for f in glob.glob("./messenger/%s/messenger.*" % get_messenger_dir()): shutil.copy(f, "./pymatbridge/matlab") - -# Get version and release info, which is all stored in pymatbridge/version.py -ver_file = os.path.join('pymatbridge', 'version.py') -exec(open(ver_file).read()) - -opts = dict(name=NAME, - maintainer=MAINTAINER, - maintainer_email=MAINTAINER_EMAIL, - description=DESCRIPTION, - long_description=LONG_DESCRIPTION, - url=URL, - download_url=DOWNLOAD_URL, - license=LICENSE, - classifiers=CLASSIFIERS, - author=AUTHOR, - author_email=AUTHOR_EMAIL, - platforms=PLATFORMS, - version=VERSION, - packages=PACKAGES, - package_data=PACKAGE_DATA, - zip_safe=False, - requires=REQUIRES, - #extras_require=EXTRAS_REQUIRE, - scripts=BIN - ) - - # Now call the actual setup function if __name__ == '__main__': - setup(**opts) + setup( + name="pymatbridge", + maintainer="Ariel Rokem", + maintainer_email="arokem@gmail.com", + description=__doc__, + long_description=open('LICENSE').read(), + url="https://github.com/arokem/python-matlab-bridge", + download_url="https://github.com/arokem/python-matlab-bridge/archive/master.tar.gz", + license='BSD', + author="https://github.com/arokem/python-matlab-bridge/contributors", + author_email="arokem@gmail.com", + platforms="OS Independent", + version='.'.join([__version__, __build__]), + packages=['pymatbridge'], + package_data={ + "pymatbridge": [ + "matlab/matlabserver.m", "matlab/messenger.*", + "matlab/usrprog/*", "matlab/util/*.m", + "matlab/util/json_v0.2.2/LICENSE", + "matlab/util/json_v0.2.2/README.md", + "matlab/util/json_v0.2.2/test/*", + "matlab/util/json_v0.2.2/json/*.m", + "matlab/util/json_v0.2.2/json/java/*", + "tests/*.py", "examples/*.ipynb" + ] + }, + zip_safe=False, + requires=['pyzmq'], + scripts=['scripts/publish-notebook'], + classifiers=[ + "Development Status :: 3 - Alpha", + "Environment :: Console", + "Intended Audience :: Science/Research", + "License :: OSI Approved :: BSD License", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Topic :: Scientific/Engineering", + ], + #extras_require=['numpy', 'scipy', 'ipython'] + ) diff --git a/version.py b/version.py new file mode 120000 index 0000000..c3709ac --- /dev/null +++ b/version.py @@ -0,0 +1 @@ +pymatbridge/__version__.py \ No newline at end of file From 1071a1a69781ec1432b215634ed1b5ba9c0f2e89 Mon Sep 17 00:00:00 2001 From: Sang Han Date: Fri, 27 Mar 2015 09:21:18 -0700 Subject: [PATCH 52/58] import only bare minimum through exec --- setup.py | 14 +++++++++----- version.py | 1 - 2 files changed, 9 insertions(+), 6 deletions(-) delete mode 120000 version.py diff --git a/setup.py b/setup.py index efa1ee5..a99557d 100755 --- a/setup.py +++ b/setup.py @@ -2,7 +2,6 @@ """ Pymatbridge: A python interface to call out to Matlab(R) """ - import os import shutil import glob @@ -12,6 +11,9 @@ if os.path.exists('MANIFEST'): os.remove('MANIFEST') +# Set Version Info +exec(open('pymatbridge/__version__.py').read()) + try: from setuptools import setup except ImportError: @@ -19,10 +21,9 @@ # Find the messenger binary file(s) and copy it to /matlab folder. from messenger.make import get_messenger_dir -from version import __version__, __build__ -for f in glob.glob("./messenger/%s/messenger.*" % get_messenger_dir()): - shutil.copy(f, "./pymatbridge/matlab") +for f in glob.glob("messenger/%s/messenger.*" % get_messenger_dir()): + shutil.copy(f, 'pymatbridge/matlab/') # Now call the actual setup function if __name__ == '__main__': @@ -39,7 +40,10 @@ author_email="arokem@gmail.com", platforms="OS Independent", version='.'.join([__version__, __build__]), - packages=['pymatbridge'], + packages=['pymatbridge', 'messenger'], + data_files=[ + ('pymatbridge/matlab', ['messenger/mexmaci64/messenger.mex']) + ], package_data={ "pymatbridge": [ "matlab/matlabserver.m", "matlab/messenger.*", diff --git a/version.py b/version.py deleted file mode 120000 index c3709ac..0000000 --- a/version.py +++ /dev/null @@ -1 +0,0 @@ -pymatbridge/__version__.py \ No newline at end of file From 321ab0e0507f3d74969e442e7466274b5a3a3929 Mon Sep 17 00:00:00 2001 From: Sang Han Date: Wed, 22 Apr 2015 07:04:04 -0700 Subject: [PATCH 53/58] working build on osx --- .travis.yml | 7 +- pymatbridge/__version__.py | 4 +- .../messenger}/__init__.py | 2 +- .../messenger}/__main__.py | 0 {messenger => pymatbridge/messenger}/make.py | 0 .../messenger}/mexa64/messenger.mex | Bin .../messenger}/mexa64/messenger.mex.zmq4 | Bin .../messenger}/mexa64/messenger.mexa64 | Bin .../messenger}/mexmaci64/messenger.mex | Bin .../messenger}/mexmaci64/messenger.mex.zmq3 | Bin .../messenger}/mexmaci64/messenger.mexmaci64 | Bin .../mexmaci64/messenger.mexmaci64.zmq3 | Bin .../messenger}/mexw64/README.md | 0 .../messenger}/mexw64/messenger.mex | Bin .../messenger}/mexw64/messenger.mexw64 | Bin .../messenger}/settings.py | 0 .../messenger}/src/messenger.c | 0 .../messenger}/tests/test_env.py | 12 +- pymatbridge/pymatbridge.py | 2 +- requirements.txt | 2 +- setup.py | 128 ++++++++++-------- version.py | 3 + 22 files changed, 82 insertions(+), 78 deletions(-) rename {messenger => pymatbridge/messenger}/__init__.py (54%) rename {messenger => pymatbridge/messenger}/__main__.py (100%) rename {messenger => pymatbridge/messenger}/make.py (100%) rename {messenger => pymatbridge/messenger}/mexa64/messenger.mex (100%) rename {messenger => pymatbridge/messenger}/mexa64/messenger.mex.zmq4 (100%) rename {messenger => pymatbridge/messenger}/mexa64/messenger.mexa64 (100%) rename {messenger => pymatbridge/messenger}/mexmaci64/messenger.mex (100%) rename {messenger => pymatbridge/messenger}/mexmaci64/messenger.mex.zmq3 (100%) rename {messenger => pymatbridge/messenger}/mexmaci64/messenger.mexmaci64 (100%) rename {messenger => pymatbridge/messenger}/mexmaci64/messenger.mexmaci64.zmq3 (100%) rename {messenger => pymatbridge/messenger}/mexw64/README.md (100%) rename {messenger => pymatbridge/messenger}/mexw64/messenger.mex (100%) rename {messenger => pymatbridge/messenger}/mexw64/messenger.mexw64 (100%) rename {messenger => pymatbridge/messenger}/settings.py (100%) rename {messenger => pymatbridge/messenger}/src/messenger.c (100%) rename {messenger => pymatbridge/messenger}/tests/test_env.py (80%) create mode 100644 version.py diff --git a/.travis.yml b/.travis.yml index dd6961b..e85b084 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,12 +33,7 @@ install: - python setup.py install script: - # run coverage on py2.7, regular on others - - if [[ $CONDA == python=2.7* ]]; then - nosetests --exe -v --with-cov --cover-package pymatbridge; - else - nosetests --exe -v pymatbridge; - fi + - python setup.py test after_success: - coveralls diff --git a/pymatbridge/__version__.py b/pymatbridge/__version__.py index ec2406a..8f0f77e 100644 --- a/pymatbridge/__version__.py +++ b/pymatbridge/__version__.py @@ -1,3 +1,3 @@ __version__ = '0.5.0' -__build__ = 'dev' - +__build__ = 'dev1' +__release__ = '.'.join([__version__, __build__]) diff --git a/messenger/__init__.py b/pymatbridge/messenger/__init__.py similarity index 54% rename from messenger/__init__.py rename to pymatbridge/messenger/__init__.py index da40056..8a14d96 100644 --- a/messenger/__init__.py +++ b/pymatbridge/messenger/__init__.py @@ -1,2 +1,2 @@ from .settings import * -from .make import * \ No newline at end of file +from .make import * diff --git a/messenger/__main__.py b/pymatbridge/messenger/__main__.py similarity index 100% rename from messenger/__main__.py rename to pymatbridge/messenger/__main__.py diff --git a/messenger/make.py b/pymatbridge/messenger/make.py similarity index 100% rename from messenger/make.py rename to pymatbridge/messenger/make.py diff --git a/messenger/mexa64/messenger.mex b/pymatbridge/messenger/mexa64/messenger.mex similarity index 100% rename from messenger/mexa64/messenger.mex rename to pymatbridge/messenger/mexa64/messenger.mex diff --git a/messenger/mexa64/messenger.mex.zmq4 b/pymatbridge/messenger/mexa64/messenger.mex.zmq4 similarity index 100% rename from messenger/mexa64/messenger.mex.zmq4 rename to pymatbridge/messenger/mexa64/messenger.mex.zmq4 diff --git a/messenger/mexa64/messenger.mexa64 b/pymatbridge/messenger/mexa64/messenger.mexa64 similarity index 100% rename from messenger/mexa64/messenger.mexa64 rename to pymatbridge/messenger/mexa64/messenger.mexa64 diff --git a/messenger/mexmaci64/messenger.mex b/pymatbridge/messenger/mexmaci64/messenger.mex similarity index 100% rename from messenger/mexmaci64/messenger.mex rename to pymatbridge/messenger/mexmaci64/messenger.mex diff --git a/messenger/mexmaci64/messenger.mex.zmq3 b/pymatbridge/messenger/mexmaci64/messenger.mex.zmq3 similarity index 100% rename from messenger/mexmaci64/messenger.mex.zmq3 rename to pymatbridge/messenger/mexmaci64/messenger.mex.zmq3 diff --git a/messenger/mexmaci64/messenger.mexmaci64 b/pymatbridge/messenger/mexmaci64/messenger.mexmaci64 similarity index 100% rename from messenger/mexmaci64/messenger.mexmaci64 rename to pymatbridge/messenger/mexmaci64/messenger.mexmaci64 diff --git a/messenger/mexmaci64/messenger.mexmaci64.zmq3 b/pymatbridge/messenger/mexmaci64/messenger.mexmaci64.zmq3 similarity index 100% rename from messenger/mexmaci64/messenger.mexmaci64.zmq3 rename to pymatbridge/messenger/mexmaci64/messenger.mexmaci64.zmq3 diff --git a/messenger/mexw64/README.md b/pymatbridge/messenger/mexw64/README.md similarity index 100% rename from messenger/mexw64/README.md rename to pymatbridge/messenger/mexw64/README.md diff --git a/messenger/mexw64/messenger.mex b/pymatbridge/messenger/mexw64/messenger.mex similarity index 100% rename from messenger/mexw64/messenger.mex rename to pymatbridge/messenger/mexw64/messenger.mex diff --git a/messenger/mexw64/messenger.mexw64 b/pymatbridge/messenger/mexw64/messenger.mexw64 similarity index 100% rename from messenger/mexw64/messenger.mexw64 rename to pymatbridge/messenger/mexw64/messenger.mexw64 diff --git a/messenger/settings.py b/pymatbridge/messenger/settings.py similarity index 100% rename from messenger/settings.py rename to pymatbridge/messenger/settings.py diff --git a/messenger/src/messenger.c b/pymatbridge/messenger/src/messenger.c similarity index 100% rename from messenger/src/messenger.c rename to pymatbridge/messenger/src/messenger.c diff --git a/messenger/tests/test_env.py b/pymatbridge/messenger/tests/test_env.py similarity index 80% rename from messenger/tests/test_env.py rename to pymatbridge/messenger/tests/test_env.py index d858e94..e957735 100644 --- a/messenger/tests/test_env.py +++ b/pymatbridge/messenger/tests/test_env.py @@ -1,15 +1,13 @@ import numpy.testing as npt import sys import os +import pkg_resources -ROOT = os.path.join(os.path.dirname(__file__), '..', '..') +from pymatbridge import messenger -# Necessary since messenger is not installed with pymatbridge -sys.path.append(ROOT) - -import messenger - -CONFIG = os.path.join(ROOT, 'config.ini') +ROOT = __file__ +CONFIG = os.path.realpath(os.path.join(ROOT, '../../../../config.ini')) +print(CONFIG) BIN = messenger.get_matlab_bin(config=CONFIG) def test_config(): diff --git a/pymatbridge/pymatbridge.py b/pymatbridge/pymatbridge.py index 31855fa..8a94f96 100644 --- a/pymatbridge/pymatbridge.py +++ b/pymatbridge/pymatbridge.py @@ -41,7 +41,6 @@ class spmatrix: pass - def encode_ndarray(obj): """Write a numpy array and its shape to base64 buffers""" shape = obj.shape @@ -403,6 +402,7 @@ def _bind_method(self, name, unconditionally=False): class Matlab(_Session): + def __init__(self, executable='matlab', socket_addr=None, id='python-matlab-bridge', log=False, maxtime=60, platform=None, startup_options=None): diff --git a/requirements.txt b/requirements.txt index ae3bcc7..a77d8b4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,2 @@ pyzmq -numpy>=1.7 +numpy diff --git a/setup.py b/setup.py index a99557d..f5a0ccc 100755 --- a/setup.py +++ b/setup.py @@ -2,71 +2,79 @@ """ Pymatbridge: A python interface to call out to Matlab(R) """ -import os -import shutil -import glob - -# BEFORE importing distutils, remove MANIFEST. distutils doesn't properly -# update it when the contents of directories change. -if os.path.exists('MANIFEST'): - os.remove('MANIFEST') -# Set Version Info -exec(open('pymatbridge/__version__.py').read()) +import os +import sys +import filecmp +import itertools try: - from setuptools import setup + import pkg_resources except ImportError: - from distutils.core import setup + import ez_setup + ez_setup.use_setuptools() -# Find the messenger binary file(s) and copy it to /matlab folder. -from messenger.make import get_messenger_dir +from setuptools import setup, find_packages +from setuptools.command.test import test as TestCommand +from distutils import file_util +from distutils.extension import Extension +from pymatbridge.messenger import get_messenger_dir -for f in glob.glob("messenger/%s/messenger.*" % get_messenger_dir()): - shutil.copy(f, 'pymatbridge/matlab/') +from version import __version__, __build__, __release__ -# Now call the actual setup function -if __name__ == '__main__': - setup( - name="pymatbridge", - maintainer="Ariel Rokem", - maintainer_email="arokem@gmail.com", - description=__doc__, - long_description=open('LICENSE').read(), - url="https://github.com/arokem/python-matlab-bridge", - download_url="https://github.com/arokem/python-matlab-bridge/archive/master.tar.gz", - license='BSD', - author="https://github.com/arokem/python-matlab-bridge/contributors", - author_email="arokem@gmail.com", - platforms="OS Independent", - version='.'.join([__version__, __build__]), - packages=['pymatbridge', 'messenger'], - data_files=[ - ('pymatbridge/matlab', ['messenger/mexmaci64/messenger.mex']) - ], - package_data={ - "pymatbridge": [ - "matlab/matlabserver.m", "matlab/messenger.*", - "matlab/usrprog/*", "matlab/util/*.m", - "matlab/util/json_v0.2.2/LICENSE", - "matlab/util/json_v0.2.2/README.md", - "matlab/util/json_v0.2.2/test/*", - "matlab/util/json_v0.2.2/json/*.m", - "matlab/util/json_v0.2.2/json/java/*", - "tests/*.py", "examples/*.ipynb" - ] - }, - zip_safe=False, - requires=['pyzmq'], - scripts=['scripts/publish-notebook'], - classifiers=[ - "Development Status :: 3 - Alpha", - "Environment :: Console", - "Intended Audience :: Science/Research", - "License :: OSI Approved :: BSD License", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Topic :: Scientific/Engineering", +messenger = pkg_resources.resource_filename('pymatbridge.messenger', get_messenger_dir()) +matlab = pkg_resources.resource_filename('pymatbridge', 'matlab') +newfiles = filecmp.cmpfiles(messenger, matlab, os.listdir(messenger), shallow=False)[1:] + +for binary in itertools.chain(*newfiles): + cmd = (os.path.join(messenger, binary), os.path.join(matlab, binary)) + print('Copying %s' % binary) + file_util.copy_file(*cmd, update=True) + +extension = Extension( + name='messenger.mexmaci', + sources=['messenger/src/messenger.c'], + include_dirs=['/usr/local/include'], + library_dirs=['/usr/local/lib/'], + libraries=['zmq'], +) + +class NoseTestCommand(TestCommand): + + def finalize_options(self): + TestCommand.finalize_options(self) + self.test_args = [] + self.test_suite = True + + def run_tests(self): + import nose + args = 'nosetests -v --exe --with-cov ' + if sys.version_info == (2, 7): + args += '--cover-package pymatbridge' + nose.run_exit(argv=args.split()) + +setup( + name="pymatbridge", + maintainer="Ariel Rokem", + maintainer_email="arokem@gmail.com", + description=__doc__, + tests_require=['nose', 'coverage'], + setup_requires=['wheel'], + cmdclass={'test': NoseTestCommand}, + version=__release__, + packages=find_packages(exclude=['tests*']), + zip_safe = False, + requires=['numpy', 'pyzmq'], + package_data={ + "pymatbridge": [ + "matlab/matlabserver.m", "matlab/messenger.*", + "matlab/usrprog/*", "matlab/util/*.m", + "matlab/util/json_v0.2.2/LICENSE", + "matlab/util/json_v0.2.2/README.md", + "matlab/util/json_v0.2.2/test/*", + "matlab/util/json_v0.2.2/json/*.m", + "matlab/util/json_v0.2.2/json/java/*", + "tests/*.py", "examples/*.ipynb" ], - #extras_require=['numpy', 'scipy', 'ipython'] - ) + }, +) diff --git a/version.py b/version.py new file mode 100644 index 0000000..fcd9f36 --- /dev/null +++ b/version.py @@ -0,0 +1,3 @@ +# Set Version Info +exec(open('pymatbridge/__version__.py').read()) + From 6442b608afdf9724b3acb64dea3c29b7dd739b88 Mon Sep 17 00:00:00 2001 From: Sang Han Date: Wed, 22 Apr 2015 07:07:46 -0700 Subject: [PATCH 54/58] setup --- MANIFEST.in | 9 +++++++++ setup.cfg | 28 ++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 MANIFEST.in create mode 100644 setup.cfg diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..220eacf --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,9 @@ +recursive-include pymatbridge * + +include *.md +include *.py +include *.txt +include LICENSE +include config.ini +recursive-include pymatbridge *.py +recursive-include tools *.py diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..7de82dc --- /dev/null +++ b/setup.cfg @@ -0,0 +1,28 @@ +[global] +verbose=1 + +[build_ext] +inplace=1 + +[bdist_wheel] +universal = 1 + +[metadata] +summary = pymatbridge: A python interface to call out to Matlab(R) +license = BSD +scripts = scripts/publish-notebook +download_url = https://github.com/arokem/python-matlab-bridge/archive/master.tar.gz +long_description = + README.md + LICENSE +description-file = + README.md + LICENSE +classifiers = + Development Status :: 3 - Alpha + Environment :: Console + Intended Audience :: Science/Research + License :: OSI Approved :: BSD License + Operating System :: OS Independent + Programming Language :: Python + Topic :: Scientific/Engineering From 3301167ee68e8914986d2dd439cc2e7ec6222a42 Mon Sep 17 00:00:00 2001 From: Sang Han Date: Wed, 22 Apr 2015 09:37:25 -0700 Subject: [PATCH 55/58] holy crap it works --- MANIFEST.in | 29 ++++++++++++++---- pymatbridge/messenger/make.py | 7 +++-- pymatbridge/messenger/mexw64/README.md | 41 -------------------------- pymatbridge/messenger/settings.py | 24 +-------------- setup.cfg | 20 +++++++++++-- setup.py | 38 ++++++++++-------------- 6 files changed, 60 insertions(+), 99 deletions(-) delete mode 100644 pymatbridge/messenger/mexw64/README.md diff --git a/MANIFEST.in b/MANIFEST.in index 220eacf..62719b8 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,9 +1,26 @@ -recursive-include pymatbridge * +exclude messenger.* -include *.md -include *.py -include *.txt include LICENSE include config.ini -recursive-include pymatbridge *.py -recursive-include tools *.py +include README.md +include requirements.txt +include setup.cfg +include scripts/publish-notebook + +include pymatbridge/messenger/src/messenger.c + +include pymatbridge/messenger/mexa64/ +include pymatbridge/messenger/mexmaci64/ +include pymatbridge/messenger/mexw64/ +include pymatbridge/messenger/mexa64/ + +include pymatbridge/matlab/messenger.mex +include pymatbridge/matlab/messenger.mex.zmq3 +include pymatbridge/matlab/messenger.mexmaci64 +include pymatbridge/matlab/messenger.mexmaci64.zmq3 +include pymatbridge/matlab/util/json_v0.2.2/json/java/json.jar +include pymatbridge/matlab/util/json_v0.2.2/LICENSE + +include *.ipynb +include *.m +include *.py diff --git a/pymatbridge/messenger/make.py b/pymatbridge/messenger/make.py index 09064dc..a4f8cde 100644 --- a/pymatbridge/messenger/make.py +++ b/pymatbridge/messenger/make.py @@ -134,7 +134,7 @@ def build_octave(static=False): do_build(split_command_line(make_cmd), 'messenger.mex') -def build_matlab(static=False): +def build_matlab(static=False, messenger='messenger.c'): """ Build the messenger mex for MATLAB @@ -155,12 +155,13 @@ def build_matlab(static=False): # Build the mex file mex = os.path.join(matlab_bin, "mex") paths = "-L'%(zmq_lib)s' -I'%(zmq_inc)s'" % cfg - make_cmd = '%s -O %s -lzmq messenger/src/messenger.c' % (mex, paths) + make_cmd = '%s -O %s -lzmq %s' % (mex, paths, messenger) if static: make_cmd += ' -DZMQ_STATIC' - do_build(split_command_line(make_cmd), 'messenger.%s' % extension) + print(make_cmd) + subprocess.check_output(split_command_line(make_cmd), shell=use_shell) def get_matlab_bin(config='config.ini'): diff --git a/pymatbridge/messenger/mexw64/README.md b/pymatbridge/messenger/mexw64/README.md deleted file mode 100644 index 47100e8..0000000 --- a/pymatbridge/messenger/mexw64/README.md +++ /dev/null @@ -1,41 +0,0 @@ -Dynamically linked building instructions ----------------------------------------- - -1) Install zeromq from the website: http://zeromq.org/distro:microsoft-windows - -2) Rename one of the lib/libzmq-*.lib files to libzmq.lib in the ZeroMQ - installation directory - -3) Add the ZeroMQ bin directory to your path. - -4) Edit the messenger/mexw64/local.cfg file in messenger to point to the - zeromq install directory (you will need to update both ZMQ_INC and ZMQ_LIB). - Also ensure the MATLAB directory is correct. - -5) Run ```make.py matlab``` in the messenger directory. This should build - messenger.mexw64 - -Statically linked building instructions ---------------------------------------- - -A statically linked library has the advantage of not requiring libzmq.dll to -be found in the path. For this reason, including it in the installer results -in a simpler and more robust installation process. While building a statically -linked mex is simple in practice, but because zeromq (as of 3/10/15) does not -provide a .lib for static linking with the windows installer, you will need to -compile this yourself. These directions are from zeromq 4.0.5. - -1) Download and unzip the zeromq zip file (listed as Windows sources) from - http://zeromq.org/intro:get-the-software - -2) In the builds/msvc directory open the msvc.sln file in Visual Studio. - -3) Create a new Platform for x64. In the Librarian section of properties, set - the target section to /Machine:X64 - -4) Build libzmq with the "StaticRelease" for x64. - -5) Edit the messenger/mexw64/local.cfg file to point to where you built ZeroMQ - and your MATLAB bin directory. - -6) Build messenger.mexw64 with ```make matlab --static``` diff --git a/pymatbridge/messenger/settings.py b/pymatbridge/messenger/settings.py index 81b60b7..5597983 100644 --- a/pymatbridge/messenger/settings.py +++ b/pymatbridge/messenger/settings.py @@ -9,7 +9,7 @@ from urllib import urlretrieve import string -__all__= ['get_matlab_bin', 'get_matlab_env', 'fetch_zmq'] +__all__= ['get_matlab_env'] def get_matlab_env(matlab='matlab'): @@ -34,25 +34,3 @@ def get_matlab_env(matlab='matlab'): return dict(string.split(env, '=', maxsplit=1) for env in envs) - -def fetch_zmq(prefix, version=(4,0,5)): - """ - Download and extract libzmq into `prefix` - - Parameters - ---------- - save: str - File Save Location - version: 3-tuple - ZMQ Version Number - """ - print('Downloading ZMQ Source Version %i.%i.%i' % version) - url = ("http://download.zeromq.org/zeromq-%i.%i.%i.tar.gz" % version) - name = urlretrieve(url, url.rsplit('/')[-1])[0] - - print('Extracting into prefix %s' % prefix) - with tarfile.open(name) as tar: - tar.extractall(prefix) - - print('Download Complete') - os.remove(name) diff --git a/setup.cfg b/setup.cfg index 7de82dc..125b3a4 100644 --- a/setup.cfg +++ b/setup.cfg @@ -5,7 +5,7 @@ verbose=1 inplace=1 [bdist_wheel] -universal = 1 +universal = 0 [metadata] summary = pymatbridge: A python interface to call out to Matlab(R) @@ -23,6 +23,20 @@ classifiers = Environment :: Console Intended Audience :: Science/Research License :: OSI Approved :: BSD License - Operating System :: OS Independent - Programming Language :: Python Topic :: Scientific/Engineering + Topic :: Software Development :: Build Tools' + Intended Audience :: Developers' + Programming Language :: Python :: 2' + Programming Language :: Python :: 2.7' + Programming Language :: Python :: 3' + Programming Language :: Python :: 3.3' + Programming Language :: Python :: 3.4' + Programming Language :: Other Scripting Engines + Operating System :: Microsoft :: Windows + Operating System :: OS Independent + Intended Audience :: Developers + Intended Audience :: Education + Intended Audience :: Science/Research + +keywords = matlab python packaging + diff --git a/setup.py b/setup.py index f5a0ccc..9d48c64 100755 --- a/setup.py +++ b/setup.py @@ -7,6 +7,7 @@ import sys import filecmp import itertools +import platform try: import pkg_resources @@ -17,8 +18,9 @@ from setuptools import setup, find_packages from setuptools.command.test import test as TestCommand from distutils import file_util -from distutils.extension import Extension -from pymatbridge.messenger import get_messenger_dir +from setuptools.command.build_ext import build_ext + +from pymatbridge.messenger import build_matlab, get_messenger_dir from version import __version__, __build__, __release__ @@ -31,14 +33,6 @@ print('Copying %s' % binary) file_util.copy_file(*cmd, update=True) -extension = Extension( - name='messenger.mexmaci', - sources=['messenger/src/messenger.c'], - include_dirs=['/usr/local/include'], - library_dirs=['/usr/local/lib/'], - libraries=['zmq'], -) - class NoseTestCommand(TestCommand): def finalize_options(self): @@ -53,6 +47,13 @@ def run_tests(self): args += '--cover-package pymatbridge' nose.run_exit(argv=args.split()) +class CompileMEX(build_ext): + def run(self): + return build_matlab(messenger='pymatbridge/messenger/src/messenger.c') + + + + setup( name="pymatbridge", maintainer="Ariel Rokem", @@ -60,21 +61,12 @@ def run_tests(self): description=__doc__, tests_require=['nose', 'coverage'], setup_requires=['wheel'], - cmdclass={'test': NoseTestCommand}, + cmdclass={ + 'test': NoseTestCommand, + 'messenger': CompileMEX, + }, version=__release__, packages=find_packages(exclude=['tests*']), zip_safe = False, requires=['numpy', 'pyzmq'], - package_data={ - "pymatbridge": [ - "matlab/matlabserver.m", "matlab/messenger.*", - "matlab/usrprog/*", "matlab/util/*.m", - "matlab/util/json_v0.2.2/LICENSE", - "matlab/util/json_v0.2.2/README.md", - "matlab/util/json_v0.2.2/test/*", - "matlab/util/json_v0.2.2/json/*.m", - "matlab/util/json_v0.2.2/json/java/*", - "tests/*.py", "examples/*.ipynb" - ], - }, ) From 668ad8051fe50d5013b1b1c55630500a6085fb13 Mon Sep 17 00:00:00 2001 From: Sang Han Date: Fri, 24 Apr 2015 21:01:54 -0700 Subject: [PATCH 56/58] Fixed issue with coverage --- MANIFEST.in | 16 +++++++--------- setup.cfg | 4 ++-- setup.py | 31 +++++++++++++++---------------- 3 files changed, 24 insertions(+), 27 deletions(-) diff --git a/MANIFEST.in b/MANIFEST.in index 62719b8..86ea71e 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,5 +1,3 @@ -exclude messenger.* - include LICENSE include config.ini include README.md @@ -9,10 +7,10 @@ include scripts/publish-notebook include pymatbridge/messenger/src/messenger.c -include pymatbridge/messenger/mexa64/ -include pymatbridge/messenger/mexmaci64/ -include pymatbridge/messenger/mexw64/ -include pymatbridge/messenger/mexa64/ +include pymatbridge/messenger/mexa64/* +include pymatbridge/messenger/mexmaci64/* +include pymatbridge/messenger/mexw64/* +include pymatbridge/messenger/mexa64/* include pymatbridge/matlab/messenger.mex include pymatbridge/matlab/messenger.mex.zmq3 @@ -21,6 +19,6 @@ include pymatbridge/matlab/messenger.mexmaci64.zmq3 include pymatbridge/matlab/util/json_v0.2.2/json/java/json.jar include pymatbridge/matlab/util/json_v0.2.2/LICENSE -include *.ipynb -include *.m -include *.py +recursive-include pymatbridge *.py *.ipynb *.m +recursive-include scripts * +recursive-include tools * \ No newline at end of file diff --git a/setup.cfg b/setup.cfg index 125b3a4..ac08504 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,8 +1,8 @@ [global] -verbose=1 +verbose = 1 [build_ext] -inplace=1 +inplace = 1 [bdist_wheel] universal = 0 diff --git a/setup.py b/setup.py index 9d48c64..9c318aa 100755 --- a/setup.py +++ b/setup.py @@ -9,29 +9,31 @@ import itertools import platform +# if setupools setuptools doesnt exist install it try: import pkg_resources except ImportError: import ez_setup ez_setup.use_setuptools() + import pkg_resources from setuptools import setup, find_packages from setuptools.command.test import test as TestCommand -from distutils import file_util from setuptools.command.build_ext import build_ext +from distutils import file_util -from pymatbridge.messenger import build_matlab, get_messenger_dir +# from pymatbridge.messenger import build_matlab, get_messenger_dir from version import __version__, __build__, __release__ -messenger = pkg_resources.resource_filename('pymatbridge.messenger', get_messenger_dir()) -matlab = pkg_resources.resource_filename('pymatbridge', 'matlab') -newfiles = filecmp.cmpfiles(messenger, matlab, os.listdir(messenger), shallow=False)[1:] +# messenger = pkg_resources.resource_filename('pymatbridge.messenger', get_messenger_dir()) +# matlab = pkg_resources.resource_filename('pymatbridge', 'matlab') +# newfiles = filecmp.cmpfiles(messenger, matlab, os.listdir(messenger), shallow=False)[1:] -for binary in itertools.chain(*newfiles): - cmd = (os.path.join(messenger, binary), os.path.join(matlab, binary)) - print('Copying %s' % binary) - file_util.copy_file(*cmd, update=True) +# for binary in itertools.chain(*newfiles): +# cmd = (os.path.join(messenger, binary), os.path.join(matlab, binary)) +# print('Copying %s' % binary) +# file_util.copy_file(*cmd, update=True) class NoseTestCommand(TestCommand): @@ -42,24 +44,21 @@ def finalize_options(self): def run_tests(self): import nose - args = 'nosetests -v --exe --with-cov ' - if sys.version_info == (2, 7): - args += '--cover-package pymatbridge' + args = 'nosetests -v --exe' + if sys.version_info[0:2] == (2, 7): + args += ' --with-cov --cover-package pymatbridge' nose.run_exit(argv=args.split()) class CompileMEX(build_ext): def run(self): return build_matlab(messenger='pymatbridge/messenger/src/messenger.c') - - - setup( name="pymatbridge", maintainer="Ariel Rokem", maintainer_email="arokem@gmail.com", description=__doc__, - tests_require=['nose', 'coverage'], + tests_require=['wheel', 'nose', 'coverage', 'ipython[all]', 'numpy', 'pyzmq'], setup_requires=['wheel'], cmdclass={ 'test': NoseTestCommand, From 155a196e4bef31871636cdc5fba5e82e67ea6b99 Mon Sep 17 00:00:00 2001 From: Sang Han Date: Mon, 27 Apr 2015 23:25:40 -0700 Subject: [PATCH 57/58] setup.cfg metadata is deprecated, so moved information back into setup.py --- setup.cfg | 34 -------------------------------- setup.py | 45 +++++++++++++++++++++++++++++++++++++------ test_requirements.txt | 3 +++ 3 files changed, 42 insertions(+), 40 deletions(-) create mode 100644 test_requirements.txt diff --git a/setup.cfg b/setup.cfg index ac08504..4f550d4 100644 --- a/setup.cfg +++ b/setup.cfg @@ -6,37 +6,3 @@ inplace = 1 [bdist_wheel] universal = 0 - -[metadata] -summary = pymatbridge: A python interface to call out to Matlab(R) -license = BSD -scripts = scripts/publish-notebook -download_url = https://github.com/arokem/python-matlab-bridge/archive/master.tar.gz -long_description = - README.md - LICENSE -description-file = - README.md - LICENSE -classifiers = - Development Status :: 3 - Alpha - Environment :: Console - Intended Audience :: Science/Research - License :: OSI Approved :: BSD License - Topic :: Scientific/Engineering - Topic :: Software Development :: Build Tools' - Intended Audience :: Developers' - Programming Language :: Python :: 2' - Programming Language :: Python :: 2.7' - Programming Language :: Python :: 3' - Programming Language :: Python :: 3.3' - Programming Language :: Python :: 3.4' - Programming Language :: Other Scripting Engines - Operating System :: Microsoft :: Windows - Operating System :: OS Independent - Intended Audience :: Developers - Intended Audience :: Education - Intended Audience :: Science/Research - -keywords = matlab python packaging - diff --git a/setup.py b/setup.py index 9c318aa..e2b546c 100755 --- a/setup.py +++ b/setup.py @@ -9,7 +9,7 @@ import itertools import platform -# if setupools setuptools doesnt exist install it +# if setuptools doesnt exist install it try: import pkg_resources except ImportError: @@ -22,7 +22,7 @@ from setuptools.command.build_ext import build_ext from distutils import file_util -# from pymatbridge.messenger import build_matlab, get_messenger_dir +from pymatbridge.messenger import build_matlab, get_messenger_dir from version import __version__, __build__, __release__ @@ -35,6 +35,14 @@ # print('Copying %s' % binary) # file_util.copy_file(*cmd, update=True) +def read(*files): + """ + Takes an arbitrary number of file names based from the package root + returns their contents concatenated with two newlines. + """ + return '\n\n'.join([open(f, 'rt').read() for f in files if os.path.isfile(f)]) + + class NoseTestCommand(TestCommand): def finalize_options(self): @@ -46,7 +54,8 @@ def run_tests(self): import nose args = 'nosetests -v --exe' if sys.version_info[0:2] == (2, 7): - args += ' --with-cov --cover-package pymatbridge' + args += ' ' + args += '--with-cov --cover-package pymatbridge' nose.run_exit(argv=args.split()) class CompileMEX(build_ext): @@ -58,14 +67,38 @@ def run(self): maintainer="Ariel Rokem", maintainer_email="arokem@gmail.com", description=__doc__, - tests_require=['wheel', 'nose', 'coverage', 'ipython[all]', 'numpy', 'pyzmq'], + long_description=read('README.md', 'LICENSE'), + tests_require=['ipython', 'nose', 'coverage', 'numpy', 'pyzmq'], setup_requires=['wheel'], cmdclass={ 'test': NoseTestCommand, 'messenger': CompileMEX, }, + license=read('LICENSE'), + scripts='scripts/publish-notebook', version=__release__, packages=find_packages(exclude=['tests*']), - zip_safe = False, - requires=['numpy', 'pyzmq'], + zip_safe=False, + requires=['pyzmq', 'numpy'], + keywords='matlab python packaging', + classifiers=[ + 'Development Status :: 3 - Alpha', + 'Environment :: Console', + 'Intended Audience :: Science/Research', + 'License :: OSI Approved :: BSD License', + 'Topic :: Scientific/Engineering', + 'Topic :: Software Development :: Build Tools', + 'Intended Audience :: Developers', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.3', + 'Programming Language :: Python :: 3.4', + 'Programming Language :: Other Scripting Engines', + 'Operating System :: Microsoft :: Windows', + 'Operating System :: OS Independent', + 'Intended Audience :: Developers', + 'Intended Audience :: Education', + 'Intended Audience :: Science/Research', + ], ) diff --git a/test_requirements.txt b/test_requirements.txt new file mode 100644 index 0000000..518b2cf --- /dev/null +++ b/test_requirements.txt @@ -0,0 +1,3 @@ +nose +coverage +ipython From 21e7f286ba02a42f668be9cecc161a6f3cad871f Mon Sep 17 00:00:00 2001 From: Sang Han Date: Mon, 27 Apr 2015 23:31:53 -0700 Subject: [PATCH 58/58] Go back to running nosetests for now --- .travis.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e85b084..dd6961b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,7 +33,12 @@ install: - python setup.py install script: - - python setup.py test + # run coverage on py2.7, regular on others + - if [[ $CONDA == python=2.7* ]]; then + nosetests --exe -v --with-cov --cover-package pymatbridge; + else + nosetests --exe -v pymatbridge; + fi after_success: - coveralls