From 8941becc9a92e36f0395f94cbe45541abe9fe739 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ma=C5=9Blanka?= <piotr.maslanka@henrietta.com.pl> Date: Sat, 19 Dec 2020 17:38:48 +0100 Subject: [PATCH] feature added to build the modules as separate extensions for debugging --- .travis.yml | 2 ++ CHANGELOG.md | 5 +++-- example/__init__.py | 5 ----- example/setup.py | 13 +++++++++++-- snakehouse/__init__.py | 2 +- snakehouse/build.py | 4 ++-- snakehouse/multibuild.py | 30 ++++++++++++++++++++++-------- 7 files changed, 41 insertions(+), 20 deletions(-) diff --git a/.travis.yml b/.travis.yml index a737ee5..7f1c66d 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 ffbfe9e..ae28912 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 fa84e47..e69de29 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 b0832cd..f209796 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 6cf3640..d507142 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 1d4329e..6d333fb 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 baba3d9..7a1137a 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)] -- GitLab