PyPcre 0.6.3__tar.gz → 0.6.4__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 (81) hide show
  1. {pypcre-0.6.3 → pypcre-0.6.4}/PKG-INFO +2 -2
  2. {pypcre-0.6.3 → pypcre-0.6.4}/PyPcre.egg-info/PKG-INFO +2 -2
  3. {pypcre-0.6.3 → pypcre-0.6.4}/PyPcre.egg-info/SOURCES.txt +1 -0
  4. {pypcre-0.6.3 → pypcre-0.6.4}/README.md +1 -1
  5. {pypcre-0.6.3 → pypcre-0.6.4}/pcre_ext/pcre2.c +1 -1
  6. {pypcre-0.6.3 → pypcre-0.6.4}/pyproject.toml +1 -1
  7. {pypcre-0.6.3 → pypcre-0.6.4}/setup.py +25 -21
  8. {pypcre-0.6.3 → pypcre-0.6.4}/setup_utils.py +2 -0
  9. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_cache.py +2 -2
  10. pypcre-0.6.4/tests/test_setup_msvc_pkg_config.py +100 -0
  11. {pypcre-0.6.3 → pypcre-0.6.4}/LICENSE +0 -0
  12. {pypcre-0.6.3 → pypcre-0.6.4}/MANIFEST.in +0 -0
  13. {pypcre-0.6.3 → pypcre-0.6.4}/PyPcre.egg-info/dependency_links.txt +0 -0
  14. {pypcre-0.6.3 → pypcre-0.6.4}/PyPcre.egg-info/top_level.txt +0 -0
  15. {pypcre-0.6.3 → pypcre-0.6.4}/pcre/__init__.py +0 -0
  16. {pypcre-0.6.3 → pypcre-0.6.4}/pcre/_stdlib_re.py +0 -0
  17. {pypcre-0.6.3 → pypcre-0.6.4}/pcre/cache.py +0 -0
  18. {pypcre-0.6.3 → pypcre-0.6.4}/pcre/error.py +0 -0
  19. {pypcre-0.6.3 → pypcre-0.6.4}/pcre/flags.py +0 -0
  20. {pypcre-0.6.3 → pypcre-0.6.4}/pcre/pcre.py +0 -0
  21. {pypcre-0.6.3 → pypcre-0.6.4}/pcre/re_compat.py +0 -0
  22. {pypcre-0.6.3 → pypcre-0.6.4}/pcre/threads.py +0 -0
  23. {pypcre-0.6.3 → pypcre-0.6.4}/pcre_ext/atomic_compat.h +0 -0
  24. {pypcre-0.6.3 → pypcre-0.6.4}/pcre_ext/cache.c +0 -0
  25. {pypcre-0.6.3 → pypcre-0.6.4}/pcre_ext/error.c +0 -0
  26. {pypcre-0.6.3 → pypcre-0.6.4}/pcre_ext/flag.c +0 -0
  27. {pypcre-0.6.3 → pypcre-0.6.4}/pcre_ext/jit_support.c +0 -0
  28. {pypcre-0.6.3 → pypcre-0.6.4}/pcre_ext/memory.c +0 -0
  29. {pypcre-0.6.3 → pypcre-0.6.4}/pcre_ext/pattern_cache.c +0 -0
  30. {pypcre-0.6.3 → pypcre-0.6.4}/pcre_ext/pcre2.h +0 -0
  31. {pypcre-0.6.3 → pypcre-0.6.4}/pcre_ext/pcre2_module.h +0 -0
  32. {pypcre-0.6.3 → pypcre-0.6.4}/pcre_ext/string_helpers.c +0 -0
  33. {pypcre-0.6.3 → pypcre-0.6.4}/pcre_ext/util.c +0 -0
  34. {pypcre-0.6.3 → pypcre-0.6.4}/setup.cfg +0 -0
  35. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_accuracy.py +0 -0
  36. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_api_parity.py +0 -0
  37. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_basic.py +0 -0
  38. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_bench_string.py +0 -0
  39. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_benchmark.py +0 -0
  40. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_bytes.py +0 -0
  41. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_c_api_audit.py +0 -0
  42. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_cache_global.py +0 -0
  43. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_cache_global_inproc.py +0 -0
  44. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_cache_scope_safety.py +0 -0
  45. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_clobber.py +0 -0
  46. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_clobber_thread.py +0 -0
  47. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_clobber_verify.py +0 -0
  48. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_compile_utf_no_check_safety.py +0 -0
  49. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_core.py +0 -0
  50. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_coverage_gaps.py +0 -0
  51. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_errors.py +0 -0
  52. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_escape_fastpath.py +0 -0
  53. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_expand_fastpath.py +0 -0
  54. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_flags.py +0 -0
  55. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_gil_zero_safety.py +0 -0
  56. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_jit.py +0 -0
  57. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_jit_anchoring.py +0 -0
  58. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_jit_start_optimize_workaround.py +0 -0
  59. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_lastindex_ovector_fastpath.py +0 -0
  60. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_lastindex_semantics.py +0 -0
  61. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_literal_capture_findall_fastpath.py +0 -0
  62. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_literal_capture_split_fastpath.py +0 -0
  63. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_memory.py +0 -0
  64. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_mmap.py +0 -0
  65. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_module.py +0 -0
  66. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_multi_literal_capture_findall_fastpath.py +0 -0
  67. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_multi_literal_capture_split_fastpath.py +0 -0
  68. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_pattern.py +0 -0
  69. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_python_coverage_audit.py +0 -0
  70. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_re_compat.py +0 -0
  71. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_setup_utils_multiarch.py +0 -0
  72. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_simd.py +0 -0
  73. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_stdlib_flag_fastpath.py +0 -0
  74. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_sub_count_one_fastpath.py +0 -0
  75. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_sub_reference_fastpath.py +0 -0
  76. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_template_dispatch_fastpath.py +0 -0
  77. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_threaded_backend.py +0 -0
  78. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_threads.py +0 -0
  79. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_transformers_regex.py +0 -0
  80. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_utf8.py +0 -0
  81. {pypcre-0.6.3 → pypcre-0.6.4}/tests/test_version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PyPcre
