From 4237f1ab99200edd640c253e13bcd8d3f4130edd Mon Sep 17 00:00:00 2001 From: Juro Oravec Date: Tue, 21 Oct 2025 21:44:20 +0200 Subject: [PATCH 1/8] chore: update onto python 3.14 --- .github/FUNDING.yml | 2 +- .github/workflows/publish.yml | 28 ++++++++++++++-------------- .github/workflows/tests.yml | 4 ++-- CHANGELOG.md | 4 ++++ Cargo.lock | 2 +- Cargo.toml | 2 +- pyproject.toml | 3 ++- 7 files changed, 25 insertions(+), 20 deletions(-) diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 97ca688..740dbf2 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,2 +1,2 @@ -github: ["EmilStenstrom"] +github: ["EmilStenstrom", "JuroOravec"] diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index f3c5fd9..807cb6c 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -22,23 +22,23 @@ jobs: strategy: matrix: platform: - - runner: ubuntu-22.04 + - runner: ubuntu-latest target: x86_64 - - runner: ubuntu-22.04 + - runner: ubuntu-latest target: x86 - - runner: ubuntu-22.04 + - runner: ubuntu-latest target: aarch64 - - runner: ubuntu-22.04 + - runner: ubuntu-latest target: armv7 - - runner: ubuntu-22.04 + - runner: ubuntu-latest target: s390x - - runner: ubuntu-22.04 + - runner: ubuntu-latest target: ppc64le steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "3.14" - name: Build wheels uses: PyO3/maturin-action@v1 with: @@ -57,19 +57,19 @@ jobs: strategy: matrix: platform: - - runner: ubuntu-22.04 + - runner: ubuntu-latest target: x86_64 - - runner: ubuntu-22.04 + - runner: ubuntu-latest target: x86 - - runner: ubuntu-22.04 + - runner: ubuntu-latest target: aarch64 - - runner: ubuntu-22.04 + - runner: ubuntu-latest target: armv7 steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "3.14" - name: Build wheels uses: PyO3/maturin-action@v1 with: @@ -96,7 +96,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "3.14" architecture: ${{ matrix.platform.target }} - name: Build wheels uses: PyO3/maturin-action@v1 @@ -123,7 +123,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "3.14" - name: Build wheels uses: PyO3/maturin-action@v1 with: diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 161a84e..26dd44c 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -13,8 +13,8 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13'] - os: [ubuntu-20.04, windows-latest] + python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13', '3.14'] + os: [ubuntu-latest, windows-latest] steps: - uses: actions/checkout@v4 diff --git a/CHANGELOG.md b/CHANGELOG.md index 57b956a..4160fc0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Release notes +## v1.0.3 + +- Update to Python 3.14 + ## v1.0.2 - Add build for Python 3.13 for Windows. diff --git a/Cargo.lock b/Cargo.lock index c7e960c..e23cc08 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,7 +22,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "djc_core_html_parser" -version = "1.0.2" +version = "1.0.3" dependencies = [ "pyo3", "quick-xml", diff --git a/Cargo.toml b/Cargo.toml index 340f74f..06728f8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "djc_core_html_parser" -version = "1.0.2" +version = "1.0.3" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/pyproject.toml b/pyproject.toml index a557a9e..5e4bb6d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "maturin" [project] name = "djc_core_html_parser" -version = "1.0.2" +version = "1.0.3" requires-python = ">=3.8, <4.0" description = "HTML parser used by django-components written in Rust." keywords = ["django", "components", "html"] @@ -21,6 +21,7 @@ classifiers = [ "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Programming Language :: Rust", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", From b9965b58d178ba6be1a739019d2fdf59841083c8 Mon Sep 17 00:00:00 2001 From: Juro Oravec Date: Tue, 21 Oct 2025 22:06:56 +0200 Subject: [PATCH 2/8] refactor: update pyo3 to v0.21 --- Cargo.lock | 155 ++++++++++++++++++--------------------------- Cargo.toml | 2 +- src/html_parser.rs | 6 +- src/lib.rs | 3 +- 4 files changed, 65 insertions(+), 101 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e23cc08..a64cc3c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,15 +10,15 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "bitflags" -version = "2.8.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "djc_core_html_parser" @@ -28,11 +28,20 @@ dependencies = [ "quick-xml", ] +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + [[package]] name = "indoc" -version = "1.0.9" +version = "2.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa799dd5ed20a7e349f3b4639aa80d74549c81716d9ec4f994c9b5815598306" +checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706" +dependencies = [ + "rustversion", +] [[package]] name = "libc" @@ -42,11 +51,10 @@ checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" [[package]] name = "lock_api" -version = "0.4.12" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" dependencies = [ - "autocfg", "scopeguard", ] @@ -67,15 +75,15 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.2" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "parking_lot" -version = "0.12.3" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" dependencies = [ "lock_api", "parking_lot_core", @@ -83,17 +91,23 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.10" +version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-targets", + "windows-link", ] +[[package]] +name = "portable-atomic" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" + [[package]] name = "proc-macro2" version = "1.0.93" @@ -105,15 +119,16 @@ dependencies = [ [[package]] name = "pyo3" -version = "0.19.2" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e681a6cfdc4adcc93b4d3cf993749a4552018ee0a9b65fc0ccfad74352c72a38" +checksum = "a5e00b96a521718e08e03b1a622f01c8a8deb50719335de3f60b3b3950f069d8" dependencies = [ "cfg-if", "indoc", "libc", "memoffset", "parking_lot", + "portable-atomic", "pyo3-build-config", "pyo3-ffi", "pyo3-macros", @@ -122,9 +137,9 @@ dependencies = [ [[package]] name = "pyo3-build-config" -version = "0.19.2" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "076c73d0bc438f7a4ef6fdd0c3bb4732149136abd952b110ac93e4edb13a6ba5" +checksum = "7883df5835fafdad87c0d888b266c8ec0f4c9ca48a5bed6bbb592e8dedee1b50" dependencies = [ "once_cell", "target-lexicon", @@ -132,9 +147,9 @@ dependencies = [ [[package]] name = "pyo3-ffi" -version = "0.19.2" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e53cee42e77ebe256066ba8aa77eff722b3bb91f3419177cf4cd0f304d3284d9" +checksum = "01be5843dc60b916ab4dad1dca6d20b9b4e6ddc8e15f50c47fe6d85f1fb97403" dependencies = [ "libc", "pyo3-build-config", @@ -142,9 +157,9 @@ dependencies = [ [[package]] name = "pyo3-macros" -version = "0.19.2" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfeb4c99597e136528c6dd7d5e3de5434d1ceaf487436a3f03b2d56b6fc9efd1" +checksum = "77b34069fc0682e11b31dbd10321cbf94808394c56fd996796ce45217dfac53c" dependencies = [ "proc-macro2", "pyo3-macros-backend", @@ -154,11 +169,13 @@ dependencies = [ [[package]] name = "pyo3-macros-backend" -version = "0.19.2" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "947dc12175c254889edc0c02e399476c2f652b4b9ebd123aa655c224de259536" +checksum = "08260721f32db5e1a5beae69a55553f56b99bd0e1c3e6e0a5e8851a9d0f5a85c" dependencies = [ + "heck", "proc-macro2", + "pyo3-build-config", "quote", "syn", ] @@ -183,13 +200,19 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.8" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ "bitflags", ] +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + [[package]] name = "scopeguard" version = "1.2.0" @@ -198,15 +221,15 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "smallvec" -version = "1.13.2" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +checksum = "2a26dbd934e5451d21ef060c018dae56fc073894c5a7896f882928a76e6d081b" dependencies = [ "proc-macro2", "quote", @@ -227,70 +250,12 @@ checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] name = "unindent" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1766d682d402817b5ac4490b3c3002d91dfa0d22812f341609f97b08757359c" - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3" [[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" +name = "windows-link" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" diff --git a/Cargo.toml b/Cargo.toml index 06728f8..d12d81d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ name = "djc_core_html_parser" crate-type = ["cdylib"] [dependencies] -pyo3 = { version = "0.19.0", features = ["extension-module"] } +pyo3 = { version = "0.21.0", features = ["extension-module"] } quick-xml = "0.37.2" # https://ohadravid.github.io/posts/2023-03-rusty-python diff --git a/src/html_parser.rs b/src/html_parser.rs index 5bb7eef..adc2e35 100644 --- a/src/html_parser.rs +++ b/src/html_parser.rs @@ -48,7 +48,7 @@ pub fn set_html_attributes( all_attributes: Vec, check_end_names: Option, watch_on_attribute: Option, -) -> PyResult { +) -> PyResult> { let config = HtmlTransformerConfig::new( root_attributes, all_attributes, @@ -59,12 +59,12 @@ pub fn set_html_attributes( match transform(&config, html) { Ok((html, captured)) => { // Convert captured attributes to a Python dictionary - let captured_dict = PyDict::new(py); + let captured_dict = PyDict::new_bound(py); for (id, attrs) in captured { captured_dict.set_item(id, attrs)?; } - let result = PyTuple::new(py, &[html.into_py(py), captured_dict.into_py(py)]); + let result = PyTuple::new_bound(py, &[html.into_py(py), captured_dict.into_py(py)]); Ok(result.into()) } Err(e) => Err(PyValueError::new_err(e.to_string())), diff --git a/src/lib.rs b/src/lib.rs index 050fa3e..4d591d1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,11 +1,10 @@ use pyo3::prelude::*; -use pyo3::types::PyModule; mod html_parser; /// A Python module implemented in Rust for high-performance HTML transformation. #[pymodule] -fn djc_core_html_parser(_py: Python, m: &PyModule) -> PyResult<()> { +fn djc_core_html_parser(m: &Bound<'_, PyModule>) -> PyResult<()> { m.add_function(wrap_pyfunction!(html_parser::set_html_attributes, m)?)?; Ok(()) } From 3409d1415fde16b9960448535beeb0c32cdadd88 Mon Sep 17 00:00:00 2001 From: Juro Oravec Date: Tue, 21 Oct 2025 22:12:09 +0200 Subject: [PATCH 3/8] refactor: bump pyo3 to v0.22 --- Cargo.lock | 91 +++++++--------------------------------------- Cargo.toml | 2 +- src/html_parser.rs | 1 + 3 files changed, 15 insertions(+), 79 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a64cc3c..8bb3db3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,12 +8,6 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" -[[package]] -name = "bitflags" -version = "2.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" - [[package]] name = "cfg-if" version = "1.0.4" @@ -30,9 +24,9 @@ dependencies = [ [[package]] name = "heck" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "indoc" @@ -49,15 +43,6 @@ version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" -[[package]] -name = "lock_api" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" -dependencies = [ - "scopeguard", -] - [[package]] name = "memchr" version = "2.7.4" @@ -79,29 +64,6 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" -[[package]] -name = "parking_lot" -version = "0.12.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-link", -] - [[package]] name = "portable-atomic" version = "1.11.1" @@ -119,15 +81,15 @@ dependencies = [ [[package]] name = "pyo3" -version = "0.21.2" +version = "0.22.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e00b96a521718e08e03b1a622f01c8a8deb50719335de3f60b3b3950f069d8" +checksum = "f402062616ab18202ae8319da13fa4279883a2b8a9d9f83f20dbade813ce1884" dependencies = [ "cfg-if", "indoc", "libc", "memoffset", - "parking_lot", + "once_cell", "portable-atomic", "pyo3-build-config", "pyo3-ffi", @@ -137,9 +99,9 @@ dependencies = [ [[package]] name = "pyo3-build-config" -version = "0.21.2" +version = "0.22.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7883df5835fafdad87c0d888b266c8ec0f4c9ca48a5bed6bbb592e8dedee1b50" +checksum = "b14b5775b5ff446dd1056212d778012cbe8a0fbffd368029fd9e25b514479c38" dependencies = [ "once_cell", "target-lexicon", @@ -147,9 +109,9 @@ dependencies = [ [[package]] name = "pyo3-ffi" -version = "0.21.2" +version = "0.22.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01be5843dc60b916ab4dad1dca6d20b9b4e6ddc8e15f50c47fe6d85f1fb97403" +checksum = "9ab5bcf04a2cdcbb50c7d6105de943f543f9ed92af55818fd17b660390fc8636" dependencies = [ "libc", "pyo3-build-config", @@ -157,9 +119,9 @@ dependencies = [ [[package]] name = "pyo3-macros" -version = "0.21.2" +version = "0.22.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77b34069fc0682e11b31dbd10321cbf94808394c56fd996796ce45217dfac53c" +checksum = "0fd24d897903a9e6d80b968368a34e1525aeb719d568dba8b3d4bfa5dc67d453" dependencies = [ "proc-macro2", "pyo3-macros-backend", @@ -169,9 +131,9 @@ dependencies = [ [[package]] name = "pyo3-macros-backend" -version = "0.21.2" +version = "0.22.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08260721f32db5e1a5beae69a55553f56b99bd0e1c3e6e0a5e8851a9d0f5a85c" +checksum = "36c011a03ba1e50152b4b394b479826cad97e7a21eb52df179cd91ac411cbfbe" dependencies = [ "heck", "proc-macro2", @@ -198,33 +160,12 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "redox_syscall" -version = "0.5.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" -dependencies = [ - "bitflags", -] - [[package]] name = "rustversion" version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "smallvec" -version = "1.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" - [[package]] name = "syn" version = "2.0.107" @@ -253,9 +194,3 @@ name = "unindent" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3" - -[[package]] -name = "windows-link" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" diff --git a/Cargo.toml b/Cargo.toml index d12d81d..11c49e3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ name = "djc_core_html_parser" crate-type = ["cdylib"] [dependencies] -pyo3 = { version = "0.21.0", features = ["extension-module"] } +pyo3 = { version = "0.22.0", features = ["extension-module"] } quick-xml = "0.37.2" # https://ohadravid.github.io/posts/2023-03-rusty-python diff --git a/src/html_parser.rs b/src/html_parser.rs index adc2e35..0f2c2b5 100644 --- a/src/html_parser.rs +++ b/src/html_parser.rs @@ -38,6 +38,7 @@ const VOID_ELEMENTS: [&str; 14] = [ /// Raises: /// ValueError: If the HTML is malformed or cannot be parsed. #[pyfunction] +#[pyo3(signature = (html, root_attributes, all_attributes, check_end_names=None, watch_on_attribute=None))] #[pyo3( text_signature = "(html, root_attributes, all_attributes, *, check_end_names=False, watch_on_attribute=None)" )] From c3dea8bef2d4c99c79a9001349f629d2e94eb72c Mon Sep 17 00:00:00 2001 From: Juro Oravec Date: Tue, 21 Oct 2025 22:21:52 +0200 Subject: [PATCH 4/8] refactor: update pyo3 to 0.23 --- Cargo.lock | 20 ++++++++++---------- Cargo.toml | 2 +- src/html_parser.rs | 10 +++++++--- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8bb3db3..df8bfbd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -81,9 +81,9 @@ dependencies = [ [[package]] name = "pyo3" -version = "0.22.6" +version = "0.23.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f402062616ab18202ae8319da13fa4279883a2b8a9d9f83f20dbade813ce1884" +checksum = "7778bffd85cf38175ac1f545509665d0b9b92a198ca7941f131f85f7a4f9a872" dependencies = [ "cfg-if", "indoc", @@ -99,9 +99,9 @@ dependencies = [ [[package]] name = "pyo3-build-config" -version = "0.22.6" +version = "0.23.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b14b5775b5ff446dd1056212d778012cbe8a0fbffd368029fd9e25b514479c38" +checksum = "94f6cbe86ef3bf18998d9df6e0f3fc1050a8c5efa409bf712e661a4366e010fb" dependencies = [ "once_cell", "target-lexicon", @@ -109,9 +109,9 @@ dependencies = [ [[package]] name = "pyo3-ffi" -version = "0.22.6" +version = "0.23.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ab5bcf04a2cdcbb50c7d6105de943f543f9ed92af55818fd17b660390fc8636" +checksum = "e9f1b4c431c0bb1c8fb0a338709859eed0d030ff6daa34368d3b152a63dfdd8d" dependencies = [ "libc", "pyo3-build-config", @@ -119,9 +119,9 @@ dependencies = [ [[package]] name = "pyo3-macros" -version = "0.22.6" +version = "0.23.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fd24d897903a9e6d80b968368a34e1525aeb719d568dba8b3d4bfa5dc67d453" +checksum = "fbc2201328f63c4710f68abdf653c89d8dbc2858b88c5d88b0ff38a75288a9da" dependencies = [ "proc-macro2", "pyo3-macros-backend", @@ -131,9 +131,9 @@ dependencies = [ [[package]] name = "pyo3-macros-backend" -version = "0.22.6" +version = "0.23.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36c011a03ba1e50152b4b394b479826cad97e7a21eb52df179cd91ac411cbfbe" +checksum = "fca6726ad0f3da9c9de093d6f116a93c1a38e417ed73bf138472cf4064f72028" dependencies = [ "heck", "proc-macro2", diff --git a/Cargo.toml b/Cargo.toml index 11c49e3..c5f34d8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ name = "djc_core_html_parser" crate-type = ["cdylib"] [dependencies] -pyo3 = { version = "0.22.0", features = ["extension-module"] } +pyo3 = { version = "0.23.0", features = ["extension-module"] } quick-xml = "0.37.2" # https://ohadravid.github.io/posts/2023-03-rusty-python diff --git a/src/html_parser.rs b/src/html_parser.rs index 0f2c2b5..a8a5352 100644 --- a/src/html_parser.rs +++ b/src/html_parser.rs @@ -60,13 +60,17 @@ pub fn set_html_attributes( match transform(&config, html) { Ok((html, captured)) => { // Convert captured attributes to a Python dictionary - let captured_dict = PyDict::new_bound(py); + let captured_dict = PyDict::new(py); for (id, attrs) in captured { captured_dict.set_item(id, attrs)?; } - let result = PyTuple::new_bound(py, &[html.into_py(py), captured_dict.into_py(py)]); - Ok(result.into()) + // Convert items to Bound for the tuple + use pyo3::types::PyString; + let html_obj = PyString::new(py, &html).as_any().clone(); + let dict_obj = captured_dict.as_any().clone(); + let result = PyTuple::new(py, vec![html_obj, dict_obj])?; + Ok(result.into_any().unbind()) } Err(e) => Err(PyValueError::new_err(e.to_string())), } From 4f15385af981a824975ad573dfe8ed29b0610a89 Mon Sep 17 00:00:00 2001 From: Juro Oravec Date: Tue, 21 Oct 2025 22:26:06 +0200 Subject: [PATCH 5/8] chore: bump pyo3 to v0.27 --- Cargo.lock | 32 ++++++++++++-------------------- Cargo.toml | 2 +- 2 files changed, 13 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index df8bfbd..6416358 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,12 +8,6 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" -[[package]] -name = "cfg-if" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" - [[package]] name = "djc_core_html_parser" version = "1.0.3" @@ -81,11 +75,10 @@ dependencies = [ [[package]] name = "pyo3" -version = "0.23.5" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7778bffd85cf38175ac1f545509665d0b9b92a198ca7941f131f85f7a4f9a872" +checksum = "fa8e48c12afdeb26aa4be4e5c49fb5e11c3efa0878db783a960eea2b9ac6dd19" dependencies = [ - "cfg-if", "indoc", "libc", "memoffset", @@ -99,19 +92,18 @@ dependencies = [ [[package]] name = "pyo3-build-config" -version = "0.23.5" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94f6cbe86ef3bf18998d9df6e0f3fc1050a8c5efa409bf712e661a4366e010fb" +checksum = "bc1989dbf2b60852e0782c7487ebf0b4c7f43161ffe820849b56cf05f945cee1" dependencies = [ - "once_cell", "target-lexicon", ] [[package]] name = "pyo3-ffi" -version = "0.23.5" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9f1b4c431c0bb1c8fb0a338709859eed0d030ff6daa34368d3b152a63dfdd8d" +checksum = "c808286da7500385148930152e54fb6883452033085bf1f857d85d4e82ca905c" dependencies = [ "libc", "pyo3-build-config", @@ -119,9 +111,9 @@ dependencies = [ [[package]] name = "pyo3-macros" -version = "0.23.5" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc2201328f63c4710f68abdf653c89d8dbc2858b88c5d88b0ff38a75288a9da" +checksum = "83a0543c16be0d86cf0dbf2e2b636ece9fd38f20406bb43c255e0bc368095f92" dependencies = [ "proc-macro2", "pyo3-macros-backend", @@ -131,9 +123,9 @@ dependencies = [ [[package]] name = "pyo3-macros-backend" -version = "0.23.5" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fca6726ad0f3da9c9de093d6f116a93c1a38e417ed73bf138472cf4064f72028" +checksum = "2a00da2ce064dcd582448ea24a5a26fa9527e0483103019b741ebcbe632dcd29" dependencies = [ "heck", "proc-macro2", @@ -179,9 +171,9 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.12.16" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" +checksum = "df7f62577c25e07834649fc3b39fafdc597c0a3527dc1c60129201ccfcbaa50c" [[package]] name = "unicode-ident" diff --git a/Cargo.toml b/Cargo.toml index c5f34d8..62ffc0f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ name = "djc_core_html_parser" crate-type = ["cdylib"] [dependencies] -pyo3 = { version = "0.23.0", features = ["extension-module"] } +pyo3 = { version = "0.27.0", features = ["extension-module"] } quick-xml = "0.37.2" # https://ohadravid.github.io/posts/2023-03-rusty-python From 017adb026d822043ea99b23b416ad5b8be69bef0 Mon Sep 17 00:00:00 2001 From: Juro Oravec Date: Tue, 21 Oct 2025 22:36:29 +0200 Subject: [PATCH 6/8] chore: bump quick-xml to v0.38.3 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- src/html_parser.rs | 3 +++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6416358..bc7c6a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -136,9 +136,9 @@ dependencies = [ [[package]] name = "quick-xml" -version = "0.37.2" +version = "0.38.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "165859e9e55f79d67b96c5d96f4e88b6f2695a1972849c15a6a3f5c59fc2c003" +checksum = "42a232e7487fc2ef313d96dde7948e7a3c05101870d8985e4fd8d26aedd27b89" dependencies = [ "memchr", ] diff --git a/Cargo.toml b/Cargo.toml index 62ffc0f..dae24e3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ crate-type = ["cdylib"] [dependencies] pyo3 = { version = "0.27.0", features = ["extension-module"] } -quick-xml = "0.37.2" +quick-xml = "0.38.3" # https://ohadravid.github.io/posts/2023-03-rusty-python [profile.release] diff --git a/src/html_parser.rs b/src/html_parser.rs index a8a5352..844e002 100644 --- a/src/html_parser.rs +++ b/src/html_parser.rs @@ -154,6 +154,9 @@ pub fn transform( let mut reader = Reader::from_str(html); let reader_config = reader.config_mut(); reader_config.check_end_names = config.check_end_names; + // Allow bare & in HTML content (e.g. "Hello & Welcome" instead of requiring "Hello & Welcome") + // This is needed for compatibility with HTML5 which is more lenient than strict XML + reader_config.allow_dangling_amp = true; // We transform the HTML by reading it and writing it simultaneously let mut writer = Writer::new(Cursor::new(Vec::new())); From dc70776080a325a161efb6f4c7cb98a7493fb062 Mon Sep 17 00:00:00 2001 From: Juro Oravec Date: Tue, 21 Oct 2025 22:44:51 +0200 Subject: [PATCH 7/8] chore: bump maturin --- requirements-ci.txt | 2 +- requirements-dev.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements-ci.txt b/requirements-ci.txt index 0607ebc..cc9e114 100644 --- a/requirements-ci.txt +++ b/requirements-ci.txt @@ -6,7 +6,7 @@ # iniconfig==2.0.0 # via pytest -maturin==1.8.1 +maturin==1.9.6 # via -r requirements-ci.in packaging==24.2 # via pytest diff --git a/requirements-dev.txt b/requirements-dev.txt index ea6c360..44e3a8c 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -6,7 +6,7 @@ # iniconfig==2.0.0 # via pytest -maturin==1.8.1 +maturin==1.9.6 # via -r requirements-dev.in packaging==24.2 # via pytest From bc3ffab24c22ccfb07902011432821f20d3374e6 Mon Sep 17 00:00:00 2001 From: Juro Oravec Date: Tue, 21 Oct 2025 22:48:18 +0200 Subject: [PATCH 8/8] chore: update github actions --- .github/workflows/publish.yml | 34 +++++++------- .github/workflows/tests.yml | 84 +++++++++++++++++------------------ 2 files changed, 59 insertions(+), 59 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 807cb6c..363eec7 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -8,7 +8,7 @@ name: Publish to PyPI on: push: tags: - - '*' + - "*" # Allows you to run this workflow manually from the Actions tab workflow_dispatch: @@ -35,8 +35,8 @@ jobs: - runner: ubuntu-latest target: ppc64le steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - uses: actions/checkout@v5 + - uses: actions/setup-python@v6 with: python-version: "3.14" - name: Build wheels @@ -44,7 +44,7 @@ jobs: with: target: ${{ matrix.platform.target }} args: --release --out dist --find-interpreter - sccache: 'true' + sccache: "true" manylinux: auto - name: Upload wheels uses: actions/upload-artifact@v4 @@ -66,8 +66,8 @@ jobs: - runner: ubuntu-latest target: armv7 steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - uses: actions/checkout@v5 + - uses: actions/setup-python@v6 with: python-version: "3.14" - name: Build wheels @@ -75,7 +75,7 @@ jobs: with: target: ${{ matrix.platform.target }} args: --release --out dist --find-interpreter - sccache: 'true' + sccache: "true" manylinux: musllinux_1_2 - name: Upload wheels uses: actions/upload-artifact@v4 @@ -93,8 +93,8 @@ jobs: - runner: windows-latest target: x86 steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - uses: actions/checkout@v5 + - uses: actions/setup-python@v6 with: python-version: "3.14" architecture: ${{ matrix.platform.target }} @@ -103,7 +103,7 @@ jobs: with: target: ${{ matrix.platform.target }} args: --release --out dist --find-interpreter - sccache: 'true' + sccache: "true" - name: Upload wheels uses: actions/upload-artifact@v4 with: @@ -120,8 +120,8 @@ jobs: - runner: macos-14 target: aarch64 steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - uses: actions/checkout@v5 + - uses: actions/setup-python@v6 with: python-version: "3.14" - name: Build wheels @@ -129,7 +129,7 @@ jobs: with: target: ${{ matrix.platform.target }} args: --release --out dist --find-interpreter - sccache: 'true' + sccache: "true" - name: Upload wheels uses: actions/upload-artifact@v4 with: @@ -139,7 +139,7 @@ jobs: sdist: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Build sdist uses: PyO3/maturin-action@v1 with: @@ -164,11 +164,11 @@ jobs: # Used to generate artifact attestation attestations: write steps: - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v5 - name: Generate artifact attestation - uses: actions/attest-build-provenance@v2 + uses: actions/attest-build-provenance@v3 with: - subject-path: 'wheels-*/*' + subject-path: "wheels-*/*" - name: Publish to PyPI if: ${{ startsWith(github.ref, 'refs/tags/') }} uses: PyO3/maturin-action@v1 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 26dd44c..ef40687 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -3,8 +3,8 @@ name: Run tests on: push: branches: - - 'main' - - 'dev' + - "main" + - "dev" pull_request: workflow_dispatch: @@ -13,46 +13,46 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13', '3.14'] + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] os: [ubuntu-latest, windows-latest] steps: - - uses: actions/checkout@v4 - - # First check Rust tests - - name: Install Rust toolchain - uses: dtolnay/rust-toolchain@stable - with: - toolchain: stable - components: rustfmt, clippy - - - name: Cache Rust dependencies - uses: Swatinem/rust-cache@v2 - - - name: Run Rust tests - run: cargo test - - # After Rust tests pass, run Python tests next - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - cache: "pip" - - - name: Install Python dependencies - run: | - # NOTE: maturin requires a virtual environment to be active - python -m venv .venv - ${{ runner.os == 'Windows' && '.venv\Scripts\activate' || 'source .venv/bin/activate' }} - python -m pip install --upgrade pip - python -m pip install -r requirements-ci.txt - - - name: Build Python package - run: | - ${{ runner.os == 'Windows' && '.venv\Scripts\activate' || 'source .venv/bin/activate' }} - maturin develop - - - name: Run Python tests - run: | - ${{ runner.os == 'Windows' && '.venv\Scripts\activate' || 'source .venv/bin/activate' }} - pytest + - uses: actions/checkout@v5 + + # First check Rust tests + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + toolchain: stable + components: rustfmt, clippy + + - name: Cache Rust dependencies + uses: Swatinem/rust-cache@v2 + + - name: Run Rust tests + run: cargo test + + # After Rust tests pass, run Python tests next + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v6 + with: + python-version: ${{ matrix.python-version }} + cache: "pip" + + - name: Install Python dependencies + run: | + # NOTE: maturin requires a virtual environment to be active + python -m venv .venv + ${{ runner.os == 'Windows' && '.venv\Scripts\activate' || 'source .venv/bin/activate' }} + python -m pip install --upgrade pip + python -m pip install -r requirements-ci.txt + + - name: Build Python package + run: | + ${{ runner.os == 'Windows' && '.venv\Scripts\activate' || 'source .venv/bin/activate' }} + maturin develop + + - name: Run Python tests + run: | + ${{ runner.os == 'Windows' && '.venv\Scripts\activate' || 'source .venv/bin/activate' }} + pytest