summaryrefslogtreecommitdiff
path: root/setup.py
diff options
context:
space:
mode:
authorAnthon van der Neut <anthon@mnt.org>2017-01-18 09:32:22 +0100
committerAnthon van der Neut <anthon@mnt.org>2017-01-18 09:32:22 +0100
commit87a5ef4574e4cb666ab0752e729693ad1ab3d782 (patch)
tree89e81d64b84c355f4e1c912e6beb76a44315a3e9 /setup.py
parentf6fe5bcac3694c10e3300875398b1f94873dd091 (diff)
downloadruamel.yaml-87a5ef4574e4cb666ab0752e729693ad1ab3d782.tar.gz
fix deepcopy of TimeStamp, fix #91: crash if no compiler0.13.8
Diffstat (limited to 'setup.py')
-rw-r--r--setup.py146
1 files changed, 131 insertions, 15 deletions
diff --git a/setup.py b/setup.py
index 1807402..495d08a 100644
--- a/setup.py
+++ b/setup.py
@@ -39,6 +39,12 @@ if sys.version_info < (3, 4):
class NameConstant:
pass
+if sys.version_info < (3, ):
+ open_kw = dict()
+else:
+ open_kw = dict(encoding='utf-8')
+
+
if sys.version_info < (2, 7) or platform.python_implementation() == 'Jython':
class Set():
pass
@@ -119,7 +125,7 @@ def literal_eval(node_or_string):
# parses python ( "= dict( )" ) or ( "= {" )
def _package_data(fn):
data = {}
- with open(fn) as fp:
+ with open(fn, **open_kw) as fp:
parsing = False
lines = []
for line in fp.readlines():
@@ -225,6 +231,74 @@ class MyInstallLib(install_lib.install_lib):
return alt_files
+class InMemoryZipFile(object):
+ def __init__(self, file_name=None):
+ try:
+ from cStringIO import StringIO
+ except ImportError:
+ from io import BytesIO as StringIO
+ import zipfile
+ self.zip_file = zipfile
+ # Create the in-memory file-like object
+ self._file_name = file_name
+ self.in_memory_data = StringIO()
+ # Create the in-memory zipfile
+ self.in_memory_zip = self.zip_file.ZipFile(
+ self.in_memory_data, "w", self.zip_file.ZIP_DEFLATED, False)
+ self.in_memory_zip.debug = 3
+
+ def append(self, filename_in_zip, file_contents):
+ '''Appends a file with name filename_in_zip and contents of
+ file_contents to the in-memory zip.'''
+ self.in_memory_zip.writestr(filename_in_zip, file_contents)
+ return self # so you can daisy-chain
+
+ def write_to_file(self, filename):
+ '''Writes the in-memory zip to a file.'''
+ # Mark the files as having been created on Windows so that
+ # Unix permissions are not inferred as 0000
+ for zfile in self.in_memory_zip.filelist:
+ zfile.create_system = 0
+ self.in_memory_zip.close()
+ with open(filename, 'wb') as f:
+ f.write(self.in_memory_data.getvalue())
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, exc_type, exc_value, traceback):
+ if self._file_name is None:
+ return
+ self.write_to_file(self._file_name)
+
+ def delete_from_zip_file(self, pattern=None, file_names=None):
+ """
+ zip_file can be a string or a zipfile.ZipFile object, the latter will be closed
+ any name in file_names is deleted, all file_names provided have to be in the ZIP
+ archive or else an IOError is raised
+ """
+ if pattern and isinstance(pattern, string_type):
+ import re
+ pattern = re.compile(pattern)
+ if file_names:
+ if not isinstance(file_names, list):
+ file_names = [file_names]
+ else:
+ file_names = []
+ with self.zip_file.ZipFile(self._file_name) as zf:
+ for l in zf.infolist():
+ if l.filename in file_names:
+ file_names.remove(l.filename)
+ continue
+ if pattern and pattern.match(l.filename):
+ continue
+ self.append(l.filename, zf.read(l))
+ if file_names:
+ raise IOError('[Errno 2] No such file{}: {}'.format(
+ '' if len(file_names) == 1 else 's',
+ ', '.join([repr(f) for f in file_names])))
+
+
class NameSpacePackager(object):
def __init__(self, pkg_data):
assert isinstance(pkg_data, dict)
@@ -232,6 +306,7 @@ class NameSpacePackager(object):
self.full_package_name = self.pn(self._pkg_data['full_package_name'])
self._split = None
self.depth = self.full_package_name.count('.')
+ self.nested = self._pkg_data.get('nested', False)
self.command = None
self.python_version()
self._pkg = [None, None] # required and pre-installable packages
@@ -526,6 +601,11 @@ class NameSpacePackager(object):
packages = ir.get('any', [])
if isinstance(packages, string_type):
packages = packages.split() # assume white space separated string
+ if self.nested:
+ # parent dir is also a package, make sure it is installed (need its .pth file)
+ parent_pkg = self.full_package_name.rsplit('.', 1)[0]
+ if parent_pkg not in packages:
+ packages.append(parent_pkg)
implementation = platform.python_implementation()
if implementation == 'CPython':
pyver = 'py{0}{1}'.format(*sys.version_info)
@@ -566,8 +646,16 @@ class NameSpacePackager(object):
@property
def ext_modules(self):
- """check if the C module can be build by trying to compile a small
- program against the libyaml development library"""
+ """check if all modules specified in the value for 'ext_modules' can be build
+ that value (if not None) is a list of dicts with 'name', 'src', 'lib'
+ Optional 'test' can be used to make sure trying to compile will work on the host
+
+ creates and return the external modules as Extensions, unless that
+ is not necessary at all for the action (like --version)
+
+ test existence of compiler by using export CC=nonexistent; export CXX=nonexistent
+ """
+
if hasattr(self, '_ext_modules'):
return self._ext_modules
if '--version' in sys.argv:
@@ -582,6 +670,23 @@ class NameSpacePackager(object):
return None
except ValueError:
pass
+ self._ext_modules = []
+ no_test_compile = False
+ if '--restructuredtext' in sys.argv:
+ no_test_compile = True
+ elif 'sdist' in sys.argv:
+ no_test_compile = True
+ if no_test_compile:
+ for target in self._pkg_data.get('ext_modules', []):
+ ext = Extension(
+ self.pn(target['name']),
+ sources=[self.pn(x) for x in target['src']],
+ libraries=[self.pn(x) for x in target.get('lib')],
+ )
+ self._ext_modules.append(ext)
+ return self._ext_modules
+
+ print('sys.argv', sys.argv)
import tempfile
import shutil
from textwrap import dedent
@@ -590,16 +695,13 @@ class NameSpacePackager(object):
import distutils.ccompiler
from distutils.errors import CompileError, LinkError
- self._ext_modules = []
for target in self._pkg_data.get('ext_modules', []): # list of dicts
- test_code = target.get('test')
- libraries = [self.pn(x) for x in target.get('lib')]
ext = Extension(
self.pn(target['name']),
sources=[self.pn(x) for x in target['src']],
- libraries=libraries,
+ libraries=[self.pn(x) for x in target.get('lib')],
)
- if not test_code:
+ if 'test' not in target: # no test just hope it works
self._ext_modules.append(ext)
continue
# write a temporary .c file to compile
@@ -607,24 +709,30 @@ class NameSpacePackager(object):
try:
tmp_dir = tempfile.mkdtemp(prefix='tmp_ruamel_')
bin_file_name = 'test' + self.pn(target['name'])
+ print('test compiling', bin_file_name)
file_name = os.path.join(tmp_dir, bin_file_name + '.c')
- with open(file_name, 'w') as fp:
+ with open(file_name, 'w') as fp: # write source
fp.write(c_code)
-
# and try to compile it
compiler = distutils.ccompiler.new_compiler()
assert isinstance(compiler, distutils.ccompiler.CCompiler)
+ # do any platform specific initialisations
distutils.sysconfig.customize_compiler(compiler)
-
+ # make sure you can reach header files because compile does change dir
+ compiler.add_include_dir(os.getcwd())
+ if sys.version_info < (3, ):
+ tmp_dir = tmp_dir.encode('utf-8')
+ # used to be a different directory, not necessary
+ compile_out_dir = tmp_dir
try:
compiler.link_executable(
compiler.compile(
[file_name],
- output_dir='/', # as file_name has absolute prefix
+ output_dir=compile_out_dir,
),
bin_file_name,
output_dir=tmp_dir,
- libraries=libraries,
+ libraries=ext.libraries,
)
except CompileError:
print('compile error:', file_name)
@@ -634,7 +742,7 @@ class NameSpacePackager(object):
continue
self._ext_modules.append(ext)
except Exception as e: # NOQA
- # print('Exception:', e)
+ print('Exception:', e)
pass
finally:
shutil.rmtree(tmp_dir)
@@ -728,6 +836,14 @@ def main():
break
try_dir = os.path.dirname(try_dir)
setup(**kw)
-
+ if nsp.nested and sys.argv[:2] == ['-c', 'bdist_wheel']:
+ d = sys.argv[sys.argv.index('-d')+1]
+ for x in os.listdir(d):
+ if x.endswith('.whl'):
+ # remove .pth file from the wheel
+ full_name = os.path.join(d, x)
+ with InMemoryZipFile(full_name) as imz:
+ imz.delete_from_zip_file(nsp.full_package_name + '.*.pth')
+ break
main()