pandas-dev/pandas · error · NotImplementedError

count not implemented with {flags=}

Error message

count not implemented with {flags=}

What it means

Raised by _str_count (the string `.str.count` accessor on arrow-backed strings) when a non-zero `flags` argument is passed. pyarrow's count_substring_regex does not accept regex flags, so pandas rejects any non-zero flags value rather than silently ignoring them.

Source

Thrown at pandas/core/arrays/arrow/array.py:3624

                for val in chunk.to_numpy(zero_copy_only=False)
            ]
            for chunk in self._pa_array.iterchunks()
        ]

    def _convert_bool_result(self, result, na=lib.no_default, method_name=None):
        if na is not lib.no_default and not isna(na):  # pyright: ignore [reportGeneralTypeIssues]
            result = result.fill_null(na)
        return self._from_pyarrow_array(result)

    def _convert_int_result(self, result):
        return self._from_pyarrow_array(result)

    def _convert_rank_result(self, result):
        return self._from_pyarrow_array(result)

    def _str_count(self, pat: str, flags: int = 0) -> Self:
        if flags:
            raise NotImplementedError(f"count not implemented with {flags=}")
        return self._from_pyarrow_array(pc.count_substring_regex(self._pa_array, pat))

    def _str_repeat(self, repeats: int | Sequence[int]) -> Self:
        if not isinstance(repeats, int):
            raise NotImplementedError(
                f"repeat is not implemented when repeats is {type(repeats).__name__}"
            )
        return self._from_pyarrow_array(pc.binary_repeat(self._pa_array, repeats))

    def _str_join(self, sep: str) -> Self:
        if pa.types.is_string(self._pa_array.type) or pa.types.is_large_string(
            self._pa_array.type
        ):
            result = self._apply_elementwise(list)
            result = pa.chunked_array(result, type=pa.list_(pa.string()))
        else:
            result = self._pa_array
        return self._from_pyarrow_array(pc.binary_join(result, sep))

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Inline the flag into the pattern instead, e.g. use `(?i)...` for case-insensitive: `s.str.count(r'(?i)foo')`.
  2. Switch the Series dtype to `object` or `string[python]` if you must pass re flags.
  3. Pre-compile and apply via `.map` if more complex flag handling is needed.

Example fix

// before
s = pd.Series(["Foo", "foo"], dtype="string[pyarrow]")
s.str.count("foo", flags=re.IGNORECASE)

// after
s.str.count(r"(?i)foo")
Defensive patterns

Strategy: validation

Validate before calling

def safe_str_count(s, pat, flags=0):
    if flags:
        # inline common flags into pattern
        import re
        pat = (("(?i)" if flags & re.IGNORECASE else "")
               + ("(?x)" if flags & re.VERBOSE else "")
               + pat)
    return s.str.count(pat)

Type guard

def flags_inlineable(flags) -> bool:
    import re
    # only flags we know how to inline are supported on arrow path
    return flags == 0 or (flags & ~(re.IGNORECASE | re.VERBOSE)) == 0

Try / catch

try:
    s.str.count(pat, flags=flags)
except NotImplementedError as e:
    if "count not implemented with flags" in str(e):
        s.astype("object").str.count(pat, flags=flags)
    else:
        raise

Prevention

When it happens

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

Common situations: Porting code that used `re.IGNORECASE`/`re.VERBOSE` flags with object/string Series `.str.count`, which worked because the object path deferred to the `re` module.

Related errors


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