liburlparser 2.0.0__tar.gz → 2.2.0__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 (136) hide show
  1. {liburlparser-2.0.0 → liburlparser-2.2.0}/.github/workflows/orchestrator.yml +15 -0
  2. {liburlparser-2.0.0 → liburlparser-2.2.0}/.github/workflows/wheels.yml +1 -1
  3. liburlparser-2.2.0/CHANGELOG.md +212 -0
  4. {liburlparser-2.0.0 → liburlparser-2.2.0}/CMakeLists.txt +100 -40
  5. {liburlparser-2.0.0 → liburlparser-2.2.0}/PKG-INFO +91 -25
  6. {liburlparser-2.0.0 → liburlparser-2.2.0}/README.md +90 -24
  7. liburlparser-2.2.0/benchmarks/CMakeLists.txt +148 -0
  8. liburlparser-2.2.0/benchmarks/OPTIMIZATION_NOTES.md +334 -0
  9. {liburlparser-2.0.0 → liburlparser-2.2.0}/benchmarks/README.md +24 -3
  10. liburlparser-2.2.0/benchmarks/cmake/Download.cmake +26 -0
  11. liburlparser-2.2.0/benchmarks/corpus/.gitignore +3 -0
  12. liburlparser-2.2.0/benchmarks/corpus/generate_corpus.py +71 -0
  13. {liburlparser-2.0.0 → liburlparser-2.2.0}/benchmarks/cpp/CMakeLists.txt +2 -2
  14. liburlparser-2.2.0/benchmarks/cpp/abspath_fix_verification/README.md +41 -0
  15. liburlparser-2.2.0/benchmarks/cpp/abspath_fix_verification/fair_compare.cpp +81 -0
  16. liburlparser-2.2.0/benchmarks/cpp/bench.cpp +605 -0
  17. liburlparser-2.2.0/benchmarks/cpp/psl_structures/README.md +95 -0
  18. liburlparser-2.2.0/benchmarks/cpp/psl_structures/psl_structure_comparison.cpp +713 -0
  19. liburlparser-2.2.0/benchmarks/python/CMakeLists.txt +77 -0
  20. liburlparser-2.2.0/benchmarks/python/bench.py +523 -0
  21. liburlparser-2.2.0/benchmarks/python/binding_fast_path_ab.py +50 -0
  22. {liburlparser-2.0.0 → liburlparser-2.2.0}/benchmarks/python/requirements.txt +5 -0
  23. liburlparser-2.2.0/benchmarks/report/CMakeLists.txt +53 -0
  24. liburlparser-2.2.0/benchmarks/report/generate_report.py +214 -0
  25. liburlparser-2.2.0/benchmarks/report/template.html.jinja2 +192 -0
  26. liburlparser-2.2.0/benchmarks/results/report.html +918 -0
  27. liburlparser-2.2.0/cmake/liburlparserConfig.cmake +26 -0
  28. {liburlparser-2.0.0 → liburlparser-2.2.0}/docs/index.html.in +5 -2
  29. {liburlparser-2.0.0 → liburlparser-2.2.0}/docs/page.html.in +3 -0
  30. {liburlparser-2.0.0 → liburlparser-2.2.0}/docs/section.html.in +3 -0
  31. liburlparser-2.2.0/examples/find_liburlparser_via_python/CMakeLists.txt +26 -0
  32. liburlparser-2.2.0/examples/find_liburlparser_via_python/main.cpp +13 -0
  33. {liburlparser-2.0.0 → liburlparser-2.2.0}/include/urlparser.h +301 -7
  34. {liburlparser-2.0.0 → liburlparser-2.2.0}/src/bindings/python/binding_py.cpp +264 -7
  35. liburlparser-2.2.0/src/bindings/python/liburlparser/__init__.py +45 -0
  36. {liburlparser-2.0.0 → liburlparser-2.2.0}/src/bindings/python/liburlparser/__main__.py +16 -1
  37. {liburlparser-2.0.0 → liburlparser-2.2.0}/src/bindings/python/liburlparser/core.py +6 -1
  38. {liburlparser-2.0.0 → liburlparser-2.2.0}/src/public_suffix_list.dat +1294 -495
  39. {liburlparser-2.0.0 → liburlparser-2.2.0}/src/urlparser.cpp +1033 -16
  40. {liburlparser-2.0.0 → liburlparser-2.2.0}/tests/cpp/CMakeLists.txt +29 -0
  41. liburlparser-2.2.0/tests/cpp/fuzz_abspath.cpp +113 -0
  42. liburlparser-2.2.0/tests/cpp/perf_regression_guard.cpp +129 -0
  43. liburlparser-2.2.0/tests/cpp/test_idna.cpp +62 -0
  44. liburlparser-2.2.0/tests/cpp/test_normalize.cpp +234 -0
  45. liburlparser-2.2.0/tests/cpp/test_percent_codec.cpp +82 -0
  46. liburlparser-2.2.0/tests/cpp/test_resolve.cpp +74 -0
  47. liburlparser-2.2.0/tests/cpp/test_scp_url.cpp +93 -0
  48. {liburlparser-2.0.0 → liburlparser-2.2.0}/tests/cpp/test_url.cpp +57 -0
  49. liburlparser-2.2.0/tests/python/test_idna.py +43 -0
  50. liburlparser-2.2.0/tests/python/test_normalize.py +146 -0
  51. liburlparser-2.2.0/tests/python/test_percent_codec.py +60 -0
  52. liburlparser-2.2.0/tests/python/test_resolve.py +39 -0
  53. liburlparser-2.2.0/tests/python/test_scp_url.py +66 -0
  54. liburlparser-2.0.0/benchmarks/CMakeLists.txt +0 -120
  55. liburlparser-2.0.0/benchmarks/OPTIMIZATION_NOTES.md +0 -224
  56. liburlparser-2.0.0/benchmarks/cpp/bench.cpp +0 -248
  57. liburlparser-2.0.0/benchmarks/python/CMakeLists.txt +0 -33
  58. liburlparser-2.0.0/benchmarks/python/bench.py +0 -242
  59. liburlparser-2.0.0/src/bindings/python/liburlparser/__init__.py +0 -14
  60. {liburlparser-2.0.0 → liburlparser-2.2.0}/.clang-format +0 -0
  61. {liburlparser-2.0.0 → liburlparser-2.2.0}/.github/workflows/cmake.yml +0 -0
  62. {liburlparser-2.0.0 → liburlparser-2.2.0}/.github/workflows/process_release.py +0 -0
  63. {liburlparser-2.0.0 → liburlparser-2.2.0}/.github/workflows/release_template.md +0 -0
  64. {liburlparser-2.0.0 → liburlparser-2.2.0}/.gitignore +0 -0
  65. {liburlparser-2.0.0 → liburlparser-2.2.0}/ARCHITECTURE.md +0 -0
  66. {liburlparser-2.0.0 → liburlparser-2.2.0}/LICENSE +0 -0
  67. {liburlparser-2.0.0 → liburlparser-2.2.0}/benchmarks/.gitignore +0 -0
  68. {liburlparser-2.0.0 → liburlparser-2.2.0}/cmake/DynamicVersion.cmake +0 -0
  69. {liburlparser-2.0.0 → liburlparser-2.2.0}/cmake/EmbedFile.cmake +0 -0
  70. {liburlparser-2.0.0 → liburlparser-2.2.0}/cmake/FixLCovPaths.cmake +0 -0
  71. {liburlparser-2.0.0 → liburlparser-2.2.0}/cmake/GenerateIframe.cmake +0 -0
  72. {liburlparser-2.0.0 → liburlparser-2.2.0}/cmake/PublicSuffixList.cmake +0 -0
  73. {liburlparser-2.0.0 → liburlparser-2.2.0}/cmake/PyProject.cmake +0 -0
  74. {liburlparser-2.0.0 → liburlparser-2.2.0}/cmake/coverage_iframe.html.in +0 -0
  75. {liburlparser-2.0.0 → liburlparser-2.2.0}/cmake/utils/embedded_string.in.h +0 -0
  76. {liburlparser-2.0.0 → liburlparser-2.2.0}/conda.recipe/meta.yaml +0 -0
  77. {liburlparser-2.0.0 → liburlparser-2.2.0}/docs/CMakeLists.txt +0 -0
  78. {liburlparser-2.0.0 → liburlparser-2.2.0}/docs/CreateDocs.cmake +0 -0
  79. {liburlparser-2.0.0 → liburlparser-2.2.0}/docs/InjectComment.cmake +0 -0
  80. {liburlparser-2.0.0 → liburlparser-2.2.0}/docs/UrlParserPages.cmake +0 -0
  81. {liburlparser-2.0.0 → liburlparser-2.2.0}/docs/cli/examples.md +0 -0
  82. {liburlparser-2.0.0 → liburlparser-2.2.0}/docs/cli/index.md +0 -0
  83. {liburlparser-2.0.0 → liburlparser-2.2.0}/docs/cli/installation.md +0 -0
  84. {liburlparser-2.0.0 → liburlparser-2.2.0}/docs/cli/options.md +0 -0
  85. {liburlparser-2.0.0 → liburlparser-2.2.0}/docs/convert_page.py +0 -0
  86. {liburlparser-2.0.0 → liburlparser-2.2.0}/docs/cpp/CreateDocs.cmake +0 -0
  87. {liburlparser-2.0.0 → liburlparser-2.2.0}/docs/cpp/Doxyfile.in +0 -0
  88. {liburlparser-2.0.0 → liburlparser-2.2.0}/docs/cpp/footer.html.in +0 -0
  89. {liburlparser-2.0.0 → liburlparser-2.2.0}/docs/cpp/header.html +0 -0
  90. {liburlparser-2.0.0 → liburlparser-2.2.0}/docs/cpp/images/interface-arch.svg +0 -0
  91. {liburlparser-2.0.0 → liburlparser-2.2.0}/docs/cpp/images/url-parsing-process.svg +0 -0
  92. {liburlparser-2.0.0 → liburlparser-2.2.0}/docs/cpp/mainpage.md +0 -0
  93. {liburlparser-2.0.0 → liburlparser-2.2.0}/docs/images/liburlparser-sq.txt +0 -0
  94. {liburlparser-2.0.0 → liburlparser-2.2.0}/docs/images/logo/liburlparser-logo-1.svg +0 -0
  95. {liburlparser-2.0.0 → liburlparser-2.2.0}/docs/images/logo/liburlparser-logo-2.svg +0 -0
  96. {liburlparser-2.0.0 → liburlparser-2.2.0}/docs/initial_comment.in +0 -0
  97. {liburlparser-2.0.0 → liburlparser-2.2.0}/docs/python/CreateDocs.cmake +0 -0
  98. {liburlparser-2.0.0 → liburlparser-2.2.0}/docs/python/docs/api/host.md +0 -0
  99. {liburlparser-2.0.0 → liburlparser-2.2.0}/docs/python/docs/api/psl.md +0 -0
  100. {liburlparser-2.0.0 → liburlparser-2.2.0}/docs/python/docs/api/reference.rst +0 -0
  101. {liburlparser-2.0.0 → liburlparser-2.2.0}/docs/python/docs/api/url.md +0 -0
  102. {liburlparser-2.0.0 → liburlparser-2.2.0}/docs/python/docs/conf.py +0 -0
  103. {liburlparser-2.0.0 → liburlparser-2.2.0}/docs/python/docs/examples.md +0 -0
  104. {liburlparser-2.0.0 → liburlparser-2.2.0}/docs/python/docs/index.md +0 -0
  105. {liburlparser-2.0.0 → liburlparser-2.2.0}/docs/python/docs/installation.md +0 -0
  106. {liburlparser-2.0.0 → liburlparser-2.2.0}/docs/python/docs/performance.md +0 -0
  107. {liburlparser-2.0.0 → liburlparser-2.2.0}/docs/python/docs/usage/advanced.md +0 -0
  108. {liburlparser-2.0.0 → liburlparser-2.2.0}/docs/python/docs/usage/basic.md +0 -0
  109. {liburlparser-2.0.0 → liburlparser-2.2.0}/docs/python/docs/usage/cli.md +0 -0
  110. {liburlparser-2.0.0 → liburlparser-2.2.0}/docs/python/mkdocs.yml +0 -0
  111. {liburlparser-2.0.0 → liburlparser-2.2.0}/docs/urlparser-docs.css +0 -0
  112. {liburlparser-2.0.0 → liburlparser-2.2.0}/examples/common.h +0 -0
  113. {liburlparser-2.0.0 → liburlparser-2.2.0}/examples/main.cpp +0 -0
  114. {liburlparser-2.0.0 → liburlparser-2.2.0}/pyproject.toml +0 -0
  115. {liburlparser-2.0.0 → liburlparser-2.2.0}/requirements-dev.txt +0 -0
  116. {liburlparser-2.0.0 → liburlparser-2.2.0}/src/ankerl/LICENSE +0 -0
  117. {liburlparser-2.0.0 → liburlparser-2.2.0}/src/ankerl/README.md +0 -0
  118. {liburlparser-2.0.0 → liburlparser-2.2.0}/src/ankerl/stl.h +0 -0
  119. {liburlparser-2.0.0 → liburlparser-2.2.0}/src/ankerl/unordered_dense.h +0 -0
  120. {liburlparser-2.0.0 → liburlparser-2.2.0}/src/bindings/python/liburlparser/utils.py +0 -0
  121. {liburlparser-2.0.0 → liburlparser-2.2.0}/tests/CMakeLists.txt +0 -0
  122. {liburlparser-2.0.0 → liburlparser-2.2.0}/tests/coverage_dashboard.html.in +0 -0
  123. {liburlparser-2.0.0 → liburlparser-2.2.0}/tests/cpp/common.h +0 -0
  124. {liburlparser-2.0.0 → liburlparser-2.2.0}/tests/cpp/test_host.cpp +0 -0
  125. {liburlparser-2.0.0 → liburlparser-2.2.0}/tests/data/host_data.csv +0 -0
  126. {liburlparser-2.0.0 → liburlparser-2.2.0}/tests/data/url_data.csv +0 -0
  127. {liburlparser-2.0.0 → liburlparser-2.2.0}/tests/genhtml.css +0 -0
  128. {liburlparser-2.0.0 → liburlparser-2.2.0}/tests/python/CMakeLists.txt +0 -0
  129. {liburlparser-2.0.0 → liburlparser-2.2.0}/tests/python/test_cli_subprocess.py +0 -0
  130. {liburlparser-2.0.0 → liburlparser-2.2.0}/tests/python/test_extra.py +0 -0
  131. {liburlparser-2.0.0 → liburlparser-2.2.0}/tests/python/test_host.py +0 -0
  132. {liburlparser-2.0.0 → liburlparser-2.2.0}/tests/python/test_memory.py +0 -0
  133. {liburlparser-2.0.0 → liburlparser-2.2.0}/tests/python/test_url.py +0 -0
  134. {liburlparser-2.0.0 → liburlparser-2.2.0}/tests/utest/utest.h +0 -0
  135. {liburlparser-2.0.0 → liburlparser-2.2.0}/tests/utest/utest_main.cxx +0 -0
  136. {liburlparser-2.0.0 → liburlparser-2.2.0}/version.py +0 -0
