Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-nh3 for openSUSE:Factory checked in at 2026-05-12 19:26:10 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-nh3 (Old) and /work/SRC/openSUSE:Factory/.python-nh3.new.1966 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-nh3" Tue May 12 19:26:10 2026 rev:8 rq:1352318 version:0.3.5 Changes: -------- --- /work/SRC/openSUSE:Factory/python-nh3/python-nh3.changes 2026-04-08 17:13:53.903401616 +0200 +++ /work/SRC/openSUSE:Factory/.python-nh3.new.1966/python-nh3.changes 2026-05-12 19:26:22.842372016 +0200 @@ -1,0 +2,9 @@ +Sun May 10 20:16:53 UTC 2026 - Dirk Müller <[email protected]> + +- update to 0.3.5: + * Add usage examples for clean() and Cleaner arguments + * Add doctest coverage for module docstrings and RST files + * Bump pyo3 from 0.28.2 to 0.28.3 + * Add tags parameter to clean_text + +------------------------------------------------------------------- Old: ---- nh3-0.3.4.tar.gz New: ---- nh3-0.3.5.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-nh3.spec ++++++ --- /var/tmp/diff_new_pack.CyS4WV/_old 2026-05-12 19:26:23.446397049 +0200 +++ /var/tmp/diff_new_pack.CyS4WV/_new 2026-05-12 19:26:23.450397215 +0200 @@ -18,7 +18,7 @@ %{?sle15_python_module_pythons} Name: python-nh3 -Version: 0.3.4 +Version: 0.3.5 Release: 0 Summary: Ammonia HTML sanitizer Python binding License: MIT ++++++ _service ++++++ --- /var/tmp/diff_new_pack.CyS4WV/_old 2026-05-12 19:26:23.482398541 +0200 +++ /var/tmp/diff_new_pack.CyS4WV/_new 2026-05-12 19:26:23.486398707 +0200 @@ -1,7 +1,7 @@ <services> <service name="download_files" mode="manual"/> <service name="cargo_vendor" mode="manual"> - <param name="src">nh3-0.3.4.tar.gz</param> + <param name="src">nh3-0.3.5.tar.gz</param> <param name="compression">zst</param> </service> </services> ++++++ nh3-0.3.4.tar.gz -> nh3-0.3.5.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nh3-0.3.4/.github/workflows/CI.yml new/nh3-0.3.5/.github/workflows/CI.yml --- old/nh3-0.3.4/.github/workflows/CI.yml 2006-07-24 03:21:28.000000000 +0200 +++ new/nh3-0.3.5/.github/workflows/CI.yml 2006-07-24 03:21:28.000000000 +0200 @@ -33,7 +33,7 @@ run: | pip install nh3 --no-index --find-links dist --force-reinstall pip install pytest - cd tests && pytest + pytest - name: Upload wheels uses: actions/upload-artifact@v7 with: @@ -66,7 +66,7 @@ run: | pip install nh3 --no-index --find-links dist --force-reinstall pip install pytest - cd tests && pytest + pytest - name: Upload wheels uses: actions/upload-artifact@v7 with: @@ -98,7 +98,7 @@ run: | pip install nh3 --no-index --find-links dist --force-reinstall pip install pytest - cd tests && pytest + pytest - name: Upload wheels uses: actions/upload-artifact@v7 with: @@ -139,7 +139,7 @@ run: | pip install nh3 --no-index --find-links dist --force-reinstall pip install pytest - cd tests && pytest + pytest - name: Upload wheels uses: actions/upload-artifact@v7 with: @@ -197,7 +197,7 @@ pip3 install -U pip pytest run: | pip3 install nh3 --no-index --find-links dist/ --force-reinstall - cd tests && pytest + pytest - name: Upload wheels uses: actions/upload-artifact@v7 with: @@ -240,7 +240,7 @@ source .venv/bin/activate pip install -U pip pytest pip install nh3 --no-index --find-links /io/dist/ --force-reinstall - cd tests && python3 -m pytest + python3 -m pytest ' - name: Upload wheels uses: actions/upload-artifact@v7 @@ -289,7 +289,7 @@ source .venv/bin/activate pip install pytest pip install nh3 --no-index --find-links dist/ --force-reinstall - cd tests && python3 -m pytest + python3 -m pytest - name: Upload wheels uses: actions/upload-artifact@v7 with: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nh3-0.3.4/Cargo.lock new/nh3-0.3.5/Cargo.lock --- old/nh3-0.3.4/Cargo.lock 2006-07-24 03:21:28.000000000 +0200 +++ new/nh3-0.3.5/Cargo.lock 2006-07-24 03:21:28.000000000 +0200 @@ -23,15 +23,15 @@ [[package]] name = "bitflags" -version = "2.11.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" +checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" [[package]] name = "cc" -version = "1.2.57" +version = "1.2.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a0dd1ca384932ff3641c8718a02769f1698e7563dc6974ffd03346116310423" +checksum = "d16d90359e986641506914ba71350897565610e87ce0ad9e6f28569db3dd5c6d" dependencies = [ "find-msvc-tools", "shlex", @@ -142,12 +142,13 @@ [[package]] name = "icu_collections" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" dependencies = [ "displaydoc", "potential_utf", + "utf8_iter", "yoke", "zerofrom", "zerovec", @@ -155,9 +156,9 @@ [[package]] name = "icu_locale_core" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" dependencies = [ "displaydoc", "litemap", @@ -168,9 +169,9 @@ [[package]] name = "icu_normalizer" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" +checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" dependencies = [ "icu_collections", "icu_normalizer_data", @@ -182,15 +183,15 @@ [[package]] name = "icu_normalizer_data" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" +checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" [[package]] name = "icu_properties" -version = "2.1.2" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" +checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" dependencies = [ "icu_collections", "icu_locale_core", @@ -202,15 +203,15 @@ [[package]] name = "icu_properties_data" -version = "2.1.2" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" +checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" [[package]] name = "icu_provider" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" dependencies = [ "displaydoc", "icu_locale_core", @@ -250,15 +251,15 @@ [[package]] name = "libc" -version = "0.2.183" +version = "0.2.186" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "litemap" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" +checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" [[package]] name = "lock_api" @@ -317,7 +318,7 @@ [[package]] name = "nh3" -version = "0.3.4" +version = "0.3.5" dependencies = [ "ammonia", "ouroboros", @@ -443,9 +444,9 @@ [[package]] name = "potential_utf" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" dependencies = [ "zerovec", ] @@ -480,9 +481,9 @@ [[package]] name = "pyo3" -version = "0.28.2" +version = "0.28.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf85e27e86080aafd5a22eae58a162e133a589551542b3e5cee4beb27e54f8e1" +checksum = "91fd8e38a3b50ed1167fb981cd6fd60147e091784c427b8f7183a7ee32c31c12" dependencies = [ "libc", "once_cell", @@ -494,9 +495,9 @@ [[package]] name = "pyo3-build-config" -version = "0.28.2" +version = "0.28.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bf94ee265674bf76c09fa430b0e99c26e319c945d96ca0d5a8215f31bf81cf7" +checksum = "e368e7ddfdeb98c9bca7f8383be1648fd84ab466bf2bc015e94008db6d35611e" dependencies = [ "python3-dll-a", "target-lexicon", @@ -504,9 +505,9 @@ [[package]] name = "pyo3-ffi" -version = "0.28.2" +version = "0.28.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "491aa5fc66d8059dd44a75f4580a2962c1862a1c2945359db36f6c2818b748dc" +checksum = "7f29e10af80b1f7ccaf7f69eace800a03ecd13e883acfacc1e5d0988605f651e" dependencies = [ "libc", "pyo3-build-config", @@ -514,9 +515,9 @@ [[package]] name = "pyo3-macros" -version = "0.28.2" +version = "0.28.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5d671734e9d7a43449f8480f8b38115df67bef8d21f76837fa75ee7aaa5e52e" +checksum = "df6e520eff47c45997d2fc7dd8214b25dd1310918bbb2642156ef66a67f29813" dependencies = [ "proc-macro2", "pyo3-macros-backend", @@ -526,9 +527,9 @@ [[package]] name = "pyo3-macros-backend" -version = "0.28.2" +version = "0.28.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22faaa1ce6c430a1f71658760497291065e6450d7b5dc2bcf254d49f66ee700a" +checksum = "c4cdc218d835738f81c2338f822078af45b4afdf8b2e33cbb5916f108b813acb" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -539,9 +540,9 @@ [[package]] name = "python3-dll-a" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d381ef313ae70b4da5f95f8a4de773c6aa5cd28f73adec4b4a31df70b66780d8" +checksum = "d80ba7540edb18890d444c5aa8e1f1f99b1bdf26fb26ae383135325f4a36042b" dependencies = [ "cc", ] @@ -557,9 +558,9 @@ [[package]] name = "rand" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" dependencies = [ "rand_core", ] @@ -710,9 +711,9 @@ [[package]] name = "tinystr" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" +checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" dependencies = [ "displaydoc", "zerovec", @@ -774,9 +775,9 @@ [[package]] name = "writeable" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" +checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" [[package]] name = "yansi" @@ -786,9 +787,9 @@ [[package]] name = "yoke" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" +checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" dependencies = [ "stable_deref_trait", "yoke-derive", @@ -797,9 +798,9 @@ [[package]] name = "yoke-derive" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" dependencies = [ "proc-macro2", "quote", @@ -809,18 +810,18 @@ [[package]] name = "zerofrom" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" dependencies = [ "proc-macro2", "quote", @@ -830,9 +831,9 @@ [[package]] name = "zerotrie" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" dependencies = [ "displaydoc", "yoke", @@ -841,9 +842,9 @@ [[package]] name = "zerovec" -version = "0.11.5" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" +checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" dependencies = [ "yoke", "zerofrom", @@ -852,9 +853,9 @@ [[package]] name = "zerovec-derive" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" +checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" dependencies = [ "proc-macro2", "quote", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nh3-0.3.4/Cargo.toml new/nh3-0.3.5/Cargo.toml --- old/nh3-0.3.4/Cargo.toml 2006-07-24 03:21:28.000000000 +0200 +++ new/nh3-0.3.5/Cargo.toml 2006-07-24 03:21:28.000000000 +0200 @@ -1,6 +1,6 @@ [package] name = "nh3" -version = "0.3.4" +version = "0.3.5" authors = ["messense <[email protected]>"] edition = "2024" description = "Python bindings to the ammonia HTML sanitization library." @@ -15,5 +15,5 @@ [dependencies] ammonia = "4.1.2" -pyo3 = { version = "0.28.2", features = ["abi3-py38", "generate-import-lib"] } +pyo3 = { version = "0.28.3", features = ["abi3-py38", "generate-import-lib"] } ouroboros = "0.18" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nh3-0.3.4/PKG-INFO new/nh3-0.3.5/PKG-INFO --- old/nh3-0.3.4/PKG-INFO 2006-07-24 03:21:28.000000000 +0200 +++ new/nh3-0.3.5/PKG-INFO 2006-07-24 03:21:28.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.4 Name: nh3 -Version: 0.3.4 +Version: 0.3.5 Classifier: Programming Language :: Rust Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nh3-0.3.4/nh3.pyi new/nh3-0.3.5/nh3.pyi --- old/nh3-0.3.4/nh3.pyi 2006-07-24 03:21:28.000000000 +0200 +++ new/nh3-0.3.5/nh3.pyi 2006-07-24 03:21:28.000000000 +0200 @@ -38,5 +38,5 @@ allowed_classes: Optional[Mapping[str, AbstractSet[str]]] = None, filter_style_properties: Optional[AbstractSet[str]] = None, ) -> str: ... -def clean_text(html: str) -> str: ... +def clean_text(html: str, tags: Optional[AbstractSet[str]] = None) -> str: ... def is_html(html: str) -> bool: ... diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nh3-0.3.4/pyproject.toml new/nh3-0.3.5/pyproject.toml --- old/nh3-0.3.4/pyproject.toml 2006-07-24 03:21:28.000000000 +0200 +++ new/nh3-0.3.5/pyproject.toml 2006-07-24 03:21:28.000000000 +0200 @@ -19,3 +19,7 @@ [tool.maturin] features = ["pyo3/extension-module"] + +[tool.pytest.ini_options] +addopts = "--doctest-glob=*.rst" +testpaths = ["tests", "docs"] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nh3-0.3.4/src/lib.rs new/nh3-0.3.5/src/lib.rs --- old/nh3-0.3.4/src/lib.rs 2006-07-24 03:21:28.000000000 +0200 +++ new/nh3-0.3.5/src/lib.rs 2006-07-24 03:21:28.000000000 +0200 @@ -93,6 +93,17 @@ /// invalid declarations and @rules will be removed, with only syntactically valid /// declarations kept. /// :type filter_style_properties: ``set[str]``, optional +/// +/// Example usage: +/// +/// .. code-block:: pycon +/// +/// >>> import nh3 +/// >>> cleaner = nh3.Cleaner(tags={"b", "i"}, attributes={}) +/// >>> cleaner.clean("<b><i>safe</i></b><script>xss</script>") +/// '<b><i>safe</i></b>' +/// >>> cleaner.clean("<b>another</b> <em>fragment</em>") +/// '<b>another</b> fragment' #[pyclass] pub struct Cleaner { inner: Inner, @@ -345,6 +356,73 @@ /// >>> nh3.clean("<b><img src='' onerror='alert(\\'hax\\')'>XSS?</b>") /// '<b><img src="">XSS?</b>' /// +/// Use ``tags`` to only allow certain HTML tags: +/// +/// .. code-block:: pycon +/// +/// >>> nh3.clean("<b><i>bold italic</i></b>", tags={"b"}) +/// '<b>bold italic</b>' +/// +/// ``clean_content_tags`` removes both the tag and its content, unlike ``tags`` +/// which strips the tag but keeps the text: +/// +/// .. code-block:: pycon +/// +/// >>> nh3.clean( +/// ... "<script>alert('xss')</script>safe", +/// ... clean_content_tags={"script"}, +/// ... ) +/// 'safe' +/// +/// The ``attributes`` parameter controls which attributes are kept per tag. +/// Use ``"*"`` as a key to allow an attribute on all tags: +/// +/// .. code-block:: pycon +/// +/// >>> nh3.clean( +/// ... '<a href="/" id="link">click</a>', +/// ... attributes={"*": {"id"}, "a": {"href"}}, +/// ... ) +/// '<a href="/" id="link" rel="noopener noreferrer">click</a>' +/// +/// ``tag_attribute_values`` restricts an attribute to a set of allowed values, +/// while ``set_tag_attribute_values`` unconditionally adds attributes: +/// +/// .. code-block:: pycon +/// +/// >>> nh3.clean( +/// ... "<div role='alert'>warning</div>", +/// ... tag_attribute_values={"div": {"role": {"alert", "status"}}}, +/// ... ) +/// '<div role="alert">warning</div>' +/// >>> nh3.clean( +/// ... "<div>content</div>", +/// ... set_tag_attribute_values={"div": {"class": "safe"}}, +/// ... ) +/// '<div class="safe">content</div>' +/// +/// ``allowed_classes`` filters CSS class names per tag: +/// +/// .. code-block:: pycon +/// +/// >>> nh3.clean( +/// ... '<span class="highlight bold">text</span>', +/// ... allowed_classes={"span": {"highlight"}}, +/// ... ) +/// '<span class="highlight">text</span>' +/// +/// To filter individual ``style`` properties, first allow the ``style`` +/// attribute, then use ``filter_style_properties``: +/// +/// .. code-block:: pycon +/// +/// >>> nh3.clean( +/// ... '<span style="color: red; position: fixed">text</span>', +/// ... attributes={"span": {"style"}}, +/// ... filter_style_properties={"color"}, +/// ... ) +/// '<span style="color:red">text</span>' +/// /// Example of using ``attribute_filter``: /// /// .. code-block:: pycon @@ -426,12 +504,18 @@ /// Turn an arbitrary string into unformatted HTML. /// -/// Roughly equivalent to Python’s html.escape() or PHP’s htmlspecialchars and +/// Roughly equivalent to Python's html.escape() or PHP's htmlspecialchars and /// htmlentities. Escaping is as strict as possible, encoding every character /// that has special meaning to the HTML parser. /// +/// If ``tags`` is given, those tags are passed through with no attributes; +/// everything else is stripped (content kept). Behaves like :func:`clean` +/// with ``attributes={}`` restricted to the given tag set. +/// /// :param html: Input HTML fragment /// :type html: ``str`` +/// :param tags: Tags to preserve; when omitted the string is fully escaped. +/// :type tags: ``set[str]``, optional /// :return: Cleaned text /// :rtype: ``str`` /// @@ -442,9 +526,23 @@ /// >>> import nh3 /// >>> nh3.clean_text('Robert"); abuse();//') /// 'Robert"); abuse();//' -#[pyfunction] -fn clean_text(py: Python, html: &str) -> String { - py.detach(|| ammonia::clean_text(html)) +/// >>> nh3.clean_text('<span>hello <mention>moto</mention>!</span>', tags={'mention'}) +/// 'hello <mention>moto</mention>!' +#[pyfunction(signature = (html, tags = None))] +fn clean_text(py: Python, html: &str, tags: Option<HashSet<String>>) -> String { + match tags { + None => py.detach(|| ammonia::clean_text(html)), + Some(tags) => { + let config = Config { + tags: Some(tags), + attributes: Some(HashMap::new()), + link_rel: None, + ..Default::default() + }; + let cleaner = Cleaner::new(config); + py.detach(|| cleaner.clean(html)) + } + } } /// Determine if a given string contains HTML. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nh3-0.3.4/tests/test_doctests.py new/nh3-0.3.5/tests/test_doctests.py --- old/nh3-0.3.4/tests/test_doctests.py 1970-01-01 01:00:00.000000000 +0100 +++ new/nh3-0.3.5/tests/test_doctests.py 2006-07-24 03:21:28.000000000 +0200 @@ -0,0 +1,17 @@ +import doctest + +import nh3 + + +def test_docstrings(): + finder = doctest.DocTestFinder() + runner = doctest.DocTestRunner(verbose=False) + globs = {"nh3": nh3} + for name in ["clean", "clean_text", "is_html"]: + obj = getattr(nh3, name) + for test in finder.find(obj, f"nh3.{name}"): + if test.examples: + test.globs.update(globs) + runner.run(test) + results = runner.summarize(verbose=False) + assert results.failed == 0, f"{results.failed} doctest(s) failed" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nh3-0.3.4/tests/test_nh3.py new/nh3-0.3.5/tests/test_nh3.py --- old/nh3-0.3.4/tests/test_nh3.py 2006-07-24 03:21:28.000000000 +0200 +++ new/nh3-0.3.5/tests/test_nh3.py 2006-07-24 03:21:28.000000000 +0200 @@ -134,6 +134,21 @@ res = nh3.clean_text('Robert"); abuse();//') assert res == "Robert"); abuse();//" + res = nh3.clean_text( + '<span>hello <mention>moto</mention>, welcome!</span>', + tags={'mention'}, + ) + assert res == 'hello <mention>moto</mention>, welcome!' + + res = nh3.clean_text('<b>bold</b> and <i>italic</i>', tags={'b'}) + assert res == '<b>bold</b> and italic' + + res = nh3.clean_text( + "<a href='http://example.com' rel='nofollow'>test</a>", + tags={'a'}, + ) + assert res == '<a>test</a>' + def test_clean_content_tags_constant(): assert isinstance(nh3.CLEAN_CONTENT_TAGS, set) ++++++ vendor.tar.zst ++++++ ++++ 378957 lines of diff (skipped)
