PyPcre 0.6.1__tar.gz → 0.6.3__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 (80) hide show
  1. {pypcre-0.6.1 → pypcre-0.6.3}/PKG-INFO +17 -13
  2. {pypcre-0.6.1 → pypcre-0.6.3}/PyPcre.egg-info/PKG-INFO +17 -13
  3. {pypcre-0.6.1 → pypcre-0.6.3}/README.md +16 -12
  4. {pypcre-0.6.1 → pypcre-0.6.3}/pcre/pcre.py +254 -29
  5. {pypcre-0.6.1 → pypcre-0.6.3}/pcre_ext/pcre2.c +116 -30
  6. {pypcre-0.6.1 → pypcre-0.6.3}/pyproject.toml +1 -1
  7. {pypcre-0.6.1 → pypcre-0.6.3}/setup.py +1 -1
  8. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_clobber_verify.py +43 -3
  9. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_coverage_gaps.py +2 -2
  10. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_lastindex_semantics.py +20 -0
  11. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_memory.py +47 -0
  12. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_python_coverage_audit.py +3 -2
  13. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_threaded_backend.py +1 -0
  14. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_threads.py +12 -0
  15. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_version.py +15 -0
  16. {pypcre-0.6.1 → pypcre-0.6.3}/LICENSE +0 -0
  17. {pypcre-0.6.1 → pypcre-0.6.3}/MANIFEST.in +0 -0
  18. {pypcre-0.6.1 → pypcre-0.6.3}/PyPcre.egg-info/SOURCES.txt +0 -0
  19. {pypcre-0.6.1 → pypcre-0.6.3}/PyPcre.egg-info/dependency_links.txt +0 -0
  20. {pypcre-0.6.1 → pypcre-0.6.3}/PyPcre.egg-info/top_level.txt +0 -0
  21. {pypcre-0.6.1 → pypcre-0.6.3}/pcre/__init__.py +0 -0
  22. {pypcre-0.6.1 → pypcre-0.6.3}/pcre/_stdlib_re.py +0 -0
  23. {pypcre-0.6.1 → pypcre-0.6.3}/pcre/cache.py +0 -0
  24. {pypcre-0.6.1 → pypcre-0.6.3}/pcre/error.py +0 -0
  25. {pypcre-0.6.1 → pypcre-0.6.3}/pcre/flags.py +0 -0
  26. {pypcre-0.6.1 → pypcre-0.6.3}/pcre/re_compat.py +0 -0
  27. {pypcre-0.6.1 → pypcre-0.6.3}/pcre/threads.py +0 -0
  28. {pypcre-0.6.1 → pypcre-0.6.3}/pcre_ext/atomic_compat.h +0 -0
  29. {pypcre-0.6.1 → pypcre-0.6.3}/pcre_ext/cache.c +0 -0
  30. {pypcre-0.6.1 → pypcre-0.6.3}/pcre_ext/error.c +0 -0
  31. {pypcre-0.6.1 → pypcre-0.6.3}/pcre_ext/flag.c +0 -0
  32. {pypcre-0.6.1 → pypcre-0.6.3}/pcre_ext/jit_support.c +0 -0
  33. {pypcre-0.6.1 → pypcre-0.6.3}/pcre_ext/memory.c +0 -0
  34. {pypcre-0.6.1 → pypcre-0.6.3}/pcre_ext/pattern_cache.c +0 -0
  35. {pypcre-0.6.1 → pypcre-0.6.3}/pcre_ext/pcre2.h +0 -0
  36. {pypcre-0.6.1 → pypcre-0.6.3}/pcre_ext/pcre2_module.h +0 -0
  37. {pypcre-0.6.1 → pypcre-0.6.3}/pcre_ext/string_helpers.c +0 -0
  38. {pypcre-0.6.1 → pypcre-0.6.3}/pcre_ext/util.c +0 -0
  39. {pypcre-0.6.1 → pypcre-0.6.3}/setup.cfg +0 -0
  40. {pypcre-0.6.1 → pypcre-0.6.3}/setup_utils.py +0 -0
  41. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_accuracy.py +0 -0
  42. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_api_parity.py +0 -0
  43. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_basic.py +0 -0
  44. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_bench_string.py +0 -0
  45. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_benchmark.py +0 -0
  46. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_bytes.py +0 -0
  47. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_c_api_audit.py +0 -0
  48. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_cache.py +0 -0
  49. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_cache_global.py +0 -0
  50. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_cache_global_inproc.py +0 -0
  51. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_cache_scope_safety.py +0 -0
  52. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_clobber.py +0 -0
  53. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_clobber_thread.py +0 -0
  54. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_compile_utf_no_check_safety.py +0 -0
  55. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_core.py +0 -0
  56. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_errors.py +0 -0
  57. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_escape_fastpath.py +0 -0
  58. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_expand_fastpath.py +0 -0
  59. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_flags.py +0 -0
  60. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_gil_zero_safety.py +0 -0
  61. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_jit.py +0 -0
  62. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_jit_anchoring.py +0 -0
  63. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_jit_start_optimize_workaround.py +0 -0
  64. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_lastindex_ovector_fastpath.py +0 -0
  65. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_literal_capture_findall_fastpath.py +0 -0
  66. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_literal_capture_split_fastpath.py +0 -0
  67. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_mmap.py +0 -0
  68. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_module.py +0 -0
  69. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_multi_literal_capture_findall_fastpath.py +0 -0
  70. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_multi_literal_capture_split_fastpath.py +0 -0
  71. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_pattern.py +0 -0
  72. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_re_compat.py +0 -0
  73. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_setup_utils_multiarch.py +0 -0
  74. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_simd.py +0 -0
  75. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_stdlib_flag_fastpath.py +0 -0
  76. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_sub_count_one_fastpath.py +0 -0
  77. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_sub_reference_fastpath.py +0 -0
  78. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_template_dispatch_fastpath.py +0 -0
  79. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_transformers_regex.py +0 -0
  80. {pypcre-0.6.1 → pypcre-0.6.3}/tests/test_utf8.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PyPcre
