diff --git a/.travis.yml b/.travis.yml index a737ee555f1fa7a9856e0b7e432fbc68cb296d1b..7f1c66d9c5563e398caddba03372f9d007d0bcf2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,3 +15,5 @@ install: after_success: - cd .. - bash build.sh +env: + - DEBUG=true diff --git a/CHANGELOG.md b/CHANGELOG.md index ffbfe9e60f98b4a542673c1f600b355aac7f3538..ae289127a790ccfb9e21922da1f7e44863831a8d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ -# v1.2.4 +# v1.3 -* _TBA_ +* added an option to build every file as a separate extension, for + usage in tests # v1.2.3 diff --git a/example/__init__.py b/example/__init__.py index fa84e47ee529b348bfcf12c1c64433e3c127dde4..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 --- a/example/__init__.py +++ b/example/__init__.py @@ -1,5 +0,0 @@ -import logging -import typing as tp - -logger = logging.getLogger(__name__) - diff --git a/example/setup.py b/example/setup.py index b0832cd52d13aa9a62f71e117b28cbcfc8766c64..f209796191579ef0aa1dcaeb124fb1643409215e 100644 --- a/example/setup.py +++ b/example/setup.py @@ -1,3 +1,5 @@ +import os + from setuptools import setup from snakehouse import Multibuild, build, monkey_patch_parallel_compilation @@ -5,6 +7,11 @@ from setuptools import Extension monkey_patch_parallel_compilation() +dont_snakehouse = False +if 'DEBUG' in os.environ: + dont_snakehouse = True + + # note that you can include standard Extension classes in this list, those won't be touched # and will be directed directly to Cython.Build.cythonize() cython_multibuilds = [ @@ -14,9 +21,11 @@ cython_multibuilds = [ 'example_module/test3/test3.pyx', 'example_module/test3/test2.pyx', 'example_module/test_n.c'], - define_macros=[("CYTHON_TRACE_NOGIL", "1")]), + define_macros=[("CYTHON_TRACE_NOGIL", "1")], + dont_snakehouse=dont_snakehouse), Extension('example2.example', ['example2/example.pyx']), - Multibuild('example3.example3.example3', ['example3/example3/example3/test.pyx']) + Multibuild('example3.example3.example3', ['example3/example3/example3/test.pyx'], + dont_snakehouse=dont_snakehouse) ] # first argument is used directly by snakehouse, the rest and **kwargs are passed to diff --git a/snakehouse/__init__.py b/snakehouse/__init__.py index 6cf364013c0d023d39172e521913eab8f1a966d8..d5071426b7fa70055f26afaa8cdab2abd62698a5 100644 --- a/snakehouse/__init__.py +++ b/snakehouse/__init__.py @@ -2,4 +2,4 @@ from .build import build from .multibuild import Multibuild from .faster_builds import monkey_patch_parallel_compilation -__version__ = '1.2.4a2' +__version__ = '1.3a1' diff --git a/snakehouse/build.py b/snakehouse/build.py index 1d4329ef237a668194a92e7809f9047ddb80a8f4..6d333fb651d3d16a8e4cd9ed6aa8e5767a0fe1c9 100644 --- a/snakehouse/build.py +++ b/snakehouse/build.py @@ -18,7 +18,7 @@ def build(extensions: tp.List[MultiBuildType], *args, **kwargs): elif isinstance(multi_build, Multibuild): multi_build.generate() multi_builds.append(multi_build) - returns.append(multi_build.for_cythonize()) + returns.extend(multi_build.for_cythonize()) else: raise ValueError('Invalid value in list, expected either an instance of Multibuild ' 'or an Extension') @@ -26,4 +26,4 @@ def build(extensions: tp.List[MultiBuildType], *args, **kwargs): for multi_build in multi_builds: multi_build.do_after_cython() logger.warning(multi_build.module_name_to_loader_function) - return values \ No newline at end of file + return values diff --git a/snakehouse/multibuild.py b/snakehouse/multibuild.py index baba3d9e1939dd2991a679d1c6ee47737699d42c..7a1137a0262e64c5294387acd9d17730371e4e82 100644 --- a/snakehouse/multibuild.py +++ b/snakehouse/multibuild.py @@ -52,10 +52,14 @@ class Multibuild: :param extension_name: the module name :param files: list of pyx and c files :param kwargs: extra arguments to be passed to Extension() object + :param dont_snakehouse: snakehouse won't be enabled, each element will be built + as a separate extension. It is for these cases when you're testing and something segfaults. """ - def __init__(self, extension_name: str, files: tp.Iterator[str], **kwargs): + def __init__(self, extension_name: str, files: tp.Iterator[str], + dont_snakehouse: bool = False,**kwargs): # sanitize path separators so that Linux-style paths are supported on Windows files = list(files) + self.dont_snakehouse = dont_snakehouse self.kwargs = kwargs if files: files = [os.path.join(*split(file)) for file in files] @@ -137,6 +141,8 @@ class Multibuild: return path, name, cmod_name_path, module_name, coded_module_name, complete_module_name def do_after_cython(self): + if self.dont_snakehouse: + return self.generate_header_files() for filename in self.pyx_files: path, name, cmod_name_path, module_name, coded_module_name, complete_module_name = self.transform_module_name(filename) @@ -189,14 +195,22 @@ class Multibuild: f_out.write(data) def generate(self): - if self.do_generate: + if not self.dont_snakehouse and self.do_generate: self.write_bootstrap_file() self.alter_init() def for_cythonize(self, *args, **kwargs): - kwargs.update(self.kwargs) - for_cythonize = [*self.files, os.path.join(self.bootstrap_directory, '__bootstrap__.pyx')] - return Extension(self.extension_name+".__bootstrap__", - for_cythonize, - *args, - **kwargs) + if self.dont_snakehouse: + extensions = [] + for pyx_file in self.pyx_files: + ext = Extension(pyx_file.replace(os.pathsep, '.')[:-4], + [pyx_file]) + extensions.append(ext) + return extensions + else: + kwargs.update(self.kwargs) + for_cythonize = [*self.files, os.path.join(self.bootstrap_directory, '__bootstrap__.pyx')] + return [Extension(self.extension_name+".__bootstrap__", + for_cythonize, + *args, + **kwargs)]