From cb84c0521c474f5f3351622225b1aa69b3e729c0 Mon Sep 17 00:00:00 2001 From: maxbachmann Date: Sat, 29 Feb 2020 18:17:00 +0100 Subject: [PATCH] add setup.py to build python version --- .gitignore | 5 +- VERSION | 1 + cpp/fuzz.hpp | 4 +- python/rapidfuzz.cpp | 16 ++++++ setup.py | 113 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 136 insertions(+), 3 deletions(-) create mode 100644 VERSION create mode 100644 python/rapidfuzz.cpp create mode 100644 setup.py diff --git a/.gitignore b/.gitignore index dbe9c82..9f0a931 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ -.vscode/ \ No newline at end of file +.vscode/ +*.data +*.so +test.py \ No newline at end of file diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..8a9ecc2 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +0.0.1 \ No newline at end of file diff --git a/cpp/fuzz.hpp b/cpp/fuzz.hpp index ff0bbd7..8a8c70b 100644 --- a/cpp/fuzz.hpp +++ b/cpp/fuzz.hpp @@ -55,7 +55,7 @@ uint8_t full_ratio(const std::string &query, const std::string &choice, } -uint8_t partial_ratio(const std::string &query, const std::string &choice, +/*uint8_t partial_ratio(const std::string &query, const std::string &choice, uint8_t partial_scale, uint8_t score_cutoff) { float sratio = normalized_levenshtein(query, choice); @@ -69,7 +69,7 @@ uint8_t partial_ratio(const std::string &query, const std::string &choice, } } return static_cast(std::round(sratio * 100.0)); -} +}*/ uint8_t ratio(const std::string &query, const std::string &choice, diff --git a/python/rapidfuzz.cpp b/python/rapidfuzz.cpp new file mode 100644 index 0000000..fa26fd4 --- /dev/null +++ b/python/rapidfuzz.cpp @@ -0,0 +1,16 @@ +#include +#include +#include "process.hpp" + + +PYBIND11_MODULE(rapidfuzz, m) { + m.doc() = R"pbdoc( + rapid string matching library + )pbdoc"; + + m.def("extract_one", &extract_one, R"pbdoc( + Find the best match in a list of matches + )pbdoc"); + + m.attr("__version__") = VERSION_INFO; +} \ No newline at end of file diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..02a7988 --- /dev/null +++ b/setup.py @@ -0,0 +1,113 @@ +from setuptools import setup, Extension +from setuptools.command.build_ext import build_ext +import sys +import setuptools + +with open("VERSION", "r") as version_file: + version = version_file.read().strip() + + +class get_pybind_include(object): + """Helper class to determine the pybind11 include path + + The purpose of this class is to postpone importing pybind11 + until it is actually installed, so that the ``get_include()`` + method can be invoked. """ + + def __init__(self, user=False): + self.user = user + + def __str__(self): + import pybind11 + return pybind11.get_include(self.user) + + +ext_modules = [ + Extension( + 'rapidfuzz', + ['python/rapidfuzz.cpp'], + include_dirs=[ + # Path to pybind11 headers + get_pybind_include(), + get_pybind_include(user=True), + "cpp" + ], + extra_compile_args = ["-O3"], + language='c++' + ), +] + + +# As of Python 3.6, CCompiler has a `has_flag` method. +# cf http://bugs.python.org/issue26689 +def has_flag(compiler, flagname): + """Return a boolean indicating whether a flag name is supported on + the specified compiler. + """ + import tempfile + with tempfile.NamedTemporaryFile('w', suffix='.cpp') as f: + f.write('int main (int argc, char **argv) { return 0; }') + try: + compiler.compile([f.name], extra_postargs=[flagname]) + except setuptools.distutils.errors.CompileError: + return False + return True + + +def cpp_flag(compiler): + """Return the -std=c++17 compiler flag. + + The newer version is prefered over c++17 (when it is available). + """ + if has_flag(compiler, '-std=c++17'): return '-std=c++17' + + raise RuntimeError('Unsupported compiler -- at least C++17 support ' + 'is needed!') + + +class BuildExt(build_ext): + """A custom build extension for adding compiler-specific options.""" + c_opts = { + 'msvc': ['/EHsc'], + 'unix': ['-ffast-math'], + } + l_opts = { + 'msvc': [], + 'unix': [], + } + + if sys.platform == 'darwin': + darwin_opts = ['-stdlib=libc++', '-mmacosx-version-min=10.7'] + c_opts['unix'] += darwin_opts + l_opts['unix'] += darwin_opts + + def build_extensions(self): + ct = self.compiler.compiler_type + opts = self.c_opts.get(ct, []) + link_opts = self.l_opts.get(ct, []) + if ct == 'unix': + opts.append('-DVERSION_INFO="%s"' % self.distribution.get_version()) + opts.append(cpp_flag(self.compiler)) + if has_flag(self.compiler, '-fvisibility=hidden'): + opts.append('-fvisibility=hidden') + elif ct == 'msvc': + opts.append('/DVERSION_INFO=\\"%s\\"' % self.distribution.get_version()) + for ext in self.extensions: + ext.extra_compile_args = opts + ext.extra_link_args = link_opts + build_ext.build_extensions(self) + +setup( + name='rapidfuzz', + version=version, + author='Max Bachmann', + author_email='contact@maxbachmann.de', + url='https://github.com/rhasspy/rapidfuzz', + description='rapid string matching library', + long_description='', + ext_modules=ext_modules, + install_requires=['pybind11>=2.4'], + setup_requires=['pybind11>=2.4'], + cmdclass={'build_ext': BuildExt}, + zip_safe=False, +) \ No newline at end of file