Skip to content

Negative lookbehind ignored under re.IGNORECASE | re.LOCALE #155985

Description

@fedonman

Bug description:

On the main branch a negative lookbehind after a character class is ignored for bytes patterns when both re.IGNORECASE and re.LOCALE are set. [b] matches b'B' under those flags, so \w(?<!b) must not match b'B', but it does. The same flag pair also lets the new [A--B] difference operator match characters that are in B.

import re

W = re.IGNORECASE | re.LOCALE
print(re.fullmatch(rb'[b]', b'B', W))
print(re.fullmatch(rb'\w(?<!b)', b'B', W))

Output on main:

<re.Match object; span=(0, 1), match=b'B'>
<re.Match object; span=(0, 1), match=b'B'>

Expected: the second line is None, which is what 3.14.4 prints.

_fuse_difference() in Lib/re/_optimizer.py rewrites <charset> (?<![B]) into a single character set carrying NEGATE without seeing the compile flags, and under this flag pair that set compiles to IN_LOC_IGNORE, which tests the whole set once per locale case.

CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.15pre-release feature fixes, bugs and security fixesstdlibStandard Library Python modules in the Lib/ directorytopic-regextype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions