PyPcre 0.2.11__tar.gz → 0.2.13__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 (53) hide show
  1. {pypcre-0.2.11 → pypcre-0.2.13}/PKG-INFO +4 -4
  2. {pypcre-0.2.11 → pypcre-0.2.13}/PyPcre.egg-info/PKG-INFO +4 -4
  3. {pypcre-0.2.11 → pypcre-0.2.13}/README.md +3 -3
  4. {pypcre-0.2.11 → pypcre-0.2.13}/pcre/cache.py +0 -9
  5. {pypcre-0.2.11 → pypcre-0.2.13}/pcre/pcre.py +25 -0
  6. {pypcre-0.2.11 → pypcre-0.2.13}/pcre_ext/pattern_cache.c +0 -22
  7. {pypcre-0.2.11 → pypcre-0.2.13}/pcre_ext/pcre2.c +0 -5
  8. {pypcre-0.2.11 → pypcre-0.2.13}/pyproject.toml +1 -1
  9. {pypcre-0.2.11 → pypcre-0.2.13}/setup_utils.py +29 -21
  10. {pypcre-0.2.11 → pypcre-0.2.13}/LICENSE +0 -0
  11. {pypcre-0.2.11 → pypcre-0.2.13}/MANIFEST.in +0 -0
  12. {pypcre-0.2.11 → pypcre-0.2.13}/PyPcre.egg-info/SOURCES.txt +0 -0
  13. {pypcre-0.2.11 → pypcre-0.2.13}/PyPcre.egg-info/dependency_links.txt +0 -0
  14. {pypcre-0.2.11 → pypcre-0.2.13}/PyPcre.egg-info/top_level.txt +0 -0
  15. {pypcre-0.2.11 → pypcre-0.2.13}/pcre/__init__.py +0 -0
  16. {pypcre-0.2.11 → pypcre-0.2.13}/pcre/error.py +0 -0
  17. {pypcre-0.2.11 → pypcre-0.2.13}/pcre/flags.py +0 -0
  18. {pypcre-0.2.11 → pypcre-0.2.13}/pcre/re_compat.py +0 -0
  19. {pypcre-0.2.11 → pypcre-0.2.13}/pcre/threads.py +0 -0
  20. {pypcre-0.2.11 → pypcre-0.2.13}/pcre_ext/atomic_compat.h +0 -0
  21. {pypcre-0.2.11 → pypcre-0.2.13}/pcre_ext/cache.c +0 -0
  22. {pypcre-0.2.11 → pypcre-0.2.13}/pcre_ext/error.c +0 -0
  23. {pypcre-0.2.11 → pypcre-0.2.13}/pcre_ext/flag.c +0 -0
  24. {pypcre-0.2.11 → pypcre-0.2.13}/pcre_ext/jit_support.c +0 -0
  25. {pypcre-0.2.11 → pypcre-0.2.13}/pcre_ext/memory.c +0 -0
  26. {pypcre-0.2.11 → pypcre-0.2.13}/pcre_ext/pcre2.h +0 -0
  27. {pypcre-0.2.11 → pypcre-0.2.13}/pcre_ext/pcre2_module.h +0 -0
  28. {pypcre-0.2.11 → pypcre-0.2.13}/pcre_ext/string_helpers.c +0 -0
  29. {pypcre-0.2.11 → pypcre-0.2.13}/pcre_ext/util.c +0 -0
  30. {pypcre-0.2.11 → pypcre-0.2.13}/setup.cfg +0 -0
  31. {pypcre-0.2.11 → pypcre-0.2.13}/setup.py +0 -0
  32. {pypcre-0.2.11 → pypcre-0.2.13}/tests/test_accuracy.py +0 -0
  33. {pypcre-0.2.11 → pypcre-0.2.13}/tests/test_api_parity.py +0 -0
  34. {pypcre-0.2.11 → pypcre-0.2.13}/tests/test_basic.py +0 -0
  35. {pypcre-0.2.11 → pypcre-0.2.13}/tests/test_bench_string.py +0 -0
  36. {pypcre-0.2.11 → pypcre-0.2.13}/tests/test_benchmark.py +0 -0
  37. {pypcre-0.2.11 → pypcre-0.2.13}/tests/test_bytes.py +0 -0
  38. {pypcre-0.2.11 → pypcre-0.2.13}/tests/test_cache.py +0 -0
  39. {pypcre-0.2.11 → pypcre-0.2.13}/tests/test_clobber.py +0 -0
  40. {pypcre-0.2.11 → pypcre-0.2.13}/tests/test_clobber_thread.py +0 -0
  41. {pypcre-0.2.11 → pypcre-0.2.13}/tests/test_core.py +0 -0
  42. {pypcre-0.2.11 → pypcre-0.2.13}/tests/test_errors.py +0 -0
  43. {pypcre-0.2.11 → pypcre-0.2.13}/tests/test_flags.py +0 -0
  44. {pypcre-0.2.11 → pypcre-0.2.13}/tests/test_jit.py +0 -0
  45. {pypcre-0.2.11 → pypcre-0.2.13}/tests/test_memory.py +0 -0
  46. {pypcre-0.2.11 → pypcre-0.2.13}/tests/test_module.py +0 -0
  47. {pypcre-0.2.11 → pypcre-0.2.13}/tests/test_pattern.py +0 -0
  48. {pypcre-0.2.11 → pypcre-0.2.13}/tests/test_setup_utils_multiarch.py +0 -0
  49. {pypcre-0.2.11 → pypcre-0.2.13}/tests/test_simd.py +0 -0
  50. {pypcre-0.2.11 → pypcre-0.2.13}/tests/test_threaded_backend.py +0 -0
  51. {pypcre-0.2.11 → pypcre-0.2.13}/tests/test_transformers_regex.py +0 -0
  52. {pypcre-0.2.11 → pypcre-0.2.13}/tests/test_utf8.py +0 -0
  53. {pypcre-0.2.11 → pypcre-0.2.13}/tests/test_version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PyPcre
