add python fallback in installation

This commit is contained in:
Max Bachmann 2022-07-01 00:32:10 +02:00 committed by GitHub
parent 4a52561934
commit 8128469dc0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 198 additions and 163 deletions

View File

@ -1,5 +1,11 @@
## Changelog
### [2.1.1] - 2022-06-30
#### Changed
- allow installation without the C++ extension if it fails to compile
- allow selection of implementation via the environment variable `RAPIDFUZZ_IMPLEMENTATION`
which can be set to "cpp" or "python"
### [2.1.0] - 2022-06-29
#### Added
- added pure python fallback for all implementations with the following exceptions:

View File

@ -1,8 +1,8 @@
"""
rapid string matching library
"""
__author__ = "Max Bachmann"
__license__ = "MIT"
__version__ = "2.1.0"
__author__: str = "Max Bachmann"
__license__: str = "MIT"
__version__: str = "2.1.0"
from rapidfuzz import process, distance, fuzz, string_metric, utils

View File

@ -1,16 +1,10 @@
# SPDX-License-Identifier: MIT
# Copyright (C) 2022 Max Bachmann
try:
from .Hamming_cpp import (
distance,
similarity,
normalized_distance,
normalized_similarity,
)
except ImportError:
from .Hamming_py import (
distance,
similarity,
normalized_distance,
normalized_similarity,
)
from rapidfuzz.utils import _fallback_import
_mod = "rapidfuzz.distance.Hamming"
distance = _fallback_import(_mod, "distance")
similarity = _fallback_import(_mod, "similarity")
normalized_distance = _fallback_import(_mod, "normalized_distance")
normalized_similarity = _fallback_import(_mod, "normalized_similarity")

View File

@ -1,20 +1,12 @@
# SPDX-License-Identifier: MIT
# Copyright (C) 2022 Max Bachmann
try:
from .Indel_cpp import (
distance,
similarity,
normalized_distance,
normalized_similarity,
editops,
opcodes,
)
except ImportError:
from .Indel_py import (
distance,
similarity,
normalized_distance,
normalized_similarity,
editops,
opcodes,
)
from rapidfuzz.utils import _fallback_import
_mod = "rapidfuzz.distance.Indel"
distance = _fallback_import(_mod, "distance")
similarity = _fallback_import(_mod, "similarity")
normalized_distance = _fallback_import(_mod, "normalized_distance")
normalized_similarity = _fallback_import(_mod, "normalized_similarity")
editops = _fallback_import(_mod, "editops")
opcodes = _fallback_import(_mod, "opcodes")

View File

@ -1 +1,6 @@
from jarowinkler import jaro_similarity as similarity
try:
from jarowinkler import jaro_similarity as similarity
except ImportError:
def similarity(s1, s2, *, processor=None, score_cutoff=None):
raise NotImplementedError

View File

@ -1 +1,6 @@
from jarowinkler import jarowinkler_similarity as similarity
try:
from jarowinkler import jarowinkler_similarity as similarity
except ImportError:
def similarity(s1, s2, *, prefix_weight=0.1, processor=None, score_cutoff=None):
raise NotImplementedError

View File

@ -1,20 +1,12 @@
# SPDX-License-Identifier: MIT
# Copyright (C) 2022 Max Bachmann
try:
from .LCSseq_cpp import (
distance,
similarity,
normalized_distance,
normalized_similarity,
editops,
opcodes,
)
except ImportError:
from .LCSseq_py import (
distance,
similarity,
normalized_distance,
normalized_similarity,
editops,
opcodes,
)
from rapidfuzz.utils import _fallback_import
_mod = "rapidfuzz.distance.LCSseq"
distance = _fallback_import(_mod, "distance")
similarity = _fallback_import(_mod, "similarity")
normalized_distance = _fallback_import(_mod, "normalized_distance")
normalized_similarity = _fallback_import(_mod, "normalized_similarity")
editops = _fallback_import(_mod, "editops")
opcodes = _fallback_import(_mod, "opcodes")

View File

@ -1,20 +1,12 @@
# SPDX-License-Identifier: MIT
# Copyright (C) 2022 Max Bachmann
try:
from .Levenshtein_cpp import (
distance,
similarity,
normalized_distance,
normalized_similarity,
editops,
opcodes,
)
except ImportError:
from .Levenshtein_py import (
distance,
similarity,
normalized_distance,
normalized_similarity,
editops,
opcodes,
)
from rapidfuzz.utils import _fallback_import
_mod = "rapidfuzz.distance.Levenshtein"
distance = _fallback_import(_mod, "distance")
similarity = _fallback_import(_mod, "similarity")
normalized_distance = _fallback_import(_mod, "normalized_distance")
normalized_similarity = _fallback_import(_mod, "normalized_similarity")
editops = _fallback_import(_mod, "editops")
opcodes = _fallback_import(_mod, "opcodes")

