def lookup(val, field: Optional[str] = None, use_cache: bool = True) -> Optional[State]: """ Semi-fuzzy state lookup. This method will make a best effort attempt at finding the state based on the lookup value provided. * two digits will search for FIPS code * two letters will search for state abbreviation * anything else will try to match the metaphone of state names Metaphone is used to allow for incorrect, but phonetically accurate, spelling of state names. Exact matches can be done on any attribute on State objects by passing the `field` argument. This skips the fuzzy-ish matching and does an exact, case-sensitive comparison against the specified field. This method caches non-None results, but can the cache can be bypassed with the `use_cache=False` argument. """ matched_state = None if field is None: if FIPS_RE.match(val): field = "fips" elif ABBR_RE.match(val): val = val.upper() field = "abbr" else: val = pyjellyfish.metaphone(val) field = "name_metaphone" # see if result is in cache cache_key = f"{field}:{val}" if use_cache and cache_key in _lookup_cache: matched_state = _lookup_cache[cache_key] for state in STATES_AND_TERRITORIES: if val == getattr(state, field): matched_state = state if use_cache: _lookup_cache[cache_key] = state return matched_state
def test_metaphone(jf, s1, code): assert jf.metaphone(s1) == code
def test_metaphone_type(jf): assert jf.metaphone(u'abc') == 'ABK' with pytest.raises(TypeError) as exc: jf.metaphone(b'abc') assert 'expected' in str(exc.value)
def test_metaphone_type(jf): assert jf.metaphone(u"abc") == "ABK" with pytest.raises(TypeError) as exc: jf.metaphone(b"abc") assert "expected" in str(exc.value)