@@ -99,6 +99,9 @@ jobs:
99
99
  id-token: write
100
100
 
101
101
  steps:
102
+ - name: Checkout repository
103
+ uses: actions/checkout@v4
104
+
102
105
  - name: Download documentation artifact
103
106
  uses: actions/download-artifact@v4
104
107
  with:
@@ -111,6 +114,18 @@ jobs:
111
114
  name: cmake-coverage-report
112
115
  path: ./pages/coverage
113
116
 
117
+ # Benchmarks are NOT run in CI: the report is generated locally
118
+ # (cmake --build <dir> --target urlparser_benchmarks_report) and committed
119
+ # as benchmarks/results/report.html. CI only publishes it, as /benchmarks/.
120
+ - name: Add benchmark report
121
+ run: |
122
+ if [ ! -f benchmarks/results/report.html ]; then
123
+ echo "::error::benchmarks/results/report.html is missing - generate it locally and commit it"
124
+ exit 1
125
+ fi
126
+ mkdir -p pages/benchmarks
127
+ cp benchmarks/results/report.html pages/benchmarks/index.html
128
+
114
129
  - name: List pages directory
115
130
  run: find pages -maxdepth 2
116
131
 
@@ -53,7 +53,7 @@ jobs:
53
53
  - uses: actions/checkout@v4
