Skip to content

add tests for transitive_closure - #3703

Merged
ekaf merged 2 commits into
nltk:developfrom
RavSinghChandan:tests-transitive-closure-coverage
Aug 4, 2026
Merged

ekaf merged 2 commits into
nltk:developfrom
RavSinghChandan:tests-transitive-closure-coverage

Conversation

@RavSinghChandan

Copy link
Copy Markdown
Contributor

noticed transitive_closure in nltk/util.py has no unit tests, so added a few to test_util.py next to the existing everygrams ones.

covers the cases i cared about while reading it:

  • plain closure over a chain a->b->c
  • the reflexive=True path (each node includes itself)
  • a cycle, to make sure it terminates and includes both nodes
  • empty graph
  • that it doesn't mutate the input dict (it copies the sets internally, worth pinning so a future refactor doesn't break it)

all green locally, pre-commit passes.

Copilot AI 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.

Pull request overview

Adds unit tests for nltk.util.transitive_closure, improving coverage for directed-graph closure behavior and guarding against regressions in edge cases.

Changes:

  • Import transitive_closure into the existing util unit test module.
  • Add tests for chain closure, reflexive closure, cycle handling/termination, and empty graphs.
  • Add a test intended to ensure the input graph is not mutated.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread nltk/test/unit/test_util.py Outdated
Comment on lines +107 to +110
def test_transitive_closure_does_not_mutate_input():
graph = {"a": {"b"}, "b": set()}
transitive_closure(graph)
assert graph == {"a": {"b"}, "b": set()}
@ekaf

ekaf commented Jul 29, 2026

Copy link
Copy Markdown
Member

Hi @RavSinghChandan, what do you think about the unresolved review concern?

@RavSinghChandan

Copy link
Copy Markdown
Contributor Author

Good catch — you're right that value equality alone doesn't pin this.
transitive_closure copies the sets up front (agenda_graph = {k: graph[k].copy()
for k in graph}), so the input sets should stay the same objects, and that's the
guarantee worth locking down.

Updated the test to hold on to the original set objects and assert identity
after the call, alongside the value comparison. Also asserting the key set is
unchanged, since the function uses setdefault internally and a refactor could
leak that onto the input.

Checked it actually bites: patching transitive_closure to rebind the caller's
sets to new-but-equal objects passes the old assertion but fails the new one.
All 10 tests in test_util.py pass locally.

@ekaf ekaf left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The latest commit fully addresses the review concern about missing coverage for transitive_closure: it adds concrete tests for chain propagation, reflexive closure, cycles, empty graph behavior, and input non-mutation/object identity, all in nltk/test/unit/test_util.py. This is a high-quality test-only PR with clear regression value and no runtime risk, and while it is not urgent like a security fix, it is still important to merge because it hardens a core utility against silent future breakage.

@ekaf
ekaf merged commit 5f76b0a into nltk:develop Aug 4, 2026
22 checks passed
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.

3 participants