3
- Version: 0.2.11
3
+ Version: 0.2.13
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
@@ -47,7 +47,7 @@ Modern `nogil` Python bindings for the Pcre2 library with `stdlib.re` api compat
47
47
  * 02/24/2026 [0.2.10](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.10): Allow VisualStudio (VS) compiler version check override via env var.
48
48
  * 12/15/2025 [0.2.8](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.8): Fixed multi-arch Linux os compatibility where both x86_64 and i386 libs of pcre2 are installed.
49
49
  * 10/20/2025 [0.2.4](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.4): Removed dependency on system having python3-dev packge. python.h will be optimistically downloaded from python.org when needed.
50
- * 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 for all api. Expanded ci testing coverage. FreeBSD, Solaris, and Windows compatibility validated.
50
+ * 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 for all api. Expanded ci testing coverage. FreeBSD, Solaris and Windows compatibility validated.
51
51
  * 10/09/2025 [0.1.0](https://github.com/ModelCloud/PyPcre/releases/tag/v0.1.0): 🎉 First release. Thread safe, auto JIT, auto pattern caching and optimistic linking to system library for fast install.
52
52
 
53
53
  ## Why PyPcre:
@@ -70,7 +70,7 @@ The package prioritizes linking against the `libpcre2-8` shared library in syste
70
70
 
71
71
  ## Platform Support (Validated):
72
72
 
73
- `Linux`, `MacOS`, `Windows`, `WSL`, `FreeBSD`, `Solaris`
73
+ `Linux`, `MacOS`, `Windows`, `WSL`, `FreeBSD`
74
74
 
75
75
 
76
76
  ## Usage
@@ -303,7 +303,7 @@ When `pkg-config` is available the build will automatically pick up the
303
303
  required include and link flags via `pkg-config --cflags/--libs libpcre2-8`.
304
304
  Without `pkg-config`, the build script scans common installation prefixes for
305
305
  Linux distributions (Debian, Ubuntu, Fedora/RHEL/CentOS, openSUSE, Alpine),
306
- FreeBSD, macOS (including Homebrew), and Solaris to locate the headers and
306
+ FreeBSD and macOS (including Homebrew) to locate the headers and
307
307
  libraries.
308
308
 
309
309
  If your system ships `libpcre2-8` under `/usr` but you also maintain a
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PyPcre
3
- Version: 0.2.11
3
+ Version: 0.2.13
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
@@ -47,7 +47,7 @@ Modern `nogil` Python bindings for the Pcre2 library with `stdlib.re` api compat
47
47
  * 02/24/2026 [0.2.10](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.10): Allow VisualStudio (VS) compiler version check override via env var.
48
48
  * 12/15/2025 [0.2.8](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.8): Fixed multi-arch Linux os compatibility where both x86_64 and i386 libs of pcre2 are installed.
49
49
  * 10/20/2025 [0.2.4](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.4): Removed dependency on system having python3-dev packge. python.h will be optimistically downloaded from python.org when needed.
50
- * 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 for all api. Expanded ci testing coverage. FreeBSD, Solaris, and Windows compatibility validated.
50
+ * 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 for all api. Expanded ci testing coverage. FreeBSD, Solaris and Windows compatibility validated.
51
51
  * 10/09/2025 [0.1.0](https://github.com/ModelCloud/PyPcre/releases/tag/v0.1.0): 🎉 First release. Thread safe, auto JIT, auto pattern caching and optimistic linking to system library for fast install.
52
52
 
53
53
  ## Why PyPcre:
@@ -70,7 +70,7 @@ The package prioritizes linking against the `libpcre2-8` shared library in syste
70
70
 
71
71
  ## Platform Support (Validated):
72
72
 
73
- `Linux`, `MacOS`, `Windows`, `WSL`, `FreeBSD`, `Solaris`
73
+ `Linux`, `MacOS`, `Windows`, `WSL`, `FreeBSD`
74
74
 
75
75
 
76
76
  ## Usage
@@ -303,7 +303,7 @@ When `pkg-config` is available the build will automatically pick up the
303
303
  required include and link flags via `pkg-config --cflags/--libs libpcre2-8`.
304
304
  Without `pkg-config`, the build script scans common installation prefixes for
305
305
  Linux distributions (Debian, Ubuntu, Fedora/RHEL/CentOS, openSUSE, Alpine),
306
- FreeBSD, macOS (including Homebrew), and Solaris to locate the headers and
306
+ FreeBSD and macOS (including Homebrew) to locate the headers and
307
307
  libraries.
308
308
 
309
309
  If your system ships `libpcre2-8` under `/usr` but you also maintain a
@@ -24,7 +24,7 @@ Modern `nogil` Python bindings for the Pcre2 library with `stdlib.re` api compat
24
24
  * 02/24/2026 [0.2.10](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.10): Allow VisualStudio (VS) compiler version check override via env var.
25
25
  * 12/15/2025 [0.2.8](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.8): Fixed multi-arch Linux os compatibility where both x86_64 and i386 libs of pcre2 are installed.
26
26
  * 10/20/2025 [0.2.4](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.4): Removed dependency on system having python3-dev packge. python.h will be optimistically downloaded from python.org when needed.
27
- * 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 for all api. Expanded ci testing coverage. FreeBSD, Solaris, and Windows compatibility validated.
27
+ * 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 for all api. Expanded ci testing coverage. FreeBSD, Solaris and Windows compatibility validated.
28
28
  * 10/09/2025 [0.1.0](https://github.com/ModelCloud/PyPcre/releases/tag/v0.1.0): 🎉 First release. Thread safe, auto JIT, auto pattern caching and optimistic linking to system library for fast install.
29
29
 
30
30
  ## Why PyPcre:
@@ -47,7 +47,7 @@ The package prioritizes linking against the `libpcre2-8` shared library in syste
47
47
 
48
48
  ## Platform Support (Validated):
49
49
 
50
- `Linux`, `MacOS`, `Windows`, `WSL`, `FreeBSD`, `Solaris`
50
+ `Linux`, `MacOS`, `Windows`, `WSL`, `FreeBSD`
51
51
 
52
52
 
53
53
  ## Usage
@@ -280,7 +280,7 @@ When `pkg-config` is available the build will automatically pick up the
280
280
  required include and link flags via `pkg-config --cflags/--libs libpcre2-8`.
281
281
  Without `pkg-config`, the build script scans common installation prefixes for
282
282
  Linux distributions (Debian, Ubuntu, Fedora/RHEL/CentOS, openSUSE, Alpine),
283
- FreeBSD, macOS (including Homebrew), and Solaris to locate the headers and
283
+ FreeBSD and macOS (including Homebrew) to locate the headers and
284
284
  libraries.
285
285
 
286
286
  If your system ships `libpcre2-8` under `/usr` but you also maintain a
@@ -48,13 +48,6 @@ class _GlobalCacheState:
48
48
  _THREAD_LOCAL = _ThreadCacheState()
49
49
  _GLOBAL_STATE = _GlobalCacheState()
50
50
  _CACHE_STRATEGY = _CacheStrategy.THREAD_LOCAL
51
- _CACHE_STRATEGY_LOCKED = False
52
-
53
-
54
- def _lock_cache_strategy() -> None:
55
- global _CACHE_STRATEGY_LOCKED
56
- if not _CACHE_STRATEGY_LOCKED:
57
- _CACHE_STRATEGY_LOCKED = True
58
51
 
59
52
 
60
53
  def _normalize_strategy(value: str) -> _CacheStrategy:
@@ -178,8 +171,6 @@ def cached_compile(
178
171
  ) -> T:
179
172
  """Compile *pattern* with *flags*, caching wrapper results when hashable."""
180
173
 
181
- _lock_cache_strategy()
182
-
183
174
  if _CACHE_STRATEGY is _CacheStrategy.THREAD_LOCAL:
184
175
  return _cached_compile_thread_local(pattern, flags, wrapper, jit=jit)
185
176
  return _cached_compile_global(pattern, flags, wrapper, jit=jit)
@@ -473,6 +473,31 @@ class Pattern:
473
473
 
474
474
 
475
475
  def compile(pattern: Any, flags: FlagInput = 0) -> Pattern:
476
+ # Fast path for the dominant shape: compile(pattern) with default flags.
477
+ if flags == 0:
478
+ if isinstance(pattern, Pattern):
479
+ return pattern
480
+
481
+ if isinstance(pattern, _CPattern):
482
+ wrapper = Pattern(pattern)
483
+ if get_thread_default():
484
+ wrapper.enable_auto_threads()
485
+ else:
486
+ wrapper.disable_threads()
487
+ return wrapper
488
+
489
+ adjusted_pattern = _apply_regex_compat(pattern, bool(_DEFAULT_COMPAT_REGEX))
490
+ if isinstance(adjusted_pattern, str):
491
+ native_flags = _pcre2.PCRE2_UTF | _pcre2.PCRE2_UCP
492
+ else:
493
+ native_flags = 0
494
+ compiled = cached_compile(adjusted_pattern, native_flags, Pattern, jit=_DEFAULT_JIT)
495
+ if get_thread_default():
496
+ compiled.enable_auto_threads()
497
+ else:
498
+ compiled.disable_threads()
499
+ return compiled
500
+
476
501
  resolved_flags = _normalise_flags(flags)
477
502
  threads_requested = bool(resolved_flags & THREADS)
478
503
  no_threads_requested = bool(resolved_flags & NO_THREADS)
@@ -211,27 +211,6 @@ pattern_cache_teardown(void)
211
211
  atomic_store_explicit(&pattern_cache_global_mode, 0, memory_order_release);
212
212
  }
213
213
 
214
- static void
215
- pattern_cache_touch(PatternCacheState *state, PyObject *cache_key)
216
- {
217
- if (state->order == NULL) {
218
- return;
219
- }
220
- Py_ssize_t idx = PySequence_Index(state->order, cache_key);
221
- if (idx >= 0) {
222
- if (PySequence_DelItem(state->order, idx) < 0) {
223
- PyErr_Clear();
224
- return;
225
- }
226
- } else if (PyErr_Occurred()) {
227
- PyErr_Clear();
228
- return;
229
- }
230
- if (PyList_Append(state->order, cache_key) < 0) {
231
- PyErr_Clear();
232
- }
233
- }
234
-
235
214
  int
236
215
  pattern_cache_lookup(PyObject *cache_key, PatternObject **out_pattern)
237
216
  {
@@ -256,7 +235,6 @@ pattern_cache_lookup(PyObject *cache_key, PatternObject **out_pattern)
256
235
  if (cached != NULL) {
257
236
  Py_INCREF(cached);
258
237
  *out_pattern = (PatternObject *)cached;
259
- pattern_cache_touch(state, cache_key);
260
238
  } else if (PyErr_Occurred()) {
261
239
  pattern_cache_release_state(lock_held);
262
240
  return -1;
@@ -1806,11 +1806,6 @@ Pattern_compile_cached(PyObject *pattern_obj, uint32_t flags, int jit, int jit_e
1806
1806
  return NULL;
1807
1807
  }
1808
1808
 
1809
- if (PyObject_Hash(cache_key) == -1) {
1810
- PyErr_Clear();
1811
- use_cache = 0;
1812
- }
1813
-
1814
1809
  if (use_cache) {
1815
1810
  PatternObject *cached = NULL;
1816
1811
  if (pattern_cache_lookup(cache_key, &cached) == 0) {
@@ -9,7 +9,7 @@ build-backend = "setuptools.build_meta"
9
9
 
10
10
  [project]
11
11
  name = "PyPcre"
12
- version = "0.2.11"
12
+ version = "0.2.13"
13
13
  description = "Modern, GIL-friendly, Fast Python bindings for PCRE2 with auto caching and JIT of compiled patterns."
14
14
  readme = "README.md"
15
15
  requires-python = ">=3.9"
@@ -481,7 +481,11 @@ def _find_vswhere():
481
481
  def _detect_vs_generator():
482
482
  vswhere = _find_vswhere()
483
483
  if not vswhere:
484
- return None
484
+ raise RuntimeError(
485
+ "unable to find vswhere.exe\n"
486
+ "Please install Visual Studio Build Tools:\n"
487
+ f"{VS_DOWNLOAD_URL}"
488
+ )
485
489
 
486
490
  result = subprocess.run(
487
491
  [
@@ -497,32 +501,42 @@ def _detect_vs_generator():
497
501
  )
498
502
 
499
503
  if result.returncode != 0:
500
- return None
504
+ raise RuntimeError(
505
+ f"vswhere failed.\n"
506
+ f"exit code: {result.returncode}\n"
507
+ f"stdout: {result.stdout.strip()}\n"
508
+ f"stderr: {result.stderr.strip()}\n"
509
+ )
510
+
511
+ try:
512
+ data = json.loads(result.stdout or "[]")
513
+ except json.JSONDecodeError as e:
514
+ raise RuntimeError(
515
+ f"unable to parse vswhere output. Output: {result.stdout}"
516
+ ) from e
501
517
 
502
- data = json.loads(result.stdout or "[]")
503
518
  if not data:
504
- return None
519
+ raise RuntimeError(f"vswhere cannot find a valid VS installation: {result.stdout}")
505
520
 
506
521
  info = data[0]
507
522
 
508
523
  ver = info.get("installationVersion", "")
509
524
  major = ver.split(".")[0]
510
525
 
511
- year = info.get("catalog", {}).get("productLineVersion")
512
-
513
- if not year:
514
- year_map = {
515
- "15": "2017",
516
- "16": "2019",
517
- "17": "2022",
518
- "18": "2026",
519
- }
520
- year = year_map.get(major)
526
+ year_map = {
527
+ "15": "2017",
528
+ "16": "2019",
529
+ "17": "2022",
530
+ "18": "2026",
531
+ }
532
+ year = year_map.get(str(major))
521
533
 
522
534
  if year:
523
535
  return f"Visual Studio {major} {year}"
524
536
 
525
- return f"Visual Studio {major}"
537
+ raise RuntimeError(
538
+ f"Unknown Visual Studio version: installationVersion={ver}, major={major}, year={year}. vswhere result: {result.stdout}"
539
+ )
526
540
 
527
541
 
528
542
  def _prepare_pcre2_source() -> tuple[list[str], list[str], list[str]]:
@@ -635,12 +649,6 @@ def _prepare_pcre2_source() -> tuple[list[str], list[str], list[str]]:
635
649
  # On Windows, force MSVC and the /MD runtime. Never let CMake pick MinGW.
636
650
  if _is_windows_platform():
637
651
  vs_gen = os.environ.get("CMAKE_GENERATOR", _detect_vs_generator())
638
- if not vs_gen:
639
- raise RuntimeError(
640
- "Visual Studio not found.\n"
641
- "Please install Visual Studio Build Tools:\n"
642
- f"{VS_DOWNLOAD_URL}"
643
- )
644
652
  cmake_args += [
645
653
  "-G", vs_gen,
646
654
  "-A", "x64",
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes