PyPcre 0.2.14__tar.gz → 0.2.15__tar.gz

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 (57) hide show
  1. pypcre-0.2.15/PKG-INFO +247 -0
  2. pypcre-0.2.15/PyPcre.egg-info/PKG-INFO +247 -0
  3. pypcre-0.2.15/README.md +224 -0
  4. {pypcre-0.2.14 → pypcre-0.2.15}/pcre/__init__.py +3 -0
  5. {pypcre-0.2.14 → pypcre-0.2.15}/pcre/pcre.py +6 -1
  6. {pypcre-0.2.14 → pypcre-0.2.15}/pyproject.toml +1 -1
  7. {pypcre-0.2.14 → pypcre-0.2.15}/tests/test_api_parity.py +15 -0
  8. pypcre-0.2.14/PKG-INFO +0 -313
  9. pypcre-0.2.14/PyPcre.egg-info/PKG-INFO +0 -313
  10. pypcre-0.2.14/README.md +0 -290
  11. {pypcre-0.2.14 → pypcre-0.2.15}/LICENSE +0 -0
  12. {pypcre-0.2.14 → pypcre-0.2.15}/MANIFEST.in +0 -0
  13. {pypcre-0.2.14 → pypcre-0.2.15}/PyPcre.egg-info/SOURCES.txt +0 -0
  14. {pypcre-0.2.14 → pypcre-0.2.15}/PyPcre.egg-info/dependency_links.txt +0 -0
  15. {pypcre-0.2.14 → pypcre-0.2.15}/PyPcre.egg-info/top_level.txt +0 -0
  16. {pypcre-0.2.14 → pypcre-0.2.15}/pcre/_stdlib_re.py +0 -0
  17. {pypcre-0.2.14 → pypcre-0.2.15}/pcre/cache.py +0 -0
  18. {pypcre-0.2.14 → pypcre-0.2.15}/pcre/error.py +0 -0
  19. {pypcre-0.2.14 → pypcre-0.2.15}/pcre/flags.py +0 -0
  20. {pypcre-0.2.14 → pypcre-0.2.15}/pcre/re_compat.py +0 -0
  21. {pypcre-0.2.14 → pypcre-0.2.15}/pcre/threads.py +0 -0
  22. {pypcre-0.2.14 → pypcre-0.2.15}/pcre_ext/atomic_compat.h +0 -0
  23. {pypcre-0.2.14 → pypcre-0.2.15}/pcre_ext/cache.c +0 -0
  24. {pypcre-0.2.14 → pypcre-0.2.15}/pcre_ext/error.c +0 -0
  25. {pypcre-0.2.14 → pypcre-0.2.15}/pcre_ext/flag.c +0 -0
  26. {pypcre-0.2.14 → pypcre-0.2.15}/pcre_ext/jit_support.c +0 -0
  27. {pypcre-0.2.14 → pypcre-0.2.15}/pcre_ext/memory.c +0 -0
  28. {pypcre-0.2.14 → pypcre-0.2.15}/pcre_ext/pattern_cache.c +0 -0
  29. {pypcre-0.2.14 → pypcre-0.2.15}/pcre_ext/pcre2.c +0 -0
  30. {pypcre-0.2.14 → pypcre-0.2.15}/pcre_ext/pcre2.h +0 -0
  31. {pypcre-0.2.14 → pypcre-0.2.15}/pcre_ext/pcre2_module.h +0 -0
  32. {pypcre-0.2.14 → pypcre-0.2.15}/pcre_ext/string_helpers.c +0 -0
  33. {pypcre-0.2.14 → pypcre-0.2.15}/pcre_ext/util.c +0 -0
  34. {pypcre-0.2.14 → pypcre-0.2.15}/setup.cfg +0 -0
  35. {pypcre-0.2.14 → pypcre-0.2.15}/setup.py +0 -0
  36. {pypcre-0.2.14 → pypcre-0.2.15}/setup_utils.py +0 -0
  37. {pypcre-0.2.14 → pypcre-0.2.15}/tests/test_accuracy.py +0 -0
  38. {pypcre-0.2.14 → pypcre-0.2.15}/tests/test_basic.py +0 -0
  39. {pypcre-0.2.14 → pypcre-0.2.15}/tests/test_bench_string.py +0 -0
  40. {pypcre-0.2.14 → pypcre-0.2.15}/tests/test_benchmark.py +0 -0
  41. {pypcre-0.2.14 → pypcre-0.2.15}/tests/test_bytes.py +0 -0
  42. {pypcre-0.2.14 → pypcre-0.2.15}/tests/test_cache.py +0 -0
  43. {pypcre-0.2.14 → pypcre-0.2.15}/tests/test_clobber.py +0 -0
  44. {pypcre-0.2.14 → pypcre-0.2.15}/tests/test_clobber_thread.py +0 -0
  45. {pypcre-0.2.14 → pypcre-0.2.15}/tests/test_core.py +0 -0
  46. {pypcre-0.2.14 → pypcre-0.2.15}/tests/test_errors.py +0 -0
  47. {pypcre-0.2.14 → pypcre-0.2.15}/tests/test_flags.py +0 -0
  48. {pypcre-0.2.14 → pypcre-0.2.15}/tests/test_jit.py +0 -0
  49. {pypcre-0.2.14 → pypcre-0.2.15}/tests/test_memory.py +0 -0
  50. {pypcre-0.2.14 → pypcre-0.2.15}/tests/test_module.py +0 -0
  51. {pypcre-0.2.14 → pypcre-0.2.15}/tests/test_pattern.py +0 -0
  52. {pypcre-0.2.14 → pypcre-0.2.15}/tests/test_setup_utils_multiarch.py +0 -0
  53. {pypcre-0.2.14 → pypcre-0.2.15}/tests/test_simd.py +0 -0
  54. {pypcre-0.2.14 → pypcre-0.2.15}/tests/test_threaded_backend.py +0 -0
  55. {pypcre-0.2.14 → pypcre-0.2.15}/tests/test_transformers_regex.py +0 -0
  56. {pypcre-0.2.14 → pypcre-0.2.15}/tests/test_utf8.py +0 -0
  57. {pypcre-0.2.14 → pypcre-0.2.15}/tests/test_version.py +0 -0
