Skip to content

fix: deduplicate get_close_matches suggestions and support iterator targets#5664

Open
eeshsaxena wants to merge 1 commit into
kedro-org:mainfrom
eeshsaxena:fix/get-close-matches-duplicates
Open

fix: deduplicate get_close_matches suggestions and support iterator targets#5664
eeshsaxena wants to merge 1 commit into
kedro-org:mainfrom
eeshsaxena:fix/get-close-matches-duplicates

Conversation

@eeshsaxena

Copy link
Copy Markdown

Description

get_close_matches (in kedro/utils.py) has two issues when it receives a list of inputs:

  1. Duplicate suggestions. Matches are collected per input and concatenated, so a target matched by more than one input is repeated. This surfaces in the user-facing "did you mean one of these instead: ..." text of PipelineError (via _validate_datasets_exist in kedro/pipeline/pipeline.py). For example:

    get_close_matches(["pipelin", "pipeine"], ["pipeline", "catalog"])
    # ['pipeline', 'pipeline']   <- 'pipeline' repeated
  2. targets iterable can be exhausted. targets is typed as Iterable[str], but list(targets) was called once per input inside the loop. A one-shot iterable (e.g. a generator) is consumed on the first input, so later inputs match against an empty list and silently return nothing.

Development notes

  • Materialize targets = list(targets) once, before iterating the inputs.
  • Deduplicate matches while preserving order (first-seen), so shared matches appear only once.
  • Unified the str and list input handling; single-string behaviour is unchanged (a single difflib.get_close_matches call already returns unique, score-ordered results).

Testing:

  • Added two regression tests to TestGetCloseMatches in tests/test_utils.py: one asserting shared matches are deduplicated, one passing a generator as targets. Both fail on main and pass with this change; the existing string/list tests still pass (pytest tests/test_utils.py -k GetCloseMatches -> 4 passed).
  • Added a RELEASE.md entry under "Bug fixes and other changes".

An AI assistant helped spot and implement this; I reviewed the change and ran the tests locally.

Checklist

  • Read the contributing guidelines
  • Signed off each commit with a Developer Certificate of Origin (DCO)
  • Opened this PR as a 'Draft Pull Request' if it is work-in-progress
  • Updated the documentation to reflect the code changes
  • Added a description of this change in the RELEASE.md file
  • Added tests to cover my changes
  • Checked if this change will affect Kedro-Viz, and if so, communicated that with the Viz team

…argets

When get_close_matches received a list of inputs, targets matched by more than
one input were repeated in the returned suggestions (surfaced in the 'did you
mean' text of PipelineError). It also called list(targets) once per input, so a
one-shot iterable passed as targets would be exhausted after the first input.

Materialize targets once and deduplicate matches while preserving order.

Signed-off-by: eeshsaxena <eeshsaxena@gmail.com>
@merelcht
merelcht requested review from ankatiyar and ravi-kumar-pilla and removed request for merelcht July 16, 2026 08:19
@eeshsaxena eeshsaxena closed this Jul 16, 2026
@eeshsaxena eeshsaxena reopened this Jul 16, 2026
Comment thread tests/test_utils.py
def test_list_input_accepts_one_shot_iterator_targets(self):
# `targets` is typed as an Iterable; a generator must not be exhausted
# after matching the first input string.
targets = (name for name in ["data_science", "data_engineering"])

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
targets = (name for name in ["data_science", "data_engineering"])
targets = iter(["data_science", "data_engineering"])

@ankatiyar ankatiyar left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @eeshsaxena LGTM with a minor suggestion to make the test intent clearer

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants