media_type_version-0.2.1/.readthedocs.yaml0000644000000000000000000000044113615410400015545 0ustar00# SPDX-FileCopyrightText: Peter Pentchev # SPDX-License-Identifier: BSD-2-Clause version: 2 build: os: ubuntu-22.04 tools: python: "3.12" mkdocs: configuration: mkdocs.yml python: install: - requirements: python/requirements/docs.txt media_type_version-0.2.1/Cargo.lock0000644000000000000000000013141613615410400014232 0ustar00# This file is automatically @generated by Cargo. # It is not intended for manual editing. version = 4 [[package]] name = "android_system_properties" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" dependencies = [ "libc", ] [[package]] name = "anstream" version = "0.6.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" [[package]] name = "anstyle-parse" version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ "windows-sys 0.61.2", ] [[package]] name = "anstyle-wincon" version = "3.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", "once_cell_polyfill", "windows-sys 0.61.2", ] [[package]] name = "anyhow" version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "argh" version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34ff18325c8a36b82f992e533ece1ec9f9a9db446bd1c14d4f936bac88fcd240" dependencies = [ "argh_derive", "argh_shared", "rust-fuzzy-search", ] [[package]] name = "argh_derive" version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adb7b2b83a50d329d5d8ccc620f5c7064028828538bdf5646acd60dc1f767803" dependencies = [ "argh_shared", "proc-macro2", "quote", "syn", ] [[package]] name = "argh_shared" version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a464143cc82dedcdc3928737445362466b7674b5db4e2eb8e869846d6d84f4f6" [[package]] name = "autocfg" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "bitflags" version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" [[package]] name = "boml" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a96d68a303a5dd009292d8fea60bf27916d734d6841b53a53c685ad80182526d" [[package]] name = "bumpalo" version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" [[package]] name = "byteorder" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" [[package]] name = "camino" version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e629a66d692cb9ff1a1c664e41771b3dcaf961985a9774c0eb0bd1b51cf60a48" [[package]] name = "cc" version = "1.2.50" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f50d563227a1c37cc0a263f64eca3334388c01c5e4c4861a9def205c614383c" dependencies = [ "find-msvc-tools", "shlex", ] [[package]] name = "cfg-if" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "chrono" version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" dependencies = [ "iana-time-zone", "num-traits", "windows-link", ] [[package]] name = "clap" version = "4.5.53" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" version = "4.5.53" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" dependencies = [ "anstream", "anstyle", "clap_lex", "strsim", ] [[package]] name = "clap_derive" version = "4.5.49" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" dependencies = [ "heck", "proc-macro2", "quote", "syn", ] [[package]] name = "clap_lex" version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" [[package]] name = "colorchoice" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" [[package]] name = "core-foundation-sys" version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "deranged" version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" dependencies = [ "powerfmt", ] [[package]] name = "displaydoc" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "either" version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "equivalent" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", "windows-sys 0.61.2", ] [[package]] name = "eyre" version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" dependencies = [ "indenter", "once_cell", ] [[package]] name = "facet" version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f2eff8d6840932e1fbd7c4fc80a0521ab303323ea31ec341ea185384c3b1383" dependencies = [ "facet-core 0.30.0", "facet-macros 0.30.0", "static_assertions", ] [[package]] name = "facet" version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e16908c1c614bd11635c37fc22e10ba6273ac987d253c8eef4dd331697982e03" dependencies = [ "autocfg", "facet-core 0.32.3", "facet-macros 0.32.3", "static_assertions", ] [[package]] name = "facet-core" version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c80a6e22351f448828529adf1be52f3037c99ac831bcf3fb9a0df2d5c273df8a" dependencies = [ "bitflags", "impls", ] [[package]] name = "facet-core" version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56d1f4584a9378cc7b8598ffa3cd63b169fe9b89a262e90db8a4e2e607fd2e0e" dependencies = [ "autocfg", "bytes", "chrono", "impls", "indexmap", "jiff", "num-complex", "ordered-float", "ruint", "time", "ulid", "url", "uuid", ] [[package]] name = "facet-macro-parse" version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa4483074a9ece385a103b2d3c6eadcd3cf9f9763d5d281a52d9ef70f78e2e26" dependencies = [ "facet-macro-types", "proc-macro2", "quote", ] [[package]] name = "facet-macro-types" version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "522838218ea4b979d2b5db42cc03f23516823ce66ccfcb8c23b2b52b01bc77d8" dependencies = [ "proc-macro2", "quote", "unsynn 0.3.0", ] [[package]] name = "facet-macros" version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a8c1da45a93b10c5829601e19846c7f13d8cde6e0b65740fee5ea51f96d7d7e" dependencies = [ "facet-core 0.30.0", "facet-macros-emit", ] [[package]] name = "facet-macros" version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9083e8ff729fdc6145573c46649b99efbff06046817ac38f09e4b45967bd8c7d" dependencies = [ "facet-macros-impl", ] [[package]] name = "facet-macros-emit" version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "561cd90d2074ce22cb0ea0a4c4395779efd03f9b4d1a2712369b0a63ddd5cfbf" dependencies = [ "facet-macros-parse", "quote", ] [[package]] name = "facet-macros-impl" version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac43634853b8eb0867c4abbfa055b9242283bba40b2f867d908ad790283da4ab" dependencies = [ "facet-macro-parse", "facet-macro-types", "proc-macro2", "quote", "unsynn 0.3.0", ] [[package]] name = "facet-macros-parse" version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b88ddf668029af6fec4d3e3baaedc82f63667416a0e4b2487226212f70b53af9" dependencies = [ "proc-macro2", "quote", "unsynn 0.1.1", ] [[package]] name = "facet-pretty" version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1cfdcb9a0b55c6749bef2c0106ed015ee9269db117e4673ff527ed22ad18f77c" dependencies = [ "facet-core 0.30.0", "facet-reflect 0.30.0", ] [[package]] name = "facet-pretty" version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b79f81421b3b6000e4b3650fd297c49aba0e21801a2eacd604efaff3d12c8e88" dependencies = [ "facet-core 0.32.3", "facet-reflect 0.32.3", "owo-colors", ] [[package]] name = "facet-reflect" version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b6f7fd53a74e86e32b772f9c9f1b2d50027fc569eff75a2c72751d8e3cef9e3" dependencies = [ "bitflags", "facet-core 0.30.0", ] [[package]] name = "facet-reflect" version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aeba20f942e99979dcd0582dea2b935acc0341183cb0c2df7047e0e759fec2e6" dependencies = [ "facet-core 0.32.3", "miette", ] [[package]] name = "facet-testhelpers" version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6829a37eabb0cdfc63bc964b4ca71ff0bdbc8ccdbac3c94b363bdeb9d1e97bf0" dependencies = [ "facet-testhelpers-macros", "log", "owo-colors", ] [[package]] name = "facet-testhelpers-macros" version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bf6b79f5e6deac4aad51c985b4fb8f7fad8bacd47d9d387790868bc52331ff7" dependencies = [ "quote", "unsynn 0.3.0", ] [[package]] name = "fastrand" version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "feature-check" version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50f25808e6cdda5762fd5c643d40ce23eed16b9b28d6c6d201a8054a207662f6" dependencies = [ "anyhow", "clap", "clap_derive", "nom", "serde", "serde_derive", "serde_json", "thiserror", ] [[package]] name = "find-msvc-tools" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" [[package]] name = "form_urlencoded" version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" dependencies = [ "percent-encoding", ] [[package]] name = "fxhash" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" dependencies = [ "byteorder", ] [[package]] name = "getrandom" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "libc", "r-efi", "wasip2", ] [[package]] name = "hashbrown" version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" [[package]] name = "heck" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "iana-time-zone" version = "0.1.64" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "log", "wasm-bindgen", "windows-core", ] [[package]] name = "iana-time-zone-haiku" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" dependencies = [ "cc", ] [[package]] name = "icu_collections" version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" dependencies = [ "displaydoc", "potential_utf", "yoke", "zerofrom", "zerovec", ] [[package]] name = "icu_locale_core" version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" dependencies = [ "displaydoc", "litemap", "tinystr", "writeable", "zerovec", ] [[package]] name = "icu_normalizer" version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" dependencies = [ "icu_collections", "icu_normalizer_data", "icu_properties", "icu_provider", "smallvec", "zerovec", ] [[package]] name = "icu_normalizer_data" version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" [[package]] name = "icu_properties" version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" dependencies = [ "icu_collections", "icu_locale_core", "icu_properties_data", "icu_provider", "zerotrie", "zerovec", ] [[package]] name = "icu_properties_data" version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" [[package]] name = "icu_provider" version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" dependencies = [ "displaydoc", "icu_locale_core", "writeable", "yoke", "zerofrom", "zerotrie", "zerovec", ] [[package]] name = "idna" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" dependencies = [ "idna_adapter", "smallvec", "utf8_iter", ] [[package]] name = "idna_adapter" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" dependencies = [ "icu_normalizer", "icu_properties", ] [[package]] name = "impls" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a46645bbd70538861a90d0f26c31537cdf1e44aae99a794fb75a664b70951bc" [[package]] name = "indenter" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5" [[package]] name = "indexmap" version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" dependencies = [ "equivalent", "hashbrown", ] [[package]] name = "is_ci" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7655c9839580ee829dfacba1d1278c2b7883e50a277ff7541299489d6bdfdc45" [[package]] name = "is_terminal_polyfill" version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" [[package]] name = "itertools" version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" dependencies = [ "either", ] [[package]] name = "itoa" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jiff" version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49cce2b81f2098e7e3efc35bc2e0a6b7abec9d34128283d7a26fa8f32a6dbb35" dependencies = [ "jiff-static", "jiff-tzdb-platform", "log", "portable-atomic", "portable-atomic-util", "serde_core", "windows-sys 0.61.2", ] [[package]] name = "jiff-static" version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "980af8b43c3ad5d8d349ace167ec8170839f753a42d233ba19e08afe1850fa69" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "jiff-tzdb" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68971ebff725b9e2ca27a601c5eb38a4c5d64422c4cbab0c535f248087eda5c2" [[package]] name = "jiff-tzdb-platform" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "875a5a69ac2bab1a891711cf5eccbec1ce0341ea805560dcd90b7a2e925132e8" dependencies = [ "jiff-tzdb", ] [[package]] name = "js-sys" version = "0.3.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" dependencies = [ "once_cell", "wasm-bindgen", ] [[package]] name = "libc" version = "0.2.178" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" [[package]] name = "libm" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "linux-raw-sys" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" [[package]] name = "litemap" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" [[package]] name = "log" version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "media-type-version" version = "0.2.1" dependencies = [ "boml", "eyre", "facet 0.30.0", "facet 0.32.3", "facet-pretty 0.30.0", "facet-pretty 0.32.3", "facet-testhelpers", "log", "serialzero", ] [[package]] name = "memchr" version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "miette" version = "7.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f98efec8807c63c752b5bd61f862c165c115b0a35685bdcfd9238c7aeb592b7" dependencies = [ "cfg-if", "miette-derive", "owo-colors", "supports-color", "supports-hyperlinks", "supports-unicode", "terminal_size", "textwrap", "unicode-width 0.1.14", ] [[package]] name = "miette-derive" version = "7.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db5b29714e950dbb20d5e6f74f9dcec4edbcc1067bb7f8ed198c097b8c1a818b" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "mtv-extract" version = "0.2.1" dependencies = [ "argh", "boml", "camino", "eyre", "facet-testhelpers", "feature-check", "itertools", "log", "media-type-version", "serialzero", "simple_logger", "tempfile", ] [[package]] name = "mutants" version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc0287524726960e07b119cebd01678f852f147742ae0d925e6a520dca956126" [[package]] name = "nom" version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df9761775871bdef83bee530e60050f7e54b1105350d6884eb0fb4f46c2f9405" dependencies = [ "memchr", ] [[package]] name = "num-complex" version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" dependencies = [ "num-traits", ] [[package]] name = "num-conv" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" [[package]] name = "num-traits" version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", "libm", ] [[package]] name = "once_cell" version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "once_cell_polyfill" version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] name = "ordered-float" version = "5.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f4779c6901a562440c3786d08192c6fbda7c1c2060edd10006b05ee35d10f2d" dependencies = [ "num-traits", ] [[package]] name = "owo-colors" version = "4.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c6901729fa79e91a0913333229e9ca5dc725089d1c363b2f4b4760709dc4a52" [[package]] name = "percent-encoding" version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "portable-atomic" version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f59e70c4aef1e55797c2e8fd94a4f2a973fc972cfde0e0b05f683667b0cd39dd" [[package]] name = "portable-atomic-util" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" dependencies = [ "portable-atomic", ] [[package]] name = "potential_utf" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" dependencies = [ "zerovec", ] [[package]] name = "powerfmt" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ "zerocopy", ] [[package]] name = "proc-macro2" version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" dependencies = [ "unicode-ident", ] [[package]] name = "proptest" version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bee689443a2bd0a16ab0348b52ee43e3b2d1b1f931c8aa5c9f8de4c86fbe8c40" dependencies = [ "bitflags", "num-traits", "rand 0.9.2", "rand_chacha", "rand_xorshift", "unarray", ] [[package]] name = "quote" version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" dependencies = [ "proc-macro2", ] [[package]] name = "r-efi" version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] name = "rand" version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "rand_core 0.6.4", ] [[package]] name = "rand" version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ "rand_chacha", "rand_core 0.9.3", ] [[package]] name = "rand_chacha" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", "rand_core 0.9.3", ] [[package]] name = "rand_core" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" [[package]] name = "rand_core" version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ "getrandom", ] [[package]] name = "rand_xorshift" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a" dependencies = [ "rand_core 0.9.3", ] [[package]] name = "ruint" version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a68df0380e5c9d20ce49534f292a36a7514ae21350726efe1865bdb1fa91d278" dependencies = [ "proptest", "rand 0.8.5", "rand 0.9.2", "ruint-macro", "serde_core", "valuable", "zeroize", ] [[package]] name = "ruint-macro" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" [[package]] name = "rust-fuzzy-search" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a157657054ffe556d8858504af8a672a054a6e0bd9e8ee531059100c0fa11bb2" [[package]] name = "rustc-hash" version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" [[package]] name = "rustix" version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ "bitflags", "errno", "libc", "linux-raw-sys", "windows-sys 0.61.2", ] [[package]] name = "rustversion" version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "ryu" version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "serde" version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" dependencies = [ "serde_core", ] [[package]] name = "serde_core" version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "serde_json" version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" dependencies = [ "itoa", "memchr", "ryu", "serde", "serde_core", ] [[package]] name = "serialzero" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fea17e6fe863e123c0858081987e38d93d0ed0bf460d7e6edec24a016695bcb" [[package]] name = "shadow_counted" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "65da48d447333cebe1aadbdd3662f3ba56e76e67f53bc46f3dd5f67c74629d6b" [[package]] name = "shlex" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "simple_logger" version = "5.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "291bee647ce7310b0ea721bfd7e0525517b4468eb7c7e15eb8bd774343179702" dependencies = [ "log", "windows-sys 0.61.2", ] [[package]] name = "smallvec" version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "stable_deref_trait" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "static_assertions" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "strsim" version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "supports-color" version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c64fc7232dd8d2e4ac5ce4ef302b1d81e0b80d055b9d77c7c4f51f6aa4c867d6" dependencies = [ "is_ci", ] [[package]] name = "supports-hyperlinks" version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e396b6523b11ccb83120b115a0b7366de372751aa6edf19844dfb13a6af97e91" [[package]] name = "supports-unicode" version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7401a30af6cb5818bb64852270bb722533397edcfc7344954a38f420819ece2" [[package]] name = "syn" version = "2.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] [[package]] name = "synstructure" version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "tempfile" version = "3.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" dependencies = [ "fastrand", "getrandom", "once_cell", "rustix", "windows-sys 0.61.2", ] [[package]] name = "terminal_size" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60b8cb979cb11c32ce1603f8137b22262a9d131aaa5c37b5678025f22b8becd0" dependencies = [ "rustix", "windows-sys 0.60.2", ] [[package]] name = "textwrap" version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c13547615a44dc9c452a8a534638acdf07120d4b6847c8178705da06306a3057" dependencies = [ "unicode-linebreak", "unicode-width 0.2.2", ] [[package]] name = "thiserror" version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "time" version = "0.3.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" dependencies = [ "deranged", "itoa", "num-conv", "powerfmt", "serde", "time-core", "time-macros", ] [[package]] name = "time-core" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" [[package]] name = "time-macros" version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" dependencies = [ "num-conv", "time-core", ] [[package]] name = "tinystr" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" dependencies = [ "displaydoc", "zerovec", ] [[package]] name = "ulid" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "470dbf6591da1b39d43c14523b2b469c86879a53e8b758c8e090a470fe7b1fbe" dependencies = [ "rand 0.9.2", "web-time", ] [[package]] name = "unarray" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" [[package]] name = "unicode-ident" version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" [[package]] name = "unicode-linebreak" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" [[package]] name = "unicode-width" version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] name = "unicode-width" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" [[package]] name = "unsynn" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7940603a9e25cf11211cc43b81f4fcad2b8ab4df291ca855f32c40e1ac22d5bc" dependencies = [ "fxhash", "mutants", "proc-macro2", "shadow_counted", ] [[package]] name = "unsynn" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "501a7adf1a4bd9951501e5c66621e972ef8874d787628b7f90e64f936ef7ec0a" dependencies = [ "mutants", "proc-macro2", "rustc-hash", ] [[package]] name = "url" version = "2.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" dependencies = [ "form_urlencoded", "idna", "percent-encoding", ] [[package]] name = "utf8_iter" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "utf8parse" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" dependencies = [ "js-sys", "wasm-bindgen", ] [[package]] name = "valuable" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" [[package]] name = "wasip2" version = "1.0.1+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" dependencies = [ "wit-bindgen", ] [[package]] name = "wasm-bindgen" version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" dependencies = [ "cfg-if", "once_cell", "rustversion", "wasm-bindgen-macro", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" dependencies = [ "quote", "wasm-bindgen-macro-support", ] [[package]] name = "wasm-bindgen-macro-support" version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" dependencies = [ "bumpalo", "proc-macro2", "quote", "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" dependencies = [ "unicode-ident", ] [[package]] name = "web-time" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" dependencies = [ "js-sys", "wasm-bindgen", ] [[package]] name = "windows-core" version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ "windows-implement", "windows-interface", "windows-link", "windows-result", "windows-strings", ] [[package]] name = "windows-implement" version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "windows-interface" version = "0.59.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "windows-link" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] name = "windows-result" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" dependencies = [ "windows-link", ] [[package]] name = "windows-strings" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" dependencies = [ "windows-link", ] [[package]] name = "windows-sys" version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ "windows-targets", ] [[package]] name = "windows-sys" version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ "windows-link", ] [[package]] name = "windows-targets" version = "0.53.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" dependencies = [ "windows-link", "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.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" [[package]] name = "windows_aarch64_msvc" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" [[package]] name = "windows_i686_gnu" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" [[package]] name = "windows_i686_gnullvm" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" [[package]] name = "windows_i686_msvc" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" [[package]] name = "windows_x86_64_gnu" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" [[package]] name = "windows_x86_64_gnullvm" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" [[package]] name = "windows_x86_64_msvc" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "wit-bindgen" version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" [[package]] name = "writeable" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" [[package]] name = "yoke" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" dependencies = [ "stable_deref_trait", "yoke-derive", "zerofrom", ] [[package]] name = "yoke-derive" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", "syn", "synstructure", ] [[package]] name = "zerocopy" version = "0.8.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" version = "0.8.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "zerofrom" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", "syn", "synstructure", ] [[package]] name = "zeroize" version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" [[package]] name = "zerotrie" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" dependencies = [ "displaydoc", "yoke", "zerofrom", ] [[package]] name = "zerovec" version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" dependencies = [ "yoke", "zerofrom", "zerovec-derive", ] [[package]] name = "zerovec-derive" version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", "syn", ] media_type_version-0.2.1/Cargo.toml0000644000000000000000000000030113615410400014241 0ustar00# SPDX-FileCopyrightText: Peter Pentchev # SPDX-License-Identifier: BSD-2-Clause [workspace] resolver = "3" members = [ "rust/media-type-version", "rust/mtv-extract", ] media_type_version-0.2.1/REUSE.toml0000644000000000000000000000073513615410400014104 0ustar00# SPDX-FileCopyrightText: Peter Pentchev # SPDX-License-Identifier: BSD-2-Clause version = 1 SPDX-PackageName = "media-type-version" SPDX-PackageSupplier = "Peter Pentchev " SPDX-PackageDownloadLocation = "https://gitlab.com/ppentchev/media-type-version" [[annotations]] path = [ "Cargo.lock", "uv.lock", ] precedence = "aggregate" SPDX-FileCopyrightText = "Peter Pentchev " SPDX-License-Identifier = "BSD-2-Clause" media_type_version-0.2.1/mkdocs.yml0000644000000000000000000000243613615410400014327 0ustar00# SPDX-FileCopyrightText: Peter Pentchev # SPDX-License-Identifier: BSD-2-Clause theme: name: material features: - navigation.instant - navigation.tracking - toc.integrate - toc.follow - content.code.copy palette: - media: "(prefers-color-scheme: light)" scheme: default toggle: icon: material/weather-sunny name: Switch to dark mode - media: "(prefers-color-scheme: dark)" scheme: slate toggle: icon: material/weather-night name: Switch to light mode site_name: media-type-version repo_url: https://gitlab.com/ppentchev/media-type-version repo_name: media-type-version site_author: ppentchev site_url: https://devel.ringlet.net/devel/media-type-version/ site_dir: site/docs nav: - 'index.md' - 'Changelog': 'changes.md' - 'Download': 'download.md' - 'API reference': - 'Python': 'api/python.md' markdown_extensions: - toc: - pymdownx.highlight: anchor_linenums: true - pymdownx.inlinehilite: - pymdownx.superfences: plugins: - mkdocstrings: default_handler: python handlers: python: paths: [python/src] options: heading_level: 3 show_root_heading: true - search watch: - 'python/src/media_type_version' media_type_version-0.2.1/tox.ini0000644000000000000000000000431013615410400013630 0ustar00# SPDX-FileCopyrightText: Peter Pentchev # SPDX-License-Identifier: BSD-2-Clause [tox] minversion = 4.22 envlist = ruff format reuse uvoxen-sync-check ty mypy unit-tests unit-tests-cli docs isolated_build = True [defs] pyfiles = python/src/media_type_version \ python/tests/unit [testenv:ruff] skip_install = True tags = check quick dependency_groups = testenv-ruff commands = ruff check -- {[defs]pyfiles} [testenv:format] skip_install = True tags = check quick dependency_groups = testenv-ruff commands = ruff check --config python/ruff-base.toml --select=D,I --diff -- {[defs]pyfiles} ruff format --config python/ruff-base.toml --check --diff -- {[defs]pyfiles} [testenv:reformat] skip_install = True tags = format manual dependency_groups = testenv-ruff commands = ruff check --config python/ruff-base.toml --select=D,I --fix -- {[defs]pyfiles} ruff format --config python/ruff-base.toml -- {[defs]pyfiles} [testenv:docs] skip_install = True tags = docs dependency_groups = docs commands = mkdocs build [testenv:mypy] tags = check dependency_groups = testenv-mypy commands = mypy {[defs]pyfiles} [testenv:pyupgrade] skip_install = True tags = check manual dependency_groups = testenv-pyupgrade allowlist_externals = sh commands = sh -c 'pyupgrade --py311-plus python/src/media_type_version/*.py python/tests/unit/*.py' [testenv:reuse] skip_install = True tags = check quick dependency_groups = testenv-reuse commands = reuse lint [testenv:ty] tags = check quick dependency_groups = testenv-ty commands = ty check -- {[defs]pyfiles} [testenv:unit-tests] tags = tests dependency_groups = testenv-unit-tests commands = pytest --strict --ignore python/tests/unit/test_prog.py {posargs} python/tests/unit [testenv:unit-tests-cli] tags = tests dependency_groups = testenv-unit-tests-cli passenv = RUST_LOG TEST_MTV_EXTRACT_PROG commands = pytest --strict -k 'test_prog.py' {posargs} python/tests/unit [testenv:uvoxen-sync-check] tags = check quick dependency_groups = testenv-uvoxen commands = uvoxen req generate -o python/requirements/docs.txt --check --diff -g docs uvoxen tox generate --check --diff media_type_version-0.2.1/uv.lock0000644000000000000000000045702413615410400013637 0ustar00version = 1 revision = 3 requires-python = ">=3.11" resolution-markers = [ "python_full_version >= '3.13'", "python_full_version < '3.13'", ] [[package]] name = "attrs" version = "25.4.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/6b/5c/685e6633917e101e5dcb62b9dd76946cbb57c26e133bae9e0cd36033c0a9/attrs-25.4.0.tar.gz", hash = "sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11", size = 934251, upload-time = "2025-10-06T13:54:44.725Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl", hash = "sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373", size = 67615, upload-time = "2025-10-06T13:54:43.17Z" }, ] [[package]] name = "babel" version = "2.17.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/7d/6b/d52e42361e1aa00709585ecc30b3f9684b3ab62530771402248b1b1d6240/babel-2.17.0.tar.gz", hash = "sha256:0c54cffb19f690cdcc52a3b50bcbf71e07a808d1c80d549f2459b9d2cf0afb9d", size = 9951852, upload-time = "2025-02-01T15:17:41.026Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl", hash = "sha256:4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2", size = 10182537, upload-time = "2025-02-01T15:17:37.39Z" }, ] [[package]] name = "backrefs" version = "6.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/86/e3/bb3a439d5cb255c4774724810ad8073830fac9c9dee123555820c1bcc806/backrefs-6.1.tar.gz", hash = "sha256:3bba1749aafe1db9b915f00e0dd166cba613b6f788ffd63060ac3485dc9be231", size = 7011962, upload-time = "2025-11-15T14:52:08.323Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/3b/ee/c216d52f58ea75b5e1841022bbae24438b19834a29b163cb32aa3a2a7c6e/backrefs-6.1-py310-none-any.whl", hash = "sha256:2a2ccb96302337ce61ee4717ceacfbf26ba4efb1d55af86564b8bbaeda39cac1", size = 381059, upload-time = "2025-11-15T14:51:59.758Z" }, { url = "https://files.pythonhosted.org/packages/e6/9a/8da246d988ded941da96c7ed945d63e94a445637eaad985a0ed88787cb89/backrefs-6.1-py311-none-any.whl", hash = "sha256:e82bba3875ee4430f4de4b6db19429a27275d95a5f3773c57e9e18abc23fd2b7", size = 392854, upload-time = "2025-11-15T14:52:01.194Z" }, { url = "https://files.pythonhosted.org/packages/37/c9/fd117a6f9300c62bbc33bc337fd2b3c6bfe28b6e9701de336b52d7a797ad/backrefs-6.1-py312-none-any.whl", hash = "sha256:c64698c8d2269343d88947c0735cb4b78745bd3ba590e10313fbf3f78c34da5a", size = 398770, upload-time = "2025-11-15T14:52:02.584Z" }, { url = "https://files.pythonhosted.org/packages/eb/95/7118e935b0b0bd3f94dfec2d852fd4e4f4f9757bdb49850519acd245cd3a/backrefs-6.1-py313-none-any.whl", hash = "sha256:4c9d3dc1e2e558965202c012304f33d4e0e477e1c103663fd2c3cc9bb18b0d05", size = 400726, upload-time = "2025-11-15T14:52:04.093Z" }, { url = "https://files.pythonhosted.org/packages/1d/72/6296bad135bfafd3254ae3648cd152980a424bd6fed64a101af00cc7ba31/backrefs-6.1-py314-none-any.whl", hash = "sha256:13eafbc9ccd5222e9c1f0bec563e6d2a6d21514962f11e7fc79872fd56cbc853", size = 412584, upload-time = "2025-11-15T14:52:05.233Z" }, { url = "https://files.pythonhosted.org/packages/02/e3/a4fa1946722c4c7b063cc25043a12d9ce9b4323777f89643be74cef2993c/backrefs-6.1-py39-none-any.whl", hash = "sha256:a9e99b8a4867852cad177a6430e31b0f6e495d65f8c6c134b68c14c3c95bf4b0", size = 381058, upload-time = "2025-11-15T14:52:06.698Z" }, ] [[package]] name = "boolean-py" version = "5.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/c4/cf/85379f13b76f3a69bca86b60237978af17d6aa0bc5998978c3b8cf05abb2/boolean_py-5.0.tar.gz", hash = "sha256:60cbc4bad079753721d32649545505362c754e121570ada4658b852a3a318d95", size = 37047, upload-time = "2025-04-03T10:39:49.734Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/e5/ca/78d423b324b8d77900030fa59c4aa9054261ef0925631cd2501dd015b7b7/boolean_py-5.0-py3-none-any.whl", hash = "sha256:ef28a70bd43115208441b53a045d1549e2f0ec6e3d08a9d142cbc41c1938e8d9", size = 26577, upload-time = "2025-04-03T10:39:48.449Z" }, ] [[package]] name = "cappa" version = "0.30.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "rich" }, { name = "type-lens" }, { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/3a/f0/6ed2611b352f1e7040e1d9f579acd758be88463a32b07293c5dcf749c656/cappa-0.30.4.tar.gz", hash = "sha256:06870e8cd67636039d0c134dae7a88fe2a383e13fd3310fe5c36fd5c7eed6d52", size = 319263, upload-time = "2025-10-30T13:22:17.459Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/37/8a/4220ff1b14233d2fd7a09b601c5212356fd968d7db96cfb1bced33e18ada/cappa-0.30.4-py3-none-any.whl", hash = "sha256:9921f888e74f4af1421c5bd9368ff9c50dbf243c519246c6f79c2a536288f180", size = 68604, upload-time = "2025-10-30T13:22:15.717Z" }, ] [[package]] name = "certifi" version = "2025.11.12" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/a2/8c/58f469717fa48465e4a50c014a0400602d3c437d7c0c468e17ada824da3a/certifi-2025.11.12.tar.gz", hash = "sha256:d8ab5478f2ecd78af242878415affce761ca6bc54a22a27e026d7c25357c3316", size = 160538, upload-time = "2025-11-12T02:54:51.517Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/70/7d/9bc192684cea499815ff478dfcdc13835ddf401365057044fb721ec6bddb/certifi-2025.11.12-py3-none-any.whl", hash = "sha256:97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b", size = 159438, upload-time = "2025-11-12T02:54:49.735Z" }, ] [[package]] name = "charset-normalizer" version = "3.4.4" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/13/69/33ddede1939fdd074bce5434295f38fae7136463422fe4fd3e0e89b98062/charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a", size = 129418, upload-time = "2025-10-14T04:42:32.879Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/ed/27/c6491ff4954e58a10f69ad90aca8a1b6fe9c5d3c6f380907af3c37435b59/charset_normalizer-3.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6e1fcf0720908f200cd21aa4e6750a48ff6ce4afe7ff5a79a90d5ed8a08296f8", size = 206988, upload-time = "2025-10-14T04:40:33.79Z" }, { url = "https://files.pythonhosted.org/packages/94/59/2e87300fe67ab820b5428580a53cad894272dbb97f38a7a814a2a1ac1011/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f819d5fe9234f9f82d75bdfa9aef3a3d72c4d24a6e57aeaebba32a704553aa0", size = 147324, upload-time = "2025-10-14T04:40:34.961Z" }, { url = "https://files.pythonhosted.org/packages/07/fb/0cf61dc84b2b088391830f6274cb57c82e4da8bbc2efeac8c025edb88772/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a59cb51917aa591b1c4e6a43c132f0cdc3c76dbad6155df4e28ee626cc77a0a3", size = 142742, upload-time = "2025-10-14T04:40:36.105Z" }, { url = "https://files.pythonhosted.org/packages/62/8b/171935adf2312cd745d290ed93cf16cf0dfe320863ab7cbeeae1dcd6535f/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8ef3c867360f88ac904fd3f5e1f902f13307af9052646963ee08ff4f131adafc", size = 160863, upload-time = "2025-10-14T04:40:37.188Z" }, { url = "https://files.pythonhosted.org/packages/09/73/ad875b192bda14f2173bfc1bc9a55e009808484a4b256748d931b6948442/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d9e45d7faa48ee908174d8fe84854479ef838fc6a705c9315372eacbc2f02897", size = 157837, upload-time = "2025-10-14T04:40:38.435Z" }, { url = "https://files.pythonhosted.org/packages/6d/fc/de9cce525b2c5b94b47c70a4b4fb19f871b24995c728e957ee68ab1671ea/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:840c25fb618a231545cbab0564a799f101b63b9901f2569faecd6b222ac72381", size = 151550, upload-time = "2025-10-14T04:40:40.053Z" }, { url = "https://files.pythonhosted.org/packages/55/c2/43edd615fdfba8c6f2dfbd459b25a6b3b551f24ea21981e23fb768503ce1/charset_normalizer-3.4.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ca5862d5b3928c4940729dacc329aa9102900382fea192fc5e52eb69d6093815", size = 149162, upload-time = "2025-10-14T04:40:41.163Z" }, { url = "https://files.pythonhosted.org/packages/03/86/bde4ad8b4d0e9429a4e82c1e8f5c659993a9a863ad62c7df05cf7b678d75/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d9c7f57c3d666a53421049053eaacdd14bbd0a528e2186fcb2e672effd053bb0", size = 150019, upload-time = "2025-10-14T04:40:42.276Z" }, { url = "https://files.pythonhosted.org/packages/1f/86/a151eb2af293a7e7bac3a739b81072585ce36ccfb4493039f49f1d3cae8c/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:277e970e750505ed74c832b4bf75dac7476262ee2a013f5574dd49075879e161", size = 143310, upload-time = "2025-10-14T04:40:43.439Z" }, { url = "https://files.pythonhosted.org/packages/b5/fe/43dae6144a7e07b87478fdfc4dbe9efd5defb0e7ec29f5f58a55aeef7bf7/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:31fd66405eaf47bb62e8cd575dc621c56c668f27d46a61d975a249930dd5e2a4", size = 162022, upload-time = "2025-10-14T04:40:44.547Z" }, { url = "https://files.pythonhosted.org/packages/80/e6/7aab83774f5d2bca81f42ac58d04caf44f0cc2b65fc6db2b3b2e8a05f3b3/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:0d3d8f15c07f86e9ff82319b3d9ef6f4bf907608f53fe9d92b28ea9ae3d1fd89", size = 149383, upload-time = "2025-10-14T04:40:46.018Z" }, { url = "https://files.pythonhosted.org/packages/4f/e8/b289173b4edae05c0dde07f69f8db476a0b511eac556dfe0d6bda3c43384/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:9f7fcd74d410a36883701fafa2482a6af2ff5ba96b9a620e9e0721e28ead5569", size = 159098, upload-time = "2025-10-14T04:40:47.081Z" }, { url = "https://files.pythonhosted.org/packages/d8/df/fe699727754cae3f8478493c7f45f777b17c3ef0600e28abfec8619eb49c/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ebf3e58c7ec8a8bed6d66a75d7fb37b55e5015b03ceae72a8e7c74495551e224", size = 152991, upload-time = "2025-10-14T04:40:48.246Z" }, { url = "https://files.pythonhosted.org/packages/1a/86/584869fe4ddb6ffa3bd9f491b87a01568797fb9bd8933f557dba9771beaf/charset_normalizer-3.4.4-cp311-cp311-win32.whl", hash = "sha256:eecbc200c7fd5ddb9a7f16c7decb07b566c29fa2161a16cf67b8d068bd21690a", size = 99456, upload-time = "2025-10-14T04:40:49.376Z" }, { url = "https://files.pythonhosted.org/packages/65/f6/62fdd5feb60530f50f7e38b4f6a1d5203f4d16ff4f9f0952962c044e919a/charset_normalizer-3.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:5ae497466c7901d54b639cf42d5b8c1b6a4fead55215500d2f486d34db48d016", size = 106978, upload-time = "2025-10-14T04:40:50.844Z" }, { url = "https://files.pythonhosted.org/packages/7a/9d/0710916e6c82948b3be62d9d398cb4fcf4e97b56d6a6aeccd66c4b2f2bd5/charset_normalizer-3.4.4-cp311-cp311-win_arm64.whl", hash = "sha256:65e2befcd84bc6f37095f5961e68a6f077bf44946771354a28ad434c2cce0ae1", size = 99969, upload-time = "2025-10-14T04:40:52.272Z" }, { url = "https://files.pythonhosted.org/packages/f3/85/1637cd4af66fa687396e757dec650f28025f2a2f5a5531a3208dc0ec43f2/charset_normalizer-3.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394", size = 208425, upload-time = "2025-10-14T04:40:53.353Z" }, { url = "https://files.pythonhosted.org/packages/9d/6a/04130023fef2a0d9c62d0bae2649b69f7b7d8d24ea5536feef50551029df/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25", size = 148162, upload-time = "2025-10-14T04:40:54.558Z" }, { url = "https://files.pythonhosted.org/packages/78/29/62328d79aa60da22c9e0b9a66539feae06ca0f5a4171ac4f7dc285b83688/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef", size = 144558, upload-time = "2025-10-14T04:40:55.677Z" }, { url = "https://files.pythonhosted.org/packages/86/bb/b32194a4bf15b88403537c2e120b817c61cd4ecffa9b6876e941c3ee38fe/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d", size = 161497, upload-time = "2025-10-14T04:40:57.217Z" }, { url = "https://files.pythonhosted.org/packages/19/89/a54c82b253d5b9b111dc74aca196ba5ccfcca8242d0fb64146d4d3183ff1/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8", size = 159240, upload-time = "2025-10-14T04:40:58.358Z" }, { url = "https://files.pythonhosted.org/packages/c0/10/d20b513afe03acc89ec33948320a5544d31f21b05368436d580dec4e234d/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86", size = 153471, upload-time = "2025-10-14T04:40:59.468Z" }, { url = "https://files.pythonhosted.org/packages/61/fa/fbf177b55bdd727010f9c0a3c49eefa1d10f960e5f09d1d887bf93c2e698/charset_normalizer-3.4.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a", size = 150864, upload-time = "2025-10-14T04:41:00.623Z" }, { url = "https://files.pythonhosted.org/packages/05/12/9fbc6a4d39c0198adeebbde20b619790e9236557ca59fc40e0e3cebe6f40/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f", size = 150647, upload-time = "2025-10-14T04:41:01.754Z" }, { url = "https://files.pythonhosted.org/packages/ad/1f/6a9a593d52e3e8c5d2b167daf8c6b968808efb57ef4c210acb907c365bc4/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc", size = 145110, upload-time = "2025-10-14T04:41:03.231Z" }, { url = "https://files.pythonhosted.org/packages/30/42/9a52c609e72471b0fc54386dc63c3781a387bb4fe61c20231a4ebcd58bdd/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf", size = 162839, upload-time = "2025-10-14T04:41:04.715Z" }, { url = "https://files.pythonhosted.org/packages/c4/5b/c0682bbf9f11597073052628ddd38344a3d673fda35a36773f7d19344b23/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15", size = 150667, upload-time = "2025-10-14T04:41:05.827Z" }, { url = "https://files.pythonhosted.org/packages/e4/24/a41afeab6f990cf2daf6cb8c67419b63b48cf518e4f56022230840c9bfb2/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9", size = 160535, upload-time = "2025-10-14T04:41:06.938Z" }, { url = "https://files.pythonhosted.org/packages/2a/e5/6a4ce77ed243c4a50a1fecca6aaaab419628c818a49434be428fe24c9957/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0", size = 154816, upload-time = "2025-10-14T04:41:08.101Z" }, { url = "https://files.pythonhosted.org/packages/a8/ef/89297262b8092b312d29cdb2517cb1237e51db8ecef2e9af5edbe7b683b1/charset_normalizer-3.4.4-cp312-cp312-win32.whl", hash = "sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26", size = 99694, upload-time = "2025-10-14T04:41:09.23Z" }, { url = "https://files.pythonhosted.org/packages/3d/2d/1e5ed9dd3b3803994c155cd9aacb60c82c331bad84daf75bcb9c91b3295e/charset_normalizer-3.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525", size = 107131, upload-time = "2025-10-14T04:41:10.467Z" }, { url = "https://files.pythonhosted.org/packages/d0/d9/0ed4c7098a861482a7b6a95603edce4c0d9db2311af23da1fb2b75ec26fc/charset_normalizer-3.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3", size = 100390, upload-time = "2025-10-14T04:41:11.915Z" }, { url = "https://files.pythonhosted.org/packages/97/45/4b3a1239bbacd321068ea6e7ac28875b03ab8bc0aa0966452db17cd36714/charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794", size = 208091, upload-time = "2025-10-14T04:41:13.346Z" }, { url = "https://files.pythonhosted.org/packages/7d/62/73a6d7450829655a35bb88a88fca7d736f9882a27eacdca2c6d505b57e2e/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed", size = 147936, upload-time = "2025-10-14T04:41:14.461Z" }, { url = "https://files.pythonhosted.org/packages/89/c5/adb8c8b3d6625bef6d88b251bbb0d95f8205831b987631ab0c8bb5d937c2/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72", size = 144180, upload-time = "2025-10-14T04:41:15.588Z" }, { url = "https://files.pythonhosted.org/packages/91/ed/9706e4070682d1cc219050b6048bfd293ccf67b3d4f5a4f39207453d4b99/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328", size = 161346, upload-time = "2025-10-14T04:41:16.738Z" }, { url = "https://files.pythonhosted.org/packages/d5/0d/031f0d95e4972901a2f6f09ef055751805ff541511dc1252ba3ca1f80cf5/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede", size = 158874, upload-time = "2025-10-14T04:41:17.923Z" }, { url = "https://files.pythonhosted.org/packages/f5/83/6ab5883f57c9c801ce5e5677242328aa45592be8a00644310a008d04f922/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894", size = 153076, upload-time = "2025-10-14T04:41:19.106Z" }, { url = "https://files.pythonhosted.org/packages/75/1e/5ff781ddf5260e387d6419959ee89ef13878229732732ee73cdae01800f2/charset_normalizer-3.4.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1", size = 150601, upload-time = "2025-10-14T04:41:20.245Z" }, { url = "https://files.pythonhosted.org/packages/d7/57/71be810965493d3510a6ca79b90c19e48696fb1ff964da319334b12677f0/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490", size = 150376, upload-time = "2025-10-14T04:41:21.398Z" }, { url = "https://files.pythonhosted.org/packages/e5/d5/c3d057a78c181d007014feb7e9f2e65905a6c4ef182c0ddf0de2924edd65/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44", size = 144825, upload-time = "2025-10-14T04:41:22.583Z" }, { url = "https://files.pythonhosted.org/packages/e6/8c/d0406294828d4976f275ffbe66f00266c4b3136b7506941d87c00cab5272/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133", size = 162583, upload-time = "2025-10-14T04:41:23.754Z" }, { url = "https://files.pythonhosted.org/packages/d7/24/e2aa1f18c8f15c4c0e932d9287b8609dd30ad56dbe41d926bd846e22fb8d/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3", size = 150366, upload-time = "2025-10-14T04:41:25.27Z" }, { url = "https://files.pythonhosted.org/packages/e4/5b/1e6160c7739aad1e2df054300cc618b06bf784a7a164b0f238360721ab86/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e", size = 160300, upload-time = "2025-10-14T04:41:26.725Z" }, { url = "https://files.pythonhosted.org/packages/7a/10/f882167cd207fbdd743e55534d5d9620e095089d176d55cb22d5322f2afd/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc", size = 154465, upload-time = "2025-10-14T04:41:28.322Z" }, { url = "https://files.pythonhosted.org/packages/89/66/c7a9e1b7429be72123441bfdbaf2bc13faab3f90b933f664db506dea5915/charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac", size = 99404, upload-time = "2025-10-14T04:41:29.95Z" }, { url = "https://files.pythonhosted.org/packages/c4/26/b9924fa27db384bdcd97ab83b4f0a8058d96ad9626ead570674d5e737d90/charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14", size = 107092, upload-time = "2025-10-14T04:41:31.188Z" }, { url = "https://files.pythonhosted.org/packages/af/8f/3ed4bfa0c0c72a7ca17f0380cd9e4dd842b09f664e780c13cff1dcf2ef1b/charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2", size = 100408, upload-time = "2025-10-14T04:41:32.624Z" }, { url = "https://files.pythonhosted.org/packages/2a/35/7051599bd493e62411d6ede36fd5af83a38f37c4767b92884df7301db25d/charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd", size = 207746, upload-time = "2025-10-14T04:41:33.773Z" }, { url = "https://files.pythonhosted.org/packages/10/9a/97c8d48ef10d6cd4fcead2415523221624bf58bcf68a802721a6bc807c8f/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb", size = 147889, upload-time = "2025-10-14T04:41:34.897Z" }, { url = "https://files.pythonhosted.org/packages/10/bf/979224a919a1b606c82bd2c5fa49b5c6d5727aa47b4312bb27b1734f53cd/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e", size = 143641, upload-time = "2025-10-14T04:41:36.116Z" }, { url = "https://files.pythonhosted.org/packages/ba/33/0ad65587441fc730dc7bd90e9716b30b4702dc7b617e6ba4997dc8651495/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14", size = 160779, upload-time = "2025-10-14T04:41:37.229Z" }, { url = "https://files.pythonhosted.org/packages/67/ed/331d6b249259ee71ddea93f6f2f0a56cfebd46938bde6fcc6f7b9a3d0e09/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191", size = 159035, upload-time = "2025-10-14T04:41:38.368Z" }, { url = "https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838", size = 152542, upload-time = "2025-10-14T04:41:39.862Z" }, { url = "https://files.pythonhosted.org/packages/16/85/276033dcbcc369eb176594de22728541a925b2632f9716428c851b149e83/charset_normalizer-3.4.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6", size = 149524, upload-time = "2025-10-14T04:41:41.319Z" }, { url = "https://files.pythonhosted.org/packages/9e/f2/6a2a1f722b6aba37050e626530a46a68f74e63683947a8acff92569f979a/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e", size = 150395, upload-time = "2025-10-14T04:41:42.539Z" }, { url = "https://files.pythonhosted.org/packages/60/bb/2186cb2f2bbaea6338cad15ce23a67f9b0672929744381e28b0592676824/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c", size = 143680, upload-time = "2025-10-14T04:41:43.661Z" }, { url = "https://files.pythonhosted.org/packages/7d/a5/bf6f13b772fbb2a90360eb620d52ed8f796f3c5caee8398c3b2eb7b1c60d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090", size = 162045, upload-time = "2025-10-14T04:41:44.821Z" }, { url = "https://files.pythonhosted.org/packages/df/c5/d1be898bf0dc3ef9030c3825e5d3b83f2c528d207d246cbabe245966808d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152", size = 149687, upload-time = "2025-10-14T04:41:46.442Z" }, { url = "https://files.pythonhosted.org/packages/a5/42/90c1f7b9341eef50c8a1cb3f098ac43b0508413f33affd762855f67a410e/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828", size = 160014, upload-time = "2025-10-14T04:41:47.631Z" }, { url = "https://files.pythonhosted.org/packages/76/be/4d3ee471e8145d12795ab655ece37baed0929462a86e72372fd25859047c/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec", size = 154044, upload-time = "2025-10-14T04:41:48.81Z" }, { url = "https://files.pythonhosted.org/packages/b0/6f/8f7af07237c34a1defe7defc565a9bc1807762f672c0fde711a4b22bf9c0/charset_normalizer-3.4.4-cp314-cp314-win32.whl", hash = "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9", size = 99940, upload-time = "2025-10-14T04:41:49.946Z" }, { url = "https://files.pythonhosted.org/packages/4b/51/8ade005e5ca5b0d80fb4aff72a3775b325bdc3d27408c8113811a7cbe640/charset_normalizer-3.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c", size = 107104, upload-time = "2025-10-14T04:41:51.051Z" }, { url = "https://files.pythonhosted.org/packages/da/5f/6b8f83a55bb8278772c5ae54a577f3099025f9ade59d0136ac24a0df4bde/charset_normalizer-3.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2", size = 100743, upload-time = "2025-10-14T04:41:52.122Z" }, { url = "https://files.pythonhosted.org/packages/0a/4c/925909008ed5a988ccbb72dcc897407e5d6d3bd72410d69e051fc0c14647/charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f", size = 53402, upload-time = "2025-10-14T04:42:31.76Z" }, ] [[package]] name = "click" version = "8.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/3d/fa/656b739db8587d7b5dfa22e22ed02566950fbfbcdc20311993483657a5c0/click-8.3.1.tar.gz", hash = "sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a", size = 295065, upload-time = "2025-11-15T20:45:42.706Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl", hash = "sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6", size = 108274, upload-time = "2025-11-15T20:45:41.139Z" }, ] [[package]] name = "colorama" version = "0.4.6" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, ] [[package]] name = "feature-check" version = "2.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, { name = "pyparsing" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ab/1c/719ca263e0674fc3b246637b011cfe71bc9dc96a7c322b3d8e95132d065f/feature_check-2.3.1.tar.gz", hash = "sha256:d1108c4fb2e20474a2dd3dc9203aff446eb806a1a75e36e7ba7128c433c108bf", size = 39631, upload-time = "2025-10-10T09:17:15.471Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/2e/02/db9be90d5bfdde3dc78671757b20d4a91ed8ba630965f629758133b0b775/feature_check-2.3.1-py3-none-any.whl", hash = "sha256:8bb958e8b4153b18dd2f3450d2bf4368d1503e49ff64f4ec4c76f1f25847c378", size = 12658, upload-time = "2025-10-10T09:17:13.934Z" }, ] [[package]] name = "ghp-import" version = "2.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "python-dateutil" }, ] sdist = { url = "https://files.pythonhosted.org/packages/d9/29/d40217cbe2f6b1359e00c6c307bb3fc876ba74068cbab3dde77f03ca0dc4/ghp-import-2.1.0.tar.gz", hash = "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343", size = 10943, upload-time = "2022-05-02T15:47:16.11Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619", size = 11034, upload-time = "2022-05-02T15:47:14.552Z" }, ] [[package]] name = "griffe" version = "1.15.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama" }, ] sdist = { url = "https://files.pythonhosted.org/packages/0d/0c/3a471b6e31951dce2360477420d0a8d1e00dea6cf33b70f3e8c3ab6e28e1/griffe-1.15.0.tar.gz", hash = "sha256:7726e3afd6f298fbc3696e67958803e7ac843c1cfe59734b6251a40cdbfb5eea", size = 424112, upload-time = "2025-11-10T15:03:15.52Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/9c/83/3b1d03d36f224edded98e9affd0467630fc09d766c0e56fb1498cbb04a9b/griffe-1.15.0-py3-none-any.whl", hash = "sha256:6f6762661949411031f5fcda9593f586e6ce8340f0ba88921a0f2ef7a81eb9a3", size = 150705, upload-time = "2025-11-10T15:03:13.549Z" }, ] [[package]] name = "idna" version = "3.11" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582, upload-time = "2025-10-12T14:55:20.501Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" }, ] [[package]] name = "iniconfig" version = "2.3.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, ] [[package]] name = "jinja2" version = "3.1.6" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markupsafe" }, ] sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, ] [[package]] name = "librt" version = "0.7.4" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/93/e4/b59bdf1197fdf9888452ea4d2048cdad61aef85eb83e99dc52551d7fdc04/librt-0.7.4.tar.gz", hash = "sha256:3871af56c59864d5fd21d1ac001eb2fb3b140d52ba0454720f2e4a19812404ba", size = 145862, upload-time = "2025-12-15T16:52:43.862Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/84/64/44089b12d8b4714a7f0e2f33fb19285ba87702d4be0829f20b36ebeeee07/librt-0.7.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3485b9bb7dfa66167d5500ffdafdc35415b45f0da06c75eb7df131f3357b174a", size = 54709, upload-time = "2025-12-15T16:51:16.699Z" }, { url = "https://files.pythonhosted.org/packages/26/ef/6fa39fb5f37002f7d25e0da4f24d41b457582beea9369eeb7e9e73db5508/librt-0.7.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:188b4b1a770f7f95ea035d5bbb9d7367248fc9d12321deef78a269ebf46a5729", size = 56663, upload-time = "2025-12-15T16:51:17.856Z" }, { url = "https://files.pythonhosted.org/packages/9d/e4/cbaca170a13bee2469c90df9e47108610b4422c453aea1aec1779ac36c24/librt-0.7.4-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:1b668b1c840183e4e38ed5a99f62fac44c3a3eef16870f7f17cfdfb8b47550ed", size = 161703, upload-time = "2025-12-15T16:51:19.421Z" }, { url = "https://files.pythonhosted.org/packages/d0/32/0b2296f9cc7e693ab0d0835e355863512e5eac90450c412777bd699c76ae/librt-0.7.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0e8f864b521f6cfedb314d171630f827efee08f5c3462bcbc2244ab8e1768cd6", size = 171027, upload-time = "2025-12-15T16:51:20.721Z" }, { url = "https://files.pythonhosted.org/packages/d8/33/c70b6d40f7342716e5f1353c8da92d9e32708a18cbfa44897a93ec2bf879/librt-0.7.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4df7c9def4fc619a9c2ab402d73a0c5b53899abe090e0100323b13ccb5a3dd82", size = 184700, upload-time = "2025-12-15T16:51:22.272Z" }, { url = "https://files.pythonhosted.org/packages/e4/c8/555c405155da210e4c4113a879d378f54f850dbc7b794e847750a8fadd43/librt-0.7.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f79bc3595b6ed159a1bf0cdc70ed6ebec393a874565cab7088a219cca14da727", size = 180719, upload-time = "2025-12-15T16:51:23.561Z" }, { url = "https://files.pythonhosted.org/packages/6b/88/34dc1f1461c5613d1b73f0ecafc5316cc50adcc1b334435985b752ed53e5/librt-0.7.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:77772a4b8b5f77d47d883846928c36d730b6e612a6388c74cba33ad9eb149c11", size = 174535, upload-time = "2025-12-15T16:51:25.031Z" }, { url = "https://files.pythonhosted.org/packages/b6/5a/f3fafe80a221626bcedfa9fe5abbf5f04070989d44782f579b2d5920d6d0/librt-0.7.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:064a286e6ab0b4c900e228ab4fa9cb3811b4b83d3e0cc5cd816b2d0f548cb61c", size = 195236, upload-time = "2025-12-15T16:51:26.328Z" }, { url = "https://files.pythonhosted.org/packages/d8/77/5c048d471ce17f4c3a6e08419be19add4d291e2f7067b877437d482622ac/librt-0.7.4-cp311-cp311-win32.whl", hash = "sha256:42da201c47c77b6cc91fc17e0e2b330154428d35d6024f3278aa2683e7e2daf2", size = 42930, upload-time = "2025-12-15T16:51:27.853Z" }, { url = "https://files.pythonhosted.org/packages/fb/3b/514a86305a12c3d9eac03e424b07cd312c7343a9f8a52719aa079590a552/librt-0.7.4-cp311-cp311-win_amd64.whl", hash = "sha256:d31acb5886c16ae1711741f22504195af46edec8315fe69b77e477682a87a83e", size = 49240, upload-time = "2025-12-15T16:51:29.037Z" }, { url = "https://files.pythonhosted.org/packages/ba/01/3b7b1914f565926b780a734fac6e9a4d2c7aefe41f4e89357d73697a9457/librt-0.7.4-cp311-cp311-win_arm64.whl", hash = "sha256:114722f35093da080a333b3834fff04ef43147577ed99dd4db574b03a5f7d170", size = 42613, upload-time = "2025-12-15T16:51:30.194Z" }, { url = "https://files.pythonhosted.org/packages/f3/e7/b805d868d21f425b7e76a0ea71a2700290f2266a4f3c8357fcf73efc36aa/librt-0.7.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7dd3b5c37e0fb6666c27cf4e2c88ae43da904f2155c4cfc1e5a2fdce3b9fcf92", size = 55688, upload-time = "2025-12-15T16:51:31.571Z" }, { url = "https://files.pythonhosted.org/packages/59/5e/69a2b02e62a14cfd5bfd9f1e9adea294d5bcfeea219c7555730e5d068ee4/librt-0.7.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a9c5de1928c486201b23ed0cc4ac92e6e07be5cd7f3abc57c88a9cf4f0f32108", size = 57141, upload-time = "2025-12-15T16:51:32.714Z" }, { url = "https://files.pythonhosted.org/packages/6e/6b/05dba608aae1272b8ea5ff8ef12c47a4a099a04d1e00e28a94687261d403/librt-0.7.4-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:078ae52ffb3f036396cc4aed558e5b61faedd504a3c1f62b8ae34bf95ae39d94", size = 165322, upload-time = "2025-12-15T16:51:33.986Z" }, { url = "https://files.pythonhosted.org/packages/8f/bc/199533d3fc04a4cda8d7776ee0d79955ab0c64c79ca079366fbc2617e680/librt-0.7.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ce58420e25097b2fc201aef9b9f6d65df1eb8438e51154e1a7feb8847e4a55ab", size = 174216, upload-time = "2025-12-15T16:51:35.384Z" }, { url = "https://files.pythonhosted.org/packages/62/ec/09239b912a45a8ed117cb4a6616d9ff508f5d3131bd84329bf2f8d6564f1/librt-0.7.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b719c8730c02a606dc0e8413287e8e94ac2d32a51153b300baf1f62347858fba", size = 189005, upload-time = "2025-12-15T16:51:36.687Z" }, { url = "https://files.pythonhosted.org/packages/46/2e/e188313d54c02f5b0580dd31476bb4b0177514ff8d2be9f58d4a6dc3a7ba/librt-0.7.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3749ef74c170809e6dee68addec9d2458700a8de703de081c888e92a8b015cf9", size = 183960, upload-time = "2025-12-15T16:51:37.977Z" }, { url = "https://files.pythonhosted.org/packages/eb/84/f1d568d254518463d879161d3737b784137d236075215e56c7c9be191cee/librt-0.7.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b35c63f557653c05b5b1b6559a074dbabe0afee28ee2a05b6c9ba21ad0d16a74", size = 177609, upload-time = "2025-12-15T16:51:40.584Z" }, { url = "https://files.pythonhosted.org/packages/5d/43/060bbc1c002f0d757c33a1afe6bf6a565f947a04841139508fc7cef6c08b/librt-0.7.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1ef704e01cb6ad39ad7af668d51677557ca7e5d377663286f0ee1b6b27c28e5f", size = 199269, upload-time = "2025-12-15T16:51:41.879Z" }, { url = "https://files.pythonhosted.org/packages/ff/7f/708f8f02d8012ee9f366c07ea6a92882f48bd06cc1ff16a35e13d0fbfb08/librt-0.7.4-cp312-cp312-win32.whl", hash = "sha256:c66c2b245926ec15188aead25d395091cb5c9df008d3b3207268cd65557d6286", size = 43186, upload-time = "2025-12-15T16:51:43.149Z" }, { url = "https://files.pythonhosted.org/packages/f1/a5/4e051b061c8b2509be31b2c7ad4682090502c0a8b6406edcf8c6b4fe1ef7/librt-0.7.4-cp312-cp312-win_amd64.whl", hash = "sha256:71a56f4671f7ff723451f26a6131754d7c1809e04e22ebfbac1db8c9e6767a20", size = 49455, upload-time = "2025-12-15T16:51:44.336Z" }, { url = "https://files.pythonhosted.org/packages/d0/d2/90d84e9f919224a3c1f393af1636d8638f54925fdc6cd5ee47f1548461e5/librt-0.7.4-cp312-cp312-win_arm64.whl", hash = "sha256:419eea245e7ec0fe664eb7e85e7ff97dcdb2513ca4f6b45a8ec4a3346904f95a", size = 42828, upload-time = "2025-12-15T16:51:45.498Z" }, { url = "https://files.pythonhosted.org/packages/fe/4d/46a53ccfbb39fd0b493fd4496eb76f3ebc15bb3e45d8c2e695a27587edf5/librt-0.7.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d44a1b1ba44cbd2fc3cb77992bef6d6fdb1028849824e1dd5e4d746e1f7f7f0b", size = 55745, upload-time = "2025-12-15T16:51:46.636Z" }, { url = "https://files.pythonhosted.org/packages/7f/2b/3ac7f5212b1828bf4f979cf87f547db948d3e28421d7a430d4db23346ce4/librt-0.7.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c9cab4b3de1f55e6c30a84c8cee20e4d3b2476f4d547256694a1b0163da4fe32", size = 57166, upload-time = "2025-12-15T16:51:48.219Z" }, { url = "https://files.pythonhosted.org/packages/e8/99/6523509097cbe25f363795f0c0d1c6a3746e30c2994e25b5aefdab119b21/librt-0.7.4-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:2857c875f1edd1feef3c371fbf830a61b632fb4d1e57160bb1e6a3206e6abe67", size = 165833, upload-time = "2025-12-15T16:51:49.443Z" }, { url = "https://files.pythonhosted.org/packages/fe/35/323611e59f8fe032649b4fb7e77f746f96eb7588fcbb31af26bae9630571/librt-0.7.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b370a77be0a16e1ad0270822c12c21462dc40496e891d3b0caf1617c8cc57e20", size = 174818, upload-time = "2025-12-15T16:51:51.015Z" }, { url = "https://files.pythonhosted.org/packages/41/e6/40fb2bb21616c6e06b6a64022802228066e9a31618f493e03f6b9661548a/librt-0.7.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d05acd46b9a52087bfc50c59dfdf96a2c480a601e8898a44821c7fd676598f74", size = 189607, upload-time = "2025-12-15T16:51:52.671Z" }, { url = "https://files.pythonhosted.org/packages/32/48/1b47c7d5d28b775941e739ed2bfe564b091c49201b9503514d69e4ed96d7/librt-0.7.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:70969229cb23d9c1a80e14225838d56e464dc71fa34c8342c954fc50e7516dee", size = 184585, upload-time = "2025-12-15T16:51:54.027Z" }, { url = "https://files.pythonhosted.org/packages/75/a6/ee135dfb5d3b54d5d9001dbe483806229c6beac3ee2ba1092582b7efeb1b/librt-0.7.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4450c354b89dbb266730893862dbff06006c9ed5b06b6016d529b2bf644fc681", size = 178249, upload-time = "2025-12-15T16:51:55.248Z" }, { url = "https://files.pythonhosted.org/packages/04/87/d5b84ec997338be26af982bcd6679be0c1db9a32faadab1cf4bb24f9e992/librt-0.7.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:adefe0d48ad35b90b6f361f6ff5a1bd95af80c17d18619c093c60a20e7a5b60c", size = 199851, upload-time = "2025-12-15T16:51:56.933Z" }, { url = "https://files.pythonhosted.org/packages/86/63/ba1333bf48306fe398e3392a7427ce527f81b0b79d0d91618c4610ce9d15/librt-0.7.4-cp313-cp313-win32.whl", hash = "sha256:21ea710e96c1e050635700695095962a22ea420d4b3755a25e4909f2172b4ff2", size = 43249, upload-time = "2025-12-15T16:51:58.498Z" }, { url = "https://files.pythonhosted.org/packages/f9/8a/de2c6df06cdfa9308c080e6b060fe192790b6a48a47320b215e860f0e98c/librt-0.7.4-cp313-cp313-win_amd64.whl", hash = "sha256:772e18696cf5a64afee908662fbcb1f907460ddc851336ee3a848ef7684c8e1e", size = 49417, upload-time = "2025-12-15T16:51:59.618Z" }, { url = "https://files.pythonhosted.org/packages/31/66/8ee0949efc389691381ed686185e43536c20e7ad880c122dd1f31e65c658/librt-0.7.4-cp313-cp313-win_arm64.whl", hash = "sha256:52e34c6af84e12921748c8354aa6acf1912ca98ba60cdaa6920e34793f1a0788", size = 42824, upload-time = "2025-12-15T16:52:00.784Z" }, { url = "https://files.pythonhosted.org/packages/74/81/6921e65c8708eb6636bbf383aa77e6c7dad33a598ed3b50c313306a2da9d/librt-0.7.4-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:4f1ee004942eaaed6e06c087d93ebc1c67e9a293e5f6b9b5da558df6bf23dc5d", size = 55191, upload-time = "2025-12-15T16:52:01.97Z" }, { url = "https://files.pythonhosted.org/packages/0d/d6/3eb864af8a8de8b39cc8dd2e9ded1823979a27795d72c4eea0afa8c26c9f/librt-0.7.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:d854c6dc0f689bad7ed452d2a3ecff58029d80612d336a45b62c35e917f42d23", size = 56898, upload-time = "2025-12-15T16:52:03.356Z" }, { url = "https://files.pythonhosted.org/packages/49/bc/b1d4c0711fdf79646225d576faee8747b8528a6ec1ceb6accfd89ade7102/librt-0.7.4-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:a4f7339d9e445280f23d63dea842c0c77379c4a47471c538fc8feedab9d8d063", size = 163725, upload-time = "2025-12-15T16:52:04.572Z" }, { url = "https://files.pythonhosted.org/packages/2c/08/61c41cd8f0a6a41fc99ea78a2205b88187e45ba9800792410ed62f033584/librt-0.7.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:39003fc73f925e684f8521b2dbf34f61a5deb8a20a15dcf53e0d823190ce8848", size = 172469, upload-time = "2025-12-15T16:52:05.863Z" }, { url = "https://files.pythonhosted.org/packages/8b/c7/4ee18b4d57f01444230bc18cf59103aeab8f8c0f45e84e0e540094df1df1/librt-0.7.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6bb15ee29d95875ad697d449fe6071b67f730f15a6961913a2b0205015ca0843", size = 186804, upload-time = "2025-12-15T16:52:07.192Z" }, { url = "https://files.pythonhosted.org/packages/a1/af/009e8ba3fbf830c936842da048eda1b34b99329f402e49d88fafff6525d1/librt-0.7.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:02a69369862099e37d00765583052a99d6a68af7e19b887e1b78fee0146b755a", size = 181807, upload-time = "2025-12-15T16:52:08.554Z" }, { url = "https://files.pythonhosted.org/packages/85/26/51ae25f813656a8b117c27a974f25e8c1e90abcd5a791ac685bf5b489a1b/librt-0.7.4-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:ec72342cc4d62f38b25a94e28b9efefce41839aecdecf5e9627473ed04b7be16", size = 175595, upload-time = "2025-12-15T16:52:10.186Z" }, { url = "https://files.pythonhosted.org/packages/48/93/36d6c71f830305f88996b15c8e017aa8d1e03e2e947b40b55bbf1a34cf24/librt-0.7.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:776dbb9bfa0fc5ce64234b446995d8d9f04badf64f544ca036bd6cff6f0732ce", size = 196504, upload-time = "2025-12-15T16:52:11.472Z" }, { url = "https://files.pythonhosted.org/packages/08/11/8299e70862bb9d704735bf132c6be09c17b00fbc7cda0429a9df222fdc1b/librt-0.7.4-cp314-cp314-win32.whl", hash = "sha256:0f8cac84196d0ffcadf8469d9ded4d4e3a8b1c666095c2a291e22bf58e1e8a9f", size = 39738, upload-time = "2025-12-15T16:52:12.962Z" }, { url = "https://files.pythonhosted.org/packages/54/d5/656b0126e4e0f8e2725cd2d2a1ec40f71f37f6f03f135a26b663c0e1a737/librt-0.7.4-cp314-cp314-win_amd64.whl", hash = "sha256:037f5cb6fe5abe23f1dc058054d50e9699fcc90d0677eee4e4f74a8677636a1a", size = 45976, upload-time = "2025-12-15T16:52:14.441Z" }, { url = "https://files.pythonhosted.org/packages/60/86/465ff07b75c1067da8fa7f02913c4ead096ef106cfac97a977f763783bfb/librt-0.7.4-cp314-cp314-win_arm64.whl", hash = "sha256:a5deebb53d7a4d7e2e758a96befcd8edaaca0633ae71857995a0f16033289e44", size = 39073, upload-time = "2025-12-15T16:52:15.621Z" }, { url = "https://files.pythonhosted.org/packages/b3/a0/24941f85960774a80d4b3c2aec651d7d980466da8101cae89e8b032a3e21/librt-0.7.4-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:b4c25312c7f4e6ab35ab16211bdf819e6e4eddcba3b2ea632fb51c9a2a97e105", size = 57369, upload-time = "2025-12-15T16:52:16.782Z" }, { url = "https://files.pythonhosted.org/packages/77/a0/ddb259cae86ab415786c1547d0fe1b40f04a7b089f564fd5c0242a3fafb2/librt-0.7.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:618b7459bb392bdf373f2327e477597fff8f9e6a1878fffc1b711c013d1b0da4", size = 59230, upload-time = "2025-12-15T16:52:18.259Z" }, { url = "https://files.pythonhosted.org/packages/31/11/77823cb530ab8a0c6fac848ac65b745be446f6f301753b8990e8809080c9/librt-0.7.4-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:1437c3f72a30c7047f16fd3e972ea58b90172c3c6ca309645c1c68984f05526a", size = 183869, upload-time = "2025-12-15T16:52:19.457Z" }, { url = "https://files.pythonhosted.org/packages/a4/ce/157db3614cf3034b3f702ae5ba4fefda4686f11eea4b7b96542324a7a0e7/librt-0.7.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c96cb76f055b33308f6858b9b594618f1b46e147a4d03a4d7f0c449e304b9b95", size = 194606, upload-time = "2025-12-15T16:52:20.795Z" }, { url = "https://files.pythonhosted.org/packages/30/ef/6ec4c7e3d6490f69a4fd2803516fa5334a848a4173eac26d8ee6507bff6e/librt-0.7.4-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:28f990e6821204f516d09dc39966ef8b84556ffd648d5926c9a3f681e8de8906", size = 206776, upload-time = "2025-12-15T16:52:22.229Z" }, { url = "https://files.pythonhosted.org/packages/ad/22/750b37bf549f60a4782ab80e9d1e9c44981374ab79a7ea68670159905918/librt-0.7.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:bc4aebecc79781a1b77d7d4e7d9fe080385a439e198d993b557b60f9117addaf", size = 203205, upload-time = "2025-12-15T16:52:23.603Z" }, { url = "https://files.pythonhosted.org/packages/7a/87/2e8a0f584412a93df5faad46c5fa0a6825fdb5eba2ce482074b114877f44/librt-0.7.4-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:022cc673e69283a42621dd453e2407cf1647e77f8bd857d7ad7499901e62376f", size = 196696, upload-time = "2025-12-15T16:52:24.951Z" }, { url = "https://files.pythonhosted.org/packages/e5/ca/7bf78fa950e43b564b7de52ceeb477fb211a11f5733227efa1591d05a307/librt-0.7.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:2b3ca211ae8ea540569e9c513da052699b7b06928dcda61247cb4f318122bdb5", size = 217191, upload-time = "2025-12-15T16:52:26.194Z" }, { url = "https://files.pythonhosted.org/packages/d6/49/3732b0e8424ae35ad5c3166d9dd5bcdae43ce98775e0867a716ff5868064/librt-0.7.4-cp314-cp314t-win32.whl", hash = "sha256:8a461f6456981d8c8e971ff5a55f2e34f4e60871e665d2f5fde23ee74dea4eeb", size = 40276, upload-time = "2025-12-15T16:52:27.54Z" }, { url = "https://files.pythonhosted.org/packages/35/d6/d8823e01bd069934525fddb343189c008b39828a429b473fb20d67d5cd36/librt-0.7.4-cp314-cp314t-win_amd64.whl", hash = "sha256:721a7b125a817d60bf4924e1eec2a7867bfcf64cfc333045de1df7a0629e4481", size = 46772, upload-time = "2025-12-15T16:52:28.653Z" }, { url = "https://files.pythonhosted.org/packages/36/e9/a0aa60f5322814dd084a89614e9e31139702e342f8459ad8af1984a18168/librt-0.7.4-cp314-cp314t-win_arm64.whl", hash = "sha256:76b2ba71265c0102d11458879b4d53ccd0b32b0164d14deb8d2b598a018e502f", size = 39724, upload-time = "2025-12-15T16:52:29.836Z" }, ] [[package]] name = "license-expression" version = "30.4.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "boolean-py" }, ] sdist = { url = "https://files.pythonhosted.org/packages/40/71/d89bb0e71b1415453980fd32315f2a037aad9f7f70f695c7cec7035feb13/license_expression-30.4.4.tar.gz", hash = "sha256:73448f0aacd8d0808895bdc4b2c8e01a8d67646e4188f887375398c761f340fd", size = 186402, upload-time = "2025-07-22T11:13:32.17Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/af/40/791891d4c0c4dab4c5e187c17261cedc26285fd41541577f900470a45a4d/license_expression-30.4.4-py3-none-any.whl", hash = "sha256:421788fdcadb41f049d2dc934ce666626265aeccefddd25e162a26f23bcbf8a4", size = 120615, upload-time = "2025-07-22T11:13:31.217Z" }, ] [[package]] name = "markdown" version = "3.10" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/7d/ab/7dd27d9d863b3376fcf23a5a13cb5d024aed1db46f963f1b5735ae43b3be/markdown-3.10.tar.gz", hash = "sha256:37062d4f2aa4b2b6b32aefb80faa300f82cc790cb949a35b8caede34f2b68c0e", size = 364931, upload-time = "2025-11-03T19:51:15.007Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/70/81/54e3ce63502cd085a0c556652a4e1b919c45a446bd1e5300e10c44c8c521/markdown-3.10-py3-none-any.whl", hash = "sha256:b5b99d6951e2e4948d939255596523444c0e677c669700b1d17aa4a8a464cb7c", size = 107678, upload-time = "2025-11-03T19:51:13.887Z" }, ] [[package]] name = "markdown-it-py" version = "4.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mdurl" }, ] sdist = { url = "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3", size = 73070, upload-time = "2025-08-11T12:57:52.854Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321, upload-time = "2025-08-11T12:57:51.923Z" }, ] [[package]] name = "markupsafe" version = "3.0.3" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/08/db/fefacb2136439fc8dd20e797950e749aa1f4997ed584c62cfb8ef7c2be0e/markupsafe-3.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1cc7ea17a6824959616c525620e387f6dd30fec8cb44f649e31712db02123dad", size = 11631, upload-time = "2025-09-27T18:36:18.185Z" }, { url = "https://files.pythonhosted.org/packages/e1/2e/5898933336b61975ce9dc04decbc0a7f2fee78c30353c5efba7f2d6ff27a/markupsafe-3.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bd4cd07944443f5a265608cc6aab442e4f74dff8088b0dfc8238647b8f6ae9a", size = 12058, upload-time = "2025-09-27T18:36:19.444Z" }, { url = "https://files.pythonhosted.org/packages/1d/09/adf2df3699d87d1d8184038df46a9c80d78c0148492323f4693df54e17bb/markupsafe-3.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b5420a1d9450023228968e7e6a9ce57f65d148ab56d2313fcd589eee96a7a50", size = 24287, upload-time = "2025-09-27T18:36:20.768Z" }, { url = "https://files.pythonhosted.org/packages/30/ac/0273f6fcb5f42e314c6d8cd99effae6a5354604d461b8d392b5ec9530a54/markupsafe-3.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bf2a864d67e76e5c9a34dc26ec616a66b9888e25e7b9460e1c76d3293bd9dbf", size = 22940, upload-time = "2025-09-27T18:36:22.249Z" }, { url = "https://files.pythonhosted.org/packages/19/ae/31c1be199ef767124c042c6c3e904da327a2f7f0cd63a0337e1eca2967a8/markupsafe-3.0.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc51efed119bc9cfdf792cdeaa4d67e8f6fcccab66ed4bfdd6bde3e59bfcbb2f", size = 21887, upload-time = "2025-09-27T18:36:23.535Z" }, { url = "https://files.pythonhosted.org/packages/b2/76/7edcab99d5349a4532a459e1fe64f0b0467a3365056ae550d3bcf3f79e1e/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:068f375c472b3e7acbe2d5318dea141359e6900156b5b2ba06a30b169086b91a", size = 23692, upload-time = "2025-09-27T18:36:24.823Z" }, { url = "https://files.pythonhosted.org/packages/a4/28/6e74cdd26d7514849143d69f0bf2399f929c37dc2b31e6829fd2045b2765/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:7be7b61bb172e1ed687f1754f8e7484f1c8019780f6f6b0786e76bb01c2ae115", size = 21471, upload-time = "2025-09-27T18:36:25.95Z" }, { url = "https://files.pythonhosted.org/packages/62/7e/a145f36a5c2945673e590850a6f8014318d5577ed7e5920a4b3448e0865d/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a", size = 22923, upload-time = "2025-09-27T18:36:27.109Z" }, { url = "https://files.pythonhosted.org/packages/0f/62/d9c46a7f5c9adbeeeda52f5b8d802e1094e9717705a645efc71b0913a0a8/markupsafe-3.0.3-cp311-cp311-win32.whl", hash = "sha256:0db14f5dafddbb6d9208827849fad01f1a2609380add406671a26386cdf15a19", size = 14572, upload-time = "2025-09-27T18:36:28.045Z" }, { url = "https://files.pythonhosted.org/packages/83/8a/4414c03d3f891739326e1783338e48fb49781cc915b2e0ee052aa490d586/markupsafe-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:de8a88e63464af587c950061a5e6a67d3632e36df62b986892331d4620a35c01", size = 15077, upload-time = "2025-09-27T18:36:29.025Z" }, { url = "https://files.pythonhosted.org/packages/35/73/893072b42e6862f319b5207adc9ae06070f095b358655f077f69a35601f0/markupsafe-3.0.3-cp311-cp311-win_arm64.whl", hash = "sha256:3b562dd9e9ea93f13d53989d23a7e775fdfd1066c33494ff43f5418bc8c58a5c", size = 13876, upload-time = "2025-09-27T18:36:29.954Z" }, { url = "https://files.pythonhosted.org/packages/5a/72/147da192e38635ada20e0a2e1a51cf8823d2119ce8883f7053879c2199b5/markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e", size = 11615, upload-time = "2025-09-27T18:36:30.854Z" }, { url = "https://files.pythonhosted.org/packages/9a/81/7e4e08678a1f98521201c3079f77db69fb552acd56067661f8c2f534a718/markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce", size = 12020, upload-time = "2025-09-27T18:36:31.971Z" }, { url = "https://files.pythonhosted.org/packages/1e/2c/799f4742efc39633a1b54a92eec4082e4f815314869865d876824c257c1e/markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d", size = 24332, upload-time = "2025-09-27T18:36:32.813Z" }, { url = "https://files.pythonhosted.org/packages/3c/2e/8d0c2ab90a8c1d9a24f0399058ab8519a3279d1bd4289511d74e909f060e/markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d", size = 22947, upload-time = "2025-09-27T18:36:33.86Z" }, { url = "https://files.pythonhosted.org/packages/2c/54/887f3092a85238093a0b2154bd629c89444f395618842e8b0c41783898ea/markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a", size = 21962, upload-time = "2025-09-27T18:36:35.099Z" }, { url = "https://files.pythonhosted.org/packages/c9/2f/336b8c7b6f4a4d95e91119dc8521402461b74a485558d8f238a68312f11c/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b", size = 23760, upload-time = "2025-09-27T18:36:36.001Z" }, { url = "https://files.pythonhosted.org/packages/32/43/67935f2b7e4982ffb50a4d169b724d74b62a3964bc1a9a527f5ac4f1ee2b/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f", size = 21529, upload-time = "2025-09-27T18:36:36.906Z" }, { url = "https://files.pythonhosted.org/packages/89/e0/4486f11e51bbba8b0c041098859e869e304d1c261e59244baa3d295d47b7/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b", size = 23015, upload-time = "2025-09-27T18:36:37.868Z" }, { url = "https://files.pythonhosted.org/packages/2f/e1/78ee7a023dac597a5825441ebd17170785a9dab23de95d2c7508ade94e0e/markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d", size = 14540, upload-time = "2025-09-27T18:36:38.761Z" }, { url = "https://files.pythonhosted.org/packages/aa/5b/bec5aa9bbbb2c946ca2733ef9c4ca91c91b6a24580193e891b5f7dbe8e1e/markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c", size = 15105, upload-time = "2025-09-27T18:36:39.701Z" }, { url = "https://files.pythonhosted.org/packages/e5/f1/216fc1bbfd74011693a4fd837e7026152e89c4bcf3e77b6692fba9923123/markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f", size = 13906, upload-time = "2025-09-27T18:36:40.689Z" }, { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622, upload-time = "2025-09-27T18:36:41.777Z" }, { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029, upload-time = "2025-09-27T18:36:43.257Z" }, { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374, upload-time = "2025-09-27T18:36:44.508Z" }, { url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980, upload-time = "2025-09-27T18:36:45.385Z" }, { url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990, upload-time = "2025-09-27T18:36:46.916Z" }, { url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784, upload-time = "2025-09-27T18:36:47.884Z" }, { url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588, upload-time = "2025-09-27T18:36:48.82Z" }, { url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041, upload-time = "2025-09-27T18:36:49.797Z" }, { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543, upload-time = "2025-09-27T18:36:51.584Z" }, { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113, upload-time = "2025-09-27T18:36:52.537Z" }, { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911, upload-time = "2025-09-27T18:36:53.513Z" }, { url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658, upload-time = "2025-09-27T18:36:54.819Z" }, { url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066, upload-time = "2025-09-27T18:36:55.714Z" }, { url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639, upload-time = "2025-09-27T18:36:56.908Z" }, { url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569, upload-time = "2025-09-27T18:36:57.913Z" }, { url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284, upload-time = "2025-09-27T18:36:58.833Z" }, { url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801, upload-time = "2025-09-27T18:36:59.739Z" }, { url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769, upload-time = "2025-09-27T18:37:00.719Z" }, { url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642, upload-time = "2025-09-27T18:37:01.673Z" }, { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612, upload-time = "2025-09-27T18:37:02.639Z" }, { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200, upload-time = "2025-09-27T18:37:03.582Z" }, { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973, upload-time = "2025-09-27T18:37:04.929Z" }, { url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619, upload-time = "2025-09-27T18:37:06.342Z" }, { url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029, upload-time = "2025-09-27T18:37:07.213Z" }, { url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408, upload-time = "2025-09-27T18:37:09.572Z" }, { url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", size = 23005, upload-time = "2025-09-27T18:37:10.58Z" }, { url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", size = 22048, upload-time = "2025-09-27T18:37:11.547Z" }, { url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", size = 23821, upload-time = "2025-09-27T18:37:12.48Z" }, { url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", size = 21606, upload-time = "2025-09-27T18:37:13.485Z" }, { url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", size = 23043, upload-time = "2025-09-27T18:37:14.408Z" }, { url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747, upload-time = "2025-09-27T18:37:15.36Z" }, { url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341, upload-time = "2025-09-27T18:37:16.496Z" }, { url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073, upload-time = "2025-09-27T18:37:17.476Z" }, { url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", size = 11661, upload-time = "2025-09-27T18:37:18.453Z" }, { url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", size = 12069, upload-time = "2025-09-27T18:37:19.332Z" }, { url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", size = 25670, upload-time = "2025-09-27T18:37:20.245Z" }, { url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50", size = 23598, upload-time = "2025-09-27T18:37:21.177Z" }, { url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", size = 23261, upload-time = "2025-09-27T18:37:22.167Z" }, { url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", size = 24835, upload-time = "2025-09-27T18:37:23.296Z" }, { url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", size = 22733, upload-time = "2025-09-27T18:37:24.237Z" }, { url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", size = 23672, upload-time = "2025-09-27T18:37:25.271Z" }, { url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819, upload-time = "2025-09-27T18:37:26.285Z" }, { url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426, upload-time = "2025-09-27T18:37:27.316Z" }, { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" }, ] [[package]] name = "mdurl" version = "0.1.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, ] [[package]] name = "media-type-version" source = { editable = "." } [package.dev-dependencies] cli = [ { name = "cappa" }, ] docs = [ { name = "markupsafe" }, { name = "mkdocs" }, { name = "mkdocs-material" }, { name = "mkdocstrings" }, { name = "mkdocstrings-python" }, ] testenv-mypy = [ { name = "cappa" }, { name = "feature-check" }, { name = "mypy" }, { name = "packaging" }, { name = "pygments" }, { name = "pytest" }, { name = "tomli-w" }, ] testenv-pyupgrade = [ { name = "pyupgrade" }, ] testenv-reuse = [ { name = "reuse" }, ] testenv-ruff = [ { name = "ruff" }, ] testenv-ty = [ { name = "cappa" }, { name = "feature-check" }, { name = "packaging" }, { name = "pygments" }, { name = "pytest" }, { name = "tomli-w" }, { name = "ty" }, ] testenv-unit-tests = [ { name = "feature-check" }, { name = "packaging" }, { name = "pygments" }, { name = "pytest" }, { name = "tomli-w" }, ] testenv-unit-tests-cli = [ { name = "cappa" }, { name = "feature-check" }, { name = "packaging" }, { name = "pygments" }, { name = "pytest" }, { name = "tomli-w" }, ] testenv-uvoxen = [ { name = "uvoxen" }, ] [package.metadata] [package.metadata.requires-dev] cli = [{ name = "cappa", specifier = ">=0.27.3,<0.32" }] docs = [ { name = "markupsafe", specifier = ">=2.1" }, { name = "mkdocs", specifier = ">=1.5,<2" }, { name = "mkdocs-material", specifier = ">=9.3,<10" }, { name = "mkdocstrings", specifier = ">=1,<2" }, { name = "mkdocstrings-python", specifier = ">=1.4,<2" }, ] testenv-mypy = [ { name = "cappa", specifier = ">=0.27.3,<0.32" }, { name = "feature-check", specifier = ">=2,<3" }, { name = "mypy", specifier = ">=1.5,<2" }, { name = "packaging", specifier = ">=21.3,<26" }, { name = "pygments", specifier = ">=2.7,<3" }, { name = "pytest", specifier = ">=8.3.5,<9.0.3" }, { name = "tomli-w", specifier = ">=1,<2" }, ] testenv-pyupgrade = [{ name = "pyupgrade", specifier = ">=3,<4" }] testenv-reuse = [{ name = "reuse", specifier = ">=6,<7" }] testenv-ruff = [{ name = "ruff", specifier = "==0.14.10" }] testenv-ty = [ { name = "cappa", specifier = ">=0.27.3,<0.32" }, { name = "feature-check", specifier = ">=2,<3" }, { name = "packaging", specifier = ">=21.3,<26" }, { name = "pygments", specifier = ">=2.7,<3" }, { name = "pytest", specifier = ">=8.3.5,<9.0.3" }, { name = "tomli-w", specifier = ">=1,<2" }, { name = "ty", specifier = "==0.0.4" }, ] testenv-unit-tests = [ { name = "feature-check", specifier = ">=2,<3" }, { name = "packaging", specifier = ">=21.3,<26" }, { name = "pygments", specifier = ">=2.7,<3" }, { name = "pytest", specifier = ">=8.3.5,<9.0.3" }, { name = "tomli-w", specifier = ">=1,<2" }, ] testenv-unit-tests-cli = [ { name = "cappa", specifier = ">=0.27.3,<0.32" }, { name = "feature-check", specifier = ">=2,<3" }, { name = "packaging", specifier = ">=21.3,<26" }, { name = "pygments", specifier = ">=2.7,<3" }, { name = "pytest", specifier = ">=8.3.5,<9.0.3" }, { name = "tomli-w", specifier = ">=1,<2" }, ] testenv-uvoxen = [{ name = "uvoxen", specifier = ">=0.2.2,<0.3" }] [[package]] name = "mergedeep" version = "1.3.4" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/3a/41/580bb4006e3ed0361b8151a01d324fb03f420815446c7def45d02f74c270/mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8", size = 4661, upload-time = "2021-02-05T18:55:30.623Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307", size = 6354, upload-time = "2021-02-05T18:55:29.583Z" }, ] [[package]] name = "mkdocs" version = "1.6.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, { name = "colorama", marker = "sys_platform == 'win32'" }, { name = "ghp-import" }, { name = "jinja2" }, { name = "markdown" }, { name = "markupsafe" }, { name = "mergedeep" }, { name = "mkdocs-get-deps" }, { name = "packaging" }, { name = "pathspec" }, { name = "pyyaml" }, { name = "pyyaml-env-tag" }, { name = "watchdog" }, ] sdist = { url = "https://files.pythonhosted.org/packages/bc/c6/bbd4f061bd16b378247f12953ffcb04786a618ce5e904b8c5a01a0309061/mkdocs-1.6.1.tar.gz", hash = "sha256:7b432f01d928c084353ab39c57282f29f92136665bdd6abf7c1ec8d822ef86f2", size = 3889159, upload-time = "2024-08-30T12:24:06.899Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl", hash = "sha256:db91759624d1647f3f34aa0c3f327dd2601beae39a366d6e064c03468d35c20e", size = 3864451, upload-time = "2024-08-30T12:24:05.054Z" }, ] [[package]] name = "mkdocs-autorefs" version = "1.4.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markdown" }, { name = "markupsafe" }, { name = "mkdocs" }, ] sdist = { url = "https://files.pythonhosted.org/packages/51/fa/9124cd63d822e2bcbea1450ae68cdc3faf3655c69b455f3a7ed36ce6c628/mkdocs_autorefs-1.4.3.tar.gz", hash = "sha256:beee715b254455c4aa93b6ef3c67579c399ca092259cc41b7d9342573ff1fc75", size = 55425, upload-time = "2025-08-26T14:23:17.223Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/9f/4d/7123b6fa2278000688ebd338e2a06d16870aaf9eceae6ba047ea05f92df1/mkdocs_autorefs-1.4.3-py3-none-any.whl", hash = "sha256:469d85eb3114801d08e9cc55d102b3ba65917a869b893403b8987b601cf55dc9", size = 25034, upload-time = "2025-08-26T14:23:15.906Z" }, ] [[package]] name = "mkdocs-get-deps" version = "0.2.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mergedeep" }, { name = "platformdirs" }, { name = "pyyaml" }, ] sdist = { url = "https://files.pythonhosted.org/packages/98/f5/ed29cd50067784976f25ed0ed6fcd3c2ce9eb90650aa3b2796ddf7b6870b/mkdocs_get_deps-0.2.0.tar.gz", hash = "sha256:162b3d129c7fad9b19abfdcb9c1458a651628e4b1dea628ac68790fb3061c60c", size = 10239, upload-time = "2023-11-20T17:51:09.981Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/9f/d4/029f984e8d3f3b6b726bd33cafc473b75e9e44c0f7e80a5b29abc466bdea/mkdocs_get_deps-0.2.0-py3-none-any.whl", hash = "sha256:2bf11d0b133e77a0dd036abeeb06dec8775e46efa526dc70667d8863eefc6134", size = 9521, upload-time = "2023-11-20T17:51:08.587Z" }, ] [[package]] name = "mkdocs-material" version = "9.7.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "babel" }, { name = "backrefs" }, { name = "colorama" }, { name = "jinja2" }, { name = "markdown" }, { name = "mkdocs" }, { name = "mkdocs-material-extensions" }, { name = "paginate" }, { name = "pygments" }, { name = "pymdown-extensions" }, { name = "requests" }, ] sdist = { url = "https://files.pythonhosted.org/packages/27/e2/2ffc356cd72f1473d07c7719d82a8f2cbd261666828614ecb95b12169f41/mkdocs_material-9.7.1.tar.gz", hash = "sha256:89601b8f2c3e6c6ee0a918cc3566cb201d40bf37c3cd3c2067e26fadb8cce2b8", size = 4094392, upload-time = "2025-12-18T09:49:00.308Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/3e/32/ed071cb721aca8c227718cffcf7bd539620e9799bbf2619e90c757bfd030/mkdocs_material-9.7.1-py3-none-any.whl", hash = "sha256:3f6100937d7d731f87f1e3e3b021c97f7239666b9ba1151ab476cabb96c60d5c", size = 9297166, upload-time = "2025-12-18T09:48:56.664Z" }, ] [[package]] name = "mkdocs-material-extensions" version = "1.3.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/79/9b/9b4c96d6593b2a541e1cb8b34899a6d021d208bb357042823d4d2cabdbe7/mkdocs_material_extensions-1.3.1.tar.gz", hash = "sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443", size = 11847, upload-time = "2023-11-22T19:09:45.208Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl", hash = "sha256:adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31", size = 8728, upload-time = "2023-11-22T19:09:43.465Z" }, ] [[package]] name = "mkdocstrings" version = "1.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jinja2" }, { name = "markdown" }, { name = "markupsafe" }, { name = "mkdocs" }, { name = "mkdocs-autorefs" }, { name = "pymdown-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/e5/13/10bbf9d56565fd91b91e6f5a8cd9b9d8a2b101c4e8ad6eeafa35a706301d/mkdocstrings-1.0.0.tar.gz", hash = "sha256:351a006dbb27aefce241ade110d3cd040c1145b7a3eb5fd5ac23f03ed67f401a", size = 101086, upload-time = "2025-11-27T15:39:40.534Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/ec/fc/80aa31b79133634721cf7855d37b76ea49773599214896f2ff10be03de2a/mkdocstrings-1.0.0-py3-none-any.whl", hash = "sha256:4c50eb960bff6e05dfc631f6bc00dfabffbcb29c5ff25f676d64daae05ed82fa", size = 35135, upload-time = "2025-11-27T15:39:39.301Z" }, ] [[package]] name = "mkdocstrings-python" version = "1.19.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "griffe" }, { name = "mkdocs-autorefs" }, { name = "mkdocstrings" }, ] sdist = { url = "https://files.pythonhosted.org/packages/75/1c/3af8413919b0839b96a78f60e8bd0dfd26c844d3717eeb77f80b43f5be1c/mkdocstrings_python-1.19.0.tar.gz", hash = "sha256:917aac66cf121243c11db5b89f66b0ded6c53ec0de5318ff5e22424eb2f2e57c", size = 204010, upload-time = "2025-11-10T13:30:55.915Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/98/5c/2597cef67b6947b15c47f8dba967a0baf19fbdfdc86f6e4a8ba7af8b581a/mkdocstrings_python-1.19.0-py3-none-any.whl", hash = "sha256:395c1032af8f005234170575cc0c5d4d20980846623b623b35594281be4a3059", size = 143417, upload-time = "2025-11-10T13:30:54.164Z" }, ] [[package]] name = "mypy" version = "1.19.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "librt", marker = "platform_python_implementation != 'PyPy'" }, { name = "mypy-extensions" }, { name = "pathspec" }, { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/f5/db/4efed9504bc01309ab9c2da7e352cc223569f05478012b5d9ece38fd44d2/mypy-1.19.1.tar.gz", hash = "sha256:19d88bb05303fe63f71dd2c6270daca27cb9401c4ca8255fe50d1d920e0eb9ba", size = 3582404, upload-time = "2025-12-15T05:03:48.42Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/ef/47/6b3ebabd5474d9cdc170d1342fbf9dddc1b0ec13ec90bf9004ee6f391c31/mypy-1.19.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d8dfc6ab58ca7dda47d9237349157500468e404b17213d44fc1cb77bce532288", size = 13028539, upload-time = "2025-12-15T05:03:44.129Z" }, { url = "https://files.pythonhosted.org/packages/5c/a6/ac7c7a88a3c9c54334f53a941b765e6ec6c4ebd65d3fe8cdcfbe0d0fd7db/mypy-1.19.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e3f276d8493c3c97930e354b2595a44a21348b320d859fb4a2b9f66da9ed27ab", size = 12083163, upload-time = "2025-12-15T05:03:37.679Z" }, { url = "https://files.pythonhosted.org/packages/67/af/3afa9cf880aa4a2c803798ac24f1d11ef72a0c8079689fac5cfd815e2830/mypy-1.19.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2abb24cf3f17864770d18d673c85235ba52456b36a06b6afc1e07c1fdcd3d0e6", size = 12687629, upload-time = "2025-12-15T05:02:31.526Z" }, { url = "https://files.pythonhosted.org/packages/2d/46/20f8a7114a56484ab268b0ab372461cb3a8f7deed31ea96b83a4e4cfcfca/mypy-1.19.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a009ffa5a621762d0c926a078c2d639104becab69e79538a494bcccb62cc0331", size = 13436933, upload-time = "2025-12-15T05:03:15.606Z" }, { url = "https://files.pythonhosted.org/packages/5b/f8/33b291ea85050a21f15da910002460f1f445f8007adb29230f0adea279cb/mypy-1.19.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f7cee03c9a2e2ee26ec07479f38ea9c884e301d42c6d43a19d20fb014e3ba925", size = 13661754, upload-time = "2025-12-15T05:02:26.731Z" }, { url = "https://files.pythonhosted.org/packages/fd/a3/47cbd4e85bec4335a9cd80cf67dbc02be21b5d4c9c23ad6b95d6c5196bac/mypy-1.19.1-cp311-cp311-win_amd64.whl", hash = "sha256:4b84a7a18f41e167f7995200a1d07a4a6810e89d29859df936f1c3923d263042", size = 10055772, upload-time = "2025-12-15T05:03:26.179Z" }, { url = "https://files.pythonhosted.org/packages/06/8a/19bfae96f6615aa8a0604915512e0289b1fad33d5909bf7244f02935d33a/mypy-1.19.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a8174a03289288c1f6c46d55cef02379b478bfbc8e358e02047487cad44c6ca1", size = 13206053, upload-time = "2025-12-15T05:03:46.622Z" }, { url = "https://files.pythonhosted.org/packages/a5/34/3e63879ab041602154ba2a9f99817bb0c85c4df19a23a1443c8986e4d565/mypy-1.19.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ffcebe56eb09ff0c0885e750036a095e23793ba6c2e894e7e63f6d89ad51f22e", size = 12219134, upload-time = "2025-12-15T05:03:24.367Z" }, { url = "https://files.pythonhosted.org/packages/89/cc/2db6f0e95366b630364e09845672dbee0cbf0bbe753a204b29a944967cd9/mypy-1.19.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b64d987153888790bcdb03a6473d321820597ab8dd9243b27a92153c4fa50fd2", size = 12731616, upload-time = "2025-12-15T05:02:44.725Z" }, { url = "https://files.pythonhosted.org/packages/00/be/dd56c1fd4807bc1eba1cf18b2a850d0de7bacb55e158755eb79f77c41f8e/mypy-1.19.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c35d298c2c4bba75feb2195655dfea8124d855dfd7343bf8b8c055421eaf0cf8", size = 13620847, upload-time = "2025-12-15T05:03:39.633Z" }, { url = "https://files.pythonhosted.org/packages/6d/42/332951aae42b79329f743bf1da088cd75d8d4d9acc18fbcbd84f26c1af4e/mypy-1.19.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:34c81968774648ab5ac09c29a375fdede03ba253f8f8287847bd480782f73a6a", size = 13834976, upload-time = "2025-12-15T05:03:08.786Z" }, { url = "https://files.pythonhosted.org/packages/6f/63/e7493e5f90e1e085c562bb06e2eb32cae27c5057b9653348d38b47daaecc/mypy-1.19.1-cp312-cp312-win_amd64.whl", hash = "sha256:b10e7c2cd7870ba4ad9b2d8a6102eb5ffc1f16ca35e3de6bfa390c1113029d13", size = 10118104, upload-time = "2025-12-15T05:03:10.834Z" }, { url = "https://files.pythonhosted.org/packages/de/9f/a6abae693f7a0c697dbb435aac52e958dc8da44e92e08ba88d2e42326176/mypy-1.19.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e3157c7594ff2ef1634ee058aafc56a82db665c9438fd41b390f3bde1ab12250", size = 13201927, upload-time = "2025-12-15T05:02:29.138Z" }, { url = "https://files.pythonhosted.org/packages/9a/a4/45c35ccf6e1c65afc23a069f50e2c66f46bd3798cbe0d680c12d12935caa/mypy-1.19.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bdb12f69bcc02700c2b47e070238f42cb87f18c0bc1fc4cdb4fb2bc5fd7a3b8b", size = 12206730, upload-time = "2025-12-15T05:03:01.325Z" }, { url = "https://files.pythonhosted.org/packages/05/bb/cdcf89678e26b187650512620eec8368fded4cfd99cfcb431e4cdfd19dec/mypy-1.19.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f859fb09d9583a985be9a493d5cfc5515b56b08f7447759a0c5deaf68d80506e", size = 12724581, upload-time = "2025-12-15T05:03:20.087Z" }, { url = "https://files.pythonhosted.org/packages/d1/32/dd260d52babf67bad8e6770f8e1102021877ce0edea106e72df5626bb0ec/mypy-1.19.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c9a6538e0415310aad77cb94004ca6482330fece18036b5f360b62c45814c4ef", size = 13616252, upload-time = "2025-12-15T05:02:49.036Z" }, { url = "https://files.pythonhosted.org/packages/71/d0/5e60a9d2e3bd48432ae2b454b7ef2b62a960ab51292b1eda2a95edd78198/mypy-1.19.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:da4869fc5e7f62a88f3fe0b5c919d1d9f7ea3cef92d3689de2823fd27e40aa75", size = 13840848, upload-time = "2025-12-15T05:02:55.95Z" }, { url = "https://files.pythonhosted.org/packages/98/76/d32051fa65ecf6cc8c6610956473abdc9b4c43301107476ac03559507843/mypy-1.19.1-cp313-cp313-win_amd64.whl", hash = "sha256:016f2246209095e8eda7538944daa1d60e1e8134d98983b9fc1e92c1fc0cb8dd", size = 10135510, upload-time = "2025-12-15T05:02:58.438Z" }, { url = "https://files.pythonhosted.org/packages/de/eb/b83e75f4c820c4247a58580ef86fcd35165028f191e7e1ba57128c52782d/mypy-1.19.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:06e6170bd5836770e8104c8fdd58e5e725cfeb309f0a6c681a811f557e97eac1", size = 13199744, upload-time = "2025-12-15T05:03:30.823Z" }, { url = "https://files.pythonhosted.org/packages/94/28/52785ab7bfa165f87fcbb61547a93f98bb20e7f82f90f165a1f69bce7b3d/mypy-1.19.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:804bd67b8054a85447c8954215a906d6eff9cabeabe493fb6334b24f4bfff718", size = 12215815, upload-time = "2025-12-15T05:02:42.323Z" }, { url = "https://files.pythonhosted.org/packages/0a/c6/bdd60774a0dbfb05122e3e925f2e9e846c009e479dcec4821dad881f5b52/mypy-1.19.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:21761006a7f497cb0d4de3d8ef4ca70532256688b0523eee02baf9eec895e27b", size = 12740047, upload-time = "2025-12-15T05:03:33.168Z" }, { url = "https://files.pythonhosted.org/packages/32/2a/66ba933fe6c76bd40d1fe916a83f04fed253152f451a877520b3c4a5e41e/mypy-1.19.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:28902ee51f12e0f19e1e16fbe2f8f06b6637f482c459dd393efddd0ec7f82045", size = 13601998, upload-time = "2025-12-15T05:03:13.056Z" }, { url = "https://files.pythonhosted.org/packages/e3/da/5055c63e377c5c2418760411fd6a63ee2b96cf95397259038756c042574f/mypy-1.19.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:481daf36a4c443332e2ae9c137dfee878fcea781a2e3f895d54bd3002a900957", size = 13807476, upload-time = "2025-12-15T05:03:17.977Z" }, { url = "https://files.pythonhosted.org/packages/cd/09/4ebd873390a063176f06b0dbf1f7783dd87bd120eae7727fa4ae4179b685/mypy-1.19.1-cp314-cp314-win_amd64.whl", hash = "sha256:8bb5c6f6d043655e055be9b542aa5f3bdd30e4f3589163e85f93f3640060509f", size = 10281872, upload-time = "2025-12-15T05:03:05.549Z" }, { url = "https://files.pythonhosted.org/packages/8d/f4/4ce9a05ce5ded1de3ec1c1d96cf9f9504a04e54ce0ed55cfa38619a32b8d/mypy-1.19.1-py3-none-any.whl", hash = "sha256:f1235f5ea01b7db5468d53ece6aaddf1ad0b88d9e7462b86ef96fe04995d7247", size = 2471239, upload-time = "2025-12-15T05:03:07.248Z" }, ] [[package]] name = "mypy-extensions" version = "1.1.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/a2/6e/371856a3fb9d31ca8dac321cda606860fa4548858c0cc45d9d1d4ca2628b/mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558", size = 6343, upload-time = "2025-04-22T14:54:24.164Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" }, ] [[package]] name = "packaging" version = "25.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, ] [[package]] name = "paginate" version = "0.5.7" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/ec/46/68dde5b6bc00c1296ec6466ab27dddede6aec9af1b99090e1107091b3b84/paginate-0.5.7.tar.gz", hash = "sha256:22bd083ab41e1a8b4f3690544afb2c60c25e5c9a63a30fa2f483f6c60c8e5945", size = 19252, upload-time = "2024-08-25T14:17:24.139Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl", hash = "sha256:b885e2af73abcf01d9559fd5216b57ef722f8c42affbb63942377668e35c7591", size = 13746, upload-time = "2024-08-25T14:17:22.55Z" }, ] [[package]] name = "pathspec" version = "0.12.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043, upload-time = "2023-12-10T22:30:45Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" }, ] [[package]] name = "platformdirs" version = "4.5.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/cf/86/0248f086a84f01b37aaec0fa567b397df1a119f73c16f6c7a9aac73ea309/platformdirs-4.5.1.tar.gz", hash = "sha256:61d5cdcc6065745cdd94f0f878977f8de9437be93de97c1c12f853c9c0cdcbda", size = 21715, upload-time = "2025-12-05T13:52:58.638Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/cb/28/3bfe2fa5a7b9c46fe7e13c97bda14c895fb10fa2ebf1d0abb90e0cea7ee1/platformdirs-4.5.1-py3-none-any.whl", hash = "sha256:d03afa3963c806a9bed9d5125c8f4cb2fdaf74a55ab60e5d59b3fde758104d31", size = 18731, upload-time = "2025-12-05T13:52:56.823Z" }, ] [[package]] name = "pluggy" version = "1.6.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, ] [[package]] name = "pygments" version = "2.19.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, ] [[package]] name = "pymdown-extensions" version = "10.19.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markdown" }, { name = "pyyaml" }, ] sdist = { url = "https://files.pythonhosted.org/packages/72/2d/9f30cee56d4d6d222430d401e85b0a6a1ae229819362f5786943d1a8c03b/pymdown_extensions-10.19.1.tar.gz", hash = "sha256:4969c691009a389fb1f9712dd8e7bd70dcc418d15a0faf70acb5117d022f7de8", size = 847839, upload-time = "2025-12-14T17:25:24.42Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/fb/35/b763e8fbcd51968329b9adc52d188fc97859f85f2ee15fe9f379987d99c5/pymdown_extensions-10.19.1-py3-none-any.whl", hash = "sha256:e8698a66055b1dc0dca2a7f2c9d0ea6f5faa7834a9c432e3535ab96c0c4e509b", size = 266693, upload-time = "2025-12-14T17:25:22.999Z" }, ] [[package]] name = "pyparsing" version = "3.2.5" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/f2/a5/181488fc2b9d093e3972d2a472855aae8a03f000592dbfce716a512b3359/pyparsing-3.2.5.tar.gz", hash = "sha256:2df8d5b7b2802ef88e8d016a2eb9c7aeaa923529cd251ed0fe4608275d4105b6", size = 1099274, upload-time = "2025-09-21T04:11:06.277Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/10/5e/1aa9a93198c6b64513c9d7752de7422c06402de6600a8767da1524f9570b/pyparsing-3.2.5-py3-none-any.whl", hash = "sha256:e38a4f02064cf41fe6593d328d0512495ad1f3d8a91c4f73fc401b3079a59a5e", size = 113890, upload-time = "2025-09-21T04:11:04.117Z" }, ] [[package]] name = "pytest" version = "9.0.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, { name = "iniconfig" }, { name = "packaging" }, { name = "pluggy" }, { name = "pygments" }, ] sdist = { url = "https://files.pythonhosted.org/packages/d1/db/7ef3487e0fb0049ddb5ce41d3a49c235bf9ad299b6a25d5780a89f19230f/pytest-9.0.2.tar.gz", hash = "sha256:75186651a92bd89611d1d9fc20f0b4345fd827c41ccd5c299a868a05d70edf11", size = 1568901, upload-time = "2025-12-06T21:30:51.014Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl", hash = "sha256:711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b", size = 374801, upload-time = "2025-12-06T21:30:49.154Z" }, ] [[package]] name = "python-dateutil" version = "2.9.0.post0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "six" }, ] sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, ] [[package]] name = "python-debian" version = "1.0.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "charset-normalizer" }, ] sdist = { url = "https://files.pythonhosted.org/packages/bf/4b/3c4cf635311b6203f17c2d693dc15e898969983dd3f729bee3c428aa60d4/python-debian-1.0.1.tar.gz", hash = "sha256:3ada9b83a3d671b58081782c0969cffa0102f6ce433fbbc7cf21275b8b5cc771", size = 127249, upload-time = "2025-03-11T12:27:27.245Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/ba/15/e8096189b18dda72e4923622abc10b021ecff723b397e22eff29fb86637b/python_debian-1.0.1-py3-none-any.whl", hash = "sha256:8f137c230c1d9279c2ac892b35915068b2aca090c9fd3da5671ff87af32af12c", size = 137453, upload-time = "2025-03-11T12:27:25.014Z" }, ] [[package]] name = "python-magic" version = "0.4.27" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/da/db/0b3e28ac047452d079d375ec6798bf76a036a08182dbb39ed38116a49130/python-magic-0.4.27.tar.gz", hash = "sha256:c1ba14b08e4a5f5c31a302b7721239695b2f0f058d125bd5ce1ee36b9d9d3c3b", size = 14677, upload-time = "2022-06-07T20:16:59.508Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/6c/73/9f872cb81fc5c3bb48f7227872c28975f998f3e7c2b1c16e95e6432bbb90/python_magic-0.4.27-py2.py3-none-any.whl", hash = "sha256:c212960ad306f700aa0d01e5d7a325d20548ff97eb9920dcd29513174f0294d3", size = 13840, upload-time = "2022-06-07T20:16:57.763Z" }, ] [[package]] name = "pyupgrade" version = "3.21.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "tokenize-rt" }, ] sdist = { url = "https://files.pythonhosted.org/packages/7f/a1/dc63caaeed232b1c58eae1b7a75f262d64ab8435882f696ffa9b58c0c415/pyupgrade-3.21.2.tar.gz", hash = "sha256:1a361bea39deda78d1460f65d9dd548d3a36ff8171d2482298539b9dc11c9c06", size = 45455, upload-time = "2025-11-19T00:39:48.012Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/16/8c/433dac11910989a90c40b10149d07ef7224232236971a562d3976790ec53/pyupgrade-3.21.2-py2.py3-none-any.whl", hash = "sha256:2ac7b95cbd176475041e4dfe8ef81298bd4654a244f957167bd68af37d52be9f", size = 62814, upload-time = "2025-11-19T00:39:46.958Z" }, ] [[package]] name = "pyyaml" version = "6.0.3" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/6d/16/a95b6757765b7b031c9374925bb718d55e0a9ba8a1b6a12d25962ea44347/pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e", size = 185826, upload-time = "2025-09-25T21:31:58.655Z" }, { url = "https://files.pythonhosted.org/packages/16/19/13de8e4377ed53079ee996e1ab0a9c33ec2faf808a4647b7b4c0d46dd239/pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824", size = 175577, upload-time = "2025-09-25T21:32:00.088Z" }, { url = "https://files.pythonhosted.org/packages/0c/62/d2eb46264d4b157dae1275b573017abec435397aa59cbcdab6fc978a8af4/pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c", size = 775556, upload-time = "2025-09-25T21:32:01.31Z" }, { url = "https://files.pythonhosted.org/packages/10/cb/16c3f2cf3266edd25aaa00d6c4350381c8b012ed6f5276675b9eba8d9ff4/pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00", size = 882114, upload-time = "2025-09-25T21:32:03.376Z" }, { url = "https://files.pythonhosted.org/packages/71/60/917329f640924b18ff085ab889a11c763e0b573da888e8404ff486657602/pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d", size = 806638, upload-time = "2025-09-25T21:32:04.553Z" }, { url = "https://files.pythonhosted.org/packages/dd/6f/529b0f316a9fd167281a6c3826b5583e6192dba792dd55e3203d3f8e655a/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a", size = 767463, upload-time = "2025-09-25T21:32:06.152Z" }, { url = "https://files.pythonhosted.org/packages/f2/6a/b627b4e0c1dd03718543519ffb2f1deea4a1e6d42fbab8021936a4d22589/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4", size = 794986, upload-time = "2025-09-25T21:32:07.367Z" }, { url = "https://files.pythonhosted.org/packages/45/91/47a6e1c42d9ee337c4839208f30d9f09caa9f720ec7582917b264defc875/pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b", size = 142543, upload-time = "2025-09-25T21:32:08.95Z" }, { url = "https://files.pythonhosted.org/packages/da/e3/ea007450a105ae919a72393cb06f122f288ef60bba2dc64b26e2646fa315/pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf", size = 158763, upload-time = "2025-09-25T21:32:09.96Z" }, { url = "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", size = 182063, upload-time = "2025-09-25T21:32:11.445Z" }, { url = "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0", size = 173973, upload-time = "2025-09-25T21:32:12.492Z" }, { url = "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", size = 775116, upload-time = "2025-09-25T21:32:13.652Z" }, { url = "https://files.pythonhosted.org/packages/65/30/d7353c338e12baef4ecc1b09e877c1970bd3382789c159b4f89d6a70dc09/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", size = 844011, upload-time = "2025-09-25T21:32:15.21Z" }, { url = "https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", size = 807870, upload-time = "2025-09-25T21:32:16.431Z" }, { url = "https://files.pythonhosted.org/packages/05/c0/b3be26a015601b822b97d9149ff8cb5ead58c66f981e04fedf4e762f4bd4/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", size = 761089, upload-time = "2025-09-25T21:32:17.56Z" }, { url = "https://files.pythonhosted.org/packages/be/8e/98435a21d1d4b46590d5459a22d88128103f8da4c2d4cb8f14f2a96504e1/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", size = 790181, upload-time = "2025-09-25T21:32:18.834Z" }, { url = "https://files.pythonhosted.org/packages/74/93/7baea19427dcfbe1e5a372d81473250b379f04b1bd3c4c5ff825e2327202/pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", size = 137658, upload-time = "2025-09-25T21:32:20.209Z" }, { url = "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", size = 154003, upload-time = "2025-09-25T21:32:21.167Z" }, { url = "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", size = 140344, upload-time = "2025-09-25T21:32:22.617Z" }, { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, ] [[package]] name = "pyyaml-env-tag" version = "1.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pyyaml" }, ] sdist = { url = "https://files.pythonhosted.org/packages/eb/2e/79c822141bfd05a853236b504869ebc6b70159afc570e1d5a20641782eaa/pyyaml_env_tag-1.1.tar.gz", hash = "sha256:2eb38b75a2d21ee0475d6d97ec19c63287a7e140231e4214969d0eac923cd7ff", size = 5737, upload-time = "2025-05-13T15:24:01.64Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl", hash = "sha256:17109e1a528561e32f026364712fee1264bc2ea6715120891174ed1b980d2e04", size = 4722, upload-time = "2025-05-13T15:23:59.629Z" }, ] [[package]] name = "requests" version = "2.32.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, { name = "charset-normalizer" }, { name = "idna" }, { name = "urllib3" }, ] sdist = { url = "https://files.pythonhosted.org/packages/c9/74/b3ff8e6c8446842c3f5c837e9c3dfcfe2018ea6ecef224c710c85ef728f4/requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf", size = 134517, upload-time = "2025-08-18T20:46:02.573Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" }, ] [[package]] name = "reuse" version = "6.2.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "attrs" }, { name = "click" }, { name = "jinja2" }, { name = "license-expression" }, { name = "python-debian" }, { name = "python-magic" }, { name = "tomlkit" }, ] sdist = { url = "https://files.pythonhosted.org/packages/05/35/298d9410b3635107ce586725cdfbca4c219c08d77a3511551f5e479a78db/reuse-6.2.0.tar.gz", hash = "sha256:4feae057a2334c9a513e6933cdb9be819d8b822f3b5b435a36138bd218897d23", size = 1615611, upload-time = "2025-10-27T15:25:46.336Z" } [[package]] name = "rich" version = "14.2.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markdown-it-py" }, { name = "pygments" }, ] sdist = { url = "https://files.pythonhosted.org/packages/fb/d2/8920e102050a0de7bfabeb4c4614a49248cf8d5d7a8d01885fbb24dc767a/rich-14.2.0.tar.gz", hash = "sha256:73ff50c7c0c1c77c8243079283f4edb376f0f6442433aecb8ce7e6d0b92d1fe4", size = 219990, upload-time = "2025-10-09T14:16:53.064Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/25/7a/b0178788f8dc6cafce37a212c99565fa1fe7872c70c6c9c1e1a372d9d88f/rich-14.2.0-py3-none-any.whl", hash = "sha256:76bc51fe2e57d2b1be1f96c524b890b816e334ab4c1e45888799bfaab0021edd", size = 243393, upload-time = "2025-10-09T14:16:51.245Z" }, ] [[package]] name = "ruff" version = "0.14.10" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/57/08/52232a877978dd8f9cf2aeddce3e611b40a63287dfca29b6b8da791f5e8d/ruff-0.14.10.tar.gz", hash = "sha256:9a2e830f075d1a42cd28420d7809ace390832a490ed0966fe373ba288e77aaf4", size = 5859763, upload-time = "2025-12-18T19:28:57.98Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/60/01/933704d69f3f05ee16ef11406b78881733c186fe14b6a46b05cfcaf6d3b2/ruff-0.14.10-py3-none-linux_armv6l.whl", hash = "sha256:7a3ce585f2ade3e1f29ec1b92df13e3da262178df8c8bdf876f48fa0e8316c49", size = 13527080, upload-time = "2025-12-18T19:29:25.642Z" }, { url = "https://files.pythonhosted.org/packages/df/58/a0349197a7dfa603ffb7f5b0470391efa79ddc327c1e29c4851e85b09cc5/ruff-0.14.10-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:674f9be9372907f7257c51f1d4fc902cb7cf014b9980152b802794317941f08f", size = 13797320, upload-time = "2025-12-18T19:29:02.571Z" }, { url = "https://files.pythonhosted.org/packages/7b/82/36be59f00a6082e38c23536df4e71cdbc6af8d7c707eade97fcad5c98235/ruff-0.14.10-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d85713d522348837ef9df8efca33ccb8bd6fcfc86a2cde3ccb4bc9d28a18003d", size = 12918434, upload-time = "2025-12-18T19:28:51.202Z" }, { url = "https://files.pythonhosted.org/packages/a6/00/45c62a7f7e34da92a25804f813ebe05c88aa9e0c25e5cb5a7d23dd7450e3/ruff-0.14.10-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6987ebe0501ae4f4308d7d24e2d0fe3d7a98430f5adfd0f1fead050a740a3a77", size = 13371961, upload-time = "2025-12-18T19:29:04.991Z" }, { url = "https://files.pythonhosted.org/packages/40/31/a5906d60f0405f7e57045a70f2d57084a93ca7425f22e1d66904769d1628/ruff-0.14.10-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:16a01dfb7b9e4eee556fbfd5392806b1b8550c9b4a9f6acd3dbe6812b193c70a", size = 13275629, upload-time = "2025-12-18T19:29:21.381Z" }, { url = "https://files.pythonhosted.org/packages/3e/60/61c0087df21894cf9d928dc04bcd4fb10e8b2e8dca7b1a276ba2155b2002/ruff-0.14.10-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7165d31a925b7a294465fa81be8c12a0e9b60fb02bf177e79067c867e71f8b1f", size = 14029234, upload-time = "2025-12-18T19:29:00.132Z" }, { url = "https://files.pythonhosted.org/packages/44/84/77d911bee3b92348b6e5dab5a0c898d87084ea03ac5dc708f46d88407def/ruff-0.14.10-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:c561695675b972effb0c0a45db233f2c816ff3da8dcfbe7dfc7eed625f218935", size = 15449890, upload-time = "2025-12-18T19:28:53.573Z" }, { url = "https://files.pythonhosted.org/packages/e9/36/480206eaefa24a7ec321582dda580443a8f0671fdbf6b1c80e9c3e93a16a/ruff-0.14.10-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4bb98fcbbc61725968893682fd4df8966a34611239c9fd07a1f6a07e7103d08e", size = 15123172, upload-time = "2025-12-18T19:29:23.453Z" }, { url = "https://files.pythonhosted.org/packages/5c/38/68e414156015ba80cef5473d57919d27dfb62ec804b96180bafdeaf0e090/ruff-0.14.10-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f24b47993a9d8cb858429e97bdf8544c78029f09b520af615c1d261bf827001d", size = 14460260, upload-time = "2025-12-18T19:29:27.808Z" }, { url = "https://files.pythonhosted.org/packages/b3/19/9e050c0dca8aba824d67cc0db69fb459c28d8cd3f6855b1405b3f29cc91d/ruff-0.14.10-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59aabd2e2c4fd614d2862e7939c34a532c04f1084476d6833dddef4afab87e9f", size = 14229978, upload-time = "2025-12-18T19:29:11.32Z" }, { url = "https://files.pythonhosted.org/packages/51/eb/e8dd1dd6e05b9e695aa9dd420f4577debdd0f87a5ff2fedda33c09e9be8c/ruff-0.14.10-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:213db2b2e44be8625002dbea33bb9c60c66ea2c07c084a00d55732689d697a7f", size = 14338036, upload-time = "2025-12-18T19:29:09.184Z" }, { url = "https://files.pythonhosted.org/packages/6a/12/f3e3a505db7c19303b70af370d137795fcfec136d670d5de5391e295c134/ruff-0.14.10-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b914c40ab64865a17a9a5b67911d14df72346a634527240039eb3bd650e5979d", size = 13264051, upload-time = "2025-12-18T19:29:13.431Z" }, { url = "https://files.pythonhosted.org/packages/08/64/8c3a47eaccfef8ac20e0484e68e0772013eb85802f8a9f7603ca751eb166/ruff-0.14.10-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:1484983559f026788e3a5c07c81ef7d1e97c1c78ed03041a18f75df104c45405", size = 13283998, upload-time = "2025-12-18T19:29:06.994Z" }, { url = "https://files.pythonhosted.org/packages/12/84/534a5506f4074e5cc0529e5cd96cfc01bb480e460c7edf5af70d2bcae55e/ruff-0.14.10-py3-none-musllinux_1_2_i686.whl", hash = "sha256:c70427132db492d25f982fffc8d6c7535cc2fd2c83fc8888f05caaa248521e60", size = 13601891, upload-time = "2025-12-18T19:28:55.811Z" }, { url = "https://files.pythonhosted.org/packages/0d/1e/14c916087d8598917dbad9b2921d340f7884824ad6e9c55de948a93b106d/ruff-0.14.10-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5bcf45b681e9f1ee6445d317ce1fa9d6cba9a6049542d1c3d5b5958986be8830", size = 14336660, upload-time = "2025-12-18T19:29:16.531Z" }, { url = "https://files.pythonhosted.org/packages/f2/1c/d7b67ab43f30013b47c12b42d1acd354c195351a3f7a1d67f59e54227ede/ruff-0.14.10-py3-none-win32.whl", hash = "sha256:104c49fc7ab73f3f3a758039adea978869a918f31b73280db175b43a2d9b51d6", size = 13196187, upload-time = "2025-12-18T19:29:19.006Z" }, { url = "https://files.pythonhosted.org/packages/fb/9c/896c862e13886fae2af961bef3e6312db9ebc6adc2b156fe95e615dee8c1/ruff-0.14.10-py3-none-win_amd64.whl", hash = "sha256:466297bd73638c6bdf06485683e812db1c00c7ac96d4ddd0294a338c62fdc154", size = 14661283, upload-time = "2025-12-18T19:29:30.16Z" }, { url = "https://files.pythonhosted.org/packages/74/31/b0e29d572670dca3674eeee78e418f20bdf97fa8aa9ea71380885e175ca0/ruff-0.14.10-py3-none-win_arm64.whl", hash = "sha256:e51d046cf6dda98a4633b8a8a771451107413b0f07183b2bef03f075599e44e6", size = 13729839, upload-time = "2025-12-18T19:28:48.636Z" }, ] [[package]] name = "six" version = "1.17.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, ] [[package]] name = "tokenize-rt" version = "6.2.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/69/ed/8f07e893132d5051d86a553e749d5c89b2a4776eb3a579b72ed61f8559ca/tokenize_rt-6.2.0.tar.gz", hash = "sha256:8439c042b330c553fdbe1758e4a05c0ed460dbbbb24a606f11f0dee75da4cad6", size = 5476, upload-time = "2025-05-23T23:48:00.035Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl", hash = "sha256:a152bf4f249c847a66497a4a95f63376ed68ac6abf092a2f7cfb29d044ecff44", size = 6004, upload-time = "2025-05-23T23:47:58.812Z" }, ] [[package]] name = "tomli-w" version = "1.2.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/19/75/241269d1da26b624c0d5e110e8149093c759b7a286138f4efd61a60e75fe/tomli_w-1.2.0.tar.gz", hash = "sha256:2dd14fac5a47c27be9cd4c976af5a12d87fb1f0b4512f81d69cce3b35ae25021", size = 7184, upload-time = "2025-01-15T12:07:24.262Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/c7/18/c86eb8e0202e32dd3df50d43d7ff9854f8e0603945ff398974c1d91ac1ef/tomli_w-1.2.0-py3-none-any.whl", hash = "sha256:188306098d013b691fcadc011abd66727d3c414c571bb01b1a174ba8c983cf90", size = 6675, upload-time = "2025-01-15T12:07:22.074Z" }, ] [[package]] name = "tomlkit" version = "0.13.3" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/cc/18/0bbf3884e9eaa38819ebe46a7bd25dcd56b67434402b66a58c4b8e552575/tomlkit-0.13.3.tar.gz", hash = "sha256:430cf247ee57df2b94ee3fbe588e71d362a941ebb545dec29b53961d61add2a1", size = 185207, upload-time = "2025-06-05T07:13:44.947Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/bd/75/8539d011f6be8e29f339c42e633aae3cb73bffa95dd0f9adec09b9c58e85/tomlkit-0.13.3-py3-none-any.whl", hash = "sha256:c89c649d79ee40629a9fda55f8ace8c6a1b42deb912b2a8fd8d942ddadb606b0", size = 38901, upload-time = "2025-06-05T07:13:43.546Z" }, ] [[package]] name = "ty" version = "0.0.4" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/48/d9/97d5808e851f790e58f8a54efb5c7b9f404640baf9e295f424846040b316/ty-0.0.4.tar.gz", hash = "sha256:2ea47a0089d74730658ec4e988c8ef476a1e9bd92df3e56709c4003c2895ff3b", size = 4780289, upload-time = "2025-12-19T00:13:53.12Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/b1/94/b32a962243cc8a16e8dc74cf1fe75e8bb013d0e13e71bb540e2c86214b61/ty-0.0.4-py3-none-linux_armv6l.whl", hash = "sha256:5225da65a8d1defeb21ee9d74298b1b97c6cbab36e235a310c1430d9079e4b6a", size = 9762399, upload-time = "2025-12-19T00:14:11.261Z" }, { url = "https://files.pythonhosted.org/packages/d1/d2/7c76e0c22ddfc2fcd4a3458a65f87ce074070eb1c68c07ee475cc2b6ea68/ty-0.0.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:f87770d7988f470b795a2043185082fa959dbe1979a11b4bfe20f1214d37bd6e", size = 9590410, upload-time = "2025-12-19T00:13:55.759Z" }, { url = "https://files.pythonhosted.org/packages/a5/84/de4b1fc85669faca3622071d5a3f3ec7bfb239971f368c28fae461d3398a/ty-0.0.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:ecf68b8ea48674a289d733b4786aecc259242a2d9a920b3ec8583db18c67496a", size = 9131113, upload-time = "2025-12-19T00:14:08.593Z" }, { url = "https://files.pythonhosted.org/packages/a7/ff/b5bf385b6983be56a470856bbcbac1b7e816bcd765a7e9d39ab2399e387d/ty-0.0.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efc396d76a57e527393cae4ee8faf23b93be3df9e93202f39925721a7a2bb7b8", size = 9599152, upload-time = "2025-12-19T00:13:40.484Z" }, { url = "https://files.pythonhosted.org/packages/36/d6/9880ba106f2f20d13e6a5dca5d5ca44bfb3782936ee67ff635f89a2959c0/ty-0.0.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c893b968d2f9964a4d4db9992c9ba66b01f411b1f48dffcde08622e19cd6ab97", size = 9585368, upload-time = "2025-12-19T00:14:00.994Z" }, { url = "https://files.pythonhosted.org/packages/3f/53/503cfc18bc4c7c4e02f89dd43debc41a6e343b41eb43df658dfb493a386d/ty-0.0.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:526c925b80d68a53c165044d2370fcfc0def1f119f7b7e483ee61d24da6fb891", size = 9998412, upload-time = "2025-12-19T00:14:18.653Z" }, { url = "https://files.pythonhosted.org/packages/1d/bd/dd2d3e29834da5add2eda0ab5b433171ce9ce9a248c364d2e237f82073d7/ty-0.0.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:857f605a7fa366b6c6e6f38abc311d0606be513c2bee8977b5c8fd4bde1a82d5", size = 10853890, upload-time = "2025-12-19T00:13:50.891Z" }, { url = "https://files.pythonhosted.org/packages/07/fe/28ba3be1672e6b8df46e43de66a02dc076ffba7853d391a5466421886225/ty-0.0.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b4cc981aa3ebdac2c233421b1e58c80b0df6a8e6e6fa8b9e69fbdfd2f82768af", size = 10587263, upload-time = "2025-12-19T00:14:21.577Z" }, { url = "https://files.pythonhosted.org/packages/26/9c/bb598772043f686afe5bc26cb386020709c1a0bcc164bc22ad9da2b4f55d/ty-0.0.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b03b2708b0bf67c76424a860f848aebaa4772c05529170c3761bfcaea93ec199", size = 10401204, upload-time = "2025-12-19T00:13:43.453Z" }, { url = "https://files.pythonhosted.org/packages/ac/18/71765e9d63669bf09461c3fea84a7a63232ccb0e83b84676f07b987fc217/ty-0.0.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:469890e885544beb129c21e2f8f15321f0573d094aec13da68593c5f86389ff9", size = 10129713, upload-time = "2025-12-19T00:14:13.725Z" }, { url = "https://files.pythonhosted.org/packages/c3/2d/c03eba570aa85e9c361de5ed36d60b9ab139e93ee91057f455ab4af48e54/ty-0.0.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:abfd928d09567e12068aeca875e920def3badf1978896f474aa4b85b552703c4", size = 9586203, upload-time = "2025-12-19T00:14:03.423Z" }, { url = "https://files.pythonhosted.org/packages/61/f1/8c3c82a8df69bd4417c77be4f895d043db26dd47bfcc90b33dc109cd0096/ty-0.0.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:44b8e94f9d64df12eae4cf8031c5ca9a4c610b57092b26ad3d68d91bcc7af122", size = 9608230, upload-time = "2025-12-19T00:13:58.252Z" }, { url = "https://files.pythonhosted.org/packages/51/0c/d8ba3a85c089c246ef6bd49d0f0b40bc0f9209bb819e8c02ccbea5cb4d57/ty-0.0.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9d6a439813e21a06769daf858105818c385d88018929d4a56970d4ddd5cd3df2", size = 9725125, upload-time = "2025-12-19T00:14:05.996Z" }, { url = "https://files.pythonhosted.org/packages/4d/38/e30f64ad1e40905c766576ec70cffc69163591a5842ce14652672f6ab394/ty-0.0.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:c3cfcf26cfe6c828e91d7a529cc2dda37bc3b51ba06909c9be07002a6584af52", size = 10237174, upload-time = "2025-12-19T00:14:23.858Z" }, { url = "https://files.pythonhosted.org/packages/cb/d7/8d650aa0be8936dd3ed74e2b0655230e2904caa6077c30c16a089b523cff/ty-0.0.4-py3-none-win32.whl", hash = "sha256:58bbf70dd27af6b00dedbdebeec92d5993aa238664f96fa5c0064930f7a0d30b", size = 9188434, upload-time = "2025-12-19T00:13:45.875Z" }, { url = "https://files.pythonhosted.org/packages/82/d7/9fc0c81cf0b0d281ac9c18bfbdb4d6bae2173503ba79e40b210ab41c2c8b/ty-0.0.4-py3-none-win_amd64.whl", hash = "sha256:7c2db0f96218f08c140bd9d3fcbb1b3c8c5c4f0c9b0a5624487f0a2bf4b76163", size = 10019313, upload-time = "2025-12-19T00:14:15.968Z" }, { url = "https://files.pythonhosted.org/packages/5f/b8/3e3246738eed1cd695c5964a401f3b9c757d20ac21fdae06281af9f40ef6/ty-0.0.4-py3-none-win_arm64.whl", hash = "sha256:69f14fc98e4a847afa9f8c5d5234d008820dbc09c7dcdb3ac1ba16628f5132df", size = 9561857, upload-time = "2025-12-19T00:13:48.382Z" }, ] [[package]] name = "type-lens" version = "0.2.6" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/f8/55/8846322acedf26cafb4a66dd23fdca6bc73cb3f8c0029040a9b96f5aa0dd/type_lens-0.2.6.tar.gz", hash = "sha256:5d46ab3bc2dfafc174cad702eccb4418c31e38e258e87945a19d86ebc204d08b", size = 362277, upload-time = "2025-10-20T20:08:28.07Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/b3/c5/30de077e06f7ffc3fe21d45ce26b8088816227b678a7157f6b9e080ff2db/type_lens-0.2.6-py3-none-any.whl", hash = "sha256:aade6beb3eca337c90d1b627b509768473bbd591e233ed6b57fb93ec2a01bca6", size = 14451, upload-time = "2025-10-20T20:08:26.936Z" }, ] [[package]] name = "typedload" version = "2.39" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/58/70/fec3f45d83fe5cff2e03c2f1b4ae1d4e0b9c14f046e57a9e0320439b0971/typedload-2.39.tar.gz", hash = "sha256:bbeb448f4d8f11236bd9471adb53a1c4113a7e235626521dcebc558e3920bb46", size = 79106, upload-time = "2025-10-21T07:07:47.285Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/1d/b3/b21f88a867f81fc98faf7bbc4a67e4be0bc335f5c88a0451c8bf586c6f67/typedload-2.39-py3-none-any.whl", hash = "sha256:8e4a58a2e00e519b50fc9ac75ab8e6a2c1e5826835ac4ebfe661a909bfa79068", size = 56313, upload-time = "2025-10-21T07:07:45.796Z" }, ] [[package]] name = "typing-extensions" version = "4.15.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, ] [[package]] name = "urllib3" version = "2.6.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/1e/24/a2a2ed9addd907787d7aa0355ba36a6cadf1768b934c652ea78acbd59dcd/urllib3-2.6.2.tar.gz", hash = "sha256:016f9c98bb7e98085cb2b4b17b87d2c702975664e4f060c6532e64d1c1a5e797", size = 432930, upload-time = "2025-12-11T15:56:40.252Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/6d/b9/4095b668ea3678bf6a0af005527f39de12fb026516fb3df17495a733b7f8/urllib3-2.6.2-py3-none-any.whl", hash = "sha256:ec21cddfe7724fc7cb4ba4bea7aa8e2ef36f607a4bab81aa6ce42a13dc3f03dd", size = 131182, upload-time = "2025-12-11T15:56:38.584Z" }, ] [[package]] name = "uv" version = "0.9.18" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/e3/03/1afff9e6362dc9d3a9e03743da0a4b4c7a0809f859c79eb52bbae31ea582/uv-0.9.18.tar.gz", hash = "sha256:17b5502f7689c4dc1fdeee9d8437a9a6664dcaa8476e70046b5f4753559533f5", size = 3824466, upload-time = "2025-12-16T15:45:11.81Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/26/9c/92fad10fcee8ea170b66442d95fd2af308fe9a107909ded4b3cc384fdc69/uv-0.9.18-py3-none-linux_armv6l.whl", hash = "sha256:e9e4915bb280c1f79b9a1c16021e79f61ed7c6382856ceaa99d53258cb0b4951", size = 21345538, upload-time = "2025-12-16T15:45:13.992Z" }, { url = "https://files.pythonhosted.org/packages/81/b1/b0e5808e05acb54aa118c625d9f7b117df614703b0cbb89d419d03d117f3/uv-0.9.18-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:d91abfd2649987996e3778729140c305ef0f6ff5909f55aac35c3c372544a24f", size = 20439572, upload-time = "2025-12-16T15:45:26.397Z" }, { url = "https://files.pythonhosted.org/packages/b7/0b/9487d83adf5b7fd1e20ced33f78adf84cb18239c3d7e91f224cedba46c08/uv-0.9.18-py3-none-macosx_11_0_arm64.whl", hash = "sha256:cf33f4146fd97e94cdebe6afc5122208eea8c55b65ca4127f5a5643c9717c8b8", size = 18952907, upload-time = "2025-12-16T15:44:48.399Z" }, { url = "https://files.pythonhosted.org/packages/58/92/c8f7ae8900eff8e4ce1f7826d2e1e2ad5a95a5f141abdb539865aff79930/uv-0.9.18-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:edf965e9a5c55f74020ac82285eb0dfe7fac4f325ad0a7afc816290269ecfec1", size = 20772495, upload-time = "2025-12-16T15:45:29.614Z" }, { url = "https://files.pythonhosted.org/packages/5a/28/9831500317c1dd6cde5099e3eb3b22b88ac75e47df7b502f6aef4df5750e/uv-0.9.18-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ae10a941bd7ca1ee69edbe3998c34dce0a9fc2d2406d98198343daf7d2078493", size = 20949623, upload-time = "2025-12-16T15:44:57.482Z" }, { url = "https://files.pythonhosted.org/packages/0c/ff/1fe1ffa69c8910e54dd11f01fb0765d4fd537ceaeb0c05fa584b6b635b82/uv-0.9.18-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a1669a95b588f613b13dd10e08ced6d5bcd79169bba29a2240eee87532648790", size = 21920580, upload-time = "2025-12-16T15:44:39.009Z" }, { url = "https://files.pythonhosted.org/packages/d6/ee/eed3ec7679ee80e16316cfc95ed28ef6851700bcc66edacfc583cbd2cc47/uv-0.9.18-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:11e1e406590d3159138288203a41ff8a8904600b8628a57462f04ff87d62c477", size = 23491234, upload-time = "2025-12-16T15:45:32.59Z" }, { url = "https://files.pythonhosted.org/packages/78/58/64b15df743c79ad03ea7fbcbd27b146ba16a116c57f557425dd4e44d6684/uv-0.9.18-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e82078d3c622cb4c60da87f156168ffa78b9911136db7ffeb8e5b0a040bf30e", size = 23095438, upload-time = "2025-12-16T15:45:17.916Z" }, { url = "https://files.pythonhosted.org/packages/43/6d/3d3dae71796961603c3871699e10d6b9de2e65a3c327b58d4750610a5f93/uv-0.9.18-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704abaf6e76b4d293fc1f24bef2c289021f1df0de9ed351f476cbbf67a7edae0", size = 22140992, upload-time = "2025-12-16T15:44:45.527Z" }, { url = "https://files.pythonhosted.org/packages/31/91/1042d0966a30e937df500daed63e1f61018714406ce4023c8a6e6d2dcf7c/uv-0.9.18-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3332188fd8d96a68e5001409a52156dced910bf1bc41ec3066534cffcd46eb68", size = 22229626, upload-time = "2025-12-16T15:45:20.712Z" }, { url = "https://files.pythonhosted.org/packages/5a/1f/0a4a979bb2bf6e1292cc57882955bf1d7757cad40b1862d524c59c2a2ad8/uv-0.9.18-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:b7295e6d505f1fd61c54b1219e3b18e11907396333a9fa61cefe489c08fc7995", size = 20896524, upload-time = "2025-12-16T15:45:06.799Z" }, { url = "https://files.pythonhosted.org/packages/a5/3c/24f92e56af00cac7d9bed2888d99a580f8093c8745395ccf6213bfccf20b/uv-0.9.18-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:62ea0e518dd4ab76e6f06c0f43a25898a6342a3ecf996c12f27f08eb801ef7f1", size = 22077340, upload-time = "2025-12-16T15:44:51.271Z" }, { url = "https://files.pythonhosted.org/packages/9c/3e/73163116f748800e676bf30cee838448e74ac4cc2f716c750e1705bc3fe4/uv-0.9.18-py3-none-musllinux_1_1_armv7l.whl", hash = "sha256:8bd073e30030211ba01206caa57b4d63714e1adee2c76a1678987dd52f72d44d", size = 20932956, upload-time = "2025-12-16T15:45:00.3Z" }, { url = "https://files.pythonhosted.org/packages/59/1b/a26990b51a17de1ffe41fbf2e30de3a98f0e0bce40cc60829fb9d9ed1a8a/uv-0.9.18-py3-none-musllinux_1_1_i686.whl", hash = "sha256:f248e013d10e1fc7a41f94310628b4a8130886b6d683c7c85c42b5b36d1bcd02", size = 21357247, upload-time = "2025-12-16T15:45:23.575Z" }, { url = "https://files.pythonhosted.org/packages/5f/20/b6ba14fdd671e9237b22060d7422aba4a34503e3e42d914dbf925eff19aa/uv-0.9.18-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:17bedf2b0791e87d889e1c7f125bd5de77e4b7579aec372fa06ba832e07c957e", size = 22443585, upload-time = "2025-12-16T15:44:42.213Z" }, { url = "https://files.pythonhosted.org/packages/5e/da/1b3dd596964f90a122cfe94dcf5b6b89cf5670eb84434b8c23864382576f/uv-0.9.18-py3-none-win32.whl", hash = "sha256:de6f0bb3e9c18e484545bd1549ec3c956968a141a393d42e2efb25281cb62787", size = 20091088, upload-time = "2025-12-16T15:45:03.225Z" }, { url = "https://files.pythonhosted.org/packages/11/0b/50e13ebc1eedb36d88524b7740f78351be33213073e3faf81ac8925d0c6e/uv-0.9.18-py3-none-win_amd64.whl", hash = "sha256:c82b0e2e36b33e2146fba5f0ae6906b9679b3b5fe6a712e5d624e45e441e58e9", size = 22181193, upload-time = "2025-12-16T15:44:54.394Z" }, { url = "https://files.pythonhosted.org/packages/8c/d4/0bf338d863a3d9e5545e268d77a8e6afdd75d26bffc939603042f2e739f9/uv-0.9.18-py3-none-win_arm64.whl", hash = "sha256:4c4ce0ed080440bbda2377488575d426867f94f5922323af6d4728a1cd4d091d", size = 20564933, upload-time = "2025-12-16T15:45:09.819Z" }, ] [[package]] name = "uvoxen" version = "0.2.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cappa" }, { name = "media-type-version" }, { name = "pyparsing" }, { name = "typedload" }, { name = "uv" }, ] sdist = { url = "https://files.pythonhosted.org/packages/91/9c/804e4ac40f19f75d447e246ebf8044845c7804dbdbc9db1a04b06f7b769a/uvoxen-0.2.3.tar.gz", hash = "sha256:30ac7a005be26076127ed4735927a8f080676413cddd82f68e7ece774db4ab6d", size = 67573, upload-time = "2025-10-09T09:20:46.769Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/37/c1/54f79a29480a4974244a8321d342c105a06fb6425955a663334fd5cac543/uvoxen-0.2.3-py3-none-any.whl", hash = "sha256:bf64f877f469603b098c9415b19c4cb090fba2d61f01d23ab2454ade2549dd29", size = 20402, upload-time = "2025-10-09T09:20:45.027Z" }, ] [[package]] name = "watchdog" version = "6.0.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/db/7d/7f3d619e951c88ed75c6037b246ddcf2d322812ee8ea189be89511721d54/watchdog-6.0.0.tar.gz", hash = "sha256:9ddf7c82fda3ae8e24decda1338ede66e1c99883db93711d8fb941eaa2d8c282", size = 131220, upload-time = "2024-11-01T14:07:13.037Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/e0/24/d9be5cd6642a6aa68352ded4b4b10fb0d7889cb7f45814fb92cecd35f101/watchdog-6.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6eb11feb5a0d452ee41f824e271ca311a09e250441c262ca2fd7ebcf2461a06c", size = 96393, upload-time = "2024-11-01T14:06:31.756Z" }, { url = "https://files.pythonhosted.org/packages/63/7a/6013b0d8dbc56adca7fdd4f0beed381c59f6752341b12fa0886fa7afc78b/watchdog-6.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ef810fbf7b781a5a593894e4f439773830bdecb885e6880d957d5b9382a960d2", size = 88392, upload-time = "2024-11-01T14:06:32.99Z" }, { url = "https://files.pythonhosted.org/packages/d1/40/b75381494851556de56281e053700e46bff5b37bf4c7267e858640af5a7f/watchdog-6.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:afd0fe1b2270917c5e23c2a65ce50c2a4abb63daafb0d419fde368e272a76b7c", size = 89019, upload-time = "2024-11-01T14:06:34.963Z" }, { url = "https://files.pythonhosted.org/packages/39/ea/3930d07dafc9e286ed356a679aa02d777c06e9bfd1164fa7c19c288a5483/watchdog-6.0.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdd4e6f14b8b18c334febb9c4425a878a2ac20efd1e0b231978e7b150f92a948", size = 96471, upload-time = "2024-11-01T14:06:37.745Z" }, { url = "https://files.pythonhosted.org/packages/12/87/48361531f70b1f87928b045df868a9fd4e253d9ae087fa4cf3f7113be363/watchdog-6.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c7c15dda13c4eb00d6fb6fc508b3c0ed88b9d5d374056b239c4ad1611125c860", size = 88449, upload-time = "2024-11-01T14:06:39.748Z" }, { url = "https://files.pythonhosted.org/packages/5b/7e/8f322f5e600812e6f9a31b75d242631068ca8f4ef0582dd3ae6e72daecc8/watchdog-6.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f10cb2d5902447c7d0da897e2c6768bca89174d0c6e1e30abec5421af97a5b0", size = 89054, upload-time = "2024-11-01T14:06:41.009Z" }, { url = "https://files.pythonhosted.org/packages/68/98/b0345cabdce2041a01293ba483333582891a3bd5769b08eceb0d406056ef/watchdog-6.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:490ab2ef84f11129844c23fb14ecf30ef3d8a6abafd3754a6f75ca1e6654136c", size = 96480, upload-time = "2024-11-01T14:06:42.952Z" }, { url = "https://files.pythonhosted.org/packages/85/83/cdf13902c626b28eedef7ec4f10745c52aad8a8fe7eb04ed7b1f111ca20e/watchdog-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:76aae96b00ae814b181bb25b1b98076d5fc84e8a53cd8885a318b42b6d3a5134", size = 88451, upload-time = "2024-11-01T14:06:45.084Z" }, { url = "https://files.pythonhosted.org/packages/fe/c4/225c87bae08c8b9ec99030cd48ae9c4eca050a59bf5c2255853e18c87b50/watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b", size = 89057, upload-time = "2024-11-01T14:06:47.324Z" }, { url = "https://files.pythonhosted.org/packages/a9/c7/ca4bf3e518cb57a686b2feb4f55a1892fd9a3dd13f470fca14e00f80ea36/watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13", size = 79079, upload-time = "2024-11-01T14:06:59.472Z" }, { url = "https://files.pythonhosted.org/packages/5c/51/d46dc9332f9a647593c947b4b88e2381c8dfc0942d15b8edc0310fa4abb1/watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379", size = 79078, upload-time = "2024-11-01T14:07:01.431Z" }, { url = "https://files.pythonhosted.org/packages/d4/57/04edbf5e169cd318d5f07b4766fee38e825d64b6913ca157ca32d1a42267/watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e", size = 79076, upload-time = "2024-11-01T14:07:02.568Z" }, { url = "https://files.pythonhosted.org/packages/ab/cc/da8422b300e13cb187d2203f20b9253e91058aaf7db65b74142013478e66/watchdog-6.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:212ac9b8bf1161dc91bd09c048048a95ca3a4c4f5e5d4a7d1b1a7d5752a7f96f", size = 79077, upload-time = "2024-11-01T14:07:03.893Z" }, { url = "https://files.pythonhosted.org/packages/2c/3b/b8964e04ae1a025c44ba8e4291f86e97fac443bca31de8bd98d3263d2fcf/watchdog-6.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:e3df4cbb9a450c6d49318f6d14f4bbc80d763fa587ba46ec86f99f9e6876bb26", size = 79078, upload-time = "2024-11-01T14:07:05.189Z" }, { url = "https://files.pythonhosted.org/packages/62/ae/a696eb424bedff7407801c257d4b1afda455fe40821a2be430e173660e81/watchdog-6.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:2cce7cfc2008eb51feb6aab51251fd79b85d9894e98ba847408f662b3395ca3c", size = 79077, upload-time = "2024-11-01T14:07:06.376Z" }, { url = "https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2", size = 79078, upload-time = "2024-11-01T14:07:07.547Z" }, { url = "https://files.pythonhosted.org/packages/07/f6/d0e5b343768e8bcb4cda79f0f2f55051bf26177ecd5651f84c07567461cf/watchdog-6.0.0-py3-none-win32.whl", hash = "sha256:07df1fdd701c5d4c8e55ef6cf55b8f0120fe1aef7ef39a1c6fc6bc2e606d517a", size = 79065, upload-time = "2024-11-01T14:07:09.525Z" }, { url = "https://files.pythonhosted.org/packages/db/d9/c495884c6e548fce18a8f40568ff120bc3a4b7b99813081c8ac0c936fa64/watchdog-6.0.0-py3-none-win_amd64.whl", hash = "sha256:cbafb470cf848d93b5d013e2ecb245d4aa1c8fd0504e863ccefa32445359d680", size = 79070, upload-time = "2024-11-01T14:07:10.686Z" }, { url = "https://files.pythonhosted.org/packages/33/e8/e40370e6d74ddba47f002a32919d91310d6074130fe4e17dabcafc15cbf1/watchdog-6.0.0-py3-none-win_ia64.whl", hash = "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f", size = 79067, upload-time = "2024-11-01T14:07:11.845Z" }, ] media_type_version-0.2.1/docs/changes.md0000644000000000000000000001475213615410400015212 0ustar00 # Changelog All notable changes to the media-type-version project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] ## [0.2.1] - 2025-12-20 ### Semi-incompatible changes - Python implementation: - `mtv-extract`: - move the CLI dependencies to a separate `cli` dependency group; this means e.g. packaging systems must now install them separately - Rust implementation: - `media-type-version`: - switch to versioned names for the `facet` unstable features so that, with the 0.32.x addition, the features are now named `facet030-unstable` and `facet032-unstable` - switch to a versioned name for the `json-serialzero0-unstable` feature ### Fixes - Python implementation: - test suite: - drop the unneeded `uvoxen` dependency from the `unit-tests` group - Rust implementation: - `mtv-extract`: - pin the version of the `media-type-version` dependency - Documentation: - bump some dependency versions for `uv --resolution=lowest` ### Additions - Python implementation: - test suite: - also run `ty` 0.0.4 for type checking - Rust implementation: - `media-type-version`: - add the `facet032-unstable` feature ### Other changes - Python implementation: - `mtv-extract`: - allow `cappa` 0.31.x with no changes - test suite: - use `ruff` 0.14.10 with no changes - allow `pytest` 9.x, invoke it with the `--strict` option - Rust implementation: - `media-type-version`: - internally import `facet` 0.30.x as `facet030`, `facet` 0.32.x as `facet032`, and `serialzero` 0.x as `serialzero0` - test suite: - use `facet-testhelpers` 0.32.x with no changes - drop the isolated feature sets for `cargo-feature-combinations` - Documentation: - allow `mkdocstrings` 1.x and `mkdocstrings-python` 2.x ## [0.2.0] - 2025-10-09 ### Incompatible changes - The `mtv-extract` command-line tool now expects a subcommand; both the Python and Rust implementations currently support the `features`, `json`, `lines`, and `toml` subcommands. ### Fixes - Rust implementation: - `media-type-version`: - expose the `ConfigBuilder` struct at top level - pin the versions of the `facet` dependencies - `mtv-extract`: - bump the version of the `feature-check` test dependency to 2.3.0 for `-Zminimal-versions` ### Additions - Python implementation: - `media-type-version`: - add the `extract_from_table()` function - `mtv-extract`: - switch to subcommands; implement `features`, `json`, `lines`, and `toml` - Rust implementation: - `media-type-version`: - add configuration for the `cargo-feature-combinations` test runner - add the `Table` trait and the `extract_from_table()` function enabled by the new `extract-from-table` feature - implement the `Table` trait for `boml::table::TomlTable` enabled by the new `toml-boml1` feature - implement the `Table` trait for `serialzero::JsonValue` enabled by the new `json-serialzero-unstable` feature - `mtv-extract`: - switch to subcommands; implement `features`, `json`, `lines`, and `toml` - add a trivial stdin unit test - run the Python test framework against the built `mtv-extract` executable ### Other changes - Python implementation: - bump the `uvoxen` dependency to 0.2.2 to support our version 0.2.x - use `ruff` 0.14.0 and `reuse` 6.x with no changes - allow `cappa` up to 0.30.x and `mkdocstrings` up to 0.30.x with no changes - Rust implementation: - `media-type-version`: - allow `facet` up to 0.29.x - `mtv-extract`: - allow `facet` up to 0.29.x ## [0.1.3] - 2025-06-16 ### Semi-incompatible changes - Rust implementation: - `media-type-version`: - make the `defs` module private; we expose everything we should via `pub use` ### Fixes - Rust implementation: - `mtv-extract`: - fix the invalid "media type" Cargo metadata keyword - Documentation: - fix the download URLs ### Additions - Rust implementation: - `media-type-version`: - expose the `OwnedError` type at crate top-level - expose the source error for `Error::UIntExpected` - add a unit test for the `Facet` trait ### Other changes - Python implementation: - refresh the `uv.lock` file - Rust implementation: - `media-type-version`: - use `facet` 0.27.13 with no changes - push the `run-clippy.sh` test tool down into the `rust/` subdirectory - refresh the `Cargo.lock` file ## [0.1.2] - 2025-06-08 ### Additions - Rust implementation: - `media-type-version`: - add the documentation base URL for the `crates-io` index ### Other changes - Python implementation: - allow `cappa` 0.28 with no changes - test suite: - use `uvoxen` 0.2 and switch to a `mediaType` format version - use `ruff` 0.11.13 with no changes - Rust implementation: - `media-type-version`: - use `facet` 0.27.12 for the `facet-unstable` feature - minor refactoring - `mtv-extract`: - switch from `anyhow` to `eyre` - test suite: - switch from `anyhow` to `eyre` - switch from `test-log` to `facet-testhelpers` ## [0.1.1] - 2025-05-23 ### Fixes - Rust implementation: - replace the invalid "media type" crate keyword with "media-type" ### Other changes - Python implementation: - refresh the `uv.lock` file - Rust implementation: - constify some missed functions ## [0.1.0] - 2025-05-23 ### Started - First public release. [Unreleased]: https://gitlab.com/ppentchev/media-type-version/-/compare/release%2F0.2.1...main [0.2.1]: https://gitlab.com/ppentchev/media-type-version/-/compare/release%2F0.2.0...release/0.2.1 [0.2.0]: https://gitlab.com/ppentchev/media-type-version/-/compare/release%2F0.1.3...release/0.2.0 [0.1.3]: https://gitlab.com/ppentchev/media-type-version/-/compare/release%2F0.1.2...release/0.1.3 [0.1.2]: https://gitlab.com/ppentchev/media-type-version/-/compare/release%2F0.1.1...release/0.1.2 [0.1.1]: https://gitlab.com/ppentchev/media-type-version/-/compare/release%2F0.1.0...release/0.1.1 [0.1.0]: https://gitlab.com/ppentchev/media-type-version/-/tags/release%2F0.1.0 media_type_version-0.2.1/docs/download.md0000644000000000000000000001246513615410400015410 0ustar00 # Download These are the released versions of [media-type-version](index.md) available for download. ## [0.2.1] - 2025-12-20 ### Source tarball - [media-type-version-0.2.1.tar.gz](https://devel.ringlet.net/files/devel/media-type-version/media-type-version-0.2.1.tar.gz) (with [a PGP signature](https://devel.ringlet.net/files/devel/media-type-version/media-type-version-0.2.1.tar.gz.asc)) - [media-type-version-0.2.1.tar.bz2](https://devel.ringlet.net/files/devel/media-type-version/media-type-version-0.2.1.tar.bz2) (with [a PGP signature](https://devel.ringlet.net/files/devel/media-type-version/media-type-version-0.2.1.tar.bz2.asc)) - [media-type-version-0.2.1.tar.xz](https://devel.ringlet.net/files/devel/media-type-version/media-type-version-0.2.1.tar.xz) (with [a PGP signature](https://devel.ringlet.net/files/devel/media-type-version/media-type-version-0.2.1.tar.xz.asc)) ## [0.2.0] - 2025-10-09 ### Source tarball - [media-type-version-0.2.0.tar.gz](https://devel.ringlet.net/files/devel/media-type-version/media-type-version-0.2.0.tar.gz) (with [a PGP signature](https://devel.ringlet.net/files/devel/media-type-version/media-type-version-0.2.0.tar.gz.asc)) - [media-type-version-0.2.0.tar.bz2](https://devel.ringlet.net/files/devel/media-type-version/media-type-version-0.2.0.tar.bz2) (with [a PGP signature](https://devel.ringlet.net/files/devel/media-type-version/media-type-version-0.2.0.tar.bz2.asc)) - [media-type-version-0.2.0.tar.xz](https://devel.ringlet.net/files/devel/media-type-version/media-type-version-0.2.0.tar.xz) (with [a PGP signature](https://devel.ringlet.net/files/devel/media-type-version/media-type-version-0.2.0.tar.xz.asc)) ## [0.1.3] - 2025-06-16 ### Source tarball - [media-type-version-0.1.3.tar.gz](https://devel.ringlet.net/files/devel/media-type-version/media-type-version-0.1.3.tar.gz) (with [a PGP signature](https://devel.ringlet.net/files/devel/media-type-version/media-type-version-0.1.3.tar.gz.asc)) - [media-type-version-0.1.3.tar.bz2](https://devel.ringlet.net/files/devel/media-type-version/media-type-version-0.1.3.tar.bz2) (with [a PGP signature](https://devel.ringlet.net/files/devel/media-type-version/media-type-version-0.1.3.tar.bz2.asc)) - [media-type-version-0.1.3.tar.xz](https://devel.ringlet.net/files/devel/media-type-version/media-type-version-0.1.3.tar.xz) (with [a PGP signature](https://devel.ringlet.net/files/devel/media-type-version/media-type-version-0.1.3.tar.xz.asc)) ## [0.1.2] - 2025-06-08 ### Source tarball - [media-type-version-0.1.2.tar.gz](https://devel.ringlet.net/files/devel/media-type-version/media-type-version-0.1.2.tar.gz) (with [a PGP signature](https://devel.ringlet.net/files/devel/media-type-version/media-type-version-0.1.2.tar.gz.asc)) - [media-type-version-0.1.2.tar.bz2](https://devel.ringlet.net/files/devel/media-type-version/media-type-version-0.1.2.tar.bz2) (with [a PGP signature](https://devel.ringlet.net/files/devel/media-type-version/media-type-version-0.1.2.tar.bz2.asc)) - [media-type-version-0.1.2.tar.xz](https://devel.ringlet.net/files/devel/media-type-version/media-type-version-0.1.2.tar.xz) (with [a PGP signature](https://devel.ringlet.net/files/devel/media-type-version/media-type-version-0.1.2.tar.xz.asc)) ## [0.1.1] - 2025-05-23 ### Source tarball - [media-type-version-0.1.1.tar.gz](https://devel.ringlet.net/files/devel/media-type-version/media-type-version-0.1.1.tar.gz) (with [a PGP signature](https://devel.ringlet.net/files/devel/media-type-version/media-type-version-0.1.1.tar.gz.asc)) - [media-type-version-0.1.1.tar.bz2](https://devel.ringlet.net/files/devel/media-type-version/media-type-version-0.1.1.tar.bz2) (with [a PGP signature](https://devel.ringlet.net/files/devel/media-type-version/media-type-version-0.1.1.tar.bz2.asc)) - [media-type-version-0.1.1.tar.xz](https://devel.ringlet.net/files/devel/media-type-version/media-type-version-0.1.1.tar.xz) (with [a PGP signature](https://devel.ringlet.net/files/devel/media-type-version/media-type-version-0.1.1.tar.xz.asc)) ## [0.1.0] - 2025-05-23 ### Source tarball - [media-type-version-0.1.0.tar.gz](https://devel.ringlet.net/files/devel/media-type-version/media-type-version-0.1.0.tar.gz) (with [a PGP signature](https://devel.ringlet.net/files/devel/media-type-version/media-type-version-0.1.0.tar.gz.asc)) - [media-type-version-0.1.0.tar.bz2](https://devel.ringlet.net/files/devel/media-type-version/media-type-version-0.1.0.tar.bz2) (with [a PGP signature](https://devel.ringlet.net/files/devel/media-type-version/media-type-version-0.1.0.tar.bz2.asc)) - [media-type-version-0.1.0.tar.xz](https://devel.ringlet.net/files/devel/media-type-version/media-type-version-0.1.0.tar.xz) (with [a PGP signature](https://devel.ringlet.net/files/devel/media-type-version/media-type-version-0.1.0.tar.xz.asc)) [0.2.1]: https://gitlab.com/ppentchev/media-type-version/-/tags/release%2F0.2.1 [0.2.0]: https://gitlab.com/ppentchev/media-type-version/-/tags/release%2F0.2.0 [0.1.3]: https://gitlab.com/ppentchev/media-type-version/-/tags/release%2F0.1.3 [0.1.2]: https://gitlab.com/ppentchev/media-type-version/-/tags/release%2F0.1.2 [0.1.1]: https://gitlab.com/ppentchev/media-type-version/-/tags/release%2F0.1.1 [0.1.0]: https://gitlab.com/ppentchev/media-type-version/-/tags/release%2F0.1.0 media_type_version-0.2.1/docs/index.md0000644000000000000000000001312213615410400014677 0ustar00 # media-type-version - extract the format version from a media type string \[[Home][ringlet-home] | [GitLab][gitlab] | [PyPI][pypi] | [crates.io][crates-io] | [Python API](api/python.md) | [ReadTheDocs][readthedocs]\] ## Overview The `media-type-version` library is designed to be used as the first step in parsing structured data, e.g. configuration files, serialized classes, etc. The caller extracts the media type string (e.g. a JSON `"mediaType": "..."` key) and passes it in for parsing. The caller then decides what to do with the extracted version information - is this version supported, what fields are expected to be there, should any extraneous fields produce errors, and so on. The media type string is expected to be in a `.vX.Y` format, with a fixed prefix and suffix. The prefix will usually be a vendor-specific media type. The version part consists of two unsigned integer numbers. The suffix, if used, may correspond to the file format. A sample media type string identifying a TOML configuration file for a text-processing program could be `vnd.ringlet.textproc.publync.config/publync.v0.2+toml` ## The library The `media-type-version` library provides a single function, `extract()`, that parses a media type string, strips the specified prefix and suffix, and looks for a `.vX.Y` version string left. It then returns the (`X`, `Y`) version tuple. Python example: ``` py mtv_cfg: Final = media_type_version.Config( log=logging.Logger(...), prefix="vnd.acme/thing", suffix="+toml", ) ver_major, ver_minor = media_type_version.extract(mtv_cfg, "vnd.acme/thing.v3.12+toml") ``` Rust example: ``` rust use media_type_version::{Config as MTVConfig, Error as MTVError, Version as MTVersion}; let cfg = MTVConfig::builder() .prefix("vnd.acme/thing") .suffix("+toml") .build() .map_err(MTVError::into_owned_error)?; assert_eq!( media_type_version::extract(&cfg, "vnd.acme/thing.v3.12+toml").as_tuple(), (3, 12) ); ``` ## The mtv-extract tool The `media-type-version` library also provides a command-line tool called `mtv-extract` that can be used to extract format versions from various sources. The `mtv-extract` tool supports the following top-level command-line options: - `-q`: quiet operation; only display warnings and error messages - `-v`: verbose operation; display diagnostic output ### The "features" subcommand The `features` subcommand will display a single line of output starting with the prefix "Features: " and containing a space-separated list of "name=version" pairs. This output format is intended to be machine-readable, so that other programs may examine it using e.g. [the feature-check library and command-line tool][feature-check]. ### The "lines" subcommand The `lines` subcommand will read a series of strings from the specified files, parse them as media-type strings with the specified prefix and suffix, and output a line consisting of two tab-separated numbers for each parsed string: ``` sh $ { echo vnd.acme/thing.v3.47; echo vnd.acme/thing.v42.616; } | mtv-extract -q lines -p vnd.acme/thing -- - 3 47 42 616 $ ``` The `lines` subcommand supports the following command-line options: - `-p prefix` (required): the prefix to strip from the media type string - `-s suffix`: the optional suffix to strip from the media type string ## Supported features The `features` subcommand of the `mtv-extract` tool, as well as the `FEATURES` constant in both the Python and Rust implementations, may currently list the following features: ### media-type-version The version of the `media-type-version` library itself. ### cmd-features #### 0.1 The command-line tool supports the `features` subcommand with the output format described above. ### cmd-lines #### 0.1 The command-line tool supports the `lines` subcommand with the mandatory prefix option and the optional suffix one. It requires at least one file name to read from, and it supports `-` for reading from the standard input stream. ### extract #### 0.1 The library supports the `extract()` function. It accepts a `Config` parameter containing the prefix and suffix strings, and a string parameter to parse. The string must contain a ".vX.Y" version specification between the prefix and the suffix. ## Implementation-specific details ### Python Note that while the `media-type-version` Python module will install a `__main__.py` file that implements the `mtv-extract` command-line tool interface described above, the Python libraries needed for running it are not installed by default. They are part of the `cli` optional dependency group and must be installed separately by e.g. packaging systems. ## Contact The `media-type-version` library was written by [Peter Pentchev][roam]. It is developed in [a GitLab repository][gitlab]. This documentation is hosted at [Ringlet][ringlet-home] with a copy at [ReadTheDocs][readthedocs]. [roam]: mailto:roam@ringlet.net "Peter Pentchev" [crates-io]: https://crates.io/crates/media-type-version "The media-type-version Rust crates.io page" [feature-check]: https://devel.ringlet.net/misc/feature-check/ "The feature-check library and command-line tool" [gitlab]: https://gitlab.com/ppentchev/media-type-version "The media-type-version GitLab repository" [pypi]: https://pypi.org/project/media-type-version/ "The media-type-version Python Package Index page" [readthedocs]: https://media-type-version.readthedocs.io/ "The media-type-version ReadTheDocs page" [ringlet-home]: https://devel.ringlet.net/devel/media-type-version/ "The Ringlet media-type-version homepage" media_type_version-0.2.1/docs/api/python.md0000644000000000000000000000024613615410400015665 0ustar00 # The media-type-version Python API ::: media_type_version media_type_version-0.2.1/python/ruff-base.toml0000644000000000000000000000162113615410400016407 0ustar00# SPDX-FileCopyrightText: Peter Pentchev # SPDX-License-Identifier: BSD-2-Clause target-version = "py311" line-length = 100 [lint] select = [] ignore = [ # No blank lines before the class docstring, TYVM "D203", # The multi-line docstring summary starts on the same line "D213", # We do not document everything in the docstring "DOC201", "DOC402", "DOC501", # The /x regex modifier is common enough in many languages "FURB167", ] [lint.flake8-copyright] notice-rgx = "(?x) SPDX-FileCopyrightText: \\s \\S" [lint.isort] force-single-line = true known-first-party = ["media_type_version"] lines-after-imports = 2 single-line-exclusions = ["collections.abc", "typing"] [lint.per-file-ignores] # This is a command-line tool; console output is part of its job. "src/media_type_version/__main__.py" = ["T201"] # This is a test suite "tests/unit/**.py" = ["S101", "T201"] media_type_version-0.2.1/python/requirements/docs.txt0000644000000000000000000000033613615410400020056 0ustar00# SPDX-FileCopyrightText: Peter Pentchev # SPDX-License-Identifier: BSD-2-Clause mkdocs >= 1.5, < 2 mkdocs-material >= 9.3, < 10 mkdocstrings >= 1, < 2 mkdocstrings-python >= 1.4, < 2 markupsafe >= 2.1 media_type_version-0.2.1/python/src/media_type_version/__init__.py0000644000000000000000000000066713615410400022436 0ustar00# SPDX-FileCopyrightText: Peter Pentchev # SPDX-License-Identifier: BSD-2-Clause """Extract the format version from a media type string.""" from __future__ import annotations from .defs import VERSION from .defs import Config from .defs import MTVError from .impl import extract from .impl import extract_from_table __all__ = [ "VERSION", "Config", "MTVError", "extract", "extract_from_table", ] media_type_version-0.2.1/python/src/media_type_version/__main__.py0000644000000000000000000001703113615410400022410 0ustar00# SPDX-FileCopyrightText: Peter Pentchev # SPDX-License-Identifier: BSD-2-Clause """Do things, or do other things.""" from __future__ import annotations import dataclasses import json import pathlib import sys import tomllib import typing from typing import Annotated import cappa from . import defs from . import impl from . import util if typing.TYPE_CHECKING: from typing import Any, Final @cappa.command(name="features") @dataclasses.dataclass(frozen=True) class CmdFeatures: """List the features supported by the program.""" @cappa.command(name="json") @dataclasses.dataclass(frozen=True) class CmdJSON: """Extract the format version from a JSON document.""" prefix: Annotated[str, cappa.Arg(short=True, long=True)] """The prefix to expect in the media type string.""" files: list[str] """The files to parse; `-` denotes the standard input stream.""" suffix: Annotated[str, cappa.Arg(short=True, long=True)] = "" """The optional suffix in the media type string.""" path: Annotated[str | None, cappa.Arg(short="-P", long=True)] = None """The dot-separated path to the JSON document's section to examine.""" @cappa.command(name="lines") @dataclasses.dataclass(frozen=True) class CmdLines: """Extract the format version from successive lines of text.""" prefix: Annotated[str, cappa.Arg(short=True, long=True)] """The prefix to expect in the media type string.""" files: list[str] """The files to parse; `-` denotes the standard input stream.""" suffix: Annotated[str, cappa.Arg(short=True, long=True)] = "" """The optional suffix in the media type string.""" @cappa.command(name="toml") @dataclasses.dataclass(frozen=True) class CmdTOML: """Extract the format version from a TOML document.""" prefix: Annotated[str, cappa.Arg(short=True, long=True)] """The prefix to expect in the media type string.""" files: list[str] """The files to parse; `-` denotes the standard input stream.""" suffix: Annotated[str, cappa.Arg(short=True, long=True)] = "" """The optional suffix in the media type string.""" path: Annotated[str | None, cappa.Arg(short="-P", long=True)] = None """The dot-separated path to the TOML document's section to examine.""" @dataclasses.dataclass(frozen=True) class MtvExtract: """Extract the format version from a media type string.""" quiet: Annotated[bool, cappa.Arg(short=True, long=True)] """Quiet operation; only display warnings and error messages.""" verbose: Annotated[bool, cappa.Arg(short=True, long=True)] """Verbose operation; display diagnostic messages.""" cmd: cappa.Subcommands[CmdFeatures | CmdJSON | CmdLines | CmdTOML] """What to do, what to do?""" def do_parse_lines(cfg: defs.Config, fname: str, contents: str) -> None: """Read media type strings from a file, parse them.""" for line in contents.splitlines(): try: ver_major, ver_minor = impl.extract(cfg, line) except defs.MTVError as err: sys.exit(f"Could not parse a {fname} line: {line!r}: {err}") print(f"{ver_major}\t{ver_minor}") def parse_lines(cfg: defs.Config, fname: str) -> None: """Parse a single file containing media type strings.""" if fname == "-": cfg.log.info("Reading from the standard input stream") contents = sys.stdin.read() fname = "(standard input)" else: cfg.log.info("Reading the contents of %(fname)s", {"fname": fname}) try: contents = pathlib.Path(fname).read_text(encoding="UTF-8") except OSError as err: sys.exit(f"Could not read {fname}: {err}") cfg.log.debug("Read %(count)d characters", {"count": len(contents)}) do_parse_lines(cfg, fname, contents) def descend_and_parse(cfg: defs.Config, fname: str, path: list[str], raw: dict[str, Any]) -> None: """Parse the `mediaType` field of a TOML document.""" try: ver_major, ver_minor = impl.extract_from_table(cfg, raw, path) except defs.MTVError as err: level = impl.pathstr([*path, "mediaType"]) sys.exit(f"Could not parse the {level} value at {fname}: {err}") print(f"{ver_major}\t{ver_minor}") def parse_json(cfg: defs.Config, fname: str, path: list[str]) -> None: """Parse the `mediaType` field of a JSON document read from a file or the standard input.""" if fname == "-": cfg.log.info("Reading from the standard input stream") contents = sys.stdin.read() fname = "(standard input)" else: cfg.log.info("Reading the contents of %(fname)s", {"fname": fname}) try: contents = pathlib.Path(fname).read_text(encoding="UTF-8") except OSError as err: sys.exit(f"Could not read {fname}: {err}") cfg.log.debug("Read %(count)d characters", {"count": len(contents)}) try: raw: Final = json.loads(contents) except ValueError as err: sys.exit(f"Could not parse {fname} as valid JSON: {err}") if not isinstance(raw, dict): sys.exit(f"Expected the TOML document at {fname} to be an object at top level") descend_and_parse(cfg, fname, path, raw) def parse_toml(cfg: defs.Config, fname: str, path: list[str]) -> None: """Parse the `mediaType` field of a TOML document read from a file or the standard input.""" if fname == "-": cfg.log.info("Reading from the standard input stream") contents = sys.stdin.read() fname = "(standard input)" else: cfg.log.info("Reading the contents of %(fname)s", {"fname": fname}) try: contents = pathlib.Path(fname).read_text(encoding="UTF-8") except OSError as err: sys.exit(f"Could not read {fname}: {err}") cfg.log.debug("Read %(count)d characters", {"count": len(contents)}) try: raw: Final = tomllib.loads(contents) except ValueError as err: sys.exit(f"Could not parse {fname} as valid TOML: {err}") if not isinstance(raw, dict): sys.exit(f"Expected the TOML document at {fname} to be a table at top level") descend_and_parse(cfg, fname, path, raw) def show_features() -> None: """List the features supported by the program.""" print( f"Features: {' '.join(f'{name}={value}' for name, value in sorted(defs.FEATURES.items()))}", ) def main() -> None: """Parse command-line options, read files, extract data.""" args: Final = cappa.parse(MtvExtract, completion=False) match args.cmd: case CmdFeatures(): show_features() case CmdJSON(prefix, files, suffix, path): cfg = defs.Config( log=util.build_logger(quiet=args.quiet, verbose=args.verbose), prefix=prefix, suffix=suffix, ) for fname in files: parse_json(cfg, fname, path.split(".") if path else []) case CmdLines(prefix, files, suffix): cfg = defs.Config( log=util.build_logger(quiet=args.quiet, verbose=args.verbose), prefix=prefix, suffix=suffix, ) for fname in files: parse_lines(cfg, fname) case CmdTOML(prefix, files, suffix, path): cfg = defs.Config( log=util.build_logger(quiet=args.quiet, verbose=args.verbose), prefix=prefix, suffix=suffix, ) for fname in files: parse_toml(cfg, fname, path.split(".") if path else []) case _: raise RuntimeError(repr(args)) if __name__ == "__main__": main() media_type_version-0.2.1/python/src/media_type_version/defs.py0000644000000000000000000000246013615410400021611 0ustar00# SPDX-FileCopyrightText: Peter Pentchev # SPDX-License-Identifier: BSD-2-Clause """Common definitions for the media-type-version library.""" from __future__ import annotations import dataclasses import typing if typing.TYPE_CHECKING: import logging from typing import Final VERSION: Final = "0.2.1" """The media-type-version library version, semver-like.""" FEATURES: Final = { "media-type-version": VERSION, "cmd-features": "0.1", "cmd-json": "0.1", "cmd-lines": "0.1", "cmd-toml": "0.1", "extract": "0.1", "extract-from-table": "0.1", } """The list of features supported by the media-type-version library.""" @dataclasses.dataclass class MTVError(Exception): """An error that occurred while parsing the media type string.""" def __str__(self) -> str: """Provide a human-readable description of the error.""" return f"Could not parse a media type string: {self!r}" @dataclasses.dataclass(frozen=True) class Config: """Runtime configuration for the media-type-version library.""" log: logging.Logger """The logger to send diagnostic, informational, and error messages to.""" prefix: str """The prefix to expect in the media type string.""" suffix: str """The optional suffix in the media type string.""" media_type_version-0.2.1/python/src/media_type_version/impl.py0000644000000000000000000001266713615410400021643 0ustar00# SPDX-FileCopyrightText: Peter Pentchev # SPDX-License-Identifier: BSD-2-Clause """Extract the format version from a media type string.""" from __future__ import annotations import dataclasses import re import typing from . import defs if typing.TYPE_CHECKING: from collections.abc import Callable from typing import Any, Final RE_INT: Final = re.compile(r" 0 | [1-9][0-9]* ", re.X) """Detect an unsigned integer value.""" @dataclasses.dataclass class NoPrefixError(defs.MTVError): """The expected prefix was not found.""" value: str """The media type string to examine.""" prefix: str """The expected prefix.""" def __str__(self) -> str: """Provide a human-readable description of the error.""" return f"The expected prefix {self.prefix!r} is not present in {self.value!r}" @dataclasses.dataclass class NoSuffixError(defs.MTVError): """The expected suffix was not found.""" value: str """The media type string to examine.""" suffix: str """The expected suffix.""" def __str__(self) -> str: """Provide a human-readable description of the error.""" return f"The expected suffix {self.suffix!r} is not present in {self.value!r}" @dataclasses.dataclass class NoVersionError(defs.MTVError): """There was no '.v' component.""" value: str """The media type string to examine.""" prefix: str """The expected prefix.""" suffix: str """The expected suffix.""" def __str__(self) -> str: """Provide a human-readable description of the error.""" return ( f"No '.v' component in {self.value!r} after removing " f"the {self.prefix!r} prefix and the {self.suffix!r} suffix" ) @dataclasses.dataclass class NonIntegerComponentError(defs.MTVError): """A version component was not a decimal integer.""" value: str """The media type string to examine.""" comp: str """The version component.""" def __str__(self) -> str: """Provide a human-readable description of the error.""" return f"The {self.comp!r} component of {self.value!r} is not an unsigned decimal integer" @dataclasses.dataclass class TwoComponentsExpectedError(defs.MTVError): """The version part did not consist of two components.""" value: str """The media type string to examine.""" version_part: str """The version part of the string.""" def __str__(self) -> str: """Provide a human-readable description of the error.""" return ( f"The {self.version_part!r} part of {self.value!r} does not " f"consist of two dot-separated parts" ) @dataclasses.dataclass class WrongTypeChildError(defs.MTVError): """The expected TOML, JSON, etc. value did not contain a table/object where we expected one.""" path: list[str] """The path where we expected a child.""" tag: str """The type of the child we expected to see.""" name: str """The name of the expected child.""" def __str__(self) -> str: """Provide a human-readable description of the error.""" level = pathstr(self.path) return f"Expected the parsed value to have a '{self.name}' {self.tag} at {level}" def pathstr(elpath: list[str]) -> str: """Return the string representation of a path within a document.""" if not elpath: return "top level" joined: Final = ".".join(elpath) return f"[{joined}]" def rm_part( value: str, part: str, rm_func: Callable[[str, str], str], error_class: type[NoPrefixError | NoSuffixError], ) -> str: """Remove a part of the version string if it is specified.""" if not part: return value res: Final = rm_func(value, part) if res == value: raise error_class(value, part) return res def extract(cfg: defs.Config, value: str) -> tuple[int, int]: """Extract the media type format version as a (major, minor) tuple.""" def parse_int(comp: str) -> int: """Parse a version component into a base-10 integer.""" if not RE_INT.match(comp): raise NonIntegerComponentError(value, comp) try: return int(comp, base=10) except ValueError as err: raise NonIntegerComponentError(value, comp) from err no_pfx: Final = rm_part(value, cfg.prefix, str.removeprefix, NoPrefixError) no_sfx: Final = rm_part(no_pfx, cfg.suffix, str.removesuffix, NoSuffixError) no_vdot: Final = no_sfx.removeprefix(".v") if no_vdot == no_sfx: raise NoVersionError(value, cfg.prefix, cfg.suffix) cfg.log.debug("Parsing the media type version part %(vers)r", {"vers": no_vdot}) match no_vdot.split("."): case [major, minor]: return parse_int(major), parse_int(minor) case _: raise TwoComponentsExpectedError(value, no_vdot) def extract_from_table(cfg: defs.Config, raw: dict[str, Any], path: list[str]) -> tuple[int, int]: """Recurse into a dict, extract the media type version string, parse it.""" current_path: list[str] = [] for comp in path: next_raw = raw.get(comp) if not isinstance(next_raw, dict): raise WrongTypeChildError(current_path, "table", comp) raw = next_raw current_path.append(comp) media_type: Final = raw.get("mediaType") if not isinstance(media_type, str): raise WrongTypeChildError(path, "string", "mediaType") return extract(cfg, media_type) media_type_version-0.2.1/python/src/media_type_version/py.typed0000644000000000000000000000000013615410400022001 0ustar00media_type_version-0.2.1/python/src/media_type_version/util.py0000644000000000000000000000266013615410400021647 0ustar00# SPDX-FileCopyrightText: Peter Pentchev # SPDX-License-Identifier: BSD-2-Clause """Helper functions for the media_type_version library.""" from __future__ import annotations import functools import logging import sys import typing if typing.TYPE_CHECKING: from typing import Final @functools.lru_cache def build_logger(*, quiet: bool = False, verbose: bool = False) -> logging.Logger: """Build a logger that outputs to the standard output and error streams. Messages of level `WARNING` and higher go to the standard error stream. If `quiet` is false, messages of level `INFO` also go to the standard error stream. If `verbose` is true, messages of level `DEBUG` also go to the standard error stream. """ logger: Final = logging.getLogger("media_type_version") logger.setLevel(logging.DEBUG if verbose else logging.WARNING if quiet else logging.INFO) logger.propagate = False diag_handler: Final = logging.StreamHandler(sys.stderr) diag_handler.setLevel(logging.DEBUG if verbose else logging.WARNING) if not quiet: diag_handler.addFilter(lambda rec: rec.levelno != logging.INFO) logger.addHandler(diag_handler) if not quiet: info_handler: Final = logging.StreamHandler(sys.stderr) info_handler.setLevel(logging.INFO) info_handler.addFilter(lambda rec: rec.levelno == logging.INFO) logger.addHandler(info_handler) return logger media_type_version-0.2.1/python/tests/run-uvoxen.sh0000755000000000000000000000050413615410400017466 0ustar00# SPDX-FileCopyrightText: Peter Pentchev # SPDX-License-Identifier: BSD-2-Clause set -e set -x rm -rf .venv uvoxen uv run -- -vv uvoxen -p supported uv run -e mypy,unit-tests,unit-tests-cli -- -vv if [ -n "$RUN_UVOXEN_TOX_STAGES" ]; then "$RUN_UVOXEN_TOX_STAGES" run fi rm -rf .venv uv sync --exact media_type_version-0.2.1/python/tests/unit/__init__.py0000644000000000000000000000025113615410400020070 0ustar00# SPDX-FileCopyrightText: Peter Pentchev # SPDX-License-Identifier: BSD-2-Clause """Unit test suite for the media type version extraction library.""" media_type_version-0.2.1/python/tests/unit/test_extract.py0000644000000000000000000000146613615410400021053 0ustar00# SPDX-FileCopyrightText: Peter Pentchev # SPDX-License-Identifier: BSD-2-Clause """Test the various extraction routines in the `media-type-version` library.""" from __future__ import annotations import itertools import typing import pytest import media_type_version from . import util if typing.TYPE_CHECKING: from typing import Final @pytest.mark.parametrize( ("path", "ver_tuple"), itertools.product(util.PATHS, util.VERSIONS), ) def test_extract_from_table(*, path: list[str], ver_tuple: tuple[int, int]) -> None: """Make sure we can extract the media type version from a TOML document.""" document: Final = util.build_document(path, ver_tuple) res: Final = media_type_version.extract_from_table(util.build_test_config(), document, path) assert res == ver_tuple media_type_version-0.2.1/python/tests/unit/test_metadata.py0000644000000000000000000000201713615410400021152 0ustar00# SPDX-FileCopyrightText: Peter Pentchev # SPDX-License-Identifier: BSD-2-Clause """Basic test for file importing.""" from __future__ import annotations import re import typing from packaging import version as pkg_version from media_type_version import defs _RE_FEATURE_VALUE: Final = re.compile( r"^ (?P 0 | [1-9][0-9]* ) \. (?P 0 | [1-9][0-9]* )", re.X, ) if typing.TYPE_CHECKING: from typing import Final def test_version() -> None: """Make sure the `VERSION` variable has a sane value.""" version: Final = pkg_version.Version(defs.VERSION) assert version > pkg_version.Version("0") def test_features() -> None: """Make sure that the list of features looks right. It must include the program's name, and each value must be a X.Y number pair. """ assert defs.FEATURES["media-type-version"] == defs.VERSION for value in (value for name, value in defs.FEATURES.items() if name != "media-type-version"): assert _RE_FEATURE_VALUE.match(value) media_type_version-0.2.1/python/tests/unit/test_prog.py0000644000000000000000000002033413615410400020343 0ustar00# SPDX-FileCopyrightText: Peter Pentchev # SPDX-License-Identifier: BSD-2-Clause """Make sure that `media-type-version run` starts up at least.""" from __future__ import annotations import dataclasses import itertools import json import os import subprocess # noqa: S404 import sys import tempfile import typing import feature_check import pytest import tomli_w from feature_check import parser as fc_parser from media_type_version import defs from . import util if typing.TYPE_CHECKING: from typing import Final @dataclasses.dataclass class GlobalCache: """Some values cached between test executions.""" test_prog: list[str] """The test program to run.""" features: dict[str, feature_check.Version] """The features supported by the test program.""" def __init__(self) -> None: """Examine the program to be tested.""" env_prog: Final = os.environ.get("TEST_MTV_EXTRACT_PROG") self.test_prog = ( [env_prog] if env_prog is not None else [sys.executable, "-m", "media_type_version"] ) output: Final = subprocess.check_output([*self.test_prog, "features"], encoding="UTF-8") # noqa: S603 match output.splitlines(): case [first]: features_list: Final = first.removeprefix("Features: ") print(f"Got features line {first!r}") assert features_list != first, "Expected a 'Features: ' prefix" print(f"Got features list {features_list!r}") self.features = fc_parser.parse_features_line(features_list) case _: raise RuntimeError(repr((self.test_prog, output))) _CACHE: Final = GlobalCache() def get_prog() -> list[str]: """Determine the test program to run.""" return _CACHE.test_prog def get_features() -> dict[str, feature_check.Version]: """Obtain the list of features supported by the tested program.""" return _CACHE.features def get_feature(name: str) -> feature_check.Version | None: """Get the specified program feature's version if it is available.""" return get_features().get(name) def assert_cmd_lines() -> None: """Make sure the "lines" feature is always supported.""" assert get_feature("cmd-lines") is not None def test_features() -> None: """Make sure that `mtv-extract features` works.""" features: Final = get_features() assert features["media-type-version"] == feature_check.parse_version( defs.FEATURES["media-type-version"], ) def get_lines_output(prog: list[str], *, contents: str, from_stdin: bool) -> str: """Run `mtv-extract lines`, return the output.""" if from_stdin: return subprocess.check_output( # noqa: S603 [*prog, "lines", "-p", util.PREFIX, "-s", util.SUFFIX, "--", "-"], encoding="UTF-8", input=contents, ) with tempfile.NamedTemporaryFile( encoding="UTF-8", mode="wt", prefix="mtv-test-", suffix=".txt", ) as tempf_obj: print(contents, file=tempf_obj, end="") tempf_obj.flush() return subprocess.check_output( # noqa: S603 [*prog, "lines", "-p", util.PREFIX, "-s", util.SUFFIX, "--", tempf_obj.name], encoding="UTF-8", ) @pytest.mark.parametrize( ("from_stdin", "ver_tuple"), itertools.product([False, True], util.VERSIONS), ) def test_lines_one_by_one(*, from_stdin: bool, ver_tuple: tuple[int, int]) -> None: """Make sure that `mtv-extract lines -` can parse a string.""" assert_cmd_lines() major, minor = ver_tuple output: Final = get_lines_output( get_prog(), contents=util.build_media_type(ver_tuple), from_stdin=from_stdin, ) assert output == f"{major}\t{minor}\n" @pytest.mark.parametrize("from_stdin", [False, True]) def test_lines_all_at_once(*, from_stdin: bool) -> None: """Make sure that `mtv-extract lines -` can parse several strings at once.""" assert_cmd_lines() output: Final = get_lines_output( get_prog(), contents="".join(util.build_media_type(ver) + "\n" for ver in util.VERSIONS), from_stdin=from_stdin, ) assert output == "".join(f"{major}\t{minor}\n" for major, minor in util.VERSIONS) def get_toml_output(prog: list[str], *, contents: str, from_stdin: bool, path: list[str]) -> str: """Run `mtv-extract lines`, return the output.""" opts_path: Final = ["-P", ".".join(path)] if path else [] if from_stdin: return subprocess.check_output( # noqa: S603 [*prog, "-v", "toml", "-p", util.PREFIX, "-s", util.SUFFIX, *opts_path, "--", "-"], encoding="UTF-8", input=contents, ) with tempfile.NamedTemporaryFile( encoding="UTF-8", mode="wt", prefix="mtv-test-", suffix=".txt", ) as tempf_obj: print(contents, file=tempf_obj, end="") tempf_obj.flush() return subprocess.check_output( # noqa: S603 [*prog, "toml", "-p", util.PREFIX, "-s", util.SUFFIX, *opts_path, "--", tempf_obj.name], encoding="UTF-8", ) @pytest.mark.skipif(get_feature("cmd-toml") is None, reason="No cmd-toml support") @pytest.mark.parametrize( ("from_stdin", "path", "ver_tuple"), itertools.product([False, True], util.PATHS, util.VERSIONS), ) def test_toml_one_by_one(*, from_stdin: bool, path: list[str], ver_tuple: tuple[int, int]) -> None: """Make sure that `mtv-extract lines -` can parse a string.""" major, minor = ver_tuple contents: Final = tomli_w.dumps(util.build_document(path, ver_tuple)) output: Final = get_toml_output( get_prog(), contents=contents, from_stdin=from_stdin, path=path, ) assert output == f"{major}\t{minor}\n" @pytest.mark.skipif(get_feature("cmd-toml") is None, reason="No cmd-toml support") def test_toml_pyproject() -> None: """Read the two version strings from the `pyproject.toml` file.""" output_publync: Final = subprocess.check_output( # noqa: S603 [ *get_prog(), "-v", "toml", "-P", "tool.publync", "-p", "vnd.ringlet.misc.publync.config/publync", "-s", "+toml", "pyproject.toml", ], encoding="UTF-8", ) assert output_publync == "0\t1\n" output_uvoxen: Final = subprocess.check_output( # noqa: S603 [ *get_prog(), "-v", "toml", "-P", "tool.uvoxen", "-p", "vnd.ringlet.devel.uvoxen.config/uvoxen", "-s", "+toml", "pyproject.toml", ], encoding="UTF-8", ) assert output_uvoxen == "0\t3\n" def get_json_output(prog: list[str], *, contents: str, from_stdin: bool, path: list[str]) -> str: """Run `mtv-extract lines`, return the output.""" opts_path: Final = ["-P", ".".join(path)] if path else [] if from_stdin: return subprocess.check_output( # noqa: S603 [*prog, "-v", "json", "-p", util.PREFIX, "-s", util.SUFFIX, *opts_path, "--", "-"], encoding="UTF-8", input=contents, ) with tempfile.NamedTemporaryFile( encoding="UTF-8", mode="wt", prefix="mtv-test-", suffix=".txt", ) as tempf_obj: print(contents, file=tempf_obj, end="") tempf_obj.flush() return subprocess.check_output( # noqa: S603 [*prog, "json", "-p", util.PREFIX, "-s", util.SUFFIX, *opts_path, "--", tempf_obj.name], encoding="UTF-8", ) @pytest.mark.skipif(get_feature("cmd-json") is None, reason="No cmd-json support") @pytest.mark.parametrize( ("from_stdin", "path", "ver_tuple"), itertools.product([False, True], util.PATHS, util.VERSIONS), ) def test_json_one_by_one(*, from_stdin: bool, path: list[str], ver_tuple: tuple[int, int]) -> None: """Make sure that `mtv-extract lines -` can parse a string.""" major, minor = ver_tuple contents: Final = json.dumps(util.build_document(path, ver_tuple)) output: Final = get_json_output( get_prog(), contents=contents, from_stdin=from_stdin, path=path, ) assert output == f"{major}\t{minor}\n" media_type_version-0.2.1/python/tests/unit/util.py0000644000000000000000000000406113615410400017311 0ustar00# SPDX-FileCopyrightText: Peter Pentchev # SPDX-License-Identifier: BSD-2-Clause """Helper functions for the `media-type-version` Python unit tests.""" from __future__ import annotations import functools import logging import typing import pytest import media_type_version if typing.TYPE_CHECKING: from typing import Any, Final PREFIX: Final = "vnd.ringlet.something/else" """The prefix for the media type string before the .vX.Y part.""" SUFFIX: Final = "+toml" """The expected suffix.""" VERSIONS: Final = [ (42, 616), (0, 0), (0, 1), (3, 0), ] """The version combinations to test with.""" PATHS: Final[list[list[str]]] = [ [], ["prog"], ["tool", "media"], ] """The paths to put the `mediaType` element in for TOML, JSON, et al tests.""" @functools.lru_cache def build_test_config() -> media_type_version.Config: """Build the runtime configuration for parsing our test media type strings.""" return media_type_version.Config(log=logging.getLogger(), prefix=PREFIX, suffix=SUFFIX) @functools.lru_cache def build_media_type(ver_tuple: tuple[int, int]) -> str: """Build a media type string with our test prefix and suffix.""" return f"{PREFIX}.v{ver_tuple[0]}.{ver_tuple[1]}{SUFFIX}" def build_document( path: list[str], ver_tuple: tuple[int, int], ) -> dict[str, Any]: # ty: ignore[invalid-return-type] # GitHub ty #1112 """Build a document to be encoded into TOML, JSON, etc.""" match path: case []: return {"mediaType": build_media_type(ver_tuple), "media-type": [1, 2, 7]} case [single]: return { single: {"nothing": 0, "mediaType": build_media_type(ver_tuple)}, "something": "else", } case [first, second]: return { first: { "hello": ["there"], second: {"mediatype": "knock-knock", "mediaType": build_media_type(ver_tuple)}, }, } case _: pytest.fail(f"Internal error: {path=!r}") media_type_version-0.2.1/rust/run-clippy.sh0000755000000000000000000000256413615410400015764 0ustar00#!/bin/sh # # SPDX-FileCopyrightText: Peter Pentchev # SPDX-License-Identifier: BSD-2-Clause set -e def_cargo='cargo' usage() { cat <&2 exit 1 ;; esac done shift "$((OPTIND - 1))" # The list of allowed and ignored checks is synced with Rust 1.87. set -x "$cargo" clippy \ --tests \ -- \ -W warnings \ -W future-incompatible \ -W nonstandard-style \ -W rust-2018-compatibility \ -W rust-2018-idioms \ -W rust-2021-compatibility \ -W rust-2024-compatibility \ -W unused \ -W clippy::restriction \ -A clippy::arbitrary_source_item_ordering \ -A clippy::blanket_clippy_restriction_lints \ -A clippy::implicit_return \ -A clippy::missing_trait_methods \ -A clippy::mod_module_files \ -A clippy::question_mark_used \ -A clippy::ref_patterns \ -A clippy::semicolon_outside_block \ -A clippy::separated_literal_suffix \ -A clippy::single_call_fn \ -A clippy::self_named_module_files \ -W clippy::pedantic \ -A clippy::module_name_repetitions \ -W clippy::cargo \ ${run_nursery+-W clippy::nursery} \ "$@" media_type_version-0.2.1/rust/media-type-version/Cargo.toml0000644000000000000000000000307013615410400020765 0ustar00# SPDX-FileCopyrightText: Peter Pentchev # SPDX-License-Identifier: BSD-2-Clause [package] name = "media-type-version" version = "0.2.1" rust-version = "1.87" edition = "2024" authors = ["Peter Pentchev "] description = "Extract the format version from a media type string" license = "BSD-2-Clause" readme = "../../README.md" repository = "https://gitlab.com/ppentchev/media-type-version" keywords = ["mediaType", "media-type", "version"] categories = ["config", "data-structures", "no-std", "no-std::no-alloc", "parser-implementations"] [package.metadata.cargo-feature-combinations] exclude_feature_sets = [ ["facet030-unstable", "facet032-unstable"], ] [features] alloc = [] facet030-unstable = ["dep:facet030"] facet032-unstable = ["dep:facet032"] extract-from-table = [] json-serialzero0-unstable = ["extract-from-table", "dep:serialzero0"] toml-boml1 = ["extract-from-table", "dep:boml"] [dependencies] boml = { version = "1.0.2", optional = true } facet030 = { package = "facet", version = "0.30.0", default-features = false, optional = true } facet032 = { package = "facet", version = "0.32.3", default-features = false, features = ["alloc"], optional = true } log = { version = "0.4.27", default-features = false } serialzero0 = { package = "serialzero", version = "0.1", optional = true } [dev-dependencies] eyre = "0.6.12" facet-pretty030 = { package = "facet-pretty", version = "0.30.0", default-features = false } facet-pretty032 = { package = "facet-pretty", version = "0.32.3", default-features = false } facet-testhelpers = "0.32.3" media_type_version-0.2.1/rust/media-type-version/src/defs.rs0000644000000000000000000003704313615410400021122 0ustar00// SPDX-FileCopyrightText: Peter Pentchev // SPDX-License-Identifier: BSD-2-Clause //! Common definitions for the media-type-version library. #[cfg(any(feature = "alloc", feature = "toml-boml1"))] extern crate alloc; use core::error::Error as CoreError; use core::fmt::{Display, Error as FmtError, Formatter}; use core::num::ParseIntError; #[cfg(feature = "alloc")] use alloc::{borrow::ToOwned as _, string::String}; #[cfg(all(feature = "alloc", feature = "toml-boml1"))] use alloc::format; #[cfg(any(feature = "facet030-unstable", feature = "facet032-unstable"))] use facet::Facet; #[cfg(feature = "toml-boml1")] use boml::TomlError; /// An error that occurred while processing the media type string. #[derive(Debug)] #[non_exhaustive] #[expect(clippy::error_impl_error, reason = "common enough convention")] pub enum Error<'data> { /// No prefix specified for the config builder. BuildNoPrefix, /// Something went really wrong. Internal(u32), /// The media type did not have the specified prefix. NoPrefix(&'data str, &'data str), /// The media type did not have the specified suffix. NoSuffix(&'data str, &'data str), /// The media type did not have the ".v" part. NoVDot(&'data str), #[cfg(feature = "extract-from-table")] /// The hierarchical structure did not contain the specified element. TableNoChild(&'data str), #[cfg(feature = "extract-from-table")] /// The hierarchical structure contained something that was not a table. TableNotTable, #[cfg(feature = "toml-boml1")] /// Could not parse a TOML document. TomlParse(TomlError<'data>), /// The media type's version part did not consist of two dot-separated components. TwoComponentsExpected(&'data str), /// The media type contained an invalid version component. UIntExpected(&'data str, &'data str, ParseIntError), } impl Display for Error<'_> { /// Describe the error that occurred. #[inline] fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> { match *self { Self::BuildNoPrefix => write!( f, "No prefix specified for the media-type-version config builder" ), Self::Internal(code) => write!(f, "media-type-version internal error: code {code}"), Self::NoPrefix(value, prefix) => { write!( f, "The '{value}' media type does not have the expected prefix '{prefix}'" ) } Self::NoSuffix(value, suffix) => { write!( f, "The '{value}' media type does not have the expected suffix '{suffix}'" ) } Self::NoVDot(value) => write!( f, "The '{value}' media type does not have the expected '.v' part" ), Self::TwoComponentsExpected(value) => write!( f, "The '{value}' media type does not have two dot-separated version components" ), #[cfg(feature = "extract-from-table")] Self::TableNoChild(comp) => { write!(f, "The parsed structure did not contain the '{comp}' child") } #[cfg(feature = "extract-from-table")] Self::TableNotTable => write!( f, "The parsed structure did not contain an expected table or string" ), #[cfg(feature = "toml-boml1")] Self::TomlParse(ref err) => write!(f, "Could not parse a TOML document: {err}"), Self::UIntExpected(value, comp, _) => write!( f, "The '{value}' media type contains an invalid unsigned integer '{comp}'" ), } } } impl CoreError for Error<'_> { #[inline] fn source(&self) -> Option<&(dyn CoreError + 'static)> { match *self { Self::BuildNoPrefix | Self::Internal(_) | Self::NoPrefix(_, _) | Self::NoSuffix(_, _) | Self::NoVDot(_) | Self::TwoComponentsExpected(_) => None, #[cfg(feature = "extract-from-table")] Self::TableNoChild(_) | Self::TableNotTable => None, #[cfg(feature = "toml-boml1")] Self::TomlParse(_) => None, Self::UIntExpected(_, _, ref err) => Some(err), } } } #[cfg(feature = "alloc")] impl Error<'_> { /// Store the error strings into an owned object. #[inline] #[must_use] pub fn into_owned_error(self) -> OwnedError { match self { Self::BuildNoPrefix => OwnedError::BuildNoPrefix, Self::Internal(code) => OwnedError::Internal(code), Self::NoPrefix(value, prefix) => { OwnedError::NoPrefix(value.to_owned(), prefix.to_owned()) } Self::NoSuffix(value, suffix) => { OwnedError::NoSuffix(value.to_owned(), suffix.to_owned()) } Self::NoVDot(value) => OwnedError::NoVDot(value.to_owned()), #[cfg(feature = "extract-from-table")] Self::TableNoChild(comp) => OwnedError::TableNoChild(comp.to_owned()), #[cfg(feature = "extract-from-table")] Self::TableNotTable => OwnedError::TableNotTable, #[cfg(feature = "toml-boml1")] Self::TomlParse(err) => OwnedError::TomlBoml(format!("{err}")), Self::TwoComponentsExpected(value) => { OwnedError::TwoComponentsExpected(value.to_owned()) } Self::UIntExpected(value, comp, err) => { OwnedError::UIntExpected(value.to_owned(), comp.to_owned(), err) } } } } /// An equivalent to [`Error`] that owns the error parameters. #[cfg(feature = "alloc")] #[derive(Debug)] #[non_exhaustive] pub enum OwnedError { /// No prefix specified for the config builder. BuildNoPrefix, /// Something went really, really wrong... Internal(u32), /// The media type did not have the specified prefix. NoPrefix(String, String), /// The media type did not have the specified suffix. NoSuffix(String, String), /// The media type did not have the ".v" part. NoVDot(String), #[cfg(feature = "extract-from-table")] /// The hierarchical structure did not contain the specified element. TableNoChild(String), #[cfg(feature = "extract-from-table")] /// The hierarchical structure did not contain the expected table or string. TableNotTable, #[cfg(feature = "toml-boml1")] /// Could not parse a TOML document. TomlBoml(String), /// The media type's version part did not consist of two dot-separated components. TwoComponentsExpected(String), /// The media type contained an invalid version component. UIntExpected(String, String, ParseIntError), } #[cfg(feature = "alloc")] impl Display for OwnedError { /// Describe the error that occurred. #[inline] fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> { match *self { Self::BuildNoPrefix => Error::BuildNoPrefix.fmt(f), Self::Internal(ref code) => Error::Internal(*code).fmt(f), Self::NoPrefix(ref value, ref prefix) => Error::NoPrefix(value, prefix).fmt(f), Self::NoSuffix(ref value, ref suffix) => Error::NoSuffix(value, suffix).fmt(f), Self::NoVDot(ref value) => Error::NoVDot(value).fmt(f), #[cfg(feature = "extract-from-table")] Self::TableNoChild(ref comp) => Error::TableNoChild(comp).fmt(f), #[cfg(feature = "extract-from-table")] Self::TableNotTable => Error::TableNotTable.fmt(f), #[cfg(feature = "toml-boml1")] Self::TomlBoml(ref err) => write!(f, "Could not parse a TOML document: {err}"), Self::TwoComponentsExpected(ref value) => Error::TwoComponentsExpected(value).fmt(f), Self::UIntExpected(ref value, ref comp, ref err) => { Error::UIntExpected(value, comp, (*err).clone()).fmt(f) } } } } #[cfg(feature = "alloc")] impl CoreError for OwnedError { #[inline] fn source(&self) -> Option<&(dyn CoreError + 'static)> { match *self { Self::BuildNoPrefix | Self::Internal(_) | Self::NoPrefix(_, _) | Self::NoSuffix(_, _) | Self::NoVDot(_) | Self::TwoComponentsExpected(_) => None, #[cfg(feature = "extract-from-table")] Self::TableNoChild(_) | Self::TableNotTable => None, #[cfg(feature = "toml-boml1")] Self::TomlBoml(_) => None, Self::UIntExpected(_, _, ref err) => Some(err), } } } /// The extracted format version. #[cfg_attr( any(feature = "facet030-unstable", feature = "facet032-unstable"), derive(Facet) )] pub struct Version { /// The major version number. major: u32, /// The minor version number. minor: u32, } impl Version { /// The major version number. #[inline] #[must_use] pub const fn major(&self) -> u32 { self.major } /// The minor version number. #[inline] #[must_use] pub const fn minor(&self) -> u32 { self.minor } /// Return a (major, minor) tuple. #[inline] #[must_use] pub const fn as_tuple(&self) -> (u32, u32) { (self.major, self.minor) } } impl From<(u32, u32)> for Version { /// Build a [`Version`] object from the major and minor version numbers. #[inline] fn from(value: (u32, u32)) -> Self { Self { major: value.0, minor: value.1, } } } impl From for (u32, u32) { /// Break a [`Version`] object down into the major and minor version numbers. #[inline] fn from(value: Version) -> Self { value.as_tuple() } } /// Runtime configuration for the media-type-version library. #[cfg_attr( any(feature = "facet030-unstable", feature = "facet032-unstable"), derive(Facet) )] pub struct Config<'data> { /// The prefix to strip from the media type string. prefix: &'data str, /// The suffix (possibly empty) to strip from the media type string. suffix: &'data str, } impl<'data> Config<'data> { /// The prefix to strip from the media type string. #[inline] #[must_use] pub const fn prefix(&self) -> &str { self.prefix } /// The suffix (possibly empty) to strip from the media type string. #[inline] #[must_use] pub const fn suffix(&self) -> &str { self.suffix } /// Start building a configuration object. #[inline] #[must_use] pub fn builder() -> ConfigBuilder<'data> { ConfigBuilder::default() } /// For test porpoises only, build something out of things. #[cfg(test)] #[inline] #[must_use] pub const fn from_parts(prefix: &'data str, suffix: &'data str) -> Self { Self { prefix, suffix } } } /// Build the runtime configuration. #[derive(Default)] pub struct ConfigBuilder<'data> { /// The prefix to strip from the media type string. prefix: Option<&'data str>, /// The suffix (possibly empty) to strip from the media type string. suffix: Option<&'data str>, } impl<'data> ConfigBuilder<'data> { /// Set the prefix to strip from the media type string. #[inline] #[must_use] pub const fn prefix(self, value: &'data str) -> Self { Self { prefix: Some(value), ..self } } /// Set the suffix (possibly empty) to strip from the media type string. #[inline] #[must_use] pub const fn suffix(self, value: &'data str) -> Self { Self { suffix: Some(value), ..self } } /// Build a [`Config`] object with the specified settings. /// /// # Errors /// /// [`Error::BuildNoPrefix`] if [`ConfigBuilder::prefix`] was not called. #[inline] pub fn build(self) -> Result, Error<'data>> { Ok(Config { prefix: self.prefix.ok_or(Error::BuildNoPrefix)?, suffix: self.suffix.unwrap_or_default(), }) } } #[cfg(test)] #[expect(clippy::unwrap_used, reason = "this is a test suite")] mod tests { extern crate alloc; use alloc::format; use alloc::string::String; #[cfg(any(feature = "facet030-unstable", feature = "facet032-unstable"))] use alloc::string::ToString as _; #[cfg(feature = "alloc")] use core::str::FromStr as _; use eyre::{Result, WrapErr as _}; use facet_testhelpers::test; use log::{info, trace}; #[cfg(feature = "facet030-unstable")] use facet_pretty030::FacetPretty as _; #[cfg(feature = "facet032-unstable")] use facet_pretty032::FacetPretty as _; use super::Config; #[cfg(feature = "alloc")] use super::Error; #[cfg(any(feature = "facet030-unstable", feature = "facet032-unstable"))] use super::Version; #[cfg(any(feature = "facet030-unstable", feature = "facet032-unstable"))] fn pretty_cfg(cfg: &Config<'_>) -> String { format!("{cfg}", cfg = cfg.pretty()) } #[cfg(not(any(feature = "facet030-unstable", feature = "facet032-unstable")))] fn pretty_cfg(cfg: &Config<'_>) -> String { format!( "Config {{ prefix = {prefix:?}, suffix = {suffix:?} }}", prefix = cfg.prefix(), suffix = cfg.suffix() ) } /// Make sure the builder, well, builds a [`Config`] object. #[test] fn builder() -> Result<()> { info!("Building a config builder"); let cfg = Config::builder() .prefix("hello") .suffix("goodbye") .build() .context("build")?; trace!("{cfg}", cfg = pretty_cfg(&cfg)); assert_eq!(cfg.prefix(), "hello"); assert_eq!(cfg.suffix(), "goodbye"); Ok(()) } /// Make sure the error message does not change. #[cfg(feature = "alloc")] #[test] fn error_to_owned() { let check_to_owned_msg = |err: Error<'_>| { let msg = format!("{err}"); trace!("{msg}"); let owned = err.into_owned_error(); let owned_msg = format!("{owned}"); trace!("{owned_msg}"); assert_eq!(msg, owned_msg); }; check_to_owned_msg(Error::BuildNoPrefix); check_to_owned_msg(Error::NoPrefix("some value", "some prefix")); check_to_owned_msg(Error::NoSuffix("some value", "some suffix")); check_to_owned_msg(Error::NoVDot("stuff")); check_to_owned_msg(Error::TwoComponentsExpected("some kind of thing")); check_to_owned_msg(Error::UIntExpected( "something", "something else", u32::from_str("?").unwrap_err(), )); } /// Make sure the [`Facet`] trait for [`Version`] works. #[cfg(any(feature = "facet030-unstable", feature = "facet032-unstable"))] #[test] fn facet_pretty_contains_things() { let major = 42; let minor = 616; let ver = Version::from((major, minor)); let repr = format!("{ver}", ver = ver.pretty()); assert!( repr.contains("Version"), "no Version in the pretty representation: {repr:?}" ); assert!( repr.contains(&major.to_string()), "no '{major}' in the pretty representation: {repr:?}" ); assert!( repr.contains(&minor.to_string()), "no '{minor}' in the pretty representation: {repr:?}" ); assert!( repr.contains('\n'), "no newline in the pretty representation: {repr:?}" ); } } media_type_version-0.2.1/rust/media-type-version/src/lib.rs0000644000000000000000000003044513615410400020746 0ustar00#![deny(missing_docs)] #![deny(clippy::missing_docs_in_private_items)] #![no_std] // SPDX-FileCopyrightText: Peter Pentchev // SPDX-License-Identifier: BSD-2-Clause //! media-type-version - extract the format version from a media type string //! //! ## Overview //! //! The `media-type-version` library is designed to be used as the first step in //! parsing structured data, e.g. configuration files, serialized classes, etc. //! The caller extracts the media type string (e.g. a JSON `"mediaType": "..."` key) and //! passes it in for parsing. //! The caller then decides what to do with the extracted version information - //! is this version supported, what fields are expected to be there, should any //! extraneous fields produce errors, and so on. //! //! The main entry point is the [`extract`] function which is passed two parameters: //! a [`Config`] object defining the expected media type prefix and suffix, and //! a media type string to parse. //! On success, it returns a [`Version`] object, basically a tuple of a major and //! minor version numbers. //! //! ## Media type string format //! //! The media type string is expected to be in a `.vX.Y` format, with //! a fixed prefix and suffix. //! The prefix will usually be a vendor-specific media type. //! The version part consists of two unsigned integer numbers. //! The suffix, if used, may correspond to the file format. //! //! A sample media type string identifying a TOML configuration file for //! a text-processing program could be //! `vnd.ringlet.textproc.publync.config/publync.v0.2+toml` //! //! ## Crate features //! //! - `alloc` - enable the [`Error::into_owned_error`] method //! - `extract-from-table` - enable the [`Table`] trait and the [`extract_from_table`] method //! - `facet030-unstable` - [`Config`] and [`Version`] will derive from `Facet` so that //! they can be examined or serialized that way. //! - `facet032-unstable` - [`Config`] and [`Version`] will derive from `Facet` so that //! they can be examined or serialized that way. //! - `toml-boml1` - implement the [`Table`] trait for the `TomlTable` type from //! the `boml` crate so that [`extract_from_table`] may be used for values of that type. //! //! Note that the `facet032-unstable` feature builds the `facet` crate with //! its `alloc` feature enabled regardless of whether the `alloc` feature is //! enabled for the `media-type-version` crate itself. #![doc(html_root_url = "https://docs.rs/media-type-version/0.2.1")] #![expect(clippy::pub_use, reason = "re-export common symbols")] use core::str::FromStr as _; use log::debug; #[cfg(feature = "toml-boml1")] use boml::prelude::TomlGetError as TomlBomlGetError; #[cfg(feature = "toml-boml1")] use boml::table::TomlTable as TomlBomlTable; #[cfg(all(feature = "facet030-unstable", not(feature = "facet032-unstable")))] extern crate facet030 as facet; #[cfg(feature = "facet032-unstable")] extern crate facet032 as facet; #[cfg(feature = "json-serialzero0-unstable")] use serialzero0::JsonValue; mod defs; pub use defs::{Config, ConfigBuilder, Error, Version}; #[cfg(feature = "alloc")] pub use defs::OwnedError; /// The number of features that are always defined. const FEATURES_COUNT_BASE: usize = 2; #[cfg(not(feature = "extract-from-table"))] /// Do not add 1 if `extract-from-table` is not enabled. const FEATURES_COUNT_EXTRACT_FROM_TABLE: usize = 0; #[cfg(feature = "extract-from-table")] /// Add 1 if `extract-from-table` is enabled. const FEATURES_COUNT_EXTRACT_FROM_TABLE: usize = 1; /// The number of currently enabled features. const FEATURES_COUNT: usize = FEATURES_COUNT_BASE + FEATURES_COUNT_EXTRACT_FROM_TABLE; /// The features supported by this version of the library. pub const FEATURES: [(&str, &str); FEATURES_COUNT] = [ ("media-type-version", env!("CARGO_PKG_VERSION")), ("extract", "0.1"), #[cfg(feature = "extract-from-table")] ("extract-from-table", "0.1"), ]; /// Extract the format version from a media type string. /// /// # Errors /// /// [`Error::NoPrefix`], [`Error::NoSuffix`], [`Error::NoVDot`] if /// the media type string does not contain the required string parts at all. /// /// [`Error::TwoComponentsExpected`] if the version part does not consist of /// exactly two dot-separated components. /// /// [`Error::UIntExpected`] if those components are not unsigned integers. #[inline] pub fn extract<'data>( cfg: &'data Config<'data>, value: &'data str, ) -> Result> { debug!( "Parsing a media type string '{value}', expecting prefix '{prefix}' and suffix '{suffix}'", prefix = cfg.prefix(), suffix = cfg.suffix() ); let no_prefix = value .strip_prefix(cfg.prefix()) .ok_or_else(|| Error::NoPrefix(value, cfg.prefix()))?; let no_suffix = no_prefix .strip_suffix(cfg.suffix()) .ok_or_else(|| Error::NoSuffix(value, cfg.suffix()))?; let no_vdot = no_suffix .strip_prefix(".v") .ok_or(Error::NoVDot(no_suffix))?; let (first, second) = { let mut parts_it = no_vdot.split('.'); let first = parts_it.next().ok_or(Error::TwoComponentsExpected(value))?; let second = parts_it.next().ok_or(Error::TwoComponentsExpected(value))?; if parts_it.next().is_some() { return Err(Error::TwoComponentsExpected(value)); } (first, second) }; let major = u32::from_str(first).map_err(|err| Error::UIntExpected(value, first, err))?; let minor = u32::from_str(second).map_err(|err| Error::UIntExpected(value, second, err))?; Ok(Version::from((major, minor))) } #[cfg(feature = "extract-from-table")] /// A hierarchical structure that may contain at least child tables and strings. pub trait Table<'data> { /// Is this particular element a key/value table? fn is_table(&'data self) -> bool; /// Get the child table with the specified key. /// /// # Errors /// /// [`Error::TableNoChild`] if there is no child by that name. fn get_child_table(&'data self, name: &'data str) -> Result<&'data Self, Error<'data>>; /// Get the child string slice with the specified key. /// /// # Errors /// /// [`Error::TableNoChild`] if there is no child by that name. fn get_child_string(&'data self, name: &'data str) -> Result<&'data str, Error<'data>>; } #[cfg(feature = "extract-from-table")] /// Extract the media type version from a hierarchical data structure. /// /// # Errors /// /// [`Error::TableNotTable`] if either the top-level element or something that still has /// remaining path components is not a table. /// /// [`Error::TableNoChild`] if some of the path components does not exist. #[inline] pub fn extract_from_table<'data, T>( cfg: &'data Config<'data>, mut value: &'data T, path: &'data [&'data str], ) -> Result> where T: Table<'data>, { if !value.is_table() { return Err(Error::TableNotTable); } value = path .iter() .try_fold(value, |current_value, comp| -> Result<&T, Error<'data>> { current_value.get_child_table(comp) })?; let media_type = value.get_child_string("mediaType")?; extract(cfg, media_type) } #[cfg(feature = "json-serialzero0-unstable")] impl<'data> Table<'data> for JsonValue { #[inline] fn is_table(&self) -> bool { matches!(*self, Self::Object(_)) } #[inline] fn get_child_table(&'data self, name: &'data str) -> Result<&'data Self, Error<'data>> { let Self::Object(ref map) = *self else { return Err(Error::TableNotTable); }; map.get(name).ok_or(Error::TableNoChild(name)) } #[inline] fn get_child_string(&'data self, name: &'data str) -> Result<&'data str, Error<'data>> { let Self::Object(ref map) = *self else { return Err(Error::TableNotTable); }; let child = map.get(name).ok_or(Error::TableNoChild(name))?; let Self::String(ref value) = *child else { return Err(Error::TableNotTable); }; Ok(value) } } #[cfg(feature = "toml-boml1")] impl<'data> Table<'data> for TomlBomlTable<'data> { #[inline] fn is_table(&self) -> bool { true } #[inline] fn get_child_table(&'data self, name: &'data str) -> Result<&'data Self, Error<'data>> { self.get_table(name).map_err(|err| match err { TomlBomlGetError::InvalidKey => Error::TableNoChild(name), TomlBomlGetError::TypeMismatch(_, _) => Error::TableNotTable, }) } #[inline] fn get_child_string(&'data self, name: &'data str) -> Result<&'data str, Error<'data>> { self.get_string(name).map_err(|err| match err { TomlBomlGetError::InvalidKey => Error::TableNoChild(name), TomlBomlGetError::TypeMismatch(_, _) => Error::TableNotTable, }) } } #[cfg(test)] mod tests { extern crate alloc; use alloc::format; use alloc::string::String; use eyre::{Result, WrapErr as _}; use facet_testhelpers::test; #[cfg(feature = "facet030-unstable")] use facet_pretty030::FacetPretty as _; #[cfg(feature = "facet032-unstable")] use facet_pretty032::FacetPretty as _; use crate::{Config, Error, Version}; /// The prefix and suffix to use for testing. static CFG: Config<'_> = Config::from_parts("this/and", "+that"); #[cfg(any(feature = "facet030-unstable", feature = "facet032-unstable"))] fn pretty_res(res: &Result>) -> String { match *res { Ok(ref ver) => format!("OK: {ver}", ver = ver.pretty()), Err(ref err) => format!("Error: {err}"), } } #[cfg(not(any(feature = "facet030-unstable", feature = "facet032-unstable")))] fn pretty_res(res: &Result>) -> String { match *res { Ok(ref ver) => format!( "OK: Version {{ major: {major}, minor: {minor} }}", major = ver.major(), minor = ver.minor(), ), Err(ref err) => format!("Error: {err}"), } } /// Make sure [extract][crate::extract] fails on invalid prefix. #[test] fn extract_fail_no_prefix() { let res = crate::extract(&CFG, "nothing"); assert!( matches!(res, Err(Error::NoPrefix(_, _))), "expected Error::NoPrefix, got {res}", res = pretty_res(&res) ); } /// Make sure [extract][crate::extract] fails on invalid suffix. #[test] fn extract_fail_no_suffix() { let res = crate::extract(&CFG, "this/andnothing"); assert!( matches!(res, Err(Error::NoSuffix(_, _))), "expected Error::NoSuffix, got {res}", res = pretty_res(&res) ); } /// Make sure [extract][crate::extract] fails on missing "v.". #[test] fn extract_fail_no_vdot() { let res = crate::extract(&CFG, "this/andnothing+that"); assert!( matches!(res, Err(Error::NoVDot(_))), "expected Error::NoVDot, got {res}", res = pretty_res(&res) ); } /// Make sure [extract][crate::extract] fails if no two components. #[test] fn extract_fail_two_expected() { let res = crate::extract(&CFG, "this/and.vnothing+that"); assert!( matches!(res, Err(Error::TwoComponentsExpected(_))), "expected Error::TwoComponentsExpected, got {res}", res = pretty_res(&res) ); } /// Make sure [extract][crate::extract] fails if not unsigned integers. #[test] fn extract_fail_uint_expected() { let res_first = crate::extract(&CFG, "this/and.va.42+that"); assert!( matches!(res_first, Err(Error::UIntExpected(_, _, _))), "expected Error::UIntExpected, got {res_first}", res_first = pretty_res(&res_first) ); let res_second = crate::extract(&CFG, "this/and.v42.+that"); assert!( matches!(res_second, Err(Error::UIntExpected(_, _, _))), "expected Error::UIntExpected, got {res_second}", res_second = pretty_res(&res_second) ); } /// Make sure [extract][crate::extract] succeeds on trivial correct data. #[test] fn extract_ok() -> Result<()> { let ver = crate::extract(&CFG, "this/and.v616.42+that").context("extract")?; assert_eq!(ver.as_tuple(), (616, 42)); Ok(()) } } media_type_version-0.2.1/rust/mtv-extract/Cargo.toml0000644000000000000000000000217013615410400017522 0ustar00# SPDX-FileCopyrightText: Peter Pentchev # SPDX-License-Identifier: BSD-2-Clause [package] name = "mtv-extract" version = "0.2.1" rust-version = "1.87" edition = "2024" authors = ["Peter Pentchev "] description = "Read media type strings, extract the format versions from them" license = "BSD-2-Clause" readme = "../../README.md" repository = "https://gitlab.com/ppentchev/media-type-version" keywords = ["mediaType", "media-type", "version"] categories = ["command-line-utilities", "config", "data-structures", "parser-implementations"] [dependencies] eyre = "0.6.12" argh = { version = "0.1.13", default-features = false, features = ["help"] } boml = "1.0.2" itertools = "0.14" log = { version = "0.4.27", default-features = false } serialzero = "0.1" simple_logger = { version = "5", default-features = false, features = ["stderr"] } [dependencies.media-type-version] version = "= 0.2.1" path = "../media-type-version" features = [ "alloc", "json-serialzero0-unstable", "toml-boml1", ] [dev-dependencies] camino = "1.1.10" facet-testhelpers = "0.32.3" feature-check = "2.3.0" tempfile = "3.20" media_type_version-0.2.1/rust/mtv-extract/src/main.rs0000644000000000000000000002143413615410400017657 0ustar00#![deny(missing_docs)] #![deny(clippy::missing_docs_in_private_items)] // SPDX-FileCopyrightText: Peter Pentchev // SPDX-License-Identifier: BSD-2-Clause //! mtv-extract - read media type strings, extract the format versions from them use std::fs::{self, File}; use std::io::{self, BufRead as _, BufReader, Error as IoError, Read as _}; use argh::FromArgs; use eyre::{Result, WrapErr as _, bail, eyre}; use itertools::Itertools as _; use log::{LevelFilter, info}; use simple_logger::SimpleLogger; use media_type_version::{Config, Error, FEATURES}; /// The features supported by the command-line tool. const CMD_FEATURES: [(&str, &str); 4] = [ ("cmd-features", "0.1"), ("cmd-json", "0.1"), ("cmd-lines", "0.1"), ("cmd-toml", "0.1"), ]; /// list the features supported by the program #[derive(Debug, FromArgs)] #[argh(subcommand, name = "features")] #[expect( clippy::empty_structs_with_brackets, reason = "argh does not support unit structs yet" )] struct CmdFeatures {} /// extract format versions from a JSON file #[derive(Debug, FromArgs)] #[argh(subcommand, name = "json")] struct CmdJson { /// the prefix to expect in the media type string #[argh(option, short = 'p')] prefix: String, /// the optional suffix in the media type string #[argh(option, short = 's', default = "String::new()")] suffix: String, /// the optional dot-separated path to the section containing the `mediaType` string #[argh(option, short = 'P', default = "String::new()")] path: String, /// the files to parse; `-` denotes the standard input stream #[argh(positional)] files: Vec, } /// extract format versions from a series of text lines #[derive(Debug, FromArgs)] #[argh(subcommand, name = "lines")] struct CmdLines { /// the prefix to expect in the media type string #[argh(option, short = 'p')] prefix: String, /// the optional suffix in the media type string #[argh(option, short = 's', default = "String::new()")] suffix: String, /// the files to parse; `-` denotes the standard input stream #[argh(positional)] files: Vec, } /// extract format versions from a series of text lines #[derive(Debug, FromArgs)] #[argh(subcommand, name = "toml")] struct CmdToml { /// the prefix to expect in the media type string #[argh(option, short = 'p')] prefix: String, /// the optional suffix in the media type string #[argh(option, short = 's', default = "String::new()")] suffix: String, /// the optional dot-separated path to the section containing the `mediaType` string #[argh(option, short = 'P', default = "String::new()")] path: String, /// the files to parse; `-` denotes the standard input stream #[argh(positional)] files: Vec, } /// What to do, what to do? #[derive(Debug, FromArgs)] #[argh(subcommand)] enum CliCommand { /// list the features supported by the program Features(CmdFeatures), /// extract the media type format version from a JSON file Json(CmdJson), /// extract format versions from a series of text lines Lines(CmdLines), /// extract the media type format version from a TOML file Toml(CmdToml), } /// Read media type strings, extract the format versions from them. #[derive(Debug, FromArgs)] struct MtvLines { /// quiet operation; only display warnings and error messages #[argh(switch, short = 'q')] quiet: bool, /// verbose operation; display diagnostic messages #[argh(switch, short = 'v')] verbose: bool, /// what to do, what to do? #[argh(subcommand)] cmd: CliCommand, } /// List the features supported by the program. #[expect(clippy::print_stdout, reason = "this is the whole point")] fn show_features() { println!( "Features: {features}", features = FEATURES .iter() .chain(CMD_FEATURES.iter()) .map(|&(name, value)| format!("{name}={value}")) .join(" ") ); } /// Prepare the runtime configuration when parsing tables. fn build_config<'data>(prefix: &'data str, suffix: &'data str) -> Result> { Config::builder() .prefix(prefix) .suffix(suffix) .build() .map_err(Error::into_owned_error) .context("Could not build the MTConfig") } /// Prepare the runtime configuration when parsing tables. fn build_path_vec(path: &str) -> Result> { if path.is_empty() { return Ok(Vec::new()); } let path_vec: Vec<_> = path.split('.').collect(); if path_vec.iter().any(|comp| comp.is_empty()) { bail!("Empty component in the section path"); } Ok(path_vec) } /// Read a file into a single string. fn read_to_single_string(fname: &str) -> Result { if fname == "-" { info!("Reading from the standard input"); let mut contents = String::new(); io::stdin() .read_to_string(&mut contents) .context("Could not read from the standard input stream")?; return Ok(contents); } info!("Reading from the {fname} file"); fs::read_to_string(fname).with_context(|| format!("Could not read from {fname}")) } /// Handle the "json" subcommand. #[expect(clippy::print_stdout, reason = "this is the whole point")] fn cmd_json(cmd: CmdJson) -> Result<()> { if cmd.files.is_empty() { bail!("No files to process"); } let cfg = build_config(&cmd.prefix, &cmd.suffix)?; let path_vec = build_path_vec(&cmd.path)?; for fname in cmd.files { let contents = read_to_single_string(&fname)?; let raw = serialzero::parse(&contents) .map_err(|err| eyre!("Could not parse {fname} as valid JSON: {err}"))?; let ver = media_type_version::extract_from_table(&cfg, &raw, &path_vec) .map_err(Error::into_owned_error) .with_context(|| { format!("Could not extract the JSON `mediaType` version from {fname}") })?; println!("{major}\t{minor}", major = ver.major(), minor = ver.minor()); } Ok(()) } /// Read lines from a file, extract the data from them.""" #[expect(clippy::print_stdout, reason = "this is the whole point")] fn process_lines(cfg: &Config<'_>, fname: &str, lines: L) -> Result<()> where L: Iterator>, { for line_res in lines { let line = line_res.with_context(|| format!("Could not read a line from {fname}"))?; let ver = media_type_version::extract(cfg, &line) .map_err(Error::into_owned_error) .with_context(|| format!("Could not parse a line read from {fname}: {line}"))?; println!("{major}\t{minor}", major = ver.major(), minor = ver.minor()); } Ok(()) } /// Handle the "lines" subcommand. fn cmd_lines(cmd: CmdLines) -> Result<()> { if cmd.files.is_empty() { bail!("No files to process"); } let cfg = build_config(&cmd.prefix, &cmd.suffix)?; for fname in cmd.files { if fname == "-" { info!("Reading from the standard input"); process_lines(&cfg, "(standard input)", io::stdin().lines())?; } else { info!("Reading from the {fname} file"); let infile = File::open(&fname) .with_context(|| format!("Could not open the {fname} file for reading"))?; process_lines(&cfg, &fname, BufReader::new(infile).lines())?; } } Ok(()) } /// Handle the "toml" subcommand. #[expect(clippy::print_stdout, reason = "this is the whole point")] fn cmd_toml(cmd: CmdToml) -> Result<()> { if cmd.files.is_empty() { bail!("No files to process"); } let cfg = build_config(&cmd.prefix, &cmd.suffix)?; let path_vec = build_path_vec(&cmd.path)?; for fname in cmd.files { let contents = read_to_single_string(&fname)?; let raw = boml::parse(&contents) .map_err(|err| eyre!("Could not parse {fname} as valid TOML: {err}"))?; let ver = media_type_version::extract_from_table(&cfg, &*raw, &path_vec) .map_err(Error::into_owned_error) .with_context(|| { format!("Could not extract the TOML `mediaType` version from {fname}") })?; println!("{major}\t{minor}", major = ver.major(), minor = ver.minor()); } Ok(()) } fn main() -> Result<()> { let args: MtvLines = argh::from_env(); SimpleLogger::new() .with_level(if args.verbose { LevelFilter::Trace } else if args.quiet { LevelFilter::Warn } else { LevelFilter::Info }) .init() .context("Could not set up logging")?; match args.cmd { CliCommand::Features(_) => show_features(), CliCommand::Json(cmd) => cmd_json(cmd)?, CliCommand::Lines(cmd) => cmd_lines(cmd)?, CliCommand::Toml(cmd) => cmd_toml(cmd)?, } Ok(()) } media_type_version-0.2.1/rust/mtv-extract/tests/simple.rs0000644000000000000000000001241013615410400020571 0ustar00#![deny(missing_docs)] #![deny(clippy::missing_docs_in_private_items)] // SPDX-FileCopyrightText: Peter Pentchev // SPDX-License-Identifier: BSD-2-Clause //! Run a couple of tests for the `mtv-extract` command-line utility. #![expect(clippy::tests_outside_test_module, reason = "integration test")] use core::str::FromStr as _; use std::env::{self, VarError}; use std::fs; use std::process::{Command, Stdio}; use std::sync::LazyLock; use camino::Utf8PathBuf; use eyre::{Result, WrapErr as _, bail, eyre}; use facet_testhelpers::test; use feature_check::defs::{Config as FcConfig, Obtained as FcObtained}; use feature_check::obtain as fc_obtain; use feature_check::version::Version as FcVersion; use log::info; fn get_exe_path() -> Result { static PATH: LazyLock> = LazyLock::new(|| { let current = Utf8PathBuf::from_path_buf( env::current_exe().context("Could not get the current executable file's path")?, ) .map_err(|path| { eyre!( "Could not represent {path} as valid UTF-8", path = path.display() ) })?; let exe_dir = { let basedir = current .parent() .ok_or_else(|| eyre!("Could not get the parent directory of {current}"))?; if basedir .file_name() .ok_or_else(|| eyre!("Could not get the base name of {basedir}"))? == "deps" { basedir .parent() .ok_or_else(|| eyre!("Could not get the parent directory of {basedir}"))? } else { basedir } }; let exe_path = exe_dir.join("mtv-extract"); if !exe_path.is_file() { bail!("Not a regular file: {exe_path}"); } Ok(exe_path) }); match *PATH { Ok(ref res) => Ok(res.clone()), Err(ref err) => bail!("Could not determine the path to the test program: {err}"), } } #[test] fn stdin_ok() -> Result<()> { let tempd_obj = tempfile::tempdir().context("tempd")?; let tempd = Utf8PathBuf::from_path_buf(tempd_obj.path().to_path_buf()) .map_err(|err| eyre!("tempd UTF-8: {err}", err = err.display()))?; let testfile = tempd.join("data.txt"); fs::write( &testfile, "vnd.ringlet.test/config.v0.3+plain\nvnd.ringlet.test/config.v1.6+plain\n", ) .context("testfile write")?; let exe_path = get_exe_path().context("get exe path")?; let output = Command::new(&exe_path) .args([ "lines", "-p", "vnd.ringlet.test/config", "-s", "+plain", "--", testfile.as_ref(), ]) .stdout(Stdio::piped()) .stderr(Stdio::inherit()) .output() .context("run")?; if !output.status.success() { bail!("{output:?}"); } let versions = String::from_utf8(output.stdout).context("output UTF-8")?; assert_eq!(versions, "0\t3\n1\t6\n"); Ok(()) } fn find_uvoxen() -> Result> { let uvoxen_prog = match env::var("UVOXEN") { Ok(value) => value, Err(VarError::NotPresent) => "uvoxen".to_owned(), Err(err) => { return Err(err).context("Could not examine the `UVOXEN` environment variable"); } }; info!("Trying to obtain the features supported by `{uvoxen_prog}`"); let fc_cfg = FcConfig::default().with_program(uvoxen_prog.clone()); let FcObtained::Features(features) = fc_obtain::obtain_features(&fc_cfg) .with_context(|| format!("Could not query `{uvoxen_prog}` for supported features"))? else { info!("Could not parse the output of `{uvoxen_prog} --features`, skipping the test"); return Ok(None); }; let Some(fc_ver) = features.get("uvoxen") else { info!("No 'uvoxen' feature in the output of `{uvoxen_prog} --features`, skipping the test"); return Ok(None); }; let ref_ver_min = FcVersion::from_str("0.2").context("Could not parse 0.2 as a version")?; let ref_ver_max = FcVersion::from_str("0.3").context("Could not parse 0.3 as a version")?; if *fc_ver < ref_ver_min { bail!("Unsupported version for `{uvoxen_prog}`: {fc_ver} < {ref_ver_min}"); } if *fc_ver >= ref_ver_max { bail!("Unsupported version for `{uvoxen_prog}`: {fc_ver} >= {ref_ver_max}"); } info!("Supported version {fc_ver} for `{uvoxen_prog}`"); Ok(Some(uvoxen_prog)) } #[test] fn python_test_prog_via_uvoxen() -> Result<()> { let Some(uvoxen) = find_uvoxen()? else { return Ok(()); }; // Well, here goes nothing... let top_dir = format!("{proj_dir}/../..", proj_dir = env!("CARGO_MANIFEST_DIR")); info!("Running `{uvoxen} uv run ...` in {top_dir}"); if !Command::new(&uvoxen) .args(["uv", "run", "-e", "unit-tests-cli"]) .current_dir(&top_dir) .env( "TEST_MTV_EXTRACT_PROG", &get_exe_path().context("get exe path")?, ) .stdout(Stdio::inherit()) .stderr(Stdio::inherit()) .status() .with_context(|| format!("Could not run `{uvoxen} uv run`"))? .success() { bail!("`{uvoxen} uv run` failed"); } Ok(()) } media_type_version-0.2.1/.gitignore0000644000000000000000000000021213615410400014302 0ustar00# SPDX-FileCopyrightText: Peter Pentchev # SPDX-License-Identifier: BSD-2-Clause site/ target/ .tox/ **/__pycache__/ media_type_version-0.2.1/README.md0000644000000000000000000001246413615410400013605 0ustar00 # media-type-version - extract the format version from a media type string \[[Home][ringlet-home] | [GitLab][gitlab] | [PyPI][pypi] | [crates.io][crates-io] | [Python API][ringlet-api-python] | [ReadTheDocs][readthedocs]\] ## Overview The `media-type-version` library is designed to be used as the first step in parsing structured data, e.g. configuration files, serialized classes, etc. The caller extracts the media type string (e.g. a JSON `"mediaType": "..."` key) and passes it in for parsing. The caller then decides what to do with the extracted version information - is this version supported, what fields are expected to be there, should any extraneous fields produce errors, and so on. The media type string is expected to be in a `.vX.Y` format, with a fixed prefix and suffix. The prefix will usually be a vendor-specific media type. The version part consists of two unsigned integer numbers. The suffix, if used, may correspond to the file format. A sample media type string identifying a TOML configuration file for a text-processing program could be `vnd.ringlet.textproc.publync.config/publync.v0.2+toml` ## The library The `media-type-version` library provides a single function, `extract()`, that parses a media type string, strips the specified prefix and suffix, and looks for a `.vX.Y` version string left. It then returns the (`X`, `Y`) version tuple. Python example: ``` py mtv_cfg: Final = media_type_version.Config( log=logging.Logger(...), prefix="vnd.acme/thing", suffix="+toml", ) ver_major, ver_minor = media_type_version.extract(mtv_cfg, "vnd.acme/thing.v3.12+toml") ``` Rust example: ``` rust use media_type_version::{Config as MTVConfig, Error as MTVError, Version as MTVersion}; let cfg = MTVConfig::builder() .prefix("vnd.acme/thing") .suffix("+toml") .build() .map_err(MTVError::into_owned_error)?; assert_eq!( media_type_version::extract(&cfg, "vnd.acme/thing.v3.12+toml").as_tuple(), (3, 12) ); ``` ## The mtv-extract tool The `media-type-version` library also provides a command-line tool called `mtv-extract` that can be used to extract format versions from various sources. The `mtv-extract` tool supports the following top-level command-line options: - `-q`: quiet operation; only display warnings and error messages - `-v`: verbose operation; display diagnostic output ### The "features" subcommand The `features` subcommand will display a single line of output starting with the prefix "Features: " and containing a space-separated list of "name=version" pairs. This output format is intended to be machine-readable, so that other programs may examine it using e.g. [the feature-check library and command-line tool][feature-check]. ### The "lines" subcommand The `lines` subcommand will read a series of strings from the specified files, parse them as media-type strings with the specified prefix and suffix, and output a line consisting of two tab-separated numbers for each parsed string: ``` sh $ { echo vnd.acme/thing.v3.47; echo vnd.acme/thing.v42.616; } | mtv-extract -q lines -p vnd.acme/thing -- - 3 47 42 616 $ ``` The `lines` subcommand supports the following command-line options: - `-p prefix` (required): the prefix to strip from the media type string - `-s suffix`: the optional suffix to strip from the media type string ## Supported features The `features` subcommand of the `mtv-extract` tool, as well as the `FEATURES` constant in both the Python and Rust implementations, may currently list the following features: ### media-type-version The version of the `media-type-version` library itself. ### cmd-features #### 0.1 The command-line tool supports the `features` subcommand with the output format described above. ### cmd-lines #### 0.1 The command-line tool supports the `lines` subcommand with the mandatory prefix option and the optional suffix one. It requires at least one file name to read from, and it supports `-` for reading from the standard input stream. ### extract #### 0.1 The library supports the `extract()` function. It accepts a `Config` parameter containing the prefix and suffix strings, and a string parameter to parse. The string must contain a ".vX.Y" version specification between the prefix and the suffix. ## Contact The `media-type-version` library was written by [Peter Pentchev][roam]. It is developed in [a GitLab repository][gitlab]. This documentation is hosted at [Ringlet][ringlet-home] with a copy at [ReadTheDocs][readthedocs]. [roam]: mailto:roam@ringlet.net "Peter Pentchev" [crates-io]: https://crates.io/crates/media-type-version "The media-type-version Rust crates.io page" [feature-check]: https://devel.ringlet.net/misc/feature-check/ "The feature-check library and command-line tool" [gitlab]: https://gitlab.com/ppentchev/media-type-version "The media-type-version GitLab repository" [pypi]: https://pypi.org/project/media-type-version/ "The media-type-version Python Package Index page" [readthedocs]: https://media-type-version.readthedocs.io/ "The media-type-version ReadTheDocs page" [ringlet-api-python]: https://devel.ringlet.net/devel/media-type-version/api/python/ "The Python API reference" [ringlet-home]: https://devel.ringlet.net/devel/media-type-version/ "The Ringlet media-type-version homepage" media_type_version-0.2.1/pyproject.toml0000644000000000000000000001376713615410400015251 0ustar00# SPDX-FileCopyrightText: Peter Pentchev # SPDX-License-Identifier: BSD-2-Clause [build-system] requires = [ "hatchling >= 1.26, < 2", ] build-backend = "hatchling.build" [project] name = "media-type-version" description = "Extract the format version from a media type string" readme = "README.md" license = "BSD-2-Clause" license-files = ["LICENSES/BSD-2-Clause.txt"] requires-python = ">= 3.11" dynamic = ["version"] classifiers = [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.14", "Topic :: Software Development :: Libraries", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Utilities", "Typing :: Typed", ] [[project.authors]] name = "Peter Pentchev" email = "roam@ringlet.net" [project.scripts] "mtv-extract" = "media_type_version.__main__:main" [project.urls] Homepage = "https://devel.ringlet.net/devel/media-type-version/" Changes = "https://devel.ringlet.net/devel/media-type-version/changes/" "Issue Tracker" = "https://gitlab.com/ppentchev/media-type-version/-/issues" "Source Code" = "https://gitlab.com/ppentchev/media-type-version" [dependency-groups] cli = [ "cappa >= 0.27.3, < 0.32", ] docs = [ "mkdocs >= 1.5, < 2", "mkdocs-material >= 9.3, < 10", "mkdocstrings >= 1, < 2", "mkdocstrings-python >= 1.4, < 2", # Transitive to avoid segfaults with Python 3.14 and `uv --resolution=lowest` "markupsafe >= 2.1", ] testenv-mypy = [ {include-group = "testenv-unit-tests-cli"}, "mypy >= 1.5, < 2", ] testenv-pyupgrade = [ "pyupgrade >= 3, < 4", ] testenv-reuse = [ "reuse >= 6, < 7", ] testenv-ruff = [ "ruff == 0.14.10", ] testenv-ty = [ {include-group = "testenv-unit-tests-cli"}, "ty == 0.0.4", ] testenv-unit-tests = [ "feature-check >= 2, < 3", "packaging >= 21.3, < 26", "pygments >= 2.7, < 3", "pytest >= 8.3.5, < 9.0.3", "tomli-w >= 1, < 2", ] testenv-unit-tests-cli = [ {include-group = "cli"}, {include-group = "testenv-unit-tests"}, ] testenv-uvoxen = [ "uvoxen >= 0.2.2, < 0.3", ] [tool.hatch.build.targets.wheel] packages = ["python/src/media_type_version"] [tool.hatch.version] path = "python/src/media_type_version/defs.py" pattern = '(?x) ^ VERSION \s* (?: : \s* Final \s* )? = \s* " (?P [^\s"]+ ) " \s* $' [tool.mypy] strict = true [tool.publync] mediaType = "vnd.ringlet.misc.publync.config/publync.v0.1+toml" [tool.publync.build.tox] [tool.publync.sync.rsync] remote = "marla.ludost.net:vhosts/devel.ringlet.net/public_html/devel/media-type-version" [tool.ruff] extend = "python/ruff-base.toml" output-format = "concise" preview = true [tool.ruff.lint] select = ["ALL"] [tool.test-stages] stages = [ "(@check or @docs) and @quick and not @manual", "(@check or @docs) and not @manual", "@tests and not @manual", ] [tool.ty.environment] root = [ "python/src", "python/tests", ] [tool.uvoxen] mediaType = "vnd.ringlet.devel.uvoxen.config/uvoxen.v0.3+toml" envlist = [ "ruff", "format", "reuse", "uvoxen-sync-check", "ty", "mypy", "unit-tests", "unit-tests-cli", "docs", ] [tool.uvoxen.defs] pyfiles = [ "python/src/media_type_version", "python/tests/unit", ] [tool.uvoxen.req] header = """ # SPDX-FileCopyrightText: Peter Pentchev # SPDX-License-Identifier: BSD-2-Clause """ [tool.uvoxen.tox] header = """ # SPDX-FileCopyrightText: Peter Pentchev # SPDX-License-Identifier: BSD-2-Clause """ env-order = [ "ruff", "format", "reformat", ] [tool.uvoxen.env.ruff] tags = [ "check", "quick", ] dependency-groups = [ "testenv-ruff", ] commands = [ "ruff check -- {[defs]pyfiles}", ] [tool.uvoxen.env.format] tags = [ "check", "quick", ] dependency-groups = [ "testenv-ruff", ] commands = [ "ruff check --config python/ruff-base.toml --select=D,I --diff -- {[defs]pyfiles}", "ruff format --config python/ruff-base.toml --check --diff -- {[defs]pyfiles}", ] [tool.uvoxen.env.reformat] tags = [ "format", "manual", ] dependency-groups = [ "testenv-ruff", ] commands = [ "ruff check --config python/ruff-base.toml --select=D,I --fix -- {[defs]pyfiles}", "ruff format --config python/ruff-base.toml -- {[defs]pyfiles}", ] [tool.uvoxen.env.reuse] tags = [ "check", "quick", ] dependency-groups = [ "testenv-reuse", ] commands = [ "reuse lint", ] [tool.uvoxen.env.uvoxen-sync-check] tags = [ "check", "quick", ] dependency-groups = [ "testenv-uvoxen", ] install-project = true commands = [ "uvoxen req generate -o python/requirements/docs.txt --check --diff -g docs", "uvoxen tox generate --check --diff", ] [tool.uvoxen.env.ty] tags = [ "check", "quick", ] dependency-groups = [ "testenv-ty", ] install-dependencies = true commands = [ "ty check -- {[defs]pyfiles}", ] [tool.uvoxen.env.mypy] tags = [ "check", ] dependency-groups = [ "testenv-mypy", ] install-dependencies = true commands = [ "mypy {[defs]pyfiles}", ] [tool.uvoxen.env.pyupgrade] tags = [ "check", "manual", ] dependency-groups = [ "testenv-pyupgrade", ] allowlist-externals = [ "sh", ] commands = [ "sh -c 'pyupgrade --py311-plus python/src/media_type_version/*.py python/tests/unit/*.py'", ] [tool.uvoxen.env.unit-tests] tags = [ "tests", ] dependency-groups = [ "testenv-unit-tests", ] install-project = true commands = [ "pytest --strict --ignore python/tests/unit/test_prog.py {posargs} python/tests/unit", ] [tool.uvoxen.env.unit-tests-cli] tags = [ "tests", ] dependency-groups = [ "testenv-unit-tests-cli", ] install-project = true passenv = [ "RUST_LOG", "TEST_MTV_EXTRACT_PROG", ] commands = [ "pytest --strict -k 'test_prog.py' {posargs} python/tests/unit", ] [tool.uvoxen.env.docs] tags = [ "docs", ] dependency-groups = [ "docs", ] commands = [ "mkdocs build", ] media_type_version-0.2.1/LICENSES/BSD-2-Clause.txt0000644000000000000000000000236313615410400016252 0ustar00Copyright (c) Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. media_type_version-0.2.1/PKG-INFO0000644000000000000000000001510513615410400013416 0ustar00Metadata-Version: 2.4 Name: media-type-version Version: 0.2.1 Summary: Extract the format version from a media type string Project-URL: Homepage, https://devel.ringlet.net/devel/media-type-version/ Project-URL: Changes, https://devel.ringlet.net/devel/media-type-version/changes/ Project-URL: Issue Tracker, https://gitlab.com/ppentchev/media-type-version/-/issues Project-URL: Source Code, https://gitlab.com/ppentchev/media-type-version Author-email: Peter Pentchev License-Expression: BSD-2-Clause License-File: LICENSES/BSD-2-Clause.txt Classifier: Development Status :: 4 - Beta Classifier: Intended Audience :: Developers Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3 :: Only Classifier: Programming Language :: Python :: 3.11 Classifier: Programming Language :: Python :: 3.12 Classifier: Programming Language :: Python :: 3.13 Classifier: Programming Language :: Python :: 3.14 Classifier: Topic :: Software Development :: Libraries Classifier: Topic :: Software Development :: Libraries :: Python Modules Classifier: Topic :: Utilities Classifier: Typing :: Typed Requires-Python: >=3.11 Description-Content-Type: text/markdown # media-type-version - extract the format version from a media type string \[[Home][ringlet-home] | [GitLab][gitlab] | [PyPI][pypi] | [crates.io][crates-io] | [Python API][ringlet-api-python] | [ReadTheDocs][readthedocs]\] ## Overview The `media-type-version` library is designed to be used as the first step in parsing structured data, e.g. configuration files, serialized classes, etc. The caller extracts the media type string (e.g. a JSON `"mediaType": "..."` key) and passes it in for parsing. The caller then decides what to do with the extracted version information - is this version supported, what fields are expected to be there, should any extraneous fields produce errors, and so on. The media type string is expected to be in a `.vX.Y` format, with a fixed prefix and suffix. The prefix will usually be a vendor-specific media type. The version part consists of two unsigned integer numbers. The suffix, if used, may correspond to the file format. A sample media type string identifying a TOML configuration file for a text-processing program could be `vnd.ringlet.textproc.publync.config/publync.v0.2+toml` ## The library The `media-type-version` library provides a single function, `extract()`, that parses a media type string, strips the specified prefix and suffix, and looks for a `.vX.Y` version string left. It then returns the (`X`, `Y`) version tuple. Python example: ``` py mtv_cfg: Final = media_type_version.Config( log=logging.Logger(...), prefix="vnd.acme/thing", suffix="+toml", ) ver_major, ver_minor = media_type_version.extract(mtv_cfg, "vnd.acme/thing.v3.12+toml") ``` Rust example: ``` rust use media_type_version::{Config as MTVConfig, Error as MTVError, Version as MTVersion}; let cfg = MTVConfig::builder() .prefix("vnd.acme/thing") .suffix("+toml") .build() .map_err(MTVError::into_owned_error)?; assert_eq!( media_type_version::extract(&cfg, "vnd.acme/thing.v3.12+toml").as_tuple(), (3, 12) ); ``` ## The mtv-extract tool The `media-type-version` library also provides a command-line tool called `mtv-extract` that can be used to extract format versions from various sources. The `mtv-extract` tool supports the following top-level command-line options: - `-q`: quiet operation; only display warnings and error messages - `-v`: verbose operation; display diagnostic output ### The "features" subcommand The `features` subcommand will display a single line of output starting with the prefix "Features: " and containing a space-separated list of "name=version" pairs. This output format is intended to be machine-readable, so that other programs may examine it using e.g. [the feature-check library and command-line tool][feature-check]. ### The "lines" subcommand The `lines` subcommand will read a series of strings from the specified files, parse them as media-type strings with the specified prefix and suffix, and output a line consisting of two tab-separated numbers for each parsed string: ``` sh $ { echo vnd.acme/thing.v3.47; echo vnd.acme/thing.v42.616; } | mtv-extract -q lines -p vnd.acme/thing -- - 3 47 42 616 $ ``` The `lines` subcommand supports the following command-line options: - `-p prefix` (required): the prefix to strip from the media type string - `-s suffix`: the optional suffix to strip from the media type string ## Supported features The `features` subcommand of the `mtv-extract` tool, as well as the `FEATURES` constant in both the Python and Rust implementations, may currently list the following features: ### media-type-version The version of the `media-type-version` library itself. ### cmd-features #### 0.1 The command-line tool supports the `features` subcommand with the output format described above. ### cmd-lines #### 0.1 The command-line tool supports the `lines` subcommand with the mandatory prefix option and the optional suffix one. It requires at least one file name to read from, and it supports `-` for reading from the standard input stream. ### extract #### 0.1 The library supports the `extract()` function. It accepts a `Config` parameter containing the prefix and suffix strings, and a string parameter to parse. The string must contain a ".vX.Y" version specification between the prefix and the suffix. ## Contact The `media-type-version` library was written by [Peter Pentchev][roam]. It is developed in [a GitLab repository][gitlab]. This documentation is hosted at [Ringlet][ringlet-home] with a copy at [ReadTheDocs][readthedocs]. [roam]: mailto:roam@ringlet.net "Peter Pentchev" [crates-io]: https://crates.io/crates/media-type-version "The media-type-version Rust crates.io page" [feature-check]: https://devel.ringlet.net/misc/feature-check/ "The feature-check library and command-line tool" [gitlab]: https://gitlab.com/ppentchev/media-type-version "The media-type-version GitLab repository" [pypi]: https://pypi.org/project/media-type-version/ "The media-type-version Python Package Index page" [readthedocs]: https://media-type-version.readthedocs.io/ "The media-type-version ReadTheDocs page" [ringlet-api-python]: https://devel.ringlet.net/devel/media-type-version/api/python/ "The Python API reference" [ringlet-home]: https://devel.ringlet.net/devel/media-type-version/ "The Ringlet media-type-version homepage"