pypcre-0.2.15/PKG-INFO ADDED
@@ -0,0 +1,247 @@
1
+ Metadata-Version: 2.4
2
+ Name: PyPcre
3
+ Version: 0.2.15
4
+ Summary: Modern, GIL-friendly, Fast Python bindings for PCRE2 with auto caching and JIT of compiled patterns.
5
+ Author-email: ModelCloud <qubitium@modelcloud.ai>
6
+ License-Expression: Apache-2.0
7
+ Project-URL: Homepage, https://github.com/ModelCloud/pcre
8
+ Keywords: regex,pcre2,bindings
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3 :: Only
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Classifier: Programming Language :: Python :: 3.14
16
+ Classifier: Programming Language :: C
17
+ Classifier: Topic :: Software Development :: Libraries
18
+ Classifier: Topic :: Text Processing :: Linguistic
19
+ Requires-Python: >=3.9
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Dynamic: license-file
23
+
24
+ <!--
25
+ # SPDX-FileCopyrightText: 2025 ModelCloud.ai
26
+ # SPDX-FileCopyrightText: 2025 qubitium@modelcloud.ai
27
+ # SPDX-License-Identifier: Apache-2.0
28
+ # Contact: qubitium@modelcloud.ai, x.com/qubitium
29
+ -->
30
+
31
+ # PyPcre (Python PCRE2 Binding)
32
+
33
+ Modern `nogil` Python bindings for the PCRE2 library with `stdlib.re` API compatibility.
34
+
35
+ <p align="center">
36
+ <a href="https://github.com/ModelCloud/PyPcre/releases" style="text-decoration:none;"><img alt="GitHub release" src="https://img.shields.io/github/release/ModelCloud/Pcre.svg"></a>
37
+ <a href="https://pypi.org/project/PyPcre/" style="text-decoration:none;"><img alt="PyPI - Version" src="https://img.shields.io/pypi/v/PyPcre"></a>
38
+ <a href="https://pepy.tech/projects/PyPcre" style="text-decoration:none;"><img src="https://static.pepy.tech/badge/PyPcre" alt="PyPI Downloads"></a>
39
+ <a href="https://github.com/ModelCloud/PyPcre/blob/main/LICENSE"><img src="https://img.shields.io/pypi/l/PyPcre"></a>
40
+ <a href="https://huggingface.co/modelcloud/"><img src="https://img.shields.io/badge/🤗%20Hugging%20Face-ModelCloud-%23ff8811.svg"></a>
41
+ </p>
42
+
43
+
44
+
45
+ ## Latest News
46
+ * 03/22/2026 [0.2.15](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.15): Python 3.15 `re` compatibility (`prefixmatch`, `NOFLAG`)
47
+ * 03/21/2026 [0.2.14](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.14): Python 3.14 compatibility
48
+ * 03/02/2026 [0.2.11](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.11): Auto-detect `Visual Studio` in Windows environments during install and compile.
49
+ * 02/24/2026 [0.2.10](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.10): Allow a `Visual Studio` (VS) compiler version check override via an environment variable.
50
+ * 12/15/2025 [0.2.8](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.8): Fixed multi-arch Linux OS compatibility when both x86_64 and i386 `pcre2` libraries are installed.
51
+ * 10/20/2025 [0.2.4](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.4): Removed the dependency on a system `python3-dev` package. `Python.h` will be downloaded optimistically from python.org when needed.
52
+ * 10/12/2025 [0.2.3](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.3): 🤗 Full `GIL=0` compliance for Python >= 3.13T. Reduced cache thread contention. Improved performance across all APIs. Expanded CI test coverage. FreeBSD, Solaris, and Windows compatibility validated.
53
+ * 10/09/2025 [0.1.0](https://github.com/ModelCloud/PyPcre/releases/tag/v0.1.0): 🎉 First release. Thread-safe, with auto JIT, auto pattern caching, and optimistic linking to the system library for fast installs.
54
+
55
+ ## Why PyPcre
56
+
57
+ PyPcre is a modern PCRE2 binding designed to be both fast and thread-safe in a `GIL=0` world. In the era of the global interpreter lock, Python had real threads but often only limited concurrency, aside from a handful of low-level APIs and packages. As Python moves toward a fuller `GIL=0` design, true multi-threaded concurrency becomes practical and brings Python closer to parity with other modern languages.
58
+
59
+ Many Python regular expression packages either segfault under `GIL=0` or suffer suboptimal performance because they were not designed with threaded execution in mind.
60
+
61
+ PyPcre is fully CI-tested. Every API and PCRE2 flag is exercised in a continuous development environment backed by the ModelCloud.AI team. Fuzz (clobber) tests are also run to catch memory safety, accuracy, and memory leak regressions.
62
+
63
+ For safety, PyPcre preferentially links against the OS-provided `libpcre2` package so it can benefit from upstream security patches. You can force a full source build with the `PYPCRE_BUILD_FROM_SOURCE=1` environment variable.
64
+
65
+ ## Installation
66
+
67
+ ```bash
68
+ pip install PyPcre
69
+ ```
70
+
71
+ The package prefers linking against the system `libpcre2-8` shared library for fast installs and to inherit security updates from the OS. See [Building](#building) for manual build details.
72
+
73
+ ## Platform Support (Validated)
74
+
75
+ `Linux`, `macOS`, `Windows`, `WSL`, `FreeBSD`
76
+
77
+
78
+ ## Usage
79
+
80
+ If you already rely on the standard library `re`, migrating is as
81
+ simple as changing your import:
82
+
83
+ ```python
84
+ import pcre as re
85
+ ```
86
+
87
+ The high-level API keeps the standard library shape, so most existing `re`
88
+ code can move over with little or no rewriting.
89
+
90
+ ### Quick start
91
+
92
+ ```python
93
+ from pcre import compile, findall, match, search, Flag
94
+
95
+ if match(r"(?P<word>\\w+)", "hello world"):
96
+ print("found word")
97
+
98
+ pattern = compile(rb"\d+", flags=Flag.MULTILINE)
99
+ numbers = pattern.findall(b"line 1\nline 22")
100
+ ```
101
+
102
+ ### User-facing API
103
+
104
+ - Module helpers: `prefixmatch`, `match`, `search`, `fullmatch`, `finditer`,
105
+ `findall`, `split`, `sub`, `subn`, `compile`, `escape`, `purge`, and
106
+ `parallel_map`.
107
+ - `compile()` returns a `Pattern` object with the familiar matching helpers
108
+ plus `split()`, `sub()`, and `subn()`.
109
+ - `Pattern` exposes `.pattern`, `.flags`, `.jit`, `.groupindex`, and `.groups`
110
+ for introspection.
111
+ - `Match` objects expose the usual `group()`, `groups()`, `groupdict()`,
112
+ `start()`, `end()`, `span()`, and `expand()` methods, along with `.re`,
113
+ `.string`, `.pos`, `.endpos`, `.lastindex`, `.lastgroup`, and `.regs`.
114
+ - Flags are available through `pcre.Flag` and familiar aliases such as
115
+ `IGNORECASE`, `MULTILINE`, `DOTALL`, `VERBOSE`, `ASCII`, `UNICODE`, and
116
+ `NOFLAG`.
117
+ - Errors are raised as `pcre.PcreError`; `error` and `PatternError` are kept as
118
+ compatibility aliases.
119
+
120
+ ### Common examples
121
+
122
+ Compiled patterns:
123
+
124
+ ```python
125
+ from pcre import compile, Flag
126
+
127
+ pattern = compile(r"(?P<name>[A-Za-z]+)", flags=Flag.CASELESS)
128
+ match = pattern.search("User: alice")
129
+ print(match.group("name")) # alice
130
+ ```
131
+
132
+ Substitution:
133
+
134
+ ```python
135
+ from pcre import sub
136
+
137
+ result = sub(r"\d+", "#", "room 101")
138
+ print(result) # room #
139
+ ```
140
+
141
+ Bytes:
142
+
143
+ ```python
144
+ from pcre import compile
145
+
146
+ pattern = compile(br"\w+")
147
+ print(pattern.findall(b"ab cd")) # [b'ab', b'cd']
148
+ ```
149
+
150
+ ### Stdlib `re` compatibility
151
+
152
+ - Module-level helpers and the `Pattern` class follow the same call shapes as
153
+ the standard library `re` module, including `pos`, `endpos`, and `flags`
154
+ behavior.
155
+ - Python 3.15's `prefixmatch()` alias is available at both the module level
156
+ and on compiled `Pattern` objects, and `re.NOFLAG` is re-exported as the
157
+ zero-value compatibility alias.
158
+ - `Pattern` mirrors `re.Pattern` attributes like `.pattern`, `.groupindex`,
159
+ and `.groups`, while `Match` objects surface the familiar `.re`, `.string`,
160
+ `.pos`, `.endpos`, `.lastindex`, `.lastgroup`, `.regs`, and `.expand()` API.
161
+ - Substitution helpers enforce the same type rules as the standard library
162
+ `re` module: string patterns require string replacements, byte patterns
163
+ require bytes-like replacements, and callable replacements receive the
164
+ wrapped `Match`.
165
+ - `compile()` accepts native `Flag` values as well as compatible
166
+ `re.RegexFlag` members from the standard library. Supported stdlib flags
167
+ map 1:1 to PCRE2 options (`IGNORECASE→CASELESS`, `MULTILINE→MULTILINE`,
168
+ `DOTALL→DOTALL`, `VERBOSE→EXTENDED`); passing unsupported stdlib flags
169
+ raises a compatibility `ValueError` to prevent silent divergences.
170
+ - `pcre.escape()` delegates directly to `re.escape` for byte and text
171
+ patterns so escaping semantics remain identical.
172
+ - String patterns enable Unicode behavior by default. Byte patterns do not.
173
+
174
+ ### `regex` package compatibility
175
+
176
+ The [`regex`](https://pypi.org/project/regex/) package interprets
177
+ `\uXXXX` and `\UXXXXXXXX` escapes as UTF-8 code points, while PCRE2 expects
178
+ hexadecimal escapes to use the `\x{...}` form. Enable `Flag.COMPAT_UNICODE_ESCAPE` to
179
+ translate those escapes automatically when compiling patterns:
180
+
181
+ ```python
182
+ from pcre import compile, Flag
183
+
184
+ pattern = compile(r"\\U0001F600", flags=Flag.COMPAT_UNICODE_ESCAPE)
185
+ assert pattern.pattern == r"\\x{0001F600}"
186
+ ```
187
+
188
+ Set the default behavior globally with `pcre.configure(compat_regex=True)`
189
+ so that subsequent calls to `compile()` and the module-level helpers apply
190
+ the conversion without repeating the flag.
191
+
192
+ ### Common issues
193
+
194
+ - Unsupported stdlib flags such as `re.DEBUG`, `re.LOCALE`, and `re.ASCII`
195
+ raise `ValueError`. If you want ASCII-style behavior, use `pcre.ASCII` or
196
+ `Flag.NO_UTF | Flag.NO_UCP`.
197
+ - Replacement types must match the subject type: text patterns use `str`
198
+ replacements, while byte patterns use bytes-like replacements.
199
+ - If you are porting patterns from the third-party `regex` package, check
200
+ `\u` and `\U` escapes first. That is the most common compatibility gap.
201
+ - Most users do not need to tune caching, JIT, or threading. The defaults are
202
+ intended to work well out of the box.
203
+
204
+ ### Optional runtime controls
205
+
206
+ - `pcre.configure(jit=False)` disables JIT globally. `Flag.JIT` and
207
+ `Flag.NO_JIT` let you override that per pattern.
208
+ - `pcre.set_cache_limit()`, `pcre.get_cache_limit()`, and `pcre.clear_cache()`
209
+ control the high-level compile cache.
210
+ - `pcre.configure_threads()`, `pcre.configure_thread_pool()`,
211
+ `shutdown_thread_pool()`, `Flag.THREADS`, and `Flag.NO_THREADS` are available
212
+ if you want to opt into or restrict threaded execution.
213
+
214
+ ## Building
215
+
216
+ The extension links against an existing PCRE2 installation (the `libpcre2-8`
217
+ variant). Install the development headers for your platform before building,
218
+ for example `apt install libpcre2-dev` on Debian/Ubuntu, `dnf install pcre2-devel`
219
+ on Fedora/RHEL derivatives, or `brew install pcre2` on macOS.
220
+
221
+ If the headers or library live in a non-standard location, you can export one
222
+ or more of the following environment variables prior to invoking the build
223
+ (`pip install .`, `python -m build`, etc.):
224
+
225
+ - `PYPCRE_ROOT`
226
+ - `PYPCRE_INCLUDE_DIR`
227
+ - `PYPCRE_LIBRARY_DIR`
228
+ - `PYPCRE_LIBRARY_PATH` *(pathsep-separated directories or explicit library files to
229
+ prioritize when resolving `libpcre2-8`)*
230
+ - `PYPCRE_LIBRARIES`
231
+ - `PYPCRE_CFLAGS`
232
+ - `PYPCRE_LDFLAGS`
233
+
234
+ If you would rather force a source build, set `PYPCRE_BUILD_FROM_SOURCE=1`
235
+ before installing.
236
+
237
+ When `pkg-config` is available, the build automatically picks up the
238
+ required include and link flags via `pkg-config --cflags/--libs libpcre2-8`.
239
+ Without `pkg-config`, the build script scans common installation prefixes for
240
+ Linux distributions (Debian, Ubuntu, Fedora/RHEL/CentOS, openSUSE, Alpine),
241
+ FreeBSD, and macOS (including Homebrew) to locate the headers and
242
+ libraries.
243
+
244
+ If your system ships `libpcre2-8` under `/usr` but you also maintain a
245
+ manually built copy under `/usr/local`, export `PYPCRE_LIBRARY_PATH` (and, if
246
+ needed, a matching `PYPCRE_INCLUDE_DIR`) so the build links against the desired
247
+ location.
@@ -0,0 +1,247 @@
1
+ Metadata-Version: 2.4
2
+ Name: PyPcre
3
+ Version: 0.2.15
4
+ Summary: Modern, GIL-friendly, Fast Python bindings for PCRE2 with auto caching and JIT of compiled patterns.
5
+ Author-email: ModelCloud <qubitium@modelcloud.ai>
6
+ License-Expression: Apache-2.0
7
+ Project-URL: Homepage, https://github.com/ModelCloud/pcre
8
+ Keywords: regex,pcre2,bindings
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3 :: Only
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Classifier: Programming Language :: Python :: 3.14
16
+ Classifier: Programming Language :: C
17
+ Classifier: Topic :: Software Development :: Libraries
18
+ Classifier: Topic :: Text Processing :: Linguistic
19
+ Requires-Python: >=3.9
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Dynamic: license-file
23
+
24
+ <!--
25
+ # SPDX-FileCopyrightText: 2025 ModelCloud.ai
26
+ # SPDX-FileCopyrightText: 2025 qubitium@modelcloud.ai
27
+ # SPDX-License-Identifier: Apache-2.0
28
+ # Contact: qubitium@modelcloud.ai, x.com/qubitium
29
+ -->
30
+
31
+ # PyPcre (Python PCRE2 Binding)
32
+
33
+ Modern `nogil` Python bindings for the PCRE2 library with `stdlib.re` API compatibility.
34
+
35
+ <p align="center">
36
+ <a href="https://github.com/ModelCloud/PyPcre/releases" style="text-decoration:none;"><img alt="GitHub release" src="https://img.shields.io/github/release/ModelCloud/Pcre.svg"></a>
37
+ <a href="https://pypi.org/project/PyPcre/" style="text-decoration:none;"><img alt="PyPI - Version" src="https://img.shields.io/pypi/v/PyPcre"></a>
38
+ <a href="https://pepy.tech/projects/PyPcre" style="text-decoration:none;"><img src="https://static.pepy.tech/badge/PyPcre" alt="PyPI Downloads"></a>
39
+ <a href="https://github.com/ModelCloud/PyPcre/blob/main/LICENSE"><img src="https://img.shields.io/pypi/l/PyPcre"></a>
40
+ <a href="https://huggingface.co/modelcloud/"><img src="https://img.shields.io/badge/🤗%20Hugging%20Face-ModelCloud-%23ff8811.svg"></a>
41
+ </p>
42
+
43
+
44
+
45
+ ## Latest News
46
+ * 03/22/2026 [0.2.15](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.15): Python 3.15 `re` compatibility (`prefixmatch`, `NOFLAG`)
47
+ * 03/21/2026 [0.2.14](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.14): Python 3.14 compatibility
48
+ * 03/02/2026 [0.2.11](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.11): Auto-detect `Visual Studio` in Windows environments during install and compile.
49
+ * 02/24/2026 [0.2.10](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.10): Allow a `Visual Studio` (VS) compiler version check override via an environment variable.
50
+ * 12/15/2025 [0.2.8](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.8): Fixed multi-arch Linux OS compatibility when both x86_64 and i386 `pcre2` libraries are installed.
51
+ * 10/20/2025 [0.2.4](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.4): Removed the dependency on a system `python3-dev` package. `Python.h` will be downloaded optimistically from python.org when needed.
52
+ * 10/12/2025 [0.2.3](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.3): 🤗 Full `GIL=0` compliance for Python >= 3.13T. Reduced cache thread contention. Improved performance across all APIs. Expanded CI test coverage. FreeBSD, Solaris, and Windows compatibility validated.
53
+ * 10/09/2025 [0.1.0](https://github.com/ModelCloud/PyPcre/releases/tag/v0.1.0): 🎉 First release. Thread-safe, with auto JIT, auto pattern caching, and optimistic linking to the system library for fast installs.
54
+
55
+ ## Why PyPcre
56
+
57
+ PyPcre is a modern PCRE2 binding designed to be both fast and thread-safe in a `GIL=0` world. In the era of the global interpreter lock, Python had real threads but often only limited concurrency, aside from a handful of low-level APIs and packages. As Python moves toward a fuller `GIL=0` design, true multi-threaded concurrency becomes practical and brings Python closer to parity with other modern languages.
58
+
59
+ Many Python regular expression packages either segfault under `GIL=0` or suffer suboptimal performance because they were not designed with threaded execution in mind.
60
+
61
+ PyPcre is fully CI-tested. Every API and PCRE2 flag is exercised in a continuous development environment backed by the ModelCloud.AI team. Fuzz (clobber) tests are also run to catch memory safety, accuracy, and memory leak regressions.
62
+
63
+ For safety, PyPcre preferentially links against the OS-provided `libpcre2` package so it can benefit from upstream security patches. You can force a full source build with the `PYPCRE_BUILD_FROM_SOURCE=1` environment variable.
64
+
65
+ ## Installation
66
+
67
+ ```bash
68
+ pip install PyPcre
69
+ ```
70
+
71
+ The package prefers linking against the system `libpcre2-8` shared library for fast installs and to inherit security updates from the OS. See [Building](#building) for manual build details.
72
+
73
+ ## Platform Support (Validated)
74
+
75
+ `Linux`, `macOS`, `Windows`, `WSL`, `FreeBSD`
76
+
77
+
78
+ ## Usage
79
+
80
+ If you already rely on the standard library `re`, migrating is as
81
+ simple as changing your import:
82
+
83
+ ```python
84
+ import pcre as re
85
+ ```
86
+
87
+ The high-level API keeps the standard library shape, so most existing `re`
88
+ code can move over with little or no rewriting.
89
+
90
+ ### Quick start
91
+
92
+ ```python
93
+ from pcre import compile, findall, match, search, Flag
94
+
95
+ if match(r"(?P<word>\\w+)", "hello world"):
96
+ print("found word")
97
+
98
+ pattern = compile(rb"\d+", flags=Flag.MULTILINE)
99
+ numbers = pattern.findall(b"line 1\nline 22")
100
+ ```
101
+
102
+ ### User-facing API
103
+
104
+ - Module helpers: `prefixmatch`, `match`, `search`, `fullmatch`, `finditer`,
105
+ `findall`, `split`, `sub`, `subn`, `compile`, `escape`, `purge`, and
106
+ `parallel_map`.
107
+ - `compile()` returns a `Pattern` object with the familiar matching helpers
108
+ plus `split()`, `sub()`, and `subn()`.
109
+ - `Pattern` exposes `.pattern`, `.flags`, `.jit`, `.groupindex`, and `.groups`
110
+ for introspection.
111
+ - `Match` objects expose the usual `group()`, `groups()`, `groupdict()`,
112
+ `start()`, `end()`, `span()`, and `expand()` methods, along with `.re`,
113
+ `.string`, `.pos`, `.endpos`, `.lastindex`, `.lastgroup`, and `.regs`.
114
+ - Flags are available through `pcre.Flag` and familiar aliases such as
115
+ `IGNORECASE`, `MULTILINE`, `DOTALL`, `VERBOSE`, `ASCII`, `UNICODE`, and
116
+ `NOFLAG`.
117
+ - Errors are raised as `pcre.PcreError`; `error` and `PatternError` are kept as
118
+ compatibility aliases.
119
+
120
+ ### Common examples
121
+
122
+ Compiled patterns:
123
+
124
+ ```python
125
+ from pcre import compile, Flag
126
+
127
+ pattern = compile(r"(?P<name>[A-Za-z]+)", flags=Flag.CASELESS)
128
+ match = pattern.search("User: alice")
129
+ print(match.group("name")) # alice
130
+ ```
131
+
132
+ Substitution:
133
+
134
+ ```python
135
+ from pcre import sub
136
+
137
+ result = sub(r"\d+", "#", "room 101")
138
+ print(result) # room #
139
+ ```
140
+
141
+ Bytes:
142
+
143
+ ```python
144
+ from pcre import compile
145
+
146
+ pattern = compile(br"\w+")
147
+ print(pattern.findall(b"ab cd")) # [b'ab', b'cd']
148
+ ```
149
+
150
+ ### Stdlib `re` compatibility
151
+
152
+ - Module-level helpers and the `Pattern` class follow the same call shapes as
153
+ the standard library `re` module, including `pos`, `endpos`, and `flags`
154
+ behavior.
155
+ - Python 3.15's `prefixmatch()` alias is available at both the module level
156
+ and on compiled `Pattern` objects, and `re.NOFLAG` is re-exported as the
157
+ zero-value compatibility alias.
158
+ - `Pattern` mirrors `re.Pattern` attributes like `.pattern`, `.groupindex`,
159
+ and `.groups`, while `Match` objects surface the familiar `.re`, `.string`,
160
+ `.pos`, `.endpos`, `.lastindex`, `.lastgroup`, `.regs`, and `.expand()` API.
161
+ - Substitution helpers enforce the same type rules as the standard library
162
+ `re` module: string patterns require string replacements, byte patterns
163
+ require bytes-like replacements, and callable replacements receive the
164
+ wrapped `Match`.
165
+ - `compile()` accepts native `Flag` values as well as compatible
166
+ `re.RegexFlag` members from the standard library. Supported stdlib flags
167
+ map 1:1 to PCRE2 options (`IGNORECASE→CASELESS`, `MULTILINE→MULTILINE`,
168
+ `DOTALL→DOTALL`, `VERBOSE→EXTENDED`); passing unsupported stdlib flags
169
+ raises a compatibility `ValueError` to prevent silent divergences.
170
+ - `pcre.escape()` delegates directly to `re.escape` for byte and text
171
+ patterns so escaping semantics remain identical.
172
+ - String patterns enable Unicode behavior by default. Byte patterns do not.
173
+
174
+ ### `regex` package compatibility
175
+
176
+ The [`regex`](https://pypi.org/project/regex/) package interprets
177
+ `\uXXXX` and `\UXXXXXXXX` escapes as UTF-8 code points, while PCRE2 expects
178
+ hexadecimal escapes to use the `\x{...}` form. Enable `Flag.COMPAT_UNICODE_ESCAPE` to
179
+ translate those escapes automatically when compiling patterns:
180
+
181
+ ```python
182
+ from pcre import compile, Flag
183
+
184
+ pattern = compile(r"\\U0001F600", flags=Flag.COMPAT_UNICODE_ESCAPE)
185
+ assert pattern.pattern == r"\\x{0001F600}"
186
+ ```
187
+
188
+ Set the default behavior globally with `pcre.configure(compat_regex=True)`
189
+ so that subsequent calls to `compile()` and the module-level helpers apply
190
+ the conversion without repeating the flag.
191
+
192
+ ### Common issues
193
+
194
+ - Unsupported stdlib flags such as `re.DEBUG`, `re.LOCALE`, and `re.ASCII`
195
+ raise `ValueError`. If you want ASCII-style behavior, use `pcre.ASCII` or
196
+ `Flag.NO_UTF | Flag.NO_UCP`.
197
+ - Replacement types must match the subject type: text patterns use `str`
198
+ replacements, while byte patterns use bytes-like replacements.
199
+ - If you are porting patterns from the third-party `regex` package, check
200
+ `\u` and `\U` escapes first. That is the most common compatibility gap.
201
+ - Most users do not need to tune caching, JIT, or threading. The defaults are
202
+ intended to work well out of the box.
203
+
204
+ ### Optional runtime controls
205
+
206
+ - `pcre.configure(jit=False)` disables JIT globally. `Flag.JIT` and
207
+ `Flag.NO_JIT` let you override that per pattern.
208
+ - `pcre.set_cache_limit()`, `pcre.get_cache_limit()`, and `pcre.clear_cache()`
209
+ control the high-level compile cache.
210
+ - `pcre.configure_threads()`, `pcre.configure_thread_pool()`,
211
+ `shutdown_thread_pool()`, `Flag.THREADS`, and `Flag.NO_THREADS` are available
212
+ if you want to opt into or restrict threaded execution.
213
+
214
+ ## Building
215
+
216
+ The extension links against an existing PCRE2 installation (the `libpcre2-8`
217
+ variant). Install the development headers for your platform before building,
218
+ for example `apt install libpcre2-dev` on Debian/Ubuntu, `dnf install pcre2-devel`
219
+ on Fedora/RHEL derivatives, or `brew install pcre2` on macOS.
220
+
221
+ If the headers or library live in a non-standard location, you can export one
222
+ or more of the following environment variables prior to invoking the build
223
+ (`pip install .`, `python -m build`, etc.):
224
+
225
+ - `PYPCRE_ROOT`
226
+ - `PYPCRE_INCLUDE_DIR`
227
+ - `PYPCRE_LIBRARY_DIR`
228
+ - `PYPCRE_LIBRARY_PATH` *(pathsep-separated directories or explicit library files to
229
+ prioritize when resolving `libpcre2-8`)*
230
+ - `PYPCRE_LIBRARIES`
231
+ - `PYPCRE_CFLAGS`
232
+ - `PYPCRE_LDFLAGS`
233
+
234
+ If you would rather force a source build, set `PYPCRE_BUILD_FROM_SOURCE=1`
235
+ before installing.
236
+
237
+ When `pkg-config` is available, the build automatically picks up the
238
+ required include and link flags via `pkg-config --cflags/--libs libpcre2-8`.
239
+ Without `pkg-config`, the build script scans common installation prefixes for
240
+ Linux distributions (Debian, Ubuntu, Fedora/RHEL/CentOS, openSUSE, Alpine),
241
+ FreeBSD, and macOS (including Homebrew) to locate the headers and
242
+ libraries.
243
+
244
+ If your system ships `libpcre2-8` under `/usr` but you also maintain a
245
+ manually built copy under `/usr/local`, export `PYPCRE_LIBRARY_PATH` (and, if
246
+ needed, a matching `PYPCRE_INCLUDE_DIR`) so the build links against the desired
247
+ location.