diff options
| author | natsuoto <[email protected]> | 2026-07-01 17:42:49 +0530 |
|---|---|---|
| committer | natsuoto <[email protected]> | 2026-07-01 17:42:49 +0530 |
| commit | f8cfe6cd98f751591ff2fd2cd5bed8cb59ddeb17 (patch) | |
| tree | 4a1ccf3a5dec32d8227aec701fc88db4f3a676d0 | |
| parent | 060b4089f93ea7add1ca70a2b63e6411967f9a97 (diff) | |
| download | edify-f8cfe6cd98f751591ff2fd2cd5bed8cb59ddeb17.tar.xz edify-f8cfe6cd98f751591ff2fd2cd5bed8cb59ddeb17.zip | |
feat: terminal flag kwargs on .to_regex(ignore_case=..., multiline=..., dotall=...)
| -rw-r--r-- | edify/builder/mixins/terminals.py | 27 | ||||
| -rw-r--r-- | tests/builder/flags.test.py | 64 |
2 files changed, 89 insertions, 2 deletions
diff --git a/edify/builder/mixins/terminals.py b/edify/builder/mixins/terminals.py index 9b7e62a..0887afa 100644 --- a/edify/builder/mixins/terminals.py +++ b/edify/builder/mixins/terminals.py @@ -43,15 +43,38 @@ class TerminalsMixin(BuilderProtocol): return _EMPTY_NON_CAPTURING_GROUP return unescaped_pattern - def to_regex(self) -> Regex: + def to_regex( + self, + *, + ascii_only: bool = False, + debug: bool = False, + ignore_case: bool = False, + multiline: bool = False, + dotall: bool = False, + verbose: bool = False, + ) -> Regex: """Return the pattern + flags compiled and wrapped in :class:`edify.result.Regex`. The wrapper exposes the pattern string as ``.source`` and the underlying :class:`re.Pattern` as ``.compiled``, plus the eight :mod:`re` query methods as direct delegates. + + Keyword arguments are OR-merged into the flag snapshot the builder + already carries — passing ``ignore_case=True`` here is equivalent to + having called ``.ignore_case()`` in the chain. Flags never turn off, + only on. """ pattern_string = self.to_regex_string() - flag_bitmask = _build_flag_bitmask(self._state.flags) + kwarg_flags = Flags( + ascii_only=ascii_only, + debug=debug, + ignore_case=ignore_case, + multiline=multiline, + dotall=dotall, + verbose=verbose, + ) + effective_flags = self._state.flags.with_merged(kwarg_flags) + flag_bitmask = _build_flag_bitmask(effective_flags) try: compiled_pattern = re.compile(pattern_string, flags=flag_bitmask) except re.error as compile_error: diff --git a/tests/builder/flags.test.py b/tests/builder/flags.test.py new file mode 100644 index 0000000..ad177c0 --- /dev/null +++ b/tests/builder/flags.test.py @@ -0,0 +1,64 @@ +"""Tests for the flag keyword arguments on :meth:`TerminalsMixin.to_regex`.""" + +import re + +from edify import Pattern, RegexBuilder + + +def test_no_kwargs_uses_only_the_chain_flag_snapshot(): + compiled = RegexBuilder().string("hi").to_regex() + assert compiled.compiled.flags & re.I == 0 + + +def test_ignore_case_kwarg_enables_the_ignore_case_flag(): + compiled = RegexBuilder().string("hi").to_regex(ignore_case=True) + assert compiled.compiled.flags & re.I == re.I + + +def test_multiline_kwarg_enables_the_multiline_flag(): + compiled = RegexBuilder().string("hi").to_regex(multiline=True) + assert compiled.compiled.flags & re.M == re.M + + +def test_dotall_kwarg_enables_the_dotall_flag(): + compiled = RegexBuilder().string("hi").to_regex(dotall=True) + assert compiled.compiled.flags & re.S == re.S + + +def test_ascii_only_kwarg_enables_the_ascii_flag(): + compiled = RegexBuilder().string("hi").to_regex(ascii_only=True) + assert compiled.compiled.flags & re.A == re.A + + +def test_verbose_kwarg_enables_the_verbose_flag(): + compiled = RegexBuilder().string("hi").to_regex(verbose=True) + assert compiled.compiled.flags & re.X == re.X + + +def test_debug_kwarg_enables_the_debug_flag(capsys): + RegexBuilder().string("hi").to_regex(debug=True) + captured = capsys.readouterr() + assert captured.out != "" + + +def test_kwargs_or_merge_with_chain_flags(): + compiled = RegexBuilder().ignore_case().string("hi").to_regex(multiline=True) + assert compiled.compiled.flags & re.I == re.I + assert compiled.compiled.flags & re.M == re.M + + +def test_kwargs_never_turn_off_a_chain_flag(): + compiled = RegexBuilder().ignore_case().string("hi").to_regex(ignore_case=False) + assert compiled.compiled.flags & re.I == re.I + + +def test_kwargs_work_on_pattern_too(): + compiled = Pattern().string("hi").to_regex(ignore_case=True) + assert compiled.compiled.flags & re.I == re.I + + +def test_multiple_kwargs_combine(): + compiled = RegexBuilder().string("hi").to_regex(ignore_case=True, multiline=True, dotall=True) + assert compiled.compiled.flags & re.I == re.I + assert compiled.compiled.flags & re.M == re.M + assert compiled.compiled.flags & re.S == re.S |
