Skip to content

Commit

Permalink
Remove rapidfuzz dependency (#442)
Browse files Browse the repository at this point in the history
  • Loading branch information
Secrus authored Nov 5, 2024
1 parent 395a59a commit 9698136
Show file tree
Hide file tree
Showing 6 changed files with 15 additions and 121 deletions.
1 change: 1 addition & 0 deletions news/442.deps.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Removed `rapidfuzz` dependency
107 changes: 3 additions & 104 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ classifiers = [

[tool.poetry.dependencies]
python = "^3.8"
rapidfuzz = "^3.0.0"

[tool.poetry.group.dev.dependencies]
mypy = "^1.5"
Expand Down
15 changes: 6 additions & 9 deletions src/cleo/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@
import math

from dataclasses import dataclass
from difflib import SequenceMatcher
from html.parser import HTMLParser

from rapidfuzz.distance import Levenshtein


class TagStripper(HTMLParser):
def __init__(self) -> None:
Expand Down Expand Up @@ -51,12 +50,12 @@ def find_similar_names(name: str, names: list[str]) -> list[str]:
"""
Finds names similar to a given command name.
"""
threshold = 1e3
threshold = 0.4
distance_by_name = {}

if " " in name:
names = [name for name in names if " " in name]
for actual_name in names:
# Get Levenshtein distance between the input and each command name
distance = Levenshtein.distance(name, actual_name)
distance = SequenceMatcher(None, actual_name, name).ratio()

is_similar = distance <= len(name) / 3
substring_index = actual_name.find(name)
Expand All @@ -70,9 +69,7 @@ def find_similar_names(name: str, names: list[str]) -> list[str]:

# Only keep results with a distance below the threshold
distance_by_name = {
key: value
for key, value in distance_by_name.items()
if value[0] < 2 * threshold
key: value for key, value in distance_by_name.items() if value[0] > threshold
}
# Display results with shortest distance first
return sorted(distance_by_name, key=lambda key: distance_by_name[key])
Expand Down
2 changes: 1 addition & 1 deletion tests/test_application.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ def test_find_ambiguous_namespace(app: Application) -> None:
CleoNamespaceNotFoundError,
match=(
r'There are no commands in the "f" namespace\.\n\n'
r"Did you mean one of these\?\n foo\n foo1"
r"Did you mean this\?\n foo"
),
):
app.find_namespace("f")
Expand Down
10 changes: 4 additions & 6 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,13 @@ def test_format_time(input_secs: float, expected: str) -> None:
@pytest.mark.parametrize(
["name", "expected"],
[
("", ["help", "foo1", "foo2", "bar1", "bar2", "foo bar1", "foo bar2"]),
("hellp", ["help"]),
("bar2", ["bar2", "bar1", "foo bar2"]),
("bar1", ["bar1", "bar2", "foo bar1"]),
("foo", ["foo1", "foo2", "foo bar1", "foo bar2"]),
("env add", ["env remove", "env activate", "env info", "env list", "env use"]),
("evn add", ["env activate", "env use"]),
("env", ["env remove", "env info", "env list", "env use"]),
],
)
def test_find_similar_names(name: str, expected: list[str]) -> None:
names = ["help", "foo1", "foo2", "bar1", "bar2", "foo bar1", "foo bar2"]
names = ["env info", "env use", "env activate", "env remove", "env list"]
assert find_similar_names(name, names) == expected


Expand Down

0 comments on commit 9698136

Please sign in to comment.