backrefs 5.8__py313-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. backrefs/__init__.py +2 -0
  2. backrefs/__meta__.py +197 -0
  3. backrefs/_bre_parse.py +1529 -0
  4. backrefs/_bregex_parse.py +1362 -0
  5. backrefs/_bregex_typing.py +6 -0
  6. backrefs/bre.py +652 -0
  7. backrefs/bregex.py +726 -0
  8. backrefs/py.typed +0 -0
  9. backrefs/uniprops/__init__.py +592 -0
  10. backrefs/uniprops/unidata/__init__.py +26 -0
  11. backrefs/uniprops/unidata/age.py +115 -0
  12. backrefs/uniprops/unidata/alias.py +771 -0
  13. backrefs/uniprops/unidata/bidiclass.py +99 -0
  14. backrefs/uniprops/unidata/bidipairedbrackettype.py +19 -0
  15. backrefs/uniprops/unidata/binary.py +331 -0
  16. backrefs/uniprops/unidata/block.py +1323 -0
  17. backrefs/uniprops/unidata/canonicalcombiningclass.py +1031 -0
  18. backrefs/uniprops/unidata/decompositiontype.py +79 -0
  19. backrefs/uniprops/unidata/eastasianwidth.py +31 -0
  20. backrefs/uniprops/unidata/generalcategory.py +173 -0
  21. backrefs/uniprops/unidata/graphemeclusterbreak.py +79 -0
  22. backrefs/uniprops/unidata/hangulsyllabletype.py +31 -0
  23. backrefs/uniprops/unidata/indicpositionalcategory.py +71 -0
  24. backrefs/uniprops/unidata/indicsyllabiccategory.py +151 -0
  25. backrefs/uniprops/unidata/joininggroup.py +423 -0
  26. backrefs/uniprops/unidata/joiningtype.py +31 -0
  27. backrefs/uniprops/unidata/linebreak.py +199 -0
  28. backrefs/uniprops/unidata/numerictype.py +23 -0
  29. backrefs/uniprops/unidata/numericvalue.py +583 -0
  30. backrefs/uniprops/unidata/quickcheck.py +59 -0
  31. backrefs/uniprops/unidata/script.py +667 -0
  32. backrefs/uniprops/unidata/scriptextensions.py +667 -0
  33. backrefs/uniprops/unidata/sentencebreak.py +67 -0
  34. backrefs/uniprops/unidata/verticalorientation.py +23 -0
  35. backrefs/uniprops/unidata/wordbreak.py +99 -0
  36. backrefs/util.py +163 -0
  37. backrefs-5.8.dist-info/METADATA +74 -0
  38. backrefs-5.8.dist-info/RECORD +40 -0
  39. backrefs-5.8.dist-info/WHEEL +4 -0
  40. backrefs-5.8.dist-info/licenses/LICENSE.md +21 -0