54
54
 
55
55
  - name: Build wheels
56
- uses: pypa/cibuildwheel@v2.21.3
56
+ uses: pypa/cibuildwheel@v4.2.1
57
57
  env:
58
58
  MACOSX_DEPLOYMENT_TARGET: "10.13"
59
59
  CIBW_ARCHS_MACOS: universal2
@@ -0,0 +1,212 @@
1
+ # Changelog
2
+
3
+ All notable changes to liburlparser are documented here. The format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the project follows
5
+ [Semantic Versioning](https://semver.org/). The version of the project is the one in `include/urlparser.h`
6
+ (`URLPARSER_VERSION_MAJOR/MINOR/PATCH`); `pyproject.toml` and CMake read it from there.
7
+
8
+ The entries up to 2.1.0 were written from the git history and the release tags. Since the commit messages of the 1.x
9
+ releases are short, those entries are brief.
10
+
11
+ ## [2.2.0] - 2026-11-09
12
+
13
+ ### Changed
14
+ - **The CMake package namespace is now `liburlparser::`, like the package.** The public target is
15
+ `liburlparser::urlparser`, the same name from `add_subdirectory()`, `FetchContent` and
16
+ `find_package(liburlparser CONFIG)`. A CMake package should export its targets under its own name, and the
17
+ package is `liburlparser` (`liburlparserConfig.cmake`, `python -m liburlparser --cmake-dir`). **Breaking:** the
18
+ 2.1.0 name `urlparser::urlparser` is gone and there is no alias for it. Change `target_link_libraries(... urlparser::urlparser)` to
19
+ `liburlparser::urlparser`. The C++ namespace (`urlparser::url`, `urlparser::host`) is unchanged.
20
+ - The `example` program is built only when liburlparser is the top-level project, like the tests and the docs, so it is
21
+ not compiled for nothing when the library is a dependency.
22
+
23
+ ### Fixed
24
+ - **Using liburlparser from another scikit-build-core project failed.** `SKBUILD` is defined for the whole build, so a
25
+ project that pulled liburlparser in with `add_subdirectory()` or `FetchContent` made it believe it was itself the wheel
26
+ being built: it tried to build its own nanobind module (and failed when nanobind was not installed) or stopped
27
+ with `RETURN()` before the example, tests and docs. The check is now "`SKBUILD` is defined **and** liburlparser is the
28
+ top-level project". The 2.0.0 release had a guard for this (`c140ea4`); the CMake refactor of 2.1.0 (`ac6ac03`)
29
+ dropped it.
30
+
31
+ ## [2.1.0] - 2026-10-03
32
+
33
+ ### Added
34
+ - **`find_package(liburlparser CONFIG)`.** The core is a static library that is installed with its headers and a CMake
35
+ package (`liburlparserConfig.cmake`, targets, version file, and `liburlparserPaths.cmake` with the absolute library
36
+ and include paths). The Python wheel carries the same tree (`include/`, `lib/`, `cmake/`), and
37
+ `python -m liburlparser --cmake-dir` / `--include-dir` / `--lib-dir` print the paths, the way `python -m nanobind --cmake_dir` does.
38
+ `examples/find_liburlparser_via_python` shows it.
39
+ - **IDNA normalization and percent codec APIs.**
40
+ - **scp-like git URLs** (`user@host:path/repo.git`) are parsed.
41
+ - **`url::normalized()`** returns a canonical serialization of a URL.
42
+ - Benchmarks: `search_params` against ada, a reproducible comparison of the PSL structures, benchmark artifacts kept apart
43
+ from the committed results, and an HTML report target.
44
+
45
+ ### Changed
46
+ - **The CMake targets are unified.** The historical aliases `url::base` and `liburlparser::core` are replaced by the one
47
+ public alias `urlparser::urlparser`, and `install(EXPORT)` uses the same name. (**Breaking** for anyone who linked the old aliases;
48
+ renamed again in 2.2.0.)
49
+ - The standalone `idna.cpp` and `percent_codec.cpp` are merged into `urlparser.cpp`, and stale files left from the
50
+ header/source consolidation were removed.
51
+ - The bundled `public_suffix_list.dat` is the 2026-09-08 version.
52
+ - CI: cibuildwheel is updated.
53
+
54
+ ### Performance
55
+ - AVX2 scanning for the authority of a URL.
56
+ - PSL suffix matching tracks the maximum rule depth, and the truncation scan in `suffix_of` and the TLD suffix are bounded
57
+ by the maximum length (an O(1) check instead of an O(n) scan).
58
+ - A fast path with interned keys when a `Hostname` is extracted to a Python dict.
59
+
60
+ ## [2.0.0] - 2026-09-11
61
+
62
+ ### Added
63
+ - **Public Suffix List support.** A `psl` class (a singleton that tracks the version of its data) matches suffixes; the
64
+ list is embedded into the library when CMake configures, and a configure step refreshes the tracked
65
+ `public_suffix_list.dat` in place when it can download a newer one.
66
+ - **`host`** parsing and classification, with constructor overloads and `string&&` overloads of `host::from_url` and
67
+ `url::extract_host`. Cross-platform IP address parsing replaces the platform-specific code.
68
+ - **Version macros** `URLPARSER_VERSION_*` and a version class (the prefix was renamed from `LIBURLPARSER_`); CMake reads the version from the
69
+ header.
70
+ - SIMD scanning in `find_first_of_3` (AVX2, SSE2, NEON).
71
+ - Python: a static `Url.extract_dict`, built from reusable `to_dict` helpers.
72
+ - Tooling: coverage reports for C++ and Python, leak checks with pytest-memray, benchmark and profiling targets, standalone
73
+ benchmarks (also against ada), Sphinx documentation for the Python API, a CLI reference, and architecture notes.
74
+
75
+ ### Changed
76
+ - **liburlparser is a static library**, built with position-independent code, and the default build type is Release.
77
+ - nanobind ABI handling for Python 3.12 and later.
78
+ - The googletest and doxygen-awesome-css submodules are removed, and the `online` extra is gone (the PSL update uses `urllib`).
79
+ - Tests and docs are built only when liburlparser is the top-level project, and a vendored copy does not build its Python
80
+ bindings.
81
+ - The implementation of the suffix table is hidden behind a forward declaration.
82
+
83
+ ### Fixed
84
+ - Windows compatibility (pull request #4, by CKCat).
85
+ - Regression tests for earlier URL parsing bugs.
86
+
87
+ ### Performance
88
+ - Extra capacity for URL fields, a faster `host` constructor, and the suffix position is computed by arithmetic.
89
+
90
+ ## [1.6.1] - 2025-10-24
91
+
92
+ ### Changed
93
+ - The CLI logic is refactored and covered by tests, and `flatten_dict` moved to the utils module.
94
+ - The release workflow and the wheel builds are improved (`test_cli_subprocess` is excluded in CI).
95
+
96
+ ## [1.6.0] - 2025-05-04
97
+
98
+ ### Added
99
+ - `--parts` option of the command line, and the top-level domain (TLD) of a host.
100
+ - The Public Suffix List file.
101
+ - Doxygen documentation (main page with logo and architecture diagram, doxygen-awesome theme) and the Python documentation,
102
+ published to GitHub Pages.
103
+
104
+ ## [1.5.0] - 2024-10-18
105
+
106
+ ### Changed
107
+ - The project architecture changed, and the CI runs all tests (C++ and Python).
108
+ - Build requirements are managed with pip-tools; ruff fixes.
109
+
110
+ ## [1.4.6] - 2024-02-11
111
+
112
+ ### Changed
113
+ - macOS is built in CI, the build system changed, and the README got badges.
114
+
115
+ ## [1.4.5] - 2023-11-28
116
+
117
+ ### Changed
118
+ - The Doxygen project information is read from `pyproject.toml`, and the release workflow uploads the release assets.
119
+
120
+ ## [1.4.4] - 2023-11-23
121
+
122
+ ### Changed
123
+ - The C++ tests moved to googletest and were rewritten as parametrized tests, like the Python ones; C++ and Python
124
+ tests are separate. The wheel files are created.
125
+
126
+ ## [1.4.3] - 2023-11-19
127
+
128
+ ### Fixed
129
+ - A file lock lets the tests run in parallel.
130
+
131
+ ## [1.4.2] - 2023-11-13
132
+
133
+ ### Changed
134
+ - `shared_ptr` replaces `unique_ptr`, since every method is const.
135
+
136
+ ### Fixed
137
+ - The `fulldomain` problem, and the host name was removed again.
138
+
139
+ ## [1.4.1] - 2023-11-11
140
+
141
+ ### Added
142
+ - C++ tests with gtest and gmock.
143
+ - A fast `hostName` that does not parse the host string (with a known problem with `ignore_www`).
144
+
145
+ ### Changed
146
+ - The PSL is held as data instead of a pointer (fixes the pointer-to-data conversion), and `requests` became an optional
147
+ dependency (the `online` extra).
148
+
149
+ ## [1.4.0] - 2023-11-08
150
+
151
+ ### Changed
152
+ - `urlparser.cpp` is split into a host part and a url part, a url holds its host through a pointer, and the lazy
153
+ calculation uses a smart pointer.
154
+
155
+ ### Fixed
156
+ - Problems with the operators; the move constructor and assignment were removed.
157
+
158
+ ## [1.3.0] - 2023-11-05
159
+
160
+ ### Fixed
161
+ - `fulldomain` in the substring step; accessibility of the class; test and linter issues. An automatic correction was
162
+ tried and removed.
163
+
164
+ ## [1.2.1] - 2023-10-10
165
+
166
+ ### Fixed
167
+ - The `fulldomain` issue.
168
+
169
+ ## [1.2.0] - 2023-10-09
170
+
171
+ ### Changed
172
+ - The `fulldomain` attribute was updated.
173
+
174
+ ## [1.1.0] - 2023-07-23
175
+
176
+ ### Added
177
+ - The `ignore_www` option for subdomains.
178
+
179
+ ## [1.0.2] - 2023-07-22
180
+
181
+ ### Added
182
+ - A Ruff lint check.
183
+
184
+ ## [1.0.1] - 2023-07-21
185
+
186
+ ### Fixed
187
+ - `pyproject.toml` and the wheels workflow.
188
+
189
+ ## [1.0.0] - 2023-07-21
190
+
191
+ First tagged release. The history before it is mostly the setup of the wheel builds with cibuildwheel (PyPy excluded).
192
+
193
+ [2.2.0]: https://github.com/mohammadraziei/liburlparser/compare/v2.1.0...v2.2.0
194
+ [2.1.0]: https://github.com/mohammadraziei/liburlparser/compare/v2.0.0...v2.1.0
195
+ [2.0.0]: https://github.com/mohammadraziei/liburlparser/compare/v1.6.1...v2.0.0
196
+ [1.6.1]: https://github.com/mohammadraziei/liburlparser/compare/v1.6.0...v1.6.1
197
+ [1.6.0]: https://github.com/mohammadraziei/liburlparser/compare/v1.5.0...v1.6.0
198
+ [1.5.0]: https://github.com/mohammadraziei/liburlparser/compare/v1.4.6...v1.5.0
199
+ [1.4.6]: https://github.com/mohammadraziei/liburlparser/compare/v1.4.5...v1.4.6
200
+ [1.4.5]: https://github.com/mohammadraziei/liburlparser/compare/v1.4.4...v1.4.5
201
+ [1.4.4]: https://github.com/mohammadraziei/liburlparser/compare/v1.4.3...v1.4.4
202
+ [1.4.3]: https://github.com/mohammadraziei/liburlparser/compare/v1.4.2...v1.4.3
203
+ [1.4.2]: https://github.com/mohammadraziei/liburlparser/compare/v1.4.1...v1.4.2
204
+ [1.4.1]: https://github.com/mohammadraziei/liburlparser/compare/v1.4.0...v1.4.1
205
+ [1.4.0]: https://github.com/mohammadraziei/liburlparser/compare/v1.3.0...v1.4.0
206
+ [1.3.0]: https://github.com/mohammadraziei/liburlparser/compare/v1.2.1...v1.3.0
207
+ [1.2.1]: https://github.com/mohammadraziei/liburlparser/compare/v1.2.0...v1.2.1
208
+ [1.2.0]: https://github.com/mohammadraziei/liburlparser/compare/v1.1.0...v1.2.0
209
+ [1.1.0]: https://github.com/mohammadraziei/liburlparser/compare/v1.0.2...v1.1.0
210
+ [1.0.2]: https://github.com/mohammadraziei/liburlparser/compare/v1.0.1...v1.0.2
211
+ [1.0.1]: https://github.com/mohammadraziei/liburlparser/compare/v1.0.0...v1.0.1
212
+ [1.0.0]: https://github.com/mohammadraziei/liburlparser/releases/tag/v1.0.0
@@ -38,17 +38,20 @@ if (CYGWIN OR UNIX)
38
38
  endif()
39
39
 
40
40
 
41
+ # URLPARSER_SKBUILD is true only when liburlparser itself is the scikit-build-core
42
+ # project being built (the wheel build). SKBUILD alone is not enough: it is also
43
+ # defined when another scikit-build-core project (e.g. httpp) pulls this one in with
44
+ # add_subdirectory() or FetchContent, and then it must behave as a plain C++ library:
45
+ # no nanobind module, no early RETURN() before the liburlparser::urlparser target and the tests.
46
+ if(DEFINED SKBUILD AND CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
47
+ set(URLPARSER_SKBUILD ON)
48
+ else()
49
+ set(URLPARSER_SKBUILD OFF)
50
+ endif()
51
+
41
52
  find_package(Python3 REQUIRED COMPONENTS Interpreter)
42
53
 
43
- # --- httpp local patch --------------------------------------------------
44
- # Only treat this as "liburlparser is the scikit-build-core package being
45
- # installed" when SKBUILD_PROJECT_NAME actually IS liburlparser. Without
46
- # this guard, vendoring liburlparser as a subdirectory of another
47
- # scikit-build-core project (e.g. httpp) makes it wrongly think it's the
48
- # top-level package and try to build its own nanobind bindings, which
49
- # fails when nanobind isn't installed (it isn't a dependency of the
50
- # parent project at all). See src/third_party/README.md for details.
51
- if(DEFINED SKBUILD AND SKBUILD_PROJECT_NAME STREQUAL PROJECT_NAME)
54
+ if(URLPARSER_SKBUILD)
52
55
  set(PYTHON_PROJECT_NAME "${SKBUILD_PROJECT_NAME}")
53
56
  elseif(BUILD_PYTHON)
54
57
  set(PYTHON_PROJECT_NAME "${CMAKE_BINARY_DIR}")
@@ -104,6 +107,44 @@ embed_file_as_string(
104
107
  )
105
108
 
106
109
 
110
+ # --- C++ core library (static) ---
111
+ # Built in every mode (including scikit-build), so the Python extension
112
+ # links the very same library that gets shipped to C++ consumers.
113
+ # Install layout: the wheel carries include/, lib/ and cmake/ inside the
114
+ # `liburlparser` package (nanobind/pybind11 pattern, see get_cmake_dir() in
115
+ # the Python package); a plain `cmake --install` uses the usual prefix layout.
116
+ if(URLPARSER_SKBUILD)
117
+ set(_urlparser_lib_dest liburlparser/lib)
118
+ set(_urlparser_inc_dest liburlparser/include)
119
+ set(_urlparser_cmake_dest liburlparser/cmake)
120
+ else()
121
+ set(_urlparser_lib_dest lib)
122
+ set(_urlparser_inc_dest include)
123
+ set(_urlparser_cmake_dest lib/cmake/liburlparser)
124
+ endif()
125
+
126
+ add_library(urlparser STATIC ${SOURCES})
127
+ # The public target is `liburlparser::urlparser` - the same name whether the
128
+ # library comes from FetchContent/add_subdirectory (this alias) or from an
129
+ # installed package (find_package(liburlparser), exported below).
130
+ add_library(liburlparser::urlparser ALIAS urlparser)
131
+
132
+ set_target_properties(urlparser PROPERTIES
133
+ POSITION_INDEPENDENT_CODE ON # linked into the Python extension
134
+ CXX_VISIBILITY_PRESET hidden
135
+ VISIBILITY_INLINES_HIDDEN ON
136
+ EXPORT_NAME urlparser # installed as liburlparser::urlparser (see install(EXPORT))
137
+ OUTPUT_NAME urlparser # liburlparser.a / urlparser.lib
138
+ )
139
+ target_include_directories(urlparser
140
+ PUBLIC
141
+ $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
142
+ $<INSTALL_INTERFACE:${_urlparser_inc_dest}>
143
+ PRIVATE
144
+ ${PROJECT_SOURCE_DIR}/src
145
+ ${GENERATED_HEADERS_DIR})
146
+
147
+
107
148
  if(DEFINED PYTHON_PROJECT_NAME)
108
149
  # Try to import all Python components potentially needed by nanobind
109
150
  #set(Python3_FIND_STRATEGY LOCATION)
@@ -140,12 +181,12 @@ if(DEFINED PYTHON_PROJECT_NAME)
140
181
  ${NB_ABI_ARGS}
141
182
 
142
183
  # Source code goes here
143
- ${PROJECT_SOURCE_DIR}/src/bindings/python/binding_py.cpp ${SOURCES}
184
+ ${PROJECT_SOURCE_DIR}/src/bindings/python/binding_py.cpp
144
185
  )
145
186
 
146
- target_include_directories(${NB_MODULE} PRIVATE include src ${GENERATED_HEADERS_DIR})
187
+ target_link_libraries(${NB_MODULE} PRIVATE urlparser)
147
188
 
148
- if(DEFINED SKBUILD)
189
+ if(URLPARSER_SKBUILD)
149
190
  install(TARGETS ${NB_MODULE}
150
191
  CONFIGURATIONS Release
151
192
  LIBRARY DESTINATION
@@ -157,37 +198,56 @@ if(DEFINED PYTHON_PROJECT_NAME)
157
198
  endif()
158
199
  endif()
159
200
 
160
- if(DEFINED SKBUILD AND SKBUILD_PROJECT_NAME STREQUAL PROJECT_NAME)
161
- # (see the httpp local-patch comment above) only early-return here when
162
- # liburlparser itself is the package scikit-build-core is installing —
163
- # not when it's vendored as a subdirectory of another project.
201
+ # --- install: find_package(liburlparser CONFIG) -> liburlparser::urlparser ---
202
+ include(CMakePackageConfigHelpers)
203
+ install(TARGETS urlparser EXPORT liburlparserTargets
204
+ ARCHIVE DESTINATION ${_urlparser_lib_dest}
205
+ LIBRARY DESTINATION ${_urlparser_lib_dest})
206
+ install(DIRECTORY include/ DESTINATION ${_urlparser_inc_dest})
207
+ install(EXPORT liburlparserTargets
208
+ FILE liburlparserTargets.cmake
209
+ NAMESPACE liburlparser::
210
+ DESTINATION ${_urlparser_cmake_dest})
211
+
212
+ # urlparser_LIB_PATH / urlparser_INCLUDE_PATH for consumers that want plain
213
+ # paths. The exact artifact name (liburlparser.a, urlparser.lib, ...) is only
214
+ # known to the generator, so the file is produced with file(GENERATE) - the
215
+ # generator expression is resolved when the build system is generated, and the
216
+ # result is installed next to the package config. Paths are written relative
217
+ # to the installed file itself, so the package stays relocatable.
218
+ file(RELATIVE_PATH _urlparser_rel_lib "/_/${_urlparser_cmake_dest}" "/_/${_urlparser_lib_dest}")
219
+ file(RELATIVE_PATH _urlparser_rel_inc "/_/${_urlparser_cmake_dest}" "/_/${_urlparser_inc_dest}")
220
+ string(REGEX REPLACE "/+$" "" _urlparser_rel_lib "${_urlparser_rel_lib}")
221
+ string(REGEX REPLACE "/+$" "" _urlparser_rel_inc "${_urlparser_rel_inc}")
222
+ file(GENERATE
223
+ OUTPUT ${PROJECT_BINARY_DIR}/liburlparserPaths.cmake
224
+ CONTENT
225
+ "# Generated by liburlparser's CMakeLists.txt - do not edit.
226
+ get_filename_component(urlparser_LIB_PATH
227
+ \"\${CMAKE_CURRENT_LIST_DIR}/${_urlparser_rel_lib}/$<TARGET_FILE_NAME:urlparser>\" ABSOLUTE)
228
+ get_filename_component(urlparser_INCLUDE_PATH
229
+ \"\${CMAKE_CURRENT_LIST_DIR}/${_urlparser_rel_inc}\" ABSOLUTE)
230
+ ")
231
+
232
+ write_basic_package_version_file(
233
+ ${PROJECT_BINARY_DIR}/liburlparserConfigVersion.cmake
234
+ VERSION ${PROJECT_VERSION}
235
+ COMPATIBILITY SameMajorVersion)
236
+ install(FILES
237
+ ${PROJECT_SOURCE_DIR}/cmake/liburlparserConfig.cmake
238
+ ${PROJECT_BINARY_DIR}/liburlparserPaths.cmake
239
+ ${PROJECT_BINARY_DIR}/liburlparserConfigVersion.cmake
240
+ DESTINATION ${_urlparser_cmake_dest})
241
+
242
+ if(URLPARSER_SKBUILD)
164
243
  RETURN()
165
244
  endif()
166
245
 
167
-
168
-
169
- add_library(urlparser STATIC ${SOURCES})
170
- add_library(url::base ALIAS urlparser)
171
- target_include_directories(urlparser PRIVATE ${GENERATED_HEADERS_DIR})
172
-
173
-
174
- target_include_directories(urlparser
175
- PUBLIC
176
- ${PROJECT_SOURCE_DIR}/include
177
- PRIVATE
178
- ${PROJECT_SOURCE_DIR}/src)
179
-
180
-
181
- add_executable(example examples/main.cpp)
182
- target_link_libraries(example PRIVATE url::base)
183
-
184
- install(TARGETS urlparser
185
- LIBRARY DESTINATION lib
186
- ARCHIVE DESTINATION lib
187
- INCLUDES DESTINATION include
188
- )
189
-
190
-
246
+ # The example is only for the top-level build; as a dependency it would just be compiled for nothing.
247
+ if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
248
+ add_executable(example examples/main.cpp)
249
+ target_link_libraries(example PRIVATE liburlparser::urlparser)
250
+ endif()
191
251
 
192
252
  enable_testing()
193
253
  find_package(Threads REQUIRED)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: liburlparser
3
- Version: 2.0.0
3
+ Version: 2.2.0
4
4
  Summary: Fastest Url parser in the world
5
5
  Author-Email: Mohammad Raziei <mohammadraziei1375@gmail.com>
6
6
  Classifier: Development Status :: 4 - Beta
@@ -39,7 +39,7 @@ Description-Content-Type: text/markdown
39
39
  [![forks - liburlparser](https://img.shields.io/github/forks/mohammadraziei/liburlparser?style=social)](https://github.com/mohammadraziei/liburlparser)
40
40
 
41
41
  [![PyPi](https://img.shields.io/pypi/v/liburlparser.svg)](https://pypi.org/project/liburlparser/)
42
- ![Python](https://img.shields.io/badge/Python-3.8%20%7C%203.9%20%7C%203.10%20%7C%203.11-blue)
42
+ ![Python](https://img.shields.io/badge/Python-3.10%20%7C%203.11%20%7C%203.12-blue)
43
43
  ![Cpp](https://img.shields.io/badge/C++-17-blue)
44
44
 
45
45
  [![GitHub release](https://img.shields.io/github/release/mohammadraziei/liburlparser?include_prereleases=&sort=semver&color=purple)](https://github.com/mohammadraziei/liburlparser/releases/)
@@ -240,49 +240,102 @@ you can see all methods in python we can use in c++ very easily
240
240
 
241
241
  ## Installation
242
242
 
243
- ### C++:
243
+ ### C++
244
+
245
+ Requires a C++17 compiler and CMake >= 3.19. The library is a static library plus one header (`urlparser.h`),
246
+ and its CMake target is **`liburlparser::urlparser`** - the same name no matter how you get it:
247
+
248
+ #### 1. FetchContent
244
249
 
245
- #### build steps:
250
+ ```cmake
251
+ include(FetchContent)
252
+ FetchContent_Declare(
253
+ liburlparser
254
+ GIT_REPOSITORY https://github.com/mohammadraziei/liburlparser.git
255
+ GIT_TAG master
256
+ )
257
+ FetchContent_MakeAvailable(liburlparser)
258
+
259
+ target_link_libraries(my_app PRIVATE liburlparser::urlparser)
260
+ ```
261
+
262
+ #### 2. From the pip package
263
+
264
+ The Python wheel also ships the compiled C++ library, its header and a CMake
265
+ package config (same idea as `python -m nanobind --cmake_dir`), so a C++
266
+ project can use a plain `pip install liburlparser` without building anything:
267
+
268
+ ```cmake
269
+ find_package(Python3 REQUIRED COMPONENTS Interpreter)
270
+ execute_process(
271
+ COMMAND ${Python3_EXECUTABLE} -m liburlparser --cmake-dir
272
+ OUTPUT_VARIABLE liburlparser_DIR
273
+ OUTPUT_STRIP_TRAILING_WHITESPACE
274
+ COMMAND_ERROR_IS_FATAL ANY)
275
+
276
+ find_package(liburlparser CONFIG REQUIRED)
277
+ target_link_libraries(my_app PRIVATE liburlparser::urlparser)
278
+ ```
279
+
280
+ For build systems that prefer plain paths over the target, `find_package` also sets:
281
+
282
+ | Variable | Value |
283
+ | ------------------------ | ------------------------------------------------------------------ |
284
+ | `urlparser_LIB_PATH` | full path of the compiled library (`liburlparser.a`, `urlparser.lib`, ...) |
285
+ | `urlparser_INCLUDE_PATH` | directory containing `urlparser.h` |
286
+
287
+ The same locations are available from the command line and from Python:
246
288
 
247
289
  ```sh
248
- # 1. Clone the repository with submodules (recursive)
249
- # --recursive is essential to download third-party libs like googletest
250
- git clone --recursive https://github.com/mohammadraziei/liburlparser
251
- cd liburlparser
290
+ python -m liburlparser --cmake-dir # directory with liburlparserConfig.cmake
291
+ python -m liburlparser --include-dir # directory with urlparser.h
292
+ python -m liburlparser --lib-dir # directory with the compiled library
293
+ ```
294
+
295
+ ```python
296
+ import liburlparser
297
+ liburlparser.get_cmake_dir(), liburlparser.get_include_dir(), liburlparser.get_lib_dir()
298
+ ```
252
299
 
253
- # 2. Configure the project
254
- # -B build tells CMake to create a 'build' directory and generate files there
255
- cmake -B build
300
+ A complete example project is in
301
+ [examples/find_liburlparser_via_python](examples/find_liburlparser_via_python).
256
302
 
257
- # 3. Build the project
258
- # --build abstracts the underlying build tool (Make, Ninja, MSBuild, etc.)
259
- cmake --build build --config Debug
303
+ #### 3. Build and install from source
260
304
 
261
- # 4. Run examples
262
- # Note: On Windows, the path might be ./build/Debug/example.exe
305
+ ```sh
306
+ git clone https://github.com/mohammadraziei/liburlparser
307
+ cd liburlparser
308
+
309
+ # configure and build (-B creates the 'build' directory)
310
+ cmake -B build -DCMAKE_BUILD_TYPE=Release
311
+ cmake --build build
312
+
313
+ # run the example (on Windows with multi-config generators: ./build/Release/example.exe)
263
314
  ./build/example
264
315
 
265
- # 5. Make install
266
- # --install handles the installation process
267
- sudo cmake --install build
316
+ # install the library, header and CMake package (add --prefix <dir> to choose where)
317
+ cmake --install build
318
+ ```
319
+
320
+ Then, in your project (add `-DCMAKE_PREFIX_PATH=<prefix>` if you used a custom prefix):
321
+
322
+ ```cmake
323
+ find_package(liburlparser CONFIG REQUIRED)
324
+ target_link_libraries(my_app PRIVATE liburlparser::urlparser)
268
325
  ```
269
326
 
270
327
  ### Python and Command Line:
271
328
 
272
- Be aware that it required `python>=3.8`
329
+ Be aware that it requires `python>=3.10`
273
330
 
274
331
  #### Installation
275
332
 
276
333
  ###### from source
277
334
 
278
- To install from source, you must ensure all submodules are cloned:
279
-
280
335
  ```bash
281
- # 1. Clone recursively to get third-party dependencies
282
- git clone --recursive https://github.com/mohammadraziei/liburlparser
336
+ git clone https://github.com/mohammadraziei/liburlparser
283
337
  cd liburlparser
284
338
 
285
- # 2. Install using pip
286
339
  pip install .
287
340
 
288
341
  # Optional: If you want to see build logs
@@ -314,6 +367,18 @@ pip install ./liburlparser
314
367
 
315
368
  ### Performance
316
369
 
370
+ Up-to-date, reproducible results for both C++ and Python (compared against other libraries)
371
+ are on the **[Benchmarks page](https://mohammadraziei.github.io/liburlparser/benchmarks/)**.
372
+ The report is generated locally and published with the documentation:
373
+
374
+ ```sh
375
+ cmake -S benchmarks -B build-bench -DCMAKE_BUILD_TYPE=Release
376
+ cmake --build build-bench --target urlparser_benchmarks_report
377
+ # -> benchmarks/results/report.html
378
+ ```
379
+
380
+ The two tables below are the original measurements from March 2022.
381
+
317
382
  #### Extract From Host
318
383
 
319
384
  Tests were run on a file containing 10 million random domains from various top-level domains (Mar. 13rd 2022)
@@ -354,5 +419,6 @@ Project Link:
354
419
 
355
420
  - [https://github.com/mohammadraziei/liburlparser](https://github.com/mohammadraziei/liburlparser)
356
421
  - [https://pypi.org/project/liburlparser](https://pypi.org/project/liburlparser)
422
+ - [Documentation](https://mohammadraziei.github.io/liburlparser/) and [Benchmarks](https://mohammadraziei.github.io/liburlparser/benchmarks/)
357
423
 
358
424
  [license-shield]: https://img.shields.io/github/license/othneildrew/Best-README-Template.svg?style=flat-square