3
- Version: 0.6.1
3
+ Version: 0.6.3
4
4
  Summary: Modern, GIL-friendly, Fast Python bindings for PCRE2 with auto caching and JIT of compiled patterns.
5
5
  Author-email: ModelCloud <qubitium@modelcloud.ai>
6
6
  License-Expression: Apache-2.0
@@ -37,7 +37,7 @@ Fast, free-threaded Python bindings for `PCRE2` with a stable `stdlib.re`-compat
37
37
  </p>
38
38
 
39
39
  <p align="center">
40
- <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>
40
+ <a href="https://github.com/ModelCloud/PyPcre/releases" style="text-decoration:none;"><img alt="GitHub release" src="https://img.shields.io/github/release/ModelCloud/PyPcre.svg"></a>
41
41
  <a href="https://pypi.org/project/PyPcre/" style="text-decoration:none;"><img alt="PyPI - Version" src="https://img.shields.io/pypi/v/PyPcre"></a>
42
42
  <a href="https://pepy.tech/projects/PyPcre" style="text-decoration:none;"><img src="https://static.pepy.tech/badge/PyPcre" alt="PyPI Downloads"></a>
43
43
  <a href="https://github.com/ModelCloud/PyPcre/blob/main/LICENSE"><img src="https://img.shields.io/pypi/l/PyPcre"></a>
@@ -47,8 +47,10 @@ Fast, free-threaded Python bindings for `PCRE2` with a stable `stdlib.re`-compat
47
47
 
48
48
 
49
49
  ## Latest News 🚀
50
- * 08/09–08/10/2026 **API performance and safety update**: common regex workloads and ordered `parallel_map(search)` workloads were benchmarked across Python 3.10 and free-threaded Python 3.14t/GIL=0. Compatibility fallbacks preserve complex patterns, subclasses, buffers, and callables. Unsafe UTF bytes compilation is also blocked, with differential, randomized, concurrency, subprocess, and memory-safety coverage. 🧵⚡🛡️
51
- * 08/08/2026 **0.6.0**: `findall`, `finditer`, `sub`/`subn`, `split`, and `match`/`search`/`fullmatch` are now up to **46x faster** than `stdlib.re` and **48x faster** than `regex` on `finditer`/`findall` workloads, **13x** on `split`, and **2–9x** on `sub`/`subn` backref workloads, with full `re` semantics. Free-threaded `findall` reaches **13.8x** vs `re` on 8 threads. 🚀⚡
50
+ * 10/20/2026 **[0.6.3](https://github.com/ModelCloud/PyPcre/releases/tag/v0.6.3)**: Fixed free-threaded races in `Match.lastindex` replay and PCRE2 version initialization, and reduced Python dispatch overhead across module-level and compiled-pattern `match`, `search`, `fullmatch`, `findall`, `finditer`, `split`, `sub`, and `subn` hot paths, with new concurrency and GC-cycle regression coverage plus exact fallbacks for subclasses, legacy backends, and non-default arguments. 🛡️🧵🚀⚡
51
+ * 08/25/2026 **[0.6.2](https://github.com/ModelCloud/PyPcre/releases/tag/v0.6.2)**: Hardened packaging metadata and fixed FreeBSD/WSL CI failures on PCRE2 10.42 runtimes, including legacy replacement-template and JIT-fallback compatibility. 🛠️🐧🪟
52
+ * 08/25/2026 **[0.6.1](https://github.com/ModelCloud/PyPcre/releases/tag/v0.6.1)**: Workaround for PCRE2 10.46/10.47 JIT start-optimization regressions, new verifying clobber suite, second memory/thread-safety sweep, Python 3.15 `sre_parse` removal compatibility, aligned `Pattern` `pos`/`endpos` signatures, and `setuptools` metadata fixes. 🛡️🧵🐍
53
+ * 08/09/2026 **[0.6.0](https://github.com/ModelCloud/PyPcre/releases/tag/v0.6.0)**: `findall`, `finditer`, `sub`/`subn`, `split`, and `match`/`search`/`fullmatch` hot-path speedups up to **46x** vs `stdlib.re` and **48x** vs `regex`, with free-threaded `findall` reaching **13.8x** on 8 threads. 🚀⚡
52
54
  * 07/27/2026 [0.5.0](https://github.com/ModelCloud/PyPcre/releases/tag/v0.5.0): Zero-copy buffer-protocol subject support (`mmap.mmap`, `bytearray`, `array.array`) with UTF-8 validation and GIL=0-safe memory pinning. 🗂️⚡
53
55
  * 07/24/2026 [0.4.0](https://github.com/ModelCloud/PyPcre/releases/tag/v0.4.0): C extension hardening (memory/pointer safety, bounds checks, atomic allocator init), GIL=0 safety verified, vectorized UTF-8 index/offset conversion, GIL-release threshold for small calls, C `findall` implementation, and README competitor benchmarks. 🛡️⚡
54
56
  * 04/13/2026 [0.3.0](https://github.com/ModelCloud/PyPcre/releases/tag/v0.3.0): Lower-overhead public `Match` objects, faster hot-path `match()` / `search()` / `fullmatch()` / `findall()`, and tighter free-threaded execution. ⚡
@@ -83,7 +85,7 @@ PyPcre pairs Python's familiar `re`-compatible API with the real `PCRE2` engine.
83
85
  | Syntax power | Very rich ✅ | More limited | Rich, but different from `PCRE2` |
84
86
  | JIT execution | `PCRE2` JIT ✅ | No | No |
85
87
  | `re`-compatible API surface | Stable and familiar ✅ | Native | Similar, but not the main goal |
86
- | Free-threaded support | Built and tested for `PYTHON_GIL=0` ✅ | No explicit PyPcre-style layer | Not a project focus here |
88
+ | Free-threaded support | Built and tested for `PYTHON_GIL=0` ✅ | No explicit free-threaded support | No explicit free-threaded fan-out layer |
87
89
  | Built-in threaded subject fan-out | `parallel_map()` ✅ | No | No |
88
90
  | System library updates | Uses system `libpcre2-8` by default ✅ | N/A | N/A |
89
91
 
@@ -252,8 +254,10 @@ numbers = pattern.findall(b"line 1\nline 22")
252
254
  ### API Overview 🧭
253
255
 
254
256
  - Module helpers: `prefixmatch`, `match`, `search`, `fullmatch`, `finditer`,
255
- `findall`, `split`, `sub`, `subn`, `compile`, `escape`, `purge`, and
256
- `parallel_map`.
257
+ `findall`, `split`, `sub`, `subn`, `compile`, `escape`, `purge`,
258
+ `template`, `parallel_map`, `configure`, `configure_threads`,
259
+ `configure_thread_pool`, `shutdown_thread_pool`, `set_cache_limit`,
260
+ `get_cache_limit`, and `clear_cache`.
257
261
  - `compile()` returns a `Pattern` object with the familiar matching helpers
258
262
  plus `split()`, `sub()`, and `subn()`.
259
263
  - `Pattern` exposes `.pattern`, `.flags`, `.jit`, `.groupindex`, and `.groups`
@@ -269,7 +273,7 @@ numbers = pattern.findall(b"line 1\nline 22")
269
273
 
270
274
  ### Common examples 🧪
271
275
 
272
- Compiled patterns:
276
+ 🧪 Compiled patterns:
273
277
 
274
278
  ```python
275
279
  from pcre import compile, Flag
@@ -279,7 +283,7 @@ match = pattern.search("User: alice")
279
283
  print(match.group("name")) # alice
280
284
  ```
281
285
 
282
- Substitution:
286
+ 🔁 Substitution:
283
287
 
284
288
  ```python
285
289
  from pcre import sub
@@ -288,7 +292,7 @@ result = sub(r"\d+", "#", "room 101")
288
292
  print(result) # room #
289
293
  ```
290
294
 
291
- Bytes:
295
+ 🗂️ Bytes:
292
296
 
293
297
  ```python
294
298
  from pcre import compile
@@ -353,9 +357,9 @@ the conversion without repeating the flag.
353
357
 
354
358
  ### Optional runtime controls 🎛️
355
359
 
356
- - `pcre.configure(jit=False)` disables JIT globally. `Flag.JIT` and
360
+ - ⚙️ `pcre.configure(jit=False)` disables JIT globally. `Flag.JIT` and
357
361
  `Flag.NO_JIT` let you override that per pattern.
358
- - `pcre.set_cache_limit()`, `pcre.get_cache_limit()`, and `pcre.clear_cache()`
362
+ - 🧹 `pcre.set_cache_limit()`, `pcre.get_cache_limit()`, and `pcre.clear_cache()`
359
363
  control every high-level compile/template helper cache in the active context.
360
364
  A zero limit disables them, and `None` uses a 256-entry hard safety ceiling
361
365
  rather than permitting unbounded growth. High-level cache entries never cross
@@ -363,7 +367,7 @@ the conversion without repeating the flag.
363
367
  workers' high-level helper caches on their next cache-backed call. Backend
364
368
  scratch buffers remain thread-scoped and are released when that thread exits.
365
369
  Oversized patterns and templates are not retained.
366
- - `pcre.configure_threads()`, `pcre.configure_thread_pool()`,
370
+ - 🧵 `pcre.configure_threads()`, `pcre.configure_thread_pool()`,
367
371
  `shutdown_thread_pool()`, `Flag.THREADS`, and `Flag.NO_THREADS` are available
368
372
  if you want to opt into or restrict threaded execution.
369
373
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PyPcre
3
- Version: 0.6.1
3
+ Version: 0.6.3
4
4
  Summary: Modern, GIL-friendly, Fast Python bindings for PCRE2 with auto caching and JIT of compiled patterns.
5
5
  Author-email: ModelCloud <qubitium@modelcloud.ai>
6
6
  License-Expression: Apache-2.0
@@ -37,7 +37,7 @@ Fast, free-threaded Python bindings for `PCRE2` with a stable `stdlib.re`-compat
37
37
  </p>
38
38
 
39
39
  <p align="center">
40
- <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>
40
+ <a href="https://github.com/ModelCloud/PyPcre/releases" style="text-decoration:none;"><img alt="GitHub release" src="https://img.shields.io/github/release/ModelCloud/PyPcre.svg"></a>
41
41
  <a href="https://pypi.org/project/PyPcre/" style="text-decoration:none;"><img alt="PyPI - Version" src="https://img.shields.io/pypi/v/PyPcre"></a>
42
42
  <a href="https://pepy.tech/projects/PyPcre" style="text-decoration:none;"><img src="https://static.pepy.tech/badge/PyPcre" alt="PyPI Downloads"></a>
43
43
  <a href="https://github.com/ModelCloud/PyPcre/blob/main/LICENSE"><img src="https://img.shields.io/pypi/l/PyPcre"></a>
@@ -47,8 +47,10 @@ Fast, free-threaded Python bindings for `PCRE2` with a stable `stdlib.re`-compat
47
47
 
48
48
 
49
49
  ## Latest News 🚀
50
- * 08/09–08/10/2026 **API performance and safety update**: common regex workloads and ordered `parallel_map(search)` workloads were benchmarked across Python 3.10 and free-threaded Python 3.14t/GIL=0. Compatibility fallbacks preserve complex patterns, subclasses, buffers, and callables. Unsafe UTF bytes compilation is also blocked, with differential, randomized, concurrency, subprocess, and memory-safety coverage. 🧵⚡🛡️
51
- * 08/08/2026 **0.6.0**: `findall`, `finditer`, `sub`/`subn`, `split`, and `match`/`search`/`fullmatch` are now up to **46x faster** than `stdlib.re` and **48x faster** than `regex` on `finditer`/`findall` workloads, **13x** on `split`, and **2–9x** on `sub`/`subn` backref workloads, with full `re` semantics. Free-threaded `findall` reaches **13.8x** vs `re` on 8 threads. 🚀⚡
50
+ * 10/20/2026 **[0.6.3](https://github.com/ModelCloud/PyPcre/releases/tag/v0.6.3)**: Fixed free-threaded races in `Match.lastindex` replay and PCRE2 version initialization, and reduced Python dispatch overhead across module-level and compiled-pattern `match`, `search`, `fullmatch`, `findall`, `finditer`, `split`, `sub`, and `subn` hot paths, with new concurrency and GC-cycle regression coverage plus exact fallbacks for subclasses, legacy backends, and non-default arguments. 🛡️🧵🚀⚡
51
+ * 08/25/2026 **[0.6.2](https://github.com/ModelCloud/PyPcre/releases/tag/v0.6.2)**: Hardened packaging metadata and fixed FreeBSD/WSL CI failures on PCRE2 10.42 runtimes, including legacy replacement-template and JIT-fallback compatibility. 🛠️🐧🪟
52
+ * 08/25/2026 **[0.6.1](https://github.com/ModelCloud/PyPcre/releases/tag/v0.6.1)**: Workaround for PCRE2 10.46/10.47 JIT start-optimization regressions, new verifying clobber suite, second memory/thread-safety sweep, Python 3.15 `sre_parse` removal compatibility, aligned `Pattern` `pos`/`endpos` signatures, and `setuptools` metadata fixes. 🛡️🧵🐍
53
+ * 08/09/2026 **[0.6.0](https://github.com/ModelCloud/PyPcre/releases/tag/v0.6.0)**: `findall`, `finditer`, `sub`/`subn`, `split`, and `match`/`search`/`fullmatch` hot-path speedups up to **46x** vs `stdlib.re` and **48x** vs `regex`, with free-threaded `findall` reaching **13.8x** on 8 threads. 🚀⚡
52
54
  * 07/27/2026 [0.5.0](https://github.com/ModelCloud/PyPcre/releases/tag/v0.5.0): Zero-copy buffer-protocol subject support (`mmap.mmap`, `bytearray`, `array.array`) with UTF-8 validation and GIL=0-safe memory pinning. 🗂️⚡
53
55
  * 07/24/2026 [0.4.0](https://github.com/ModelCloud/PyPcre/releases/tag/v0.4.0): C extension hardening (memory/pointer safety, bounds checks, atomic allocator init), GIL=0 safety verified, vectorized UTF-8 index/offset conversion, GIL-release threshold for small calls, C `findall` implementation, and README competitor benchmarks. 🛡️⚡
54
56
  * 04/13/2026 [0.3.0](https://github.com/ModelCloud/PyPcre/releases/tag/v0.3.0): Lower-overhead public `Match` objects, faster hot-path `match()` / `search()` / `fullmatch()` / `findall()`, and tighter free-threaded execution. ⚡
@@ -83,7 +85,7 @@ PyPcre pairs Python's familiar `re`-compatible API with the real `PCRE2` engine.
83
85
  | Syntax power | Very rich ✅ | More limited | Rich, but different from `PCRE2` |
84
86
  | JIT execution | `PCRE2` JIT ✅ | No | No |
85
87
  | `re`-compatible API surface | Stable and familiar ✅ | Native | Similar, but not the main goal |
86
- | Free-threaded support | Built and tested for `PYTHON_GIL=0` ✅ | No explicit PyPcre-style layer | Not a project focus here |
88
+ | Free-threaded support | Built and tested for `PYTHON_GIL=0` ✅ | No explicit free-threaded support | No explicit free-threaded fan-out layer |
87
89
  | Built-in threaded subject fan-out | `parallel_map()` ✅ | No | No |
88
90
  | System library updates | Uses system `libpcre2-8` by default ✅ | N/A | N/A |
89
91
 
@@ -252,8 +254,10 @@ numbers = pattern.findall(b"line 1\nline 22")
252
254
  ### API Overview 🧭
253
255
 
254
256
  - Module helpers: `prefixmatch`, `match`, `search`, `fullmatch`, `finditer`,
255
- `findall`, `split`, `sub`, `subn`, `compile`, `escape`, `purge`, and
256
- `parallel_map`.
257
+ `findall`, `split`, `sub`, `subn`, `compile`, `escape`, `purge`,
258
+ `template`, `parallel_map`, `configure`, `configure_threads`,
259
+ `configure_thread_pool`, `shutdown_thread_pool`, `set_cache_limit`,
260
+ `get_cache_limit`, and `clear_cache`.
257
261
  - `compile()` returns a `Pattern` object with the familiar matching helpers
258
262
  plus `split()`, `sub()`, and `subn()`.
259
263
  - `Pattern` exposes `.pattern`, `.flags`, `.jit`, `.groupindex`, and `.groups`
@@ -269,7 +273,7 @@ numbers = pattern.findall(b"line 1\nline 22")
269
273
 
270
274
  ### Common examples 🧪
271
275
 
272
- Compiled patterns:
276
+ 🧪 Compiled patterns:
273
277
 
274
278
  ```python
275
279
  from pcre import compile, Flag
@@ -279,7 +283,7 @@ match = pattern.search("User: alice")
279
283
  print(match.group("name")) # alice
280
284
  ```
281
285
 
282
- Substitution:
286
+ 🔁 Substitution:
283
287
 
284
288
  ```python
285
289
  from pcre import sub
@@ -288,7 +292,7 @@ result = sub(r"\d+", "#", "room 101")
288
292
  print(result) # room #
289
293
  ```
290
294
 
291
- Bytes:
295
+ 🗂️ Bytes:
292
296
 
293
297
  ```python
294
298
  from pcre import compile
@@ -353,9 +357,9 @@ the conversion without repeating the flag.
353
357
 
354
358
  ### Optional runtime controls 🎛️
355
359
 
356
- - `pcre.configure(jit=False)` disables JIT globally. `Flag.JIT` and
360
+ - ⚙️ `pcre.configure(jit=False)` disables JIT globally. `Flag.JIT` and
357
361
  `Flag.NO_JIT` let you override that per pattern.
358
- - `pcre.set_cache_limit()`, `pcre.get_cache_limit()`, and `pcre.clear_cache()`
362
+ - 🧹 `pcre.set_cache_limit()`, `pcre.get_cache_limit()`, and `pcre.clear_cache()`
359
363
  control every high-level compile/template helper cache in the active context.
360
364
  A zero limit disables them, and `None` uses a 256-entry hard safety ceiling
361
365
  rather than permitting unbounded growth. High-level cache entries never cross
@@ -363,7 +367,7 @@ the conversion without repeating the flag.
363
367
  workers' high-level helper caches on their next cache-backed call. Backend
364
368
  scratch buffers remain thread-scoped and are released when that thread exits.
365
369
  Oversized patterns and templates are not retained.
366
- - `pcre.configure_threads()`, `pcre.configure_thread_pool()`,
370
+ - 🧵 `pcre.configure_threads()`, `pcre.configure_thread_pool()`,
367
371
  `shutdown_thread_pool()`, `Flag.THREADS`, and `Flag.NO_THREADS` are available
368
372
  if you want to opt into or restrict threaded execution.
369
373
 
@@ -14,7 +14,7 @@ Fast, free-threaded Python bindings for `PCRE2` with a stable `stdlib.re`-compat
14
14
  </p>
15
15
 
16
16
  <p align="center">
17
- <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>
17
+ <a href="https://github.com/ModelCloud/PyPcre/releases" style="text-decoration:none;"><img alt="GitHub release" src="https://img.shields.io/github/release/ModelCloud/PyPcre.svg"></a>
18
18
  <a href="https://pypi.org/project/PyPcre/" style="text-decoration:none;"><img alt="PyPI - Version" src="https://img.shields.io/pypi/v/PyPcre"></a>
19
19
  <a href="https://pepy.tech/projects/PyPcre" style="text-decoration:none;"><img src="https://static.pepy.tech/badge/PyPcre" alt="PyPI Downloads"></a>
20
20
  <a href="https://github.com/ModelCloud/PyPcre/blob/main/LICENSE"><img src="https://img.shields.io/pypi/l/PyPcre"></a>
@@ -24,8 +24,10 @@ Fast, free-threaded Python bindings for `PCRE2` with a stable `stdlib.re`-compat
24
24
 
25
25
 
26
26
  ## Latest News 🚀
27
- * 08/09–08/10/2026 **API performance and safety update**: common regex workloads and ordered `parallel_map(search)` workloads were benchmarked across Python 3.10 and free-threaded Python 3.14t/GIL=0. Compatibility fallbacks preserve complex patterns, subclasses, buffers, and callables. Unsafe UTF bytes compilation is also blocked, with differential, randomized, concurrency, subprocess, and memory-safety coverage. 🧵⚡🛡️
28
- * 08/08/2026 **0.6.0**: `findall`, `finditer`, `sub`/`subn`, `split`, and `match`/`search`/`fullmatch` are now up to **46x faster** than `stdlib.re` and **48x faster** than `regex` on `finditer`/`findall` workloads, **13x** on `split`, and **2–9x** on `sub`/`subn` backref workloads, with full `re` semantics. Free-threaded `findall` reaches **13.8x** vs `re` on 8 threads. 🚀⚡
27
+ * 10/20/2026 **[0.6.3](https://github.com/ModelCloud/PyPcre/releases/tag/v0.6.3)**: Fixed free-threaded races in `Match.lastindex` replay and PCRE2 version initialization, and reduced Python dispatch overhead across module-level and compiled-pattern `match`, `search`, `fullmatch`, `findall`, `finditer`, `split`, `sub`, and `subn` hot paths, with new concurrency and GC-cycle regression coverage plus exact fallbacks for subclasses, legacy backends, and non-default arguments. 🛡️🧵🚀⚡
28
+ * 08/25/2026 **[0.6.2](https://github.com/ModelCloud/PyPcre/releases/tag/v0.6.2)**: Hardened packaging metadata and fixed FreeBSD/WSL CI failures on PCRE2 10.42 runtimes, including legacy replacement-template and JIT-fallback compatibility. 🛠️🐧🪟
29
+ * 08/25/2026 **[0.6.1](https://github.com/ModelCloud/PyPcre/releases/tag/v0.6.1)**: Workaround for PCRE2 10.46/10.47 JIT start-optimization regressions, new verifying clobber suite, second memory/thread-safety sweep, Python 3.15 `sre_parse` removal compatibility, aligned `Pattern` `pos`/`endpos` signatures, and `setuptools` metadata fixes. 🛡️🧵🐍
30
+ * 08/09/2026 **[0.6.0](https://github.com/ModelCloud/PyPcre/releases/tag/v0.6.0)**: `findall`, `finditer`, `sub`/`subn`, `split`, and `match`/`search`/`fullmatch` hot-path speedups up to **46x** vs `stdlib.re` and **48x** vs `regex`, with free-threaded `findall` reaching **13.8x** on 8 threads. 🚀⚡
29
31
  * 07/27/2026 [0.5.0](https://github.com/ModelCloud/PyPcre/releases/tag/v0.5.0): Zero-copy buffer-protocol subject support (`mmap.mmap`, `bytearray`, `array.array`) with UTF-8 validation and GIL=0-safe memory pinning. 🗂️⚡
30
32
  * 07/24/2026 [0.4.0](https://github.com/ModelCloud/PyPcre/releases/tag/v0.4.0): C extension hardening (memory/pointer safety, bounds checks, atomic allocator init), GIL=0 safety verified, vectorized UTF-8 index/offset conversion, GIL-release threshold for small calls, C `findall` implementation, and README competitor benchmarks. 🛡️⚡
31
33
  * 04/13/2026 [0.3.0](https://github.com/ModelCloud/PyPcre/releases/tag/v0.3.0): Lower-overhead public `Match` objects, faster hot-path `match()` / `search()` / `fullmatch()` / `findall()`, and tighter free-threaded execution. ⚡
@@ -60,7 +62,7 @@ PyPcre pairs Python's familiar `re`-compatible API with the real `PCRE2` engine.
60
62
  | Syntax power | Very rich ✅ | More limited | Rich, but different from `PCRE2` |
61
63
  | JIT execution | `PCRE2` JIT ✅ | No | No |
62
64
  | `re`-compatible API surface | Stable and familiar ✅ | Native | Similar, but not the main goal |
63
- | Free-threaded support | Built and tested for `PYTHON_GIL=0` ✅ | No explicit PyPcre-style layer | Not a project focus here |
65
+ | Free-threaded support | Built and tested for `PYTHON_GIL=0` ✅ | No explicit free-threaded support | No explicit free-threaded fan-out layer |
64
66
  | Built-in threaded subject fan-out | `parallel_map()` ✅ | No | No |
65
67
  | System library updates | Uses system `libpcre2-8` by default ✅ | N/A | N/A |
66
68
 
@@ -229,8 +231,10 @@ numbers = pattern.findall(b"line 1\nline 22")
229
231
  ### API Overview 🧭
230
232
 
231
233
  - Module helpers: `prefixmatch`, `match`, `search`, `fullmatch`, `finditer`,
232
- `findall`, `split`, `sub`, `subn`, `compile`, `escape`, `purge`, and
233
- `parallel_map`.
234
+ `findall`, `split`, `sub`, `subn`, `compile`, `escape`, `purge`,
235
+ `template`, `parallel_map`, `configure`, `configure_threads`,
236
+ `configure_thread_pool`, `shutdown_thread_pool`, `set_cache_limit`,
237
+ `get_cache_limit`, and `clear_cache`.
234
238
  - `compile()` returns a `Pattern` object with the familiar matching helpers
235
239
  plus `split()`, `sub()`, and `subn()`.
236
240
  - `Pattern` exposes `.pattern`, `.flags`, `.jit`, `.groupindex`, and `.groups`
@@ -246,7 +250,7 @@ numbers = pattern.findall(b"line 1\nline 22")
246
250
 
247
251
  ### Common examples 🧪
248
252
 
249
- Compiled patterns:
253
+ 🧪 Compiled patterns:
250
254
 
251
255
  ```python
252
256
  from pcre import compile, Flag
@@ -256,7 +260,7 @@ match = pattern.search("User: alice")
256
260
  print(match.group("name")) # alice
257
261
  ```
258
262
 
259
- Substitution:
263
+ 🔁 Substitution:
260
264
 
261
265
  ```python
262
266
  from pcre import sub
@@ -265,7 +269,7 @@ result = sub(r"\d+", "#", "room 101")
265
269
  print(result) # room #
266
270
  ```
267
271
 
268
- Bytes:
272
+ 🗂️ Bytes:
269
273
 
270
274
  ```python
271
275
  from pcre import compile
@@ -330,9 +334,9 @@ the conversion without repeating the flag.
330
334
 
331
335
  ### Optional runtime controls 🎛️
332
336
 
333
- - `pcre.configure(jit=False)` disables JIT globally. `Flag.JIT` and
337
+ - ⚙️ `pcre.configure(jit=False)` disables JIT globally. `Flag.JIT` and
334
338
  `Flag.NO_JIT` let you override that per pattern.
335
- - `pcre.set_cache_limit()`, `pcre.get_cache_limit()`, and `pcre.clear_cache()`
339
+ - 🧹 `pcre.set_cache_limit()`, `pcre.get_cache_limit()`, and `pcre.clear_cache()`
336
340
  control every high-level compile/template helper cache in the active context.
337
341
  A zero limit disables them, and `None` uses a 256-entry hard safety ceiling
338
342
  rather than permitting unbounded growth. High-level cache entries never cross
@@ -340,7 +344,7 @@ the conversion without repeating the flag.
340
344
  workers' high-level helper caches on their next cache-backed call. Backend
341
345
  scratch buffers remain thread-scoped and are released when that thread exits.
342
346
  Oversized patterns and templates are not retained.
343
- - `pcre.configure_threads()`, `pcre.configure_thread_pool()`,
347
+ - 🧵 `pcre.configure_threads()`, `pcre.configure_thread_pool()`,
344
348
  `shutdown_thread_pool()`, `Flag.THREADS`, and `Flag.NO_THREADS` are available
345
349
  if you want to opt into or restrict threaded execution.
346
350