From bcf9db3c886d689f4522927373d443d6a7e8702c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ma=C5=9Blanka?= <piotr.maslanka@henrietta.com.pl> Date: Sun, 28 Mar 2021 20:17:00 +0200 Subject: [PATCH] v1.4 doc added and find_* --- .gitignore | 1 + CHANGELOG.md | 5 +-- README.md | 66 +------------------------------------- docs/Makefile | 20 ++++++++++++ docs/accelerating.rst | 14 ++++++++ docs/conf.py | 54 +++++++++++++++++++++++++++++++ docs/index.rst | 57 ++++++++++++++++++++++++++++++++ docs/make.bat | 35 ++++++++++++++++++++ docs/usage.rst | 58 +++++++++++++++++++++++++++++++++ snakehouse/__init__.py | 4 +-- snakehouse/multibuild.py | 3 +- snakehouse/requirements.py | 38 +++++++++++++++++++++- 12 files changed, 284 insertions(+), 71 deletions(-) create mode 100644 docs/Makefile create mode 100644 docs/accelerating.rst create mode 100644 docs/conf.py create mode 100644 docs/index.rst create mode 100644 docs/make.bat create mode 100644 docs/usage.rst diff --git a/.gitignore b/.gitignore index 7ae2d7b..003f6b9 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ build */build */dist +docs/_build dist .eggs *.c diff --git a/CHANGELOG.md b/CHANGELOG.md index e69ac16..fcc088f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ -# v1.3.3 +# v1.4 -* _TBA_ +* added `find_pyx`, `find_c` and `find_pyx_and_c` +* added documentation # v1.3.2 diff --git a/README.md b/README.md index 32258f3..cb8b2bf 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ snakehouse [](https://pypi.python.org/pypi/snakehouse) []() []() +[](http://snakehouse.readthedocs.io/en/latest/?badge=latest) snakehouse is a tool to pack mutiple .pyx files into a single extension. @@ -26,70 +27,5 @@ a part of your pull request as well! Note what have you changed in [CHANGELOG.md](/CHANGELOG.md) as well! -Accelerating builds -------------------- - -distutils by default compiles using a single process. To enable faster, multiprocess compilations -just type: - -```python -from snakehouse import monkey_patch_parallel_compilation - -monkey_patch_parallel_compilation() -```` - -Before your `setup()` call. - Usage notes - MANDATORY READING ------------------------------- -Take a look at [example](example/) on how to multi-build your Cython extensions. - -Don't place modules compiled that way in root .py file's top level imports. -Wrap them in a layer of indirection instead! - -This applies to unit tests as well! - -When something goes wrong (eg. the application throws an unhandled exception) -the built module has a tendency to dump core. -Try to debug it first by passing `dont_snakehouse=True` to your -modules in the debug mode. - -Also note that if you are compiling in `dont_snakehouse` -mode then your modules should have at least one of the following: -* a normal Python `def` -* a normal Python class (not `cdef class`) -* a line of Python initialization, eg. - -```python -a = None -``` - -or -```python -import logging - -logger = logging.getLogger(__name__) -``` - -Otherwise `PyInit` won't be generated by Cython -and such module will be unimportable in Python. Normal import won't suffice. - -Further streamlining your builds --------------------------------- - -If you add a MANIFEST.in file with contents: - -``` -include requirements.txt -``` - -Then you can write the following in your setup.py: - -```python -from snakehouse import read_requirements_txt - -setup(install_requires=read_requirements_txt()) -``` - -This will read in your requirements.txt and extract packages from there. -Be sure to entertain it's [pydoc](snakehouse/requirements.py)! diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..d4bb2cb --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/accelerating.rst b/docs/accelerating.rst new file mode 100644 index 0000000..5c71b51 --- /dev/null +++ b/docs/accelerating.rst @@ -0,0 +1,14 @@ +Accelerating builds +=================== + +distutils by default compiles using a single process. To enable faster, multiprocess compilations +just type: + +.. code-block:: python + + from snakehouse import monkey_patch_parallel_compilation + + monkey_patch_parallel_compilation() + +Before your :code:`setup()` call. + diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..79d8e00 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,54 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os +import sys +sys.path.insert(0, os.path.abspath('..')) + + +# -- Project information ----------------------------------------------------- + +project = 'snakehouse' +copyright = '2020-2021 SMOK sp. z o. o.' +author = 'Piotr MaĹlanka' + +# The full version, including alpha/beta/rc tags +release = '1.4' + + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = ['sphinx.ext.autodoc'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'alabaster' + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..1fbf1ff --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,57 @@ +Welcome to snakehouse's documentation! +====================================== + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + usage + accelerating + + +Mandatory reading +================= + +Take a look at example_ on how to multi-build your Cython extensions. + +.. _example: https://github.com/smok-serwis/snakehouse/blob/develop/example/setup.py + +Don't place modules compiled that way in root .py file's top level imports. +Wrap them in a layer of indirection instead! + +This applies to unit tests as well! + +When something goes wrong (eg. the application throws an unhandled exception) +the built module has a tendency to dump core. +Try to debug it first by passing :code:`dont_snakehouse=True` to your +modules in the debug mode. + +Also note that if you are compiling in :code:`dont_snakehouse` +mode then your modules should have at least one of the following: + +* a normal Python :code:`def` +* a normal Python class (not :code:`cdef class`) +* a line of Python initialization, eg. + +.. code-block:: python + + a = None + +or + +.. code-block:: python + + import logging + + logger = logging.getLogger(__name__) + +Otherwise :code:`PyInit` won't be generated by Cython +and such module will be unimportable in Python. Normal import won't suffice. + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 0000000..922152e --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/docs/usage.rst b/docs/usage.rst new file mode 100644 index 0000000..43bb111 --- /dev/null +++ b/docs/usage.rst @@ -0,0 +1,58 @@ +Usage +===== + +To use snakehouse just use the following in your :code:`setup.py`: + +.. code-block:: python + + list_of_pyx_files = [ ... ] + + setup(name='example_module', + version='0.1', + packages=['example_module'], + ext_modules=Multibuild('example_module', list_of_pyx_files) + ) + +Full documentation of Multibuild is here + +.. autoclass:: snakehouse.Multibuild + :members: + +You should use :code:`dont_snakehouse` for debugging and unit tests, as +snakehouse has a sad tendency to dump core on unhandled exceptions. To prevent that +from happening remember to handle your exceptions and debug using this flag. + +Helper functions +---------------- + +Finding files +~~~~~~~~~~~~~ + +Instead of manually specifying list of pyx and c files to compile you can use the following +functions: + +.. autofunction:: snakehouse.find_pyx + +.. autofunction:: snakehouse.find_c + +.. autofunction:: snakehouse.find_pyx_and_c + +Specifying requirements +~~~~~~~~~~~~~~~~~~~~~~~ + +If you add a MANIFEST.in file with contents: + +.. code-block:: + + include requirements.txt + +Then you can write the following in your setup.py: + +.. code-block:: python + + from snakehouse import read_requirements_txt + + setup(install_requires=read_requirements_txt()) + +.. autofunction:: snakehouse.read_requirements_txt + diff --git a/snakehouse/__init__.py b/snakehouse/__init__.py index 6d8ac0d..582dff1 100644 --- a/snakehouse/__init__.py +++ b/snakehouse/__init__.py @@ -1,6 +1,6 @@ from .build import build from .multibuild import Multibuild from .faster_builds import monkey_patch_parallel_compilation -from .requirements import read_requirements_txt +from .requirements import read_requirements_txt, find_c, find_pyx_and_c, find_pyx -__version__ = '1.3.3a1' +__version__ = '1.4a1' diff --git a/snakehouse/multibuild.py b/snakehouse/multibuild.py index 50544a7..46bff48 100644 --- a/snakehouse/multibuild.py +++ b/snakehouse/multibuild.py @@ -49,11 +49,12 @@ class Multibuild: This specifies a single Cython extension, called {extension_name}.__bootstrap__ All kwargs will be sent straight to Cython's Extension + :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. + 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], dont_snakehouse: bool = False, diff --git a/snakehouse/requirements.py b/snakehouse/requirements.py index e7bedce..e4bea2a 100644 --- a/snakehouse/requirements.py +++ b/snakehouse/requirements.py @@ -1,4 +1,40 @@ -from satella.files import read_lines +import typing as tp +from satella.coding import for_argument +from satella.files import read_lines, find_files + + +@for_argument(returns=list) +def find_pyx(directory_path: str) -> tp.List[str]: + """ + Return all .pyx files found in given directory. + + :param directory_path: directory to look through + :return: .pyx files found + """ + return find_files(directory_path, r'(.*)\.pyx', scan_subdirectories=True) + + +@for_argument(returns=list) +def find_c(directory_path: str) -> tp.List[str]: + """ + Return all .c files found in given directory. + + :param directory_path: directory to look through + :return: .c files found + """ + return find_files(directory_path, r'(.*)\.c', scan_subdirectories=True) + + +def find_pyx_and_c(directory_path: str) -> tp.List[str]: + """ + Return a list of all .pyx and .c files found in given directory. + + :param directory_path: + :return: list of all .pyx and .c files found in given directory + """ + files = find_pyx(directory_path) + files.extend(find_c(directory_path)) + return files def read_requirements_txt(path: str = 'requirements.txt'): -- GitLab