summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--numpy/core/setup.py4
-rw-r--r--numpy/distutils/misc_util.py257
-rw-r--r--numpy/distutils/setup.py8
-rw-r--r--numpy/doc/DISTUTILS.txt10
4 files changed, 191 insertions, 88 deletions
diff --git a/numpy/core/setup.py b/numpy/core/setup.py
index c0f44bc34..78359fcb3 100644
--- a/numpy/core/setup.py
+++ b/numpy/core/setup.py
@@ -20,7 +20,7 @@ def configuration(parent_package='',top_path=None):
open(generate_umath_py,'U'),generate_umath_py,
('.py','U',1))
- header_dir = join(*(config.name.split('.')+['include','numpy']))
+ header_dir = 'include/numpy' # this is relative to config.path_in_package
def generate_config_h(ext, build_dir):
target = join(build_dir,'config.h')
@@ -140,7 +140,7 @@ def configuration(parent_package='',top_path=None):
f.close()
return []
- config.add_data_files(join('include','numpy','*.h'))
+ config.add_data_files('include/numpy/*.h')
config.add_include_dirs('src')
config.numpy_include_dirs.extend(config.paths('include'))
diff --git a/numpy/distutils/misc_util.py b/numpy/distutils/misc_util.py
index 8b38a8c19..f47478c4a 100644
--- a/numpy/distutils/misc_util.py
+++ b/numpy/distutils/misc_util.py
@@ -5,6 +5,11 @@ import imp
import copy
import glob
+try:
+ set
+except NameError:
+ from sets import Set as set
+
__all__ = ['Configuration', 'get_numpy_include_dirs', 'default_config_dict',
'dict_append', 'appendpath', 'generate_config_py',
'get_cmd', 'allpath', 'get_mathlibs',
@@ -25,13 +30,14 @@ def rel_path(path, parent_path):
""" Return path relative to parent_path.
"""
pd = os.path.abspath(parent_path)
- if len(path)<len(pd):
+ apath = os.path.abspath(path)
+ if len(apath)<len(pd):
return path
- if path==pd:
+ if apath==pd:
return ''
- if pd == path[:len(pd)]:
- assert path[len(pd)] in [os.sep],`path,path[len(pd)]`
- path = path[len(pd)+1:]
+ if pd == apath[:len(pd)]:
+ assert apath[len(pd)] in [os.sep],`path,apath[len(pd)]`
+ path = apath[len(pd)+1:]
return path
def get_path(mod_name, parent_path=None):
@@ -135,6 +141,7 @@ def minrelpath(path):
def _fix_paths(paths,local_path,include_non_existing):
assert is_sequence(paths), repr(type(paths))
new_paths = []
+ assert not is_string(paths),`paths`
for n in paths:
if is_string(n):
if '*' in n or '?' in n:
@@ -159,8 +166,9 @@ def _fix_paths(paths,local_path,include_non_existing):
elif include_non_existing:
new_paths.append(n)
if not os.path.exists(n):
- print 'non-existing path in %r: %s' \
+ print 'non-existing path in %r: %r' \
% (local_path,n)
+
elif is_sequence(n):
new_paths.extend(_fix_paths(n,local_path,include_non_existing))
else:
@@ -278,6 +286,9 @@ def is_sequence(seq):
return False
return True
+def is_glob_pattern(s):
+ return '*' in s or '?' is s
+
def as_list(seq):
if is_sequence(seq):
return list(seq)
@@ -367,6 +378,32 @@ def general_source_files(top_path):
if not prune_file_pat.search(f):
yield os.path.join(dirpath, f)
+def general_source_directories_files(top_path):
+ """ Return a directory name relative to top_path and
+ files contained.
+ """
+ pruned_directories = ['CVS','.svn','build']
+ prune_file_pat = re.compile(r'(?:^\..*|[~#]|\.py[co]|\.o)$')
+ for dirpath, dirnames, filenames in os.walk(top_path, topdown=True):
+ pruned = [ d for d in dirnames if d not in pruned_directories ]
+ dirnames[:] = pruned
+ for d in dirnames:
+ dpath = os.path.join(dirpath, d)
+ rpath = rel_path(dpath, top_path)
+ files = []
+ for f in os.listdir(dpath):
+ fn = os.path.join(dpath,f)
+ if os.path.isfile(fn) and not prune_file_pat.search(fn):
+ files.append(fn)
+ yield rpath, files
+ dpath = top_path
+ rpath = rel_path(dpath, top_path)
+ filenames = [os.path.join(dpath,f) for f in os.listdir(dpath) \
+ if not prune_file_pat.search(f)]
+ files = [f for f in filenames if os.path.isfile(f)]
+ yield rpath, files
+
+
def get_ext_source_files(ext):
# Get sources and any include files in the same directory.
filenames = []
@@ -466,7 +503,6 @@ class Configuration(object):
caller_frame = get_frame(caller_level)
caller_name = eval('__name__',caller_frame.f_globals,caller_frame.f_locals)
self.local_path = get_path(caller_name, top_path)
-
if top_path is None:
top_path = self.local_path
self.local_path = '.'
@@ -536,6 +572,7 @@ class Configuration(object):
""" Return configuration distionary suitable for passing
to distutils.core.setup() function.
"""
+ self._optimize_data_files()
d = {}
for n in self.list_keys + self.dict_keys + self.extra_keys:
a = getattr(self,n)
@@ -692,10 +729,11 @@ class Configuration(object):
if not config_list:
self.warn('No configuration returned, assuming unavailable.')
for config in config_list:
- try:
+ d = config
+ if isinstance(config, Configuration):
d = config.todict()
- except AttributeError:
- d = config
+ assert isinstance(d,dict),`type(d)`
+
self.info('Appending %s configuration to %s' \
% (d.get('name'), self.name))
self.dict_append(**d)
@@ -712,33 +750,76 @@ class Configuration(object):
- 2-sequence (<datadir suffix>,<path to data directory>)
- path to data directory where python datadir suffix defaults
to package dir.
- If path is not absolute then it's datadir suffix is
- `package dir + basename(subdirname)` of the path.
+
+ Rules for installation paths:
+ foo/bar -> (foo/bar, foo/bar) -> parent/foo/bar
+ (gun, foo/bar) -> parent/gun
+ foo/* -> (foo/a, foo/a), (foo/b, foo/b) -> parent/foo/a, parent/foo/b
+ (gun, foo/*) -> (gun, foo/a), (gun, foo/b) -> gun
+ (gun/*, foo/*) -> parent/gun/a, parent/gun/b
+ /foo/bar -> (bar, /foo/bar) -> parent/bar
+ (gun, /foo/bar) -> parent/gun
+ (fun/*/gun/*, sun/foo/bar) -> parent/fun/foo/gun/bar
"""
if is_sequence(data_path):
d, data_path = data_path
else:
d = None
+ if is_sequence(data_path):
+ [self.add_data_dir((d,p)) for p in data_path]
+ return
if not is_string(data_path):
raise TypeError("not a string: %r" % (data_path,))
- for path in self.paths(data_path):
- if not os.path.exists(path):
- self.warn("Not existing data dir: %s" % (path))
- continue
- filenames = list(general_source_files(path))
- if not os.path.isabs(path):
- npath = data_path
- if '*' in npath:
- npath = os.path.join(*(path.split(os.sep)[-len(npath.split(os.sep)):]))
- if d is None:
- d = self.path_in_package
- ds = os.path.join(d, npath)
- self.add_data_files((ds,filenames))
+ if d is None:
+ if os.path.isabs(data_path):
+ return self.add_data_dir((os.path.basename(data_path), data_path))
+ return self.add_data_dir((data_path, data_path))
+ paths = self.paths(data_path, include_non_existing=False)
+ if is_glob_pattern(data_path):
+ if is_glob_pattern(d):
+ pattern_list = d.split(os.sep)
+ pattern_list.reverse()
+ for path in paths:
+ path_list = path.split(os.sep)
+ path_list.reverse()
+ target_list = []
+ i = 0
+ for s in pattern_list:
+ if is_glob_pattern(s):
+ if i>=len(path_list):
+ raise ValueError,'cannot fill pattern %r with %r' \
+ % (d, path)
+ target_list.append(path_list[i])
+ i += 1
+ else:
+ target_list.append(s)
+ target_list.reverse()
+ self.add_data_dir((os.sep.join(target_list),path))
else:
- if d is None:
- self.add_data_files(*filenames)
- else:
- self.add_data_files((d,filenames))
+ for path in paths:
+ self.add_data_dir((d,path))
+ return
+ assert not is_glob_pattern(d),`d`
+
+ dist = self.get_distribution()
+ if dist is not None:
+ data_files = dist.data_files
+ else:
+ data_files = self.data_files
+
+ for path in paths:
+ for d1,f in list(general_source_directories_files(path)):
+ target_path = os.path.join(self.path_in_package,d,d1)
+ data_files.append((target_path, f))
+ return
+
+ def _optimize_data_files(self):
+ data_dict = {}
+ for p,files in self.data_files:
+ if not data_dict.has_key(p):
+ data_dict[p] = set()
+ map(data_dict[p].add,files)
+ self.data_files[:] = [(p,list(files)) for p,files in data_dict.items()]
return
def add_data_files(self,*files):
@@ -747,61 +828,82 @@ class Configuration(object):
- 2-sequence (<datadir prefix>,<path to data file(s)>)
- paths to data files where python datadir prefix defaults
to package dir.
- If path is not absolute then it's datadir prefix is
- package dir + dirname of the path.
+
+ Rules for installation paths:
+ file.txt -> (., file.txt)-> parent/file.txt
+ foo/file.txt -> (foo, foo/file.txt) -> parent/foo/file.txt
+ /foo/bar/file.txt -> (., /foo/bar/file.txt) -> parent/file.txt
+ *.txt -> parent/a.txt, parent/b.txt
+ foo/*.txt -> parent/foo/a.txt, parent/foo/b.txt
+ */*.txt -> (*, */*.txt) -> parent/c/a.txt, parent/d/b.txt
+ (sun, file.txt) -> parent/sun/file.txt
+ (sun, bar/file.txt) -> parent/sun/file.txt
+ (sun, /foo/bar/file.txt) -> parent/sun/file.txt
+ (sun, *.txt) -> parent/sun/a.txt, parent/sun/b.txt
+ (sun, bar/*.txt) -> parent/sun/a.txt, parent/sun/b.txt
+ (sun/*, */*.txt) -> parent/sun/c/a.txt, parent/d/b.txt
"""
- data_dict = {}
- new_files = []
- for p in files:
- if not is_sequence(p):
- d = self.path_in_package
- if is_string(p) and not os.path.isabs(p):
- pd = os.path.dirname(p)
- if '*' in pd:
- pn = os.path.basename(p)
- n = len(pd.split(os.sep))
- for d1 in filter(os.path.isdir,self.paths(pd)):
- p = os.path.join(d1,pn)
- d1 = os.sep.join(d1.split(os.sep)[-n:])
- new_files.append((appendpath(d,d1),p))
- continue
- d = appendpath(d,pd)
- p = (d,p)
- new_files.append(p)
-
- files = []
- for prefix,filepattern in new_files:
- assert '*' not in prefix, repr((prefix,filepattern))
- if is_string(filepattern):
- file_list = self.paths(filepattern,include_non_existing=False)
- elif callable(filepattern):
- file_list = [filepattern]
+
+ if len(files)>1:
+ map(self.add_data_files, files)
+ return
+ assert len(files)==1
+ if is_sequence(files[0]):
+ d,files = files[0]
+ else:
+ d = None
+ if is_string(files):
+ filepat = files
+ elif is_sequence(files):
+ if len(files)==1:
+ filepat = files[0]
else:
- file_list = self.paths(*filepattern)
+ for f in files:
+ self.add_data_files((d,f))
+ return
+ else:
+ raise TypeError,`type(files)`
- nof_path_components = [len(f.split(os.sep))
- for f in file_list if is_string(f)]
- if nof_path_components:
- min_path_components = min(nof_path_components)-1
+ if d is None:
+ if os.path.isabs(filepat):
+ d = ''
else:
- min_path_components = 0
+ d = os.path.dirname(filepat)
+ self.add_data_files((d,files))
+ return
- for f in file_list:
- if is_string(f):
- extra_path_components = f.split(os.sep)[min_path_components:-1]
- p = njoin([prefix]+extra_path_components)
- else:
- p = prefix
- if not data_dict.has_key(p):
- data_dict[p] = [f]
- else:
- data_dict[p].append(f)
+ paths = self.paths(filepat, include_non_existing=False)
+ if is_glob_pattern(filepat):
+ if is_glob_pattern(d):
+ pattern_list = d.split(os.sep)
+ pattern_list.reverse()
+ for path in paths:
+ path_list = path.split(os.sep)
+ path_list.reverse()
+ path_list.pop() # filename
+ target_list = []
+ i = 0
+ for s in pattern_list:
+ if is_glob_pattern(s):
+ target_list.append(path_list[i])
+ i += 1
+ else:
+ target_list.append(s)
+ target_list.reverse()
+ self.add_data_files((os.sep.join(target_list), path))
+ else:
+ self.add_data_files((d,paths))
+ return
+ assert not is_glob_pattern(d),`d,filepat`
dist = self.get_distribution()
if dist is not None:
- dist.data_files.extend(data_dict.items())
+ data_files = dist.data_files
else:
- self.data_files.extend(data_dict.items())
+ data_files = self.data_files
+
+ data_files.append((os.path.join(self.path_in_package,d),paths))
+ return
### XXX Implement add_py_modules
@@ -973,13 +1075,14 @@ class Configuration(object):
return
def __str__(self):
+ from pprint import pformat
known_keys = self.list_keys + self.dict_keys + self.extra_keys
s = '<'+5*'-' + '\n'
s += 'Configuration of '+self.name+':\n'
for k in known_keys:
a = getattr(self,k,None)
if a:
- s += '%s = %r\n' % (k,a)
+ s += '%s = %s\n' % (k,pformat(a))
s += 5*'-' + '>'
return s
@@ -1131,7 +1234,7 @@ class Configuration(object):
return target
- self.add_data_files((self.path_in_package, generate_svn_version_py()))
+ self.add_data_files(('', generate_svn_version_py()))
def make_config_py(self,name='__config__'):
""" Generate package __config__.py file containing system_info
diff --git a/numpy/distutils/setup.py b/numpy/distutils/setup.py
index ae84e290c..f26cf89af 100644
--- a/numpy/distutils/setup.py
+++ b/numpy/distutils/setup.py
@@ -1,15 +1,15 @@
#!/usr/bin/env python
-from numpy.distutils.core import setup
-from numpy.distutils.misc_util import Configuration
def configuration(parent_package='',top_path=None):
+ from numpy.distutils.misc_util import Configuration
config = Configuration('distutils',parent_package,top_path)
config.add_subpackage('command')
config.add_subpackage('fcompiler')
config.add_data_dir('tests')
config.add_data_files('site.cfg')
config.make_config_py()
- return config.todict()
+ return config
if __name__ == '__main__':
- setup(**configuration(top_path=''))
+ from numpy.distutils.core import setup
+ setup(**configuration(top_path='').todict())
diff --git a/numpy/doc/DISTUTILS.txt b/numpy/doc/DISTUTILS.txt
index 990eebc90..4620af0f0 100644
--- a/numpy/doc/DISTUTILS.txt
+++ b/numpy/doc/DISTUTILS.txt
@@ -149,7 +149,7 @@ in writing setup scripts:
::
config.add_data_files('foo.dat',
- ('fun',['gun.dat','nun/pun.dat','/tmp/sun.dat']),
+ ('fun',['gun.dat','nun/pun.dat','/tmp/sun.dat']),
'bar/car.dat'.
'/full/path/to/can.dat',
)
@@ -162,9 +162,8 @@ in writing setup scripts:
foo.dat
fun/
gun.dat
- nun/
- pun.dat
- sun.dat
+ pun.dat
+ sun.dat
bar/
car.dat
can.dat
@@ -204,7 +203,8 @@ in writing setup scripts:
car.dat
gun/
foo.dat
- car.dat
+ bar/
+ car.dat
+ ``config.add_include_dirs(*paths)`` --- prepend ``paths`` to
``include_dirs`` list. This list will be visible to all extension