View File

@ -1,6 +1,13 @@
try:
from ._initialize_cpp import Editop, Editops, Opcode, Opcodes, ScoreAlignment
except ImportError:
from ._initialize_py import Editop, Editops, Opcode, Opcodes, ScoreAlignment
# SPDX-License-Identifier: MIT
# Copyright (C) 2022 Max Bachmann
from rapidfuzz.utils import _fallback_import
_mod = "rapidfuzz.distance._initialize"
Editop = _fallback_import(_mod, "Editop")
Editops = _fallback_import(_mod, "Editops")
Opcode = _fallback_import(_mod, "Opcode")
Opcodes = _fallback_import(_mod, "Opcodes")
ScoreAlignment = _fallback_import(_mod, "ScoreAlignment")
from . import Hamming, Indel, Jaro, JaroWinkler, Levenshtein, LCSseq

View File

@ -1,31 +1,17 @@
# SPDX-License-Identifier: MIT
# Copyright (C) 2021 Max Bachmann
try:
from rapidfuzz.fuzz_cpp import (
ratio,
partial_ratio,
partial_ratio_alignment,
token_sort_ratio,
partial_token_sort_ratio,
token_set_ratio,
partial_token_set_ratio,
token_ratio,
partial_token_ratio,
WRatio,
QRatio,
)
except ImportError:
from rapidfuzz.fuzz_py import (
ratio,
partial_ratio,
partial_ratio_alignment,
token_sort_ratio,
partial_token_sort_ratio,
token_set_ratio,
partial_token_set_ratio,
token_ratio,
partial_token_ratio,
WRatio,
QRatio,
)
from rapidfuzz.utils import _fallback_import
_mod = "rapidfuzz.fuzz"
ratio = _fallback_import(_mod, "ratio")
partial_ratio = _fallback_import(_mod, "partial_ratio")
partial_ratio_alignment = _fallback_import(_mod, "partial_ratio_alignment")
token_sort_ratio = _fallback_import(_mod, "token_sort_ratio")
token_set_ratio = _fallback_import(_mod, "token_set_ratio")
token_ratio = _fallback_import(_mod, "token_ratio")
partial_token_sort_ratio = _fallback_import(_mod, "partial_token_sort_ratio")
partial_token_set_ratio = _fallback_import(_mod, "partial_token_set_ratio")
partial_token_ratio = _fallback_import(_mod, "partial_token_ratio")
WRatio = _fallback_import(_mod, "WRatio")
QRatio = _fallback_import(_mod, "QRatio")

View File

@ -1,17 +1,16 @@
# SPDX-License-Identifier: MIT
# Copyright (C) 2021 Max Bachmann
# Copyright (C) 2022 Max Bachmann
from rapidfuzz.utils import _fallback_import
_mod = "rapidfuzz.process"
extract = _fallback_import(_mod, "extract")
extractOne = _fallback_import(_mod, "extractOne")
extract_iter = _fallback_import(_mod, "extract_iter")
try:
from rapidfuzz.process_cpp import extract, extractOne, extract_iter
cdist = _fallback_import("rapidfuzz.process_cdist", "cdist")
except ImportError:
from rapidfuzz.process_py import extract, extractOne, extract_iter
try:
from rapidfuzz.process_cdist_cpp import cdist
except ImportError:
try:
from rapidfuzz.process_cdist_py import cdist
except ImportError:
def cdist(*args, **kwargs):
raise NotImplementedError("implementation requires numpy to be installed")
def cdist(*args, **kwargs):
raise NotImplementedError("implementation requires numpy to be installed")

View File

@ -1,22 +1,13 @@
# SPDX-License-Identifier: MIT
# Copyright (C) 2021 Max Bachmann
try:
from rapidfuzz.string_metric_cpp import (
levenshtein,
normalized_levenshtein,
levenshtein_editops,
hamming,
normalized_hamming,
jaro_similarity,
jaro_winkler_similarity,
)
except ImportError:
from rapidfuzz.string_metric_py import (
levenshtein,
normalized_levenshtein,
levenshtein_editops,
hamming,
normalized_hamming,
jaro_similarity,
jaro_winkler_similarity,
)
# Copyright (C) 2022 Max Bachmann
from rapidfuzz.utils import _fallback_import
_mod = "rapidfuzz.string_metric"
levenshtein = _fallback_import(_mod, "levenshtein")
normalized_levenshtein = _fallback_import(_mod, "normalized_levenshtein")
levenshtein_editops = _fallback_import(_mod, "levenshtein_editops")
hamming = _fallback_import(_mod, "hamming")
normalized_hamming = _fallback_import(_mod, "normalized_hamming")
jaro_similarity = _fallback_import(_mod, "jaro_similarity")
jaro_winkler_similarity = _fallback_import(_mod, "jaro_winkler_similarity")

View File

@ -1,7 +1,29 @@
# SPDX-License-Identifier: MIT
# Copyright (C) 2022 Max Bachmann
try:
from rapidfuzz.utils_cpp import default_process
except ImportError:
from rapidfuzz.utils_py import default_process
def _fallback_import(module: str, name: str):
import importlib
import os
impl = os.environ.get("RAPIDFUZZ_IMPLEMENTATION")
if impl == "cpp":
mod = importlib.import_module(module + "_cpp")
elif impl == "python":
mod = importlib.import_module(module + "_py")
else:
try:
mod = importlib.import_module(module + "_cpp")
except ModuleNotFoundError:
mod = importlib.import_module(module + "_py")
func = getattr(mod, name)
if not func:
raise ImportError(
f"cannot import name '{name}' from '{mod.__name}' ({mod.__file__})"
)
return func
default_process = _fallback_import("rapidfuzz.utils", "default_process")

View File

@ -1,24 +1,28 @@
from skbuild import setup
import rapidfuzz_capi
import numpy as np
import os
def show_message(*lines):
print("=" * 74)
for line in lines:
print(line)
print("=" * 74)
with open('README.md', 'rt', encoding="utf8") as f:
readme = f.read()
setup(
name="rapidfuzz",
version="2.1.0",
install_requires=["jarowinkler >= 1.0.3, < 1.1.0"],
extras_require={'full': ['numpy']},
url="https://github.com/maxbachmann/RapidFuzz",
author="Max Bachmann",
author_email="pypi@maxbachmann.de",
description="rapid fuzzy string matching",
long_description=readme,
long_description_content_type="text/markdown",
setup_args = {
"name": "rapidfuzz",
"version": "2.0.15",
"install_requires": ["jarowinkler >= 1.0.3, < 1.1.0"],
"extras_require": {'full': ['numpy']},
"url": "https://github.com/maxbachmann/RapidFuzz",
"author": "Max Bachmann",
"author_email": "pypi@maxbachmann.de",
"description": "rapid fuzzy string matching",
"long_description": readme,
"long_description_content_type": "text/markdown",
license="MIT",
classifiers=[
"license": "MIT",
"classifiers": [
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
@ -28,12 +32,52 @@ setup(
"License :: OSI Approved :: MIT License"
],
packages=["rapidfuzz", "rapidfuzz/distance"],
package_data={
"packages": ["rapidfuzz", "rapidfuzz/distance"],
"package_data": {
"rapidfuzz": ["*.pyi", "py.typed"],
"rapidfuzz/distance": ["*.pyi"]
},
python_requires=">=3.6",
"python_requires": ">=3.6"
}
cmake_args=[f'-DRF_CAPI_PATH:STRING={rapidfuzz_capi.get_include()}', f'-DNumPy_INCLUDE_DIR:STRING={np.get_include()}']
)
def run_setup(with_binary):
if with_binary:
from skbuild import setup
import rapidfuzz_capi
import numpy as np
setup(
**setup_args,
cmake_args=[
f'-DRF_CAPI_PATH:STRING={rapidfuzz_capi.get_include()}',
f'-DNumPy_INCLUDE_DIR:STRING={np.get_include()}'
]
)
else:
from setuptools import setup
setup(**setup_args)
# when packaging only build wheels which include the C extension
packaging = "1" in {
os.environ.get("CIBUILDWHEEL", "0"),
os.environ.get("CONDA_BUILD", "0"),
os.environ.get("RAPIDFUZZ_BUILD_EXTENSION", "0")
}
if packaging:
run_setup(True)
else:
try:
run_setup(True)
except:
show_message(
"WARNING: The C extension could not be compiled, speedups"
" are not enabled.",
"Failure information, if any, is above.",
"Retrying the build without the C extension now.",
)
run_setup(False)
show_message(
"WARNING: The C extension could not be compiled, speedups"
" are not enabled.",
"Plain-Python build succeeded.",
)