pandas-dev/pandas · error · NotImplementedError

contains not implemented with {flags=}

Error message

contains not implemented with {flags=}

What it means

Series.str.contains on the pyarrow backend only supports flags=0 because pyarrow's match_substring_regex has no analogue of Python re flags. Passing any non-zero flags raises NotImplementedError rather than silently ignoring the flags.

Source

Thrown at pandas/core/arrays/_arrow_string_mixins.py:407

    def _str_istitle(self):
        result = pc.utf8_is_title(self._pa_array)
        return self._convert_bool_result(result)

    def _str_isupper(self):
        result = pc.utf8_is_upper(self._pa_array)
        return self._convert_bool_result(result)

    def _str_contains(
        self,
        pat,
        case: bool = True,
        flags: int = 0,
        na: Scalar | lib.NoDefault = lib.no_default,
        regex: bool = True,
    ):
        if flags:
            raise NotImplementedError(f"contains not implemented with {flags=}")

        if regex:
            pa_contains = pc.match_substring_regex
        else:
            pa_contains = pc.match_substring
        result = pa_contains(self._pa_array, pat, ignore_case=not case)
        return self._convert_bool_result(result, na=na, method_name="contains")

    def _str_match(
        self,
        pat: str,
        case: bool = True,
        flags: int = 0,
        na: Scalar | lib.NoDefault = lib.no_default,
    ):
        if pat.startswith("^"):
            pat = pat[1:]
        pat = f"^({pat})"

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. For case-insensitivity use case=False instead of flags=re.IGNORECASE (the backend maps it to ignore_case=True).
  2. For other flags, cast to object: s.astype(object).str.contains(pat, flags=...).

Example fix

// before
s.str.contains("abc", flags=re.IGNORECASE)
// after
s.str.contains("abc", case=False)
Defensive patterns

Strategy: fallback

Validate before calling

def safe_contains(s, pat, case=True, flags=0, regex=True):
    if flags and "string[pyarrow]" in str(s.dtype):
        if flags == re.IGNORECASE:
            return s.str.contains(pat, case=False, regex=regex)
        s = s.astype(object)
    return s.str.contains(pat, case=case, flags=flags, regex=regex)

Try / catch

try:
    res = s.str.contains(pat, flags=flags)
except NotImplementedError:
    res = s.astype(object).str.contains(pat, flags=flags)

Prevention

When it happens

Trigger: s.str.contains(pat, flags=re.IGNORECASE) (or any non-zero flags value) on a string[pyarrow] Series.

Common situations: Reusing object-dtype code that uses re.IGNORECASE; wanting case-insensitive substring matching on arrow strings.

Related errors


AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07). Data as JSON: /api/errors/917dfccbd9f0edf5. Report an issue: GitHub.