From a24d3f7739c3476c7f37a34f34b5e0716cffd82d Mon Sep 17 00:00:00 2001 From: Tal Einat Date: Sat, 12 Apr 2014 13:10:52 +0300 Subject: [PATCH] nailed down automated testing and deployment, and fixed test_generic_search_cython --- .travis.yml | 2 -- Makefile | 19 ++++++++++-- requirements.txt | 1 - setup.py | 19 ++++++++---- tests/test_generic_search_cython.py | 19 +++++++----- tox.ini | 45 ++++++++++++++++++----------- 6 files changed, 68 insertions(+), 37 deletions(-) diff --git a/.travis.yml b/.travis.yml index da48654..69aff29 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,8 +5,6 @@ install: env: - TOX_ENV=py26 - TOX_ENV=py27 - # Travis no longer supports Python 3.1 - # - TOX_ENV=py31 - TOX_ENV=py32 - TOX_ENV=py33 script: diff --git a/Makefile b/Makefile index f4ea7e9..61b45f5 100644 --- a/Makefile +++ b/Makefile @@ -1,27 +1,35 @@ -.PHONY: clean-pyc clean-build docs +.PHONY: clean clean-pyc clean-build clean-cython lint test test-all coverage docs cython release sdist help: @echo "clean-build - remove build artifacts" @echo "clean-pyc - remove Python file artifacts" + @echo "clean-cython - remove compiled cython files (*.c, *.a, *.o, *.so)" + @echo "clean - run all of the above clean commands @echo "lint - check style with flake8" @echo "test - run tests quickly with the default Python" @echo "testall - run tests on every Python version with tox" @echo "coverage - check code coverage quickly with the default Python" @echo "docs - generate Sphinx HTML documentation, including API docs" + @echo "cython - compile *.pyx to *.c with cython @echo "release - package and upload a release" @echo "sdist - package" -clean: clean-build clean-pyc +clean: clean-build clean-pyc clean-cython clean-build: rm -fr build/ rm -fr dist/ rm -fr *.egg-info + find fuzzysearch -name '*.so' -exec rm -f {} + clean-pyc: find . -name '*.pyc' -exec rm -f {} + find . -name '*.pyo' -exec rm -f {} + find . -name '*~' -exec rm -f {} + + find . -type d -name __pycache__ -exec rm -rf {} + + +clean-cython: + find fuzzysearch -name '*.pyx' | sed -n 's/\(.*\/\)*\([^\/]*\)\.pyx$$/\2/p' | xargs -I {} find . -name {}.a -o -name {}.o -o -name {}.c -o -name {}.so | grep -v '^\./build/' | xargs rm -vf lint: flake8 fuzzysearch tests @@ -46,9 +54,14 @@ docs: $(MAKE) -C docs html open docs/_build/html/index.html +fuzzysearch/_generic_search.c: fuzzysearch/_generic_search.pyx + cython fuzzysearch/_generic_search.pyx + +cython: fuzzysearch/_generic_search.c + release: clean python setup.py sdist upload -sdist: clean +sdist: clean cython python setup.py sdist ls -l dist \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index f6629e0..e69de29 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +0,0 @@ -cython diff --git a/setup.py b/setup.py index ef84b57..29a89b0 100644 --- a/setup.py +++ b/setup.py @@ -3,20 +3,27 @@ import os import sys -from Cython.Build import cythonize -try: - from setuptools import setup -except ImportError: - from distutils.core import setup +from distutils.core import setup, Extension + if sys.argv[-1] == 'publish': os.system('python setup.py sdist upload') sys.exit() +os.chdir(os.path.dirname(os.path.abspath(__file__))) readme = open('README.rst').read() history = open('HISTORY.rst').read().replace('.. :changelog:', '') +_substitutions_only_module = Extension( + 'fuzzysearch._substitutions_only', + sources=['fuzzysearch/_substitutions_only.c'], +) +_generic_search_module = Extension( + 'fuzzysearch._generic_search', + sources=['fuzzysearch/_generic_search.c'], +) + setup( name='fuzzysearch', version='0.2.2', @@ -29,7 +36,7 @@ setup( 'fuzzysearch', ], package_dir={'fuzzysearch': 'fuzzysearch'}, - ext_modules=cythonize("fuzzysearch/_generic_search.pyx"), + ext_modules=[_substitutions_only_module, _generic_search_module], include_package_data=True, install_requires=[], use_2to3=True, diff --git a/tests/test_generic_search_cython.py b/tests/test_generic_search_cython.py index 1458814..b33430e 100644 --- a/tests/test_generic_search_cython.py +++ b/tests/test_generic_search_cython.py @@ -3,11 +3,8 @@ from tests.test_levenshtein import TestFindNearMatchesLevenshteinBase from fuzzysearch.common import Match, get_best_match_in_group, group_matches from tests.test_substitutions_only import TestSubstitionsOnlyBase -import pyximport -pyimporter, pyximporter = pyximport.install() from fuzzysearch._generic_search import \ find_near_matches_generic_linear_programming as fnm_generic_lp -pyximport.uninstall(pyimporter, pyximporter) class TestGenericSearchAsLevenshtein(TestFindNearMatchesLevenshteinBase, @@ -16,8 +13,9 @@ class TestGenericSearchAsLevenshtein(TestFindNearMatchesLevenshteinBase, return [ get_best_match_in_group(group) for group in group_matches( - fnm_generic_lp(subsequence, sequence, max_l_dist, - max_l_dist, max_l_dist, max_l_dist) + fnm_generic_lp(subsequence.encode('ascii'), + sequence.encode('ascii'), + max_l_dist, max_l_dist, max_l_dist, max_l_dist) ) ] @@ -26,15 +24,20 @@ class TestGenericSearchAsSubstitutionsOnly(TestSubstitionsOnlyBase, unittest.TestCase): def search(self, subsequence, sequence, max_subs): return list( - fnm_generic_lp(subsequence, sequence, max_subs, 0, 0, max_subs) + fnm_generic_lp(subsequence.encode('ascii'), + sequence.encode('ascii'), + max_subs, 0, 0, max_subs) ) class TestGenericSearch(unittest.TestCase): def search(self, pattern, sequence, max_subs, max_ins, max_dels, max_l_dist=None): - return list(fnm_generic_lp(pattern, sequence, max_subs, - max_ins, max_dels, max_l_dist)) + return list( + fnm_generic_lp(pattern.encode('ascii'), + sequence.encode('ascii'), + max_subs, max_ins, max_dels, max_l_dist) + ) def test_empty_sequence(self): self.assertEqual([], self.search('PATTERN', '', 0, 0, 0)) diff --git a/tox.ini b/tox.ini index 47ca522..0c58e7c 100644 --- a/tox.ini +++ b/tox.ini @@ -1,42 +1,51 @@ [tox] -envlist = py26, py27, py31, py32, py33 +envlist = py26, py27, py32, py33 [testenv] -commands = python setup.py test +setenv = + CFLAGS=-Qunused-arguments + CPPFLAGS=-Qunused-arguments +changedir = {toxworkdir} deps = -r{toxinidir}/requirements.txt -r{toxinidir}/test_requirements.txt whitelist_externals = rm + cp 2to3 [testenv:py26] +setenv = + PYTHONPATH = {envtmpdir} + {[testenv]setenv} +commands = + cp -r {toxinidir}/tests/ {envtmpdir}/tests/ + unit2 discover {envtmpdir}/tests -t {envtmpdir} + rm -rf {envtmpdir}/tests deps = unittest2 mock {[testenv]deps} [testenv:py27] +setenv = + PYTHONPATH = {envtmpdir} + {[testenv]setenv} +commands = + cp -r {toxinidir}/tests/ {envtmpdir}/tests/ + python -m unittest discover {envtmpdir}/tests -t {envtmpdir} + rm -rf {envtmpdir}/tests deps = mock {[testenv]deps} biopython -[testenv:py31] -changedir = {toxworkdir} -commands = - 2to3 -n -W --output-dir {envtmpdir}/tests3 {toxinidir}/tests - {envpython} -m unittest2 discover {envtmpdir}/tests3 - rm -rf {envtmpdir}/tests3 -deps = - unittest2py3k - mock - {[testenv]deps} - [testenv:py32] -changedir = {toxworkdir} +setenv = + PYTHONPATH = {envtmpdir}/tests3 + {[testenv]setenv} commands = - 2to3 -n -W --output-dir {envtmpdir}/tests3 {toxinidir}/tests + 2to3 -n -W --output-dir {envtmpdir}/tests3/tests {toxinidir}/tests {envpython} -m unittest discover {envtmpdir}/tests3 rm -rf {envtmpdir}/tests3 deps = @@ -44,9 +53,11 @@ deps = {[testenv]deps} [testenv:py33] -changedir = {toxworkdir} +setenv = + PYTHONPATH = {envtmpdir}/tests3 + {[testenv]setenv} commands = - 2to3 -n -W --output-dir {envtmpdir}/tests3 {toxinidir}/tests + 2to3 -n -W --output-dir {envtmpdir}/tests3/tests {toxinidir}/tests {envpython} -m unittest discover {envtmpdir}/tests3 rm -rf {envtmpdir}/tests3 deps =