multiformats / multiformats/py-multihash

`MultihashSet` missing `Visit()` and `ForEach()` methods

Open Beginner friendly
#51 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
17
Forks
17
Avg merge
1h 5m
Merged PRs (30d)
3

Description

Go's Set type has Visit(m Multihash) bool (add if not present, return whether added) and ForEach(f func(Multihash) error) error (iterate with error propagation). Python's MultihashSet doesn't have these methods.

Problem

Go's Set:

// Visit adds a multihash only if it is not in the set already.
// Returns true if the multihash was added (was not in the set before).
func (s *Set) Visit(m Multihash) bool {
    _, ok := s.set[string(m)]
    if !ok {
        s.set[string(m)] = struct{}{}
        return true
    }
    return false
}

// ForEach runs f(m) with each multihash in the set.
// Returns immediately if f(m) returns an error.
func (s *Set) ForEach(f func(m Multihash) error) error {
    for elem := range s.set {
        mh := Multihash(elem)
        if err := f(mh); err != nil {
            return err
        }
    }
    return nil
}

Python's MultihashSet has add(), remove(), Has(), All(), __contains__, __iter__, and set operations, but not Visit() or ForEach().

Proposed Solution

Add both methods:

class MultihashSet:
    def Visit(self, mh: Multihash) -> bool:
        """Add mh if not present. Return True if it was added."""
        if not isinstance(mh, Multihash):
            raise TypeError(f"MultihashSet can only contain Multihash objects, got {type(mh)}")
        if mh in self._set:
            return False
        self._set.add(mh)
        return True

    def visit(self, mh: Multihash) -> bool:
        """Python-style alias for Visit()."""
        return self.Visit(mh)

    def ForEach(self, func):
        """Call func(mh) for each Multihash. Stop and return error if func raises."""
        for mh in self._set:
            try:
                func(mh)
            except Exception as e:
                return e
        return None

    def for_each(self, func):
        """Python-style alias for ForEach()."""
        return self.ForEach(func)

Add tests:

def test_visit():
    mh_set = MultihashSet()
    mh1 = sum(b"file1", Func.sha2_256)
    assert mh_set.visit(mh1) is True   # Added
    assert mh_set.visit(mh1) is False  # Already present

def test_for_each():
    mh_set = MultihashSet([sum(b"a", Func.sha2_256), sum(b"b", Func.sha2_256)])
    collected = []
    mh_set.for_each(lambda mh: collected.append(mh))
    assert len(collected) == 2
Related

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by locating the Python MultihashSet implementation and its existing add(), All(), and iteration tests. Add coverage for Visit()/visit() duplicate handling and ForEach()/for_each() iteration and exception behavior, then run the existing test suite to confirm the new methods match the proposed semantics.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Feature
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.