@@ -0,0 +1,6 @@
1
+ """Typing objects for the Regex library."""
2
+ import regex # type: ignore[import]
3
+ from typing import _alias # type: ignore[attr-defined]
4
+
5
+ Pattern = _alias(type(regex.compile('')), 1)
6
+ Match = _alias(type(regex.compile('').match('')), 1)
backrefs/bre.py ADDED
@@ -0,0 +1,652 @@
1
+ r"""
2
+ Backrefs re.
3
+
4
+ Add the ability to use the following backrefs with re:
5
+
6
+ - `\l` - Lowercase character class (search)
7
+ - `\c` - Uppercase character class (search)
8
+ - `\L` - Inverse of lowercase character class (search)
9
+ - `\C` - Inverse of uppercase character class (search)
10
+ - `\Q` and `\Q...\E` - Escape/quote chars (search)
11
+ - `\c` and `\C...\E` - Uppercase char or chars (replace)
12
+ - `\l` and `\L...\E` - Lowercase char or chars (replace)
13
+ - `[:ascii:]` - Posix style classes (search)
14
+ - `[:^ascii:]` - Inverse Posix style classes (search)
15
+ - `\pL`, `\p{Lu}`, \p{Letter}, `\p{gc=Uppercase_Letter}` - Unicode properties (search Unicode)
16
+ - `\PL`, `\P{Lu}`, `\p{^Lu}` - Inverse Unicode properties (search Unicode)
17
+ - `\N{Black Club Suit}` - Unicode character by name (search & replace)
18
+ - `\u0000` and `\U00000000` - Unicode characters (replace)
19
+ - `\m` - Starting word boundary (search)
20
+ - `\M` - Ending word boundary (search)
21
+ - `\R` - Generic line breaks (search)
22
+ - `\X` - Simplified grapheme clusters (search)
23
+
24
+ Licensed under MIT
25
+ Copyright (c) 2011 - 2020 Isaac Muse <isaacmuse@gmail.com>
26
+ """
27
+ from __future__ import annotations
28
+ import re as _re
29
+ import copyreg as _copyreg
30
+ from functools import lru_cache as _lru_cache
31
+ from . import util as _util
32
+ from . import _bre_parse
33
+ from ._bre_parse import ReplaceTemplate
34
+ from typing import AnyStr, Pattern, Match, Callable, Any, Generic, Mapping, Iterator, cast
35
+
36
+ __all__ = (
37
+ "expand", "expandf", "search", "match", "fullmatch", "split", "findall", "finditer", "sub", "subf",
38
+ "subn", "subfn", "purge", "escape", "fullmatch", "DEBUG", "I", "IGNORECASE", "L", "LOCALE", "M", "MULTILINE",
39
+ "S", "DOTALL", "U", "UNICODE", "X", "VERBOSE", "compile", "compile_search", "compile_replace", "Bre",
40
+ "ReplaceTemplate", "A", "ASCII"
41
+ )
42
+
43
+ # Expose some common re flags and methods to
44
+ # save having to import re and backrefs libraries
45
+ DEBUG = _re.DEBUG
46
+ I = _re.I
47
+ IGNORECASE = _re.IGNORECASE
48
+ L = _re.L
49
+ LOCALE = _re.LOCALE
50
+ M = _re.M
51
+ MULTILINE = _re.MULTILINE
52
+ S = _re.S
53
+ DOTALL = _re.DOTALL
54
+ U = _re.U
55
+ UNICODE = _re.UNICODE
56
+ X = _re.X
57
+ VERBOSE = _re.VERBOSE
58
+ A = _re.A
59
+ ASCII = _re.ASCII
60
+ escape = _re.escape
61
+
62
+ # Replace flags
63
+ FORMAT = 1
64
+
65
+ # Maximum size of the cache.
66
+ _MAXCACHE = 500
67
+
68
+ _RE_TYPE = type(_re.compile('', 0))
69
+
70
+
71
+ @_lru_cache(maxsize=_MAXCACHE)
72
+ def _cached_search_compile(
73
+ pattern: AnyStr,
74
+ re_verbose: bool,
75
+ re_unicode: bool,
76
+ pattern_type: type[AnyStr]
77
+ ) -> AnyStr:
78
+ """Cached search compile."""
79
+
80
+ return _bre_parse._SearchParser(pattern, re_verbose, re_unicode).parse()
81
+
82
+
83
+ @_lru_cache(maxsize=_MAXCACHE)
84
+ def _cached_replace_compile(
85
+ pattern: Pattern[AnyStr],
86
+ repl: AnyStr,
87
+ flags: int,
88
+ pattern_type: type[AnyStr]
89
+ ) -> ReplaceTemplate[AnyStr]:
90
+ """Cached replace compile."""
91
+
92
+ return _bre_parse._ReplaceParser(pattern, repl, bool(flags & FORMAT)).parse()
93
+
94
+
95
+ def _get_cache_size(replace: bool = False) -> int:
96
+ """Get size of cache."""
97
+
98
+ if not replace:
99
+ size = _cached_search_compile.cache_info().currsize
100
+ else:
101
+ size = _cached_replace_compile.cache_info().currsize
102
+ return size
103
+
104
+
105
+ def _purge_cache() -> None:
106
+ """Purge the cache."""
107
+
108
+ _cached_replace_compile.cache_clear()
109
+ _cached_search_compile.cache_clear()
110
+
111
+
112
+ def _is_replace(obj: Any) -> bool:
113
+ """Check if object is a replace object."""
114
+
115
+ return isinstance(obj, ReplaceTemplate)
116
+
117
+
118
+ def _apply_replace_backrefs(
119
+ m: Match[AnyStr] | None,
120
+ repl: ReplaceTemplate[AnyStr] | AnyStr,
121
+ flags: int = 0
122
+ ) -> AnyStr:
123
+ """Expand with either the `ReplaceTemplate` or compile on the fly, or return None."""
124
+
125
+ if m is None:
126
+ raise ValueError("Match is None!")
127
+
128
+ if isinstance(repl, ReplaceTemplate):
129
+ return repl.expand(m)
130
+ return _bre_parse._ReplaceParser(m.re, repl, bool(flags & FORMAT)).parse().expand(m)
131
+
132
+
133
+ def _apply_search_backrefs(
134
+ pattern: AnyStr | Pattern[AnyStr] | Bre[AnyStr],
135
+ flags: int = 0
136
+ ) -> AnyStr | Pattern[AnyStr]:
137
+ """Apply the search backrefs to the search pattern."""
138
+
139
+ if isinstance(pattern, (str, bytes)):
140
+ re_verbose = bool(VERBOSE & flags)
141
+ re_unicode = None
142
+ if bool((ASCII | LOCALE) & flags):
143
+ re_unicode = False
144
+ elif bool(UNICODE & flags):
145
+ re_unicode = True
146
+ if not (flags & DEBUG):
147
+ p = _cached_search_compile(
148
+ pattern, re_verbose, re_unicode, type(pattern)
149
+ ) # type: AnyStr | Pattern[AnyStr]
150
+ else: # pragma: no cover
151
+ p = _bre_parse._SearchParser(pattern, re_verbose, re_unicode).parse()
152
+ elif isinstance(pattern, Bre):
153
+ if flags:
154
+ raise ValueError("Cannot process flags argument with a compiled pattern")
155
+ p = pattern._pattern
156
+ elif isinstance(pattern, _RE_TYPE):
157
+ if flags:
158
+ raise ValueError("Cannot process flags argument with a compiled pattern!")
159
+ p = pattern
160
+ else:
161
+ raise TypeError("Not a string or compiled pattern!")
162
+ return p
163
+
164
+
165
+ def _assert_expandable(repl: Any, use_format: bool = False) -> None:
166
+ """Check if replace template is expandable."""
167
+
168
+ if isinstance(repl, ReplaceTemplate):
169
+ if repl.use_format != use_format:
170
+ if use_format:
171
+ raise ValueError("Replace not compiled as a format replace")
172
+ else:
173
+ raise ValueError("Replace should not be compiled as a format replace!")
174
+ elif not isinstance(repl, (str, bytes)):
175
+ raise TypeError("Expected string, buffer, or compiled replace!")
176
+
177
+
178
+ ###########################
179
+ # API
180
+ ##########################
181
+ class Bre(_util.Immutable, Generic[AnyStr]):
182
+ """Bre object."""
183
+
184
+ _pattern: Pattern[AnyStr]
185
+ auto_compile: bool
186
+ _hash: int
187
+
188
+ __slots__ = ("_pattern", "auto_compile", "_hash")
189
+
190
+ def __init__(self, pattern: Pattern[AnyStr], auto_compile: bool = True) -> None:
191
+ """Initialization."""
192
+
193
+ super().__init__(
194
+ _pattern=pattern,
195
+ auto_compile=auto_compile,
196
+ _hash=hash((type(self), type(pattern), pattern, auto_compile))
197
+ )
198
+
199
+ @property
200
+ def pattern(self) -> AnyStr:
201
+ """Return pattern."""
202
+
203
+ return self._pattern.pattern
204
+
205
+ @property
206
+ def flags(self) -> int:
207
+ """Return flags."""
208
+
209
+ return self._pattern.flags
210
+
211
+ @property
212
+ def groupindex(self) -> Mapping[str, int]:
213
+ """Return group index."""
214
+
215
+ return self._pattern.groupindex
216
+
217
+ @property
218
+ def groups(self) -> tuple[AnyStr | None, ...]:
219
+ """Return groups."""
220
+
221
+ return cast('tuple[AnyStr | None, ...]', self._pattern.groups)
222
+
223
+ @property
224
+ def scanner(self) -> Any:
225
+ """Return scanner."""
226
+
227
+ return self._pattern.scanner # type: ignore[attr-defined]
228
+
229
+ def __hash__(self) -> int:
230
+ """Hash."""
231
+
232
+ return self._hash
233
+
234
+ def __eq__(self, other: Any) -> bool:
235
+ """Equal."""
236
+
237
+ return (
238
+ isinstance(other, Bre) and
239
+ self._pattern == other._pattern and
240
+ self.auto_compile == other.auto_compile
241
+ )
242
+
243
+ def __ne__(self, other: Any) -> bool:
244
+ """Equal."""
245
+
246
+ return (
247
+ not isinstance(other, Bre) or
248
+ self._pattern != other._pattern or
249
+ self.auto_compile != other.auto_compile
250
+ )
251
+
252
+ def __repr__(self) -> str: # pragma: no cover
253
+ """Representation."""
254
+
255
+ return '{}.{}({!r}, auto_compile={!r})'.format(
256
+ self.__module__, self.__class__.__name__, self._pattern, self.auto_compile
257
+ )
258
+
259
+ def _auto_compile(
260
+ self,
261
+ template: AnyStr | Callable[..., AnyStr],
262
+ use_format: bool = False
263
+ ) -> AnyStr | Callable[..., AnyStr]:
264
+ """Compile replacements."""
265
+
266
+ if isinstance(template, ReplaceTemplate):
267
+ if use_format != template.use_format:
268
+ raise ValueError("Compiled replace cannot be a format object!")
269
+ elif isinstance(template, ReplaceTemplate) or (isinstance(template, (str, bytes)) and self.auto_compile):
270
+ return self.compile(template, (FORMAT if use_format and not isinstance(template, ReplaceTemplate) else 0))
271
+ elif isinstance(template, (str, bytes)) and use_format:
272
+ # Reject an attempt to run format replace when auto-compiling
273
+ # of template strings has been disabled and we are using a
274
+ # template string.
275
+ raise AttributeError('Format replaces cannot be called without compiling replace template!')
276
+ return template
277
+
278
+ def compile( # noqa A001
279
+ self,
280
+ repl: AnyStr | Callable[..., AnyStr],
281
+ flags: int = 0
282
+ ) -> Callable[..., AnyStr]:
283
+ """Compile replace."""
284
+
285
+ return compile_replace(self._pattern, repl, flags)
286
+
287
+ def search(
288
+ self,
289
+ string: AnyStr,
290
+ *args: Any,
291
+ **kwargs: Any
292
+ ) -> Match[AnyStr] | None:
293
+ """Apply `search`."""
294
+
295
+ return self._pattern.search(string, *args, **kwargs)
296
+
297
+ def match(
298
+ self,
299
+ string: AnyStr,
300
+ *args: Any,
301
+ **kwargs: Any
302
+ ) -> Match[AnyStr] | None:
303
+ """Apply `match`."""
304
+
305
+ return self._pattern.match(string, *args, **kwargs)
306
+
307
+ def fullmatch(
308
+ self,
309
+ string: AnyStr,
310
+ *args: Any,
311
+ **kwargs: Any
312
+ ) -> Match[AnyStr] | None:
313
+ """Apply `fullmatch`."""
314
+
315
+ return self._pattern.fullmatch(string, *args, **kwargs)
316
+
317
+ def split(
318
+ self,
319
+ string: AnyStr,
320
+ *args: Any,
321
+ **kwargs: Any
322
+ ) -> list[AnyStr]:
323
+ """Apply `split`."""
324
+
325
+ return self._pattern.split(string, *args, **kwargs)
326
+
327
+ def findall(
328
+ self,
329
+ string: AnyStr,
330
+ *args: Any,
331
+ **kwargs: Any
332
+ ) -> list[AnyStr] | list[tuple[AnyStr, ...]]:
333
+ """Apply `findall`."""
334
+
335
+ return self._pattern.findall(string, *args, **kwargs)
336
+
337
+ def finditer(
338
+ self,
339
+ string: AnyStr,
340
+ *args: Any,
341
+ **kwargs: Any
342
+ ) -> Iterator[Match[AnyStr]]:
343
+ """Apply `finditer`."""
344
+
345
+ return self._pattern.finditer(string, *args, **kwargs)
346
+
347
+ def sub(
348
+ self,
349
+ repl: AnyStr | Callable[..., AnyStr],
350
+ string: AnyStr,
351
+ *args: Any,
352
+ **kwargs: Any
353
+ ) -> AnyStr:
354
+ """Apply `sub`."""
355
+
356
+ return self._pattern.sub(self._auto_compile(repl), string, *args, **kwargs)
357
+
358
+ def subf( # noqa A002
359
+ self,
360
+ repl: AnyStr | Callable[..., AnyStr],
361
+ string: AnyStr,
362
+ *args: Any,
363
+ **kwargs: Any
364
+ ) -> AnyStr:
365
+ """Apply `sub` with format style replace."""
366
+
367
+ return self._pattern.sub(self._auto_compile(repl, True), string, *args, **kwargs)
368
+
369
+ def subn(
370
+ self,
371
+ repl: AnyStr | Callable[..., AnyStr],
372
+ string: AnyStr,
373
+ *args: Any,
374
+ **kwargs: Any
375
+ ) -> tuple[AnyStr, int]:
376
+ """Apply `subn` with format style replace."""
377
+
378
+ return self._pattern.subn(self._auto_compile(repl), string, *args, **kwargs)
379
+
380
+ def subfn( # noqa A002
381
+ self,
382
+ repl: AnyStr | Callable[..., AnyStr],
383
+ string: AnyStr,
384
+ *args: Any,
385
+ **kwargs: Any
386
+ ) -> tuple[AnyStr, int]:
387
+ """Apply `subn` after applying backrefs."""
388
+
389
+ return self._pattern.subn(self._auto_compile(repl, True), string, *args, **kwargs)
390
+
391
+
392
+ def compile( # noqa A001
393
+ pattern: AnyStr | Pattern[AnyStr] | Bre[AnyStr],
394
+ flags: int = 0,
395
+ auto_compile: bool | None = None
396
+ ) -> Bre[AnyStr]:
397
+ """Compile both the search or search and replace into one object."""
398
+
399
+ if isinstance(pattern, Bre):
400
+ if auto_compile is not None:
401
+ raise ValueError("Cannot compile Bre with a different auto_compile!")
402
+ elif flags != 0:
403
+ raise ValueError("Cannot process flags argument with a compiled pattern")
404
+ return pattern
405
+ else:
406
+ if auto_compile is None:
407
+ auto_compile = True
408
+
409
+ return Bre(compile_search(pattern, flags), auto_compile)
410
+
411
+
412
+ def compile_search(
413
+ pattern: AnyStr | Pattern[AnyStr] | Bre[AnyStr],
414
+ flags: int = 0
415
+ ) -> Pattern[AnyStr]:
416
+ """Compile with extended search references."""
417
+
418
+ return _re.compile(_apply_search_backrefs(pattern, flags), flags)
419
+
420
+
421
+ def compile_replace(
422
+ pattern: Pattern[AnyStr],
423
+ repl: AnyStr | Callable[..., AnyStr],
424
+ flags: int = 0
425
+ ) -> Callable[..., AnyStr]:
426
+ """Construct a method that can be used as a replace method for `sub`, `subn`, etc."""
427
+
428
+ if pattern is not None and isinstance(pattern, _RE_TYPE):
429
+ if isinstance(repl, (str, bytes)):
430
+ if not (pattern.flags & DEBUG):
431
+ call = _cached_replace_compile(pattern, repl, flags, type(repl))
432
+ else: # pragma: no cover
433
+ call = _bre_parse._ReplaceParser(pattern, repl, bool(flags & FORMAT)).parse()
434
+ elif isinstance(repl, ReplaceTemplate):
435
+ if flags:
436
+ raise ValueError("Cannot process flags argument with a ReplaceTemplate!")
437
+ if repl.pattern_hash != hash(pattern):
438
+ raise ValueError("Pattern hash doesn't match hash in compiled replace!")
439
+ call = repl
440
+ else:
441
+ raise TypeError("Not a valid type!")
442
+ else:
443
+ raise TypeError("Pattern must be a compiled regular expression!")
444
+ return call
445
+
446
+
447
+ def purge() -> None:
448
+ """Purge caches."""
449
+
450
+ _purge_cache()
451
+ _re.purge()
452
+
453
+
454
+ def expand(m: Match[AnyStr] | None, repl: ReplaceTemplate[AnyStr] | AnyStr) -> AnyStr:
455
+ """Expand the string using the replace pattern or function."""
456
+
457
+ _assert_expandable(repl)
458
+ return _apply_replace_backrefs(m, repl)
459
+
460
+
461
+ def expandf(m: Match[AnyStr] | None, repl: ReplaceTemplate[AnyStr] | AnyStr) -> AnyStr:
462
+ """Expand the string using the format replace pattern or function."""
463
+
464
+ _assert_expandable(repl, True)
465
+ return _apply_replace_backrefs(m, repl, flags=FORMAT)
466
+
467
+
468
+ def search(
469
+ pattern: AnyStr | Pattern[AnyStr] | Bre[AnyStr],
470
+ string: AnyStr,
471
+ flags: int | _re.RegexFlag = 0,
472
+ *args: Any,
473
+ **kwargs: Any
474
+ ) -> Match[AnyStr] | None:
475
+ """Apply `search` after applying backrefs."""
476
+
477
+ return _re.search(_apply_search_backrefs(pattern, flags), string, flags, *args, **kwargs)
478
+
479
+
480
+ def match(
481
+ pattern: AnyStr | Pattern[AnyStr] | Bre[AnyStr],
482
+ string: AnyStr,
483
+ flags: int | _re.RegexFlag = 0,
484
+ **kwargs: Any
485
+ ) -> Match[AnyStr] | None:
486
+ """Apply `match` after applying backrefs."""
487
+
488
+ return _re.match(_apply_search_backrefs(pattern, flags), string, flags=flags, **kwargs)
489
+
490
+
491
+ def fullmatch(
492
+ pattern: AnyStr | Pattern[AnyStr] | Bre[AnyStr],
493
+ string: AnyStr,
494
+ flags: int | _re.RegexFlag = 0,
495
+ **kwargs: Any
496
+ ) -> Match[AnyStr] | None:
497
+ """Apply `fullmatch` after applying backrefs."""
498
+
499
+ return _re.fullmatch(_apply_search_backrefs(pattern, flags), string, flags=flags, **kwargs)
500
+
501
+
502
+ def split(
503
+ pattern: AnyStr | Pattern[AnyStr] | Bre[AnyStr],
504
+ string: AnyStr,
505
+ maxsplit: int = 0,
506
+ flags: int | _re.RegexFlag = 0,
507
+ **kwargs: Any
508
+ ) -> list[AnyStr]:
509
+ """Apply `split` after applying backrefs."""
510
+
511
+ return _re.split(
512
+ _apply_search_backrefs(pattern, flags),
513
+ string,
514
+ maxsplit=maxsplit,
515
+ flags=flags,
516
+ **kwargs
517
+ )
518
+
519
+
520
+ def findall(
521
+ pattern: AnyStr | Pattern[AnyStr] | Bre[AnyStr],
522
+ string: AnyStr,
523
+ flags: int | _re.RegexFlag = 0,
524
+ **kwargs: Any
525
+ ) -> list[AnyStr] | list[tuple[AnyStr, ...]]:
526
+ """Apply `findall` after applying backrefs."""
527
+
528
+ return _re.findall(_apply_search_backrefs(pattern, flags), string, flags=flags, **kwargs)
529
+
530
+
531
+ def finditer(
532
+ pattern: AnyStr | Pattern[AnyStr] | Bre[AnyStr],
533
+ string: AnyStr,
534
+ flags: int | _re.RegexFlag = 0,
535
+ **kwargs: Any
536
+ ) -> Iterator[Match[AnyStr]]:
537
+ """Apply `finditer` after applying backrefs."""
538
+
539
+ return _re.finditer(_apply_search_backrefs(pattern, flags), string, flags=flags, **kwargs)
540
+
541
+
542
+ def sub(
543
+ pattern: AnyStr | Pattern[AnyStr] | Bre[AnyStr],
544
+ repl: AnyStr | Callable[..., AnyStr],
545
+ string: AnyStr,
546
+ count: int = 0,
547
+ flags: int | _re.RegexFlag = 0,
548
+ **kwargs: Any
549
+ ) -> AnyStr:
550
+ """Apply `sub` after applying backrefs."""
551
+
552
+ is_replace = _is_replace(repl)
553
+ is_string = isinstance(repl, (str, bytes))
554
+ if is_replace and cast(ReplaceTemplate[AnyStr], repl).use_format:
555
+ raise ValueError("Compiled replace cannot be a format object!")
556
+
557
+ pattern = compile_search(pattern, flags)
558
+ return _re.sub(
559
+ pattern,
560
+ (compile_replace(pattern, repl) if is_replace or is_string else repl),
561
+ string,
562
+ count=count,
563
+ flags=0,
564
+ **kwargs
565
+ )
566
+
567
+
568
+ def subf(
569
+ pattern: AnyStr | Pattern[AnyStr] | Bre[AnyStr],
570
+ repl: AnyStr | Callable[..., AnyStr],
571
+ string: AnyStr,
572
+ count: int = 0,
573
+ flags: int | _re.RegexFlag = 0,
574
+ **kwargs: Any
575
+ ) -> AnyStr:
576
+ """Apply `sub` with format style replace."""
577
+
578
+ is_replace = _is_replace(repl)
579
+ is_string = isinstance(repl, (str, bytes))
580
+ if is_replace and not cast(ReplaceTemplate[AnyStr], repl).use_format:
581
+ raise ValueError("Compiled replace is not a format object!")
582
+
583
+ pattern = compile_search(pattern, flags)
584
+ rflags = FORMAT if is_string else 0
585
+ return _re.sub(
586
+ pattern,
587
+ (compile_replace(pattern, repl, flags=rflags) if is_replace or is_string else repl),
588
+ string,
589
+ count=count,
590
+ flags=0,
591
+ **kwargs
592
+ )
593
+
594
+
595
+ def subn(
596
+ pattern: AnyStr | Pattern[AnyStr] | Bre[AnyStr],
597
+ repl: AnyStr | Callable[..., AnyStr],
598
+ string: AnyStr,
599
+ count: int = 0,
600
+ flags: int | _re.RegexFlag = 0,
601
+ **kwargs: Any
602
+ ) -> tuple[AnyStr, int]:
603
+ """Apply `subn` with format style replace."""
604
+
605
+ is_replace = _is_replace(repl)
606
+ is_string = isinstance(repl, (str, bytes))
607
+ if is_replace and cast(ReplaceTemplate[AnyStr], repl).use_format:
608
+ raise ValueError("Compiled replace cannot be a format object!")
609
+
610
+ pattern = compile_search(pattern, flags)
611
+ return _re.subn(
612
+ pattern,
613
+ (compile_replace(pattern, repl) if is_replace or is_string else repl),
614
+ string,
615
+ count=count,
616
+ flags=0,
617
+ **kwargs
618
+ )
619
+
620
+
621
+ def subfn(
622
+ pattern: AnyStr | Pattern[AnyStr] | Bre[AnyStr],
623
+ repl: AnyStr | Callable[..., AnyStr],
624
+ string: AnyStr,
625
+ count: int = 0,
626
+ flags: int | _re.RegexFlag = 0,
627
+ **kwargs: Any
628
+ ) -> tuple[AnyStr, int]:
629
+ """Apply `subn` after applying backrefs."""
630
+
631
+ is_replace = _is_replace(repl)
632
+ is_string = isinstance(repl, (str, bytes))
633
+ if is_replace and not cast(ReplaceTemplate[AnyStr], repl).use_format:
634
+ raise ValueError("Compiled replace is not a format object!")
635
+
636
+ pattern = compile_search(pattern, flags)
637
+ rflags = FORMAT if is_string else 0
638
+ return _re.subn(
639
+ pattern,
640
+ (compile_replace(pattern, repl, flags=rflags) if is_replace or is_string else repl),
641
+ string,
642
+ count=count,
643
+ flags=0,
644
+ **kwargs
645
+ )
646
+
647
+
648
+ def _pickle(p): # type: ignore[no-untyped-def]
649
+ return Bre, (p._pattern, p.auto_compile)
650
+
651
+
652
+ _copyreg.pickle(Bre, _pickle)