mchaput / whoosh

Pure-Python full-text search library
Other
569 stars 69 forks source link

`MultiCorrector` returns `(sug, score)` instead of `(score, sug)` #21

Open CodeOptimist opened 2 years ago

CodeOptimist commented 2 years ago

File "C:\Users\Chris\AppData\Local\Python\venv\document-search\Lib\site-packages\whoosh\spelling.py", line 327, in correct_query sugs = c.suggest(token.text, prefix=prefix, maxdist=maxdist) File "C:\Users\Chris\AppData\Local\Python\venv\document-search\Lib\site-packages\whoosh\spelling.py", line 73, in suggest sugs = sorted(heap, key=lambda x: (0 - x[0], x[1])) File "C:\Users\Chris\AppData\Local\Python\venv\document-search\Lib\site-packages\whoosh\spelling.py", line 73, in sugs = sorted(heap, key=lambda x: (0 - x[0], x[1])) TypeError: unsupported operand type(s) for -: 'int' and 'str'

Happens because Corrector expects _suggestions() to return (score, sug) like the other implementations, but MultiCorrector uses iteritems(seen) on a {sug: score} dict, which gives us reversed tuples.

whoosh\spelling.py line 173

class MultiCorrector(Corrector):
    """
    Merges suggestions from a list of sub-correctors.
    """

    def __init__(self, correctors, op):
        self.correctors = correctors
        self.op = op

    def _suggestions(self, text, maxdist, prefix):
        op = self.op
        seen = {}
        for corr in self.correctors:
            for score, sug in corr._suggestions(text, maxdist, prefix):
                if sug in seen:
                    seen[sug] = op(seen[sug], score)
                else:
                    seen[sug] = score
        return iteritems(seen)  # <----- (sug, score) tuples instead of (score, sug)

Proposed fix:

        return ((v, k) for k, v in seen.items())  # generator