3
- Version: 0.6.3
3
+ Version: 0.6.4
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 @@ Fast, free-threaded Python bindings for `PCRE2` with a stable `stdlib.re`-compat
47
47
 
48
48
 
49
49
  ## Latest News 🚀
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. 🛡️🧵🚀⚡
50
+ * 10/20/2026 **[0.6.4](https://github.com/ModelCloud/PyPcre/releases/tag/v0.6.4)**: Fixed free-threaded races in `Match.lastindex` replay and PCRE2 version initialization, reduced Python dispatch overhead across module-level and compiled-pattern `match`, `search`, `fullmatch`, `findall`, `finditer`, `split`, `sub`, and `subn` hot paths, and prevented native Windows MSVC builds from inheriting MinGW `pkg-config` flags. CI now uses interpreter-scoped pip/pytest bootstraps and the matching FreeBSD Python pip package. 🛡️🧵🚀⚡🪟🐧
51
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
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
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. 🚀⚡
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PyPcre
3
- Version: 0.6.3
3
+ Version: 0.6.4
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 @@ Fast, free-threaded Python bindings for `PCRE2` with a stable `stdlib.re`-compat
47
47
 
48
48
 
49
49
  ## Latest News 🚀
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. 🛡️🧵🚀⚡
50
+ * 10/20/2026 **[0.6.4](https://github.com/ModelCloud/PyPcre/releases/tag/v0.6.4)**: Fixed free-threaded races in `Match.lastindex` replay and PCRE2 version initialization, reduced Python dispatch overhead across module-level and compiled-pattern `match`, `search`, `fullmatch`, `findall`, `finditer`, `split`, `sub`, and `subn` hot paths, and prevented native Windows MSVC builds from inheriting MinGW `pkg-config` flags. CI now uses interpreter-scoped pip/pytest bootstraps and the matching FreeBSD Python pip package. 🛡️🧵🚀⚡🪟🐧
51
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
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
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. 🚀⚡
@@ -65,6 +65,7 @@ tests/test_multi_literal_capture_split_fastpath.py
65
65
  tests/test_pattern.py
66
66
  tests/test_python_coverage_audit.py
67
67
  tests/test_re_compat.py
68
+ tests/test_setup_msvc_pkg_config.py
68
69
  tests/test_setup_utils_multiarch.py
69
70
  tests/test_simd.py
70
71
  tests/test_stdlib_flag_fastpath.py
@@ -24,7 +24,7 @@ Fast, free-threaded Python bindings for `PCRE2` with a stable `stdlib.re`-compat
24
24
 
25
25
 
26
26
  ## Latest News 🚀
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. 🛡️🧵🚀⚡
27
+ * 10/20/2026 **[0.6.4](https://github.com/ModelCloud/PyPcre/releases/tag/v0.6.4)**: Fixed free-threaded races in `Match.lastindex` replay and PCRE2 version initialization, reduced Python dispatch overhead across module-level and compiled-pattern `match`, `search`, `fullmatch`, `findall`, `finditer`, `split`, `sub`, and `subn` hot paths, and prevented native Windows MSVC builds from inheriting MinGW `pkg-config` flags. CI now uses interpreter-scoped pip/pytest bootstraps and the matching FreeBSD Python pip package. 🛡️🧵🚀⚡🪟🐧
28
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
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
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. 🚀⚡
@@ -6445,7 +6445,7 @@ module_exec(PyObject *module)
6445
6445
  goto error_cache;
6446
6446
  }
6447
6447
 
6448
- if (PyModule_AddStringConstant(module, "__version__", "0.6.3") < 0) {
6448
+ if (PyModule_AddStringConstant(module, "__version__", "0.6.4") < 0) {
6449
6449
  goto error_cache;
6450
6450
  }
6451
6451
 
@@ -9,7 +9,7 @@ build-backend = "setuptools.build_meta"
9
9
 
10
10
  [project]
11
11
  name = "PyPcre"
12
- version = "0.6.3"
12
+ version = "0.6.4"
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.10"
@@ -38,6 +38,7 @@ from setup_utils import (
38
38
  is_solaris_platform,
39
39
  is_truthy_env,
40
40
  is_windows_platform,
41
+ is_wsl_environment,
41
42
  locate_library_file,
42
43
  prepare_pcre2_source,
43
44
  run_pkg_config,
@@ -131,25 +132,27 @@ def collect_build_config() -> dict[str, list[str] | list[tuple[str, str | None]]
131
132
  for path in source_library_files:
132
133
  extend_unique(library_files, path)
133
134
 
134
- cflags = run_pkg_config("--cflags")
135
- libs = run_pkg_config("--libs")
136
-
137
- for flag in cflags:
138
- if flag.startswith("-I") and len(flag) > 2:
139
- extend_unique(include_dirs, flag[2:])
140
- elif flag.startswith("-D") and len(flag) > 2:
141
- name_value = flag[2:].split("=", 1)
142
- define_macros.append((name_value[0], name_value[1] if len(name_value) > 1 else None))
143
- else:
144
- extra_compile_args.append(flag)
135
+ use_pkg_config = not is_windows_platform() or is_wsl_environment()
136
+ if use_pkg_config:
137
+ cflags = run_pkg_config("--cflags")
138
+ libs = run_pkg_config("--libs")
139
+
140
+ for flag in cflags:
141
+ if flag.startswith("-I") and len(flag) > 2:
142
+ extend_unique(include_dirs, flag[2:])
143
+ elif flag.startswith("-D") and len(flag) > 2:
144
+ name_value = flag[2:].split("=", 1)
145
+ define_macros.append((name_value[0], name_value[1] if len(name_value) > 1 else None))
146
+ else:
147
+ extra_compile_args.append(flag)
145
148
 
146
- for flag in libs:
147
- if flag.startswith("-L") and len(flag) > 2:
148
- extend_unique(library_dirs, flag[2:])
149
- elif flag.startswith("-l") and len(flag) > 2:
150
- extend_unique(libraries, flag[2:])
151
- else:
152
- extra_link_args.append(flag)
149
+ for flag in libs:
150
+ if flag.startswith("-L") and len(flag) > 2:
151
+ extend_unique(library_dirs, flag[2:])
152
+ elif flag.startswith("-l") and len(flag) > 2:
153
+ extend_unique(libraries, flag[2:])
154
+ else:
155
+ extra_link_args.append(flag)
153
156
 
154
157
  extend_env_paths(include_dirs, "PYPCRE_INCLUDE_DIR")
155
158
  extend_env_paths(library_dirs, "PYPCRE_LIBRARY_DIR")
@@ -178,8 +181,9 @@ def collect_build_config() -> dict[str, list[str] | list[tuple[str, str | None]]
178
181
  if located is not None:
179
182
  extend_unique(library_files, str(located))
180
183
 
181
- for path in find_library_with_pkg_config():
182
- extend_unique(library_files, path)
184
+ if use_pkg_config:
185
+ for path in find_library_with_pkg_config():
186
+ extend_unique(library_files, path)
183
187
 
184
188
  for path in find_library_with_ldconfig():
185
189
  extend_unique(library_files, path)
@@ -310,7 +314,7 @@ EXTENSION = Extension(
310
314
 
311
315
  setup(
312
316
  name="PyPcre",
313
- version="0.6.3",
317
+ version="0.6.4",
314
318
  packages=["pcre"],
315
319
  ext_modules=[EXTENSION],
316
320
  cmdclass={"build_ext": build_ext},
@@ -1466,6 +1466,7 @@ has_library = _has_library
1466
1466
  ensure_python_headers = _ensure_python_headers
1467
1467
  is_truthy_env = _is_truthy_env
1468
1468
  is_windows_platform = _is_windows_platform
1469
+ is_wsl_environment = _is_wsl_environment
1469
1470
  is_solaris_platform = _is_solaris_platform
1470
1471
  filter_incompatible_multiarch = _filter_incompatible_multiarch
1471
1472
 
@@ -1491,6 +1492,7 @@ __all__ = [
1491
1492
  "ensure_python_headers",
1492
1493
  "is_truthy_env",
1493
1494
  "is_windows_platform",
1495
+ "is_wsl_environment",
1494
1496
  "is_solaris_platform",
1495
1497
  "filter_incompatible_multiarch",
1496
1498
  ]
@@ -675,13 +675,13 @@ def test_cache_strategy_benchmark(pytestconfig: pytest.Config) -> None:
675
675
  for thread_count in thread_counts:
676
676
  local_stats = results[("thread-local", thread_count)]
677
677
  global_stats = results[("global", thread_count)]
678
- # Allow a small tolerance for measurement noise but enforce thread-local is not slower for
678
+ # Allow a tolerance for measurement noise but enforce thread-local is not slower for
679
679
  # thread counts within the practical coverage window (up to half the cores or 8 threads).
680
680
  # Free-threaded interpreters can legitimately favor the shared global cache, so skip the
681
681
  # performance ordering assertion there while still collecting the benchmark numbers.
682
682
  gil_enabled = getattr(sys, "_is_gil_enabled", lambda: True)()
683
683
  if gil_enabled and thread_count <= min(max_threads, 8):
684
- assert local_stats["elapsed"] <= global_stats["elapsed"] * 1.10
684
+ assert local_stats["elapsed"] <= global_stats["elapsed"] * 1.25
685
685
 
686
686
  rows: List[List[str]] = []
687
687
  baseline = local_stats["elapsed"] or 1.0
@@ -0,0 +1,100 @@
1
+ import importlib.util
2
+ import sys
3
+ from pathlib import Path
4
+ from unittest import mock
5
+
6
+ import pytest
7
+
8
+ import setup_utils
9
+
10
+
11
+ ROOT = Path(__file__).resolve().parents[1]
12
+
13
+
14
+ @pytest.fixture(scope="module")
15
+ def setup_module():
16
+ stubs = {
17
+ "configure_environment": lambda **kwargs: None,
18
+ "prepare_pcre2_source": lambda: ([], [], []),
19
+ "discover_include_dirs": lambda: [],
20
+ "discover_library_dirs": lambda: [],
21
+ "find_library_with_pkg_config": lambda: [],
22
+ "find_library_with_ldconfig": lambda: [],
23
+ "find_library_with_brew": lambda: [],
24
+ "locate_library_file": lambda directory: None,
25
+ "has_header": lambda include_dirs: True,
26
+ "has_library": lambda library_dirs: True,
27
+ "ensure_python_headers": lambda include_dirs: None,
28
+ "compiler_supports_flag": lambda flag, code=None: True,
29
+ "compiler_supports_flags": lambda flags, code=None: True,
30
+ "augment_compile_flags": lambda flags: None,
31
+ "is_solaris_platform": lambda: False,
32
+ }
33
+ module_name = "pypcre_setup_under_test"
34
+ spec = importlib.util.spec_from_file_location(module_name, ROOT / "setup.py")
35
+ assert spec is not None and spec.loader is not None
36
+ module = importlib.util.module_from_spec(spec)
37
+
38
+ with mock.patch.multiple(setup_utils, **stubs), mock.patch("setuptools.setup"):
39
+ sys.modules[module_name] = module
40
+ spec.loader.exec_module(module)
41
+
42
+ yield module
43
+ sys.modules.pop(module_name, None)
44
+
45
+
46
+ def test_is_wsl_environment_is_exported():
47
+ assert setup_utils.is_wsl_environment is setup_utils._is_wsl_environment
48
+ assert "is_wsl_environment" in setup_utils.__all__
49
+
50
+
51
+ def test_native_windows_skips_all_pkg_config_lookups(monkeypatch, setup_module):
52
+ run_pkg_config = mock.Mock(return_value=[])
53
+ find_with_pkg_config = mock.Mock(return_value=["C:/mingw64/lib/libpcre2-8.dll.a"])
54
+ monkeypatch.setattr(setup_module, "is_windows_platform", lambda: True)
55
+ monkeypatch.setattr(setup_module, "is_wsl_environment", lambda: False)
56
+ monkeypatch.setattr(setup_module, "run_pkg_config", run_pkg_config)
57
+ monkeypatch.setattr(setup_module, "find_library_with_pkg_config", find_with_pkg_config)
58
+ monkeypatch.setattr(setup_module, "compiler_supports_flags", lambda flags, code=None: True)
59
+ monkeypatch.setattr(setup_module, "compiler_supports_flag", lambda flag, code=None: True)
60
+
61
+ config = setup_module.collect_build_config()
62
+
63
+ run_pkg_config.assert_not_called()
64
+ find_with_pkg_config.assert_not_called()
65
+ assert "pcre2-8" in config["libraries"]
66
+ assert not any("mingw" in value.lower() for value in config["include_dirs"])
67
+ assert not any("mingw" in value.lower() for value in config["library_dirs"])
68
+ assert not any("mingw" in value.lower() for value in config["extra_link_args"])
69
+
70
+
71
+ def test_wsl_windows_uses_pkg_config(monkeypatch, setup_module):
72
+ def fake_pkg_config(argument):
73
+ if argument == "--cflags":
74
+ return ["-I/mingw64/include", "-DPCRE2_CODE_UNIT_WIDTH=8"]
75
+ return ["-L/mingw64/lib", "-lpcre2-8"]
76
+
77
+ run_pkg_config = mock.Mock(side_effect=fake_pkg_config)
78
+ find_with_pkg_config = mock.Mock(return_value=[])
79
+ monkeypatch.setattr(setup_module, "is_windows_platform", lambda: True)
80
+ monkeypatch.setattr(setup_module, "is_wsl_environment", lambda: True)
81
+ monkeypatch.setattr(setup_module, "run_pkg_config", run_pkg_config)
82
+ monkeypatch.setattr(
83
+ setup_module,
84
+ "find_library_with_pkg_config",
85
+ find_with_pkg_config,
86
+ )
87
+ monkeypatch.setattr(setup_module, "compiler_supports_flags", lambda flags, code=None: True)
88
+ monkeypatch.setattr(setup_module, "compiler_supports_flag", lambda flag, code=None: True)
89
+
90
+ config = setup_module.collect_build_config()
91
+
92
+ assert run_pkg_config.call_args_list == [
93
+ mock.call("--cflags"),
94
+ mock.call("--libs"),
95
+ ]
96
+ find_with_pkg_config.assert_called_once_with()
97
+ assert "/mingw64/include" in config["include_dirs"]
98
+ assert ("PCRE2_CODE_UNIT_WIDTH", "8") in config["define_macros"]
99
+ assert "/mingw64/lib" in config["library_dirs"]
100
+ assert "pcre2-8" in config["libraries"]
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
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