Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rename string1 and string2 argument names #181

Merged
merged 1 commit into from
Mar 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion symspellpy/editdistance.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ def distance(
string_2, string_1 = string_1, string_2
if len(string_2) - len(string_1) > max_distance:
return -1
# identify common suffic and/or prefix that can be ignored
# identify common suffix and/or prefix that can be ignored
len_1, len_2, start = helpers.prefix_suffix_prep(string_1, string_2)
if len_1 == 0:
return len_2 if len_2 <= max_distance else -1
Expand Down
61 changes: 41 additions & 20 deletions symspellpy/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,29 @@

import re
import sys
import warnings
from difflib import SequenceMatcher
from typing import Optional


def _rename_args(kwargs_map: dict[str, str], version: str):
def decorator(func):
def wrapped(*args, **kwargs):
new_kwargs = {}
for k, v in kwargs.items():
if k in kwargs_map:
warnings.warn(
f"Keyword argument '{k}' is deprecated and will be removed in {version}. Use '{kwargs_map[k]}' instead.",
DeprecationWarning,
)
new_kwargs[kwargs_map.get(k, k)] = v
return func(*args, **new_kwargs)

return wrapped

return decorator


def case_transfer_matching(cased_text: str, uncased_text: str) -> str:
"""Transfers the casing from one text to another - assuming that they are
'matching' texts, alias they have the same length.
Expand Down Expand Up @@ -150,27 +169,28 @@ def is_acronym(word: str, contain_digits: bool = False) -> bool:
)


@_rename_args({"string1": "string_1", "string2": "string_2"}, "v7.0.0")
def null_distance_results(
string1: Optional[str], string2: Optional[str], max_distance: int
string_1: Optional[str], string_2: Optional[str], max_distance: int
) -> int:
"""Determines the proper return value of an edit distance function when one
or both strings are null.

Args:
string1: Base string.
string2: The string to compare.
string_1: Base string.
string_2: The string to compare.
max_distance: The maximum distance allowed.

Returns:
-1 if the distance is greater than the max_distance, 0 if the strings are
equivalent (both are None), otherwise a positive number whose
magnitude is the length of the string which is not None.
"""
if string1 is None:
if string2 is None:
if string_1 is None:
if string_2 is None:
return 0
return len(string2) if len(string2) <= max_distance else -1
return len(string1) if len(string1) <= max_distance else -1
return len(string_2) if len(string_2) <= max_distance else -1
return len(string_1) if len(string_1) <= max_distance else -1


def parse_words(
Expand Down Expand Up @@ -199,35 +219,36 @@ def parse_words(
return re.findall(r"([^\W_]+['’]*[^\W_]*)", phrase.lower())


def prefix_suffix_prep(string1: str, string2: str) -> tuple[int, int, int]:
@_rename_args({"string1": "string_1", "string2": "string_2"}, "v7.0.0")
def prefix_suffix_prep(string_1: str, string_2: str) -> tuple[int, int, int]:
"""Calculates starting position and lengths of two strings such that common
prefix and suffix substrings are excluded.
Expects len(string1) <= len(string2).
Expects len(string_1) <= len(string_2).

Args:
string1: Base string.
string2: The string to compare.
string_1: Base string.
string_2: The string to compare.

Returns:
A tuple of lengths of the part excluding common prefix and suffix, and
the starting position.
"""
# this is also the minimun length of the two strings
len1 = len(string1)
len2 = len(string2)
len_1 = len(string_1)
len_2 = len(string_2)
# suffix common to both strings can be ignored
while len1 != 0 and string1[len1 - 1] == string2[len2 - 1]:
len1 -= 1
len2 -= 1
while len_1 != 0 and string_1[len_1 - 1] == string_2[len_2 - 1]:
len_1 -= 1
len_2 -= 1
# prefix common to both strings can be ignored
start = 0
while start != len1 and string1[start] == string2[start]:
while start != len_1 and string_1[start] == string_2[start]:
start += 1
if start != 0:
len1 -= start
len_1 -= start
# length of the part excluding common prefix and suffix
len2 -= start
return len1, len2, start
len_2 -= start
return len_1, len_2, start


def to_similarity(distance: int, length: int) -> float:
Expand Down
15 changes: 15 additions & 0 deletions tests/test_compatibility.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from symspellpy.helpers import null_distance_results, prefix_suffix_prep


def test_null_distance_results():
assert null_distance_results(None, None, 1) == 0
assert null_distance_results(None, string2=None, max_distance=1) == 0
assert null_distance_results(string1=None, string2=None, max_distance=1) == 0
assert null_distance_results(string_1=None, string_2=None, max_distance=1) == 0


def test_prefix_suffix_prep():
assert prefix_suffix_prep("dabca", "ddca") == (2, 1, 1)
assert prefix_suffix_prep("dabca", string2="ddca") == (2, 1, 1)
assert prefix_suffix_prep(string1="dabca", string2="ddca") == (2, 1, 1)
assert prefix_suffix_prep(string_1="dabca", string_2="ddca") == (2, 1, 1)