From 6af98bec160222c475a7e449cf23486de7ae67ed Mon Sep 17 00:00:00 2001 From: Huayi Zhang Date: Thu, 17 Sep 2015 12:26:42 +0800 Subject: [PATCH] Fix python setup: avoid import numpy in setup.py Currently `pip install xgboost` will raise traceback like this ``` Traceback (most recent call last): File "", line 20, in File "/tmp/pip-build-IAdqYE/xgboost/setup.py", line 20, in import xgboost File "./xgboost/__init__.py", line 8, in from .core import DMatrix, Booster File "./xgboost/core.py", line 12, in import numpy as np ImportError: No module named numpy ``` We should avoid importing numpy in setup.py and let pip install numpy and scipy automatically. That's what `install_requires` for. --- python-package/setup.py | 16 ++++++++--- python-package/xgboost/VERSION | 1 + python-package/xgboost/__init__.py | 6 +++- python-package/xgboost/core.py | 39 +------------------------- python-package/xgboost/libpath.py | 44 ++++++++++++++++++++++++++++++ 5 files changed, 63 insertions(+), 43 deletions(-) create mode 100644 python-package/xgboost/VERSION create mode 100644 python-package/xgboost/libpath.py diff --git a/python-package/setup.py b/python-package/setup.py index 3f8ad9a1d..1c5a257b6 100644 --- a/python-package/setup.py +++ b/python-package/setup.py @@ -17,9 +17,17 @@ if 'pip' in __file__: output = build_sh.communicate() print(output) -import xgboost -LIB_PATH = xgboost.core.find_lib_path() +CURRENT_DIR = os.path.dirname(__file__) + +# We can not import `xgboost.libpath` in setup.py directly since xgboost/__init__.py +# import `xgboost.core` and finally will import `numpy` and `scipy` which are setup +# `install_requires`. That's why using `execfile` here. +libpath_py = os.path.join(CURRENT_DIR, 'xgboost/libpath.py') +libpath = {'__file__': libpath_py} +execfile(libpath_py, libpath, libpath) + +LIB_PATH = libpath['find_lib_path']() #print LIB_PATH #to deploy to pip, please use @@ -27,9 +35,9 @@ LIB_PATH = xgboost.core.find_lib_path() #python setup.py register sdist upload #and be sure to test it firstly using "python setup.py register sdist upload -r pypitest" setup(name='xgboost', - version=xgboost.__version__, + version=open(os.path.join(CURRENT_DIR, 'xgboost/VERSION')).read().strip(), #version='0.4a13', - description=xgboost.__doc__, + description=open(os.path.join(CURRENT_DIR, 'README.md')).read(), install_requires=[ 'numpy', 'scipy', diff --git a/python-package/xgboost/VERSION b/python-package/xgboost/VERSION new file mode 100644 index 000000000..e6adf3fc7 --- /dev/null +++ b/python-package/xgboost/VERSION @@ -0,0 +1 @@ +0.4 \ No newline at end of file diff --git a/python-package/xgboost/__init__.py b/python-package/xgboost/__init__.py index b251b4501..06892851f 100644 --- a/python-package/xgboost/__init__.py +++ b/python-package/xgboost/__init__.py @@ -5,12 +5,16 @@ Contributors: https://github.com/dmlc/xgboost/blob/master/CONTRIBUTORS.md """ from __future__ import absolute_import + +import os + from .core import DMatrix, Booster from .training import train, cv from .sklearn import XGBModel, XGBClassifier, XGBRegressor from .plotting import plot_importance, plot_tree, to_graphviz -__version__ = '0.4' +VERSION_FILE = os.path.join(os.path.dirname(__file__), 'VERSION') +__version__ = open(VERSION_FILE).read().strip() __all__ = ['DMatrix', 'Booster', 'train', 'cv', diff --git a/python-package/xgboost/core.py b/python-package/xgboost/core.py index 74170ea84..acd954f3d 100644 --- a/python-package/xgboost/core.py +++ b/python-package/xgboost/core.py @@ -6,16 +6,13 @@ from __future__ import absolute_import import os import sys import ctypes -import platform import collections import numpy as np import scipy.sparse +from .libpath import find_lib_path -class XGBoostLibraryNotFound(Exception): - """Error throwed by when xgboost is not found""" - pass class XGBoostError(Exception): """Error throwed by xgboost trainer.""" @@ -81,40 +78,6 @@ def from_cstr_to_pystr(data, length): return res -def find_lib_path(): - """Load find the path to xgboost dynamic library files. - - Returns - ------- - lib_path: list(string) - List of all found library path to xgboost - """ - curr_path = os.path.dirname(os.path.abspath(os.path.expanduser(__file__))) - #make pythonpack hack: copy this directory one level upper for setup.py - dll_path = [curr_path, os.path.join(curr_path, '../../wrapper/') - , os.path.join(curr_path, './wrapper/')] - if os.name == 'nt': - if platform.architecture()[0] == '64bit': - dll_path.append(os.path.join(curr_path, '../../windows/x64/Release/')) - #hack for pip installation when copy all parent source directory here - dll_path.append(os.path.join(curr_path, './windows/x64/Release/')) - else: - dll_path.append(os.path.join(curr_path, '../../windows/Release/')) - #hack for pip installation when copy all parent source directory here - dll_path.append(os.path.join(curr_path, './windows/Release/')) - if os.name == 'nt': - dll_path = [os.path.join(p, 'xgboost_wrapper.dll') for p in dll_path] - else: - dll_path = [os.path.join(p, 'libxgboostwrapper.so') for p in dll_path] - lib_path = [p for p in dll_path if os.path.exists(p) and os.path.isfile(p)] - if len(lib_path) == 0 and not os.environ.get('XGBOOST_BUILD_DOC', False): - raise XGBoostLibraryNotFound( - 'Cannot find XGBoost Libarary in the candicate path, ' + - 'did you run build.sh in root path?\n' - 'List of candidates:\n' + ('\n'.join(dll_path))) - return lib_path - - def _load_lib(): """Load xgboost Library.""" lib_path = find_lib_path() diff --git a/python-package/xgboost/libpath.py b/python-package/xgboost/libpath.py new file mode 100644 index 000000000..293719f01 --- /dev/null +++ b/python-package/xgboost/libpath.py @@ -0,0 +1,44 @@ +# coding: utf-8 +"""Find the path to xgboost dynamic library files.""" + +import os +import platform + + +class XGBoostLibraryNotFound(Exception): + """Error throwed by when xgboost is not found""" + pass + + +def find_lib_path(): + """Load find the path to xgboost dynamic library files. + + Returns + ------- + lib_path: list(string) + List of all found library path to xgboost + """ + curr_path = os.path.dirname(os.path.abspath(os.path.expanduser(__file__))) + # make pythonpack hack: copy this directory one level upper for setup.py + dll_path = [curr_path, os.path.join(curr_path, '../../wrapper/'), + os.path.join(curr_path, './wrapper/')] + if os.name == 'nt': + if platform.architecture()[0] == '64bit': + dll_path.append(os.path.join(curr_path, '../../windows/x64/Release/')) + # hack for pip installation when copy all parent source directory here + dll_path.append(os.path.join(curr_path, './windows/x64/Release/')) + else: + dll_path.append(os.path.join(curr_path, '../../windows/Release/')) + # hack for pip installation when copy all parent source directory here + dll_path.append(os.path.join(curr_path, './windows/Release/')) + if os.name == 'nt': + dll_path = [os.path.join(p, 'xgboost_wrapper.dll') for p in dll_path] + else: + dll_path = [os.path.join(p, 'libxgboostwrapper.so') for p in dll_path] + lib_path = [p for p in dll_path if os.path.exists(p) and os.path.isfile(p)] + if len(lib_path) == 0 and not os.environ.get('XGBOOST_BUILD_DOC', False): + raise XGBoostLibraryNotFound( + 'Cannot find XGBoost Libarary in the candicate path, ' + + 'did you run build.sh in root path?\n' + 'List of candidates:\n' + ('\n'.join(dll_path))) + return lib_path