diff --git a/.gitignore b/.gitignore index 2351bda..5c8bfee 100644 --- a/.gitignore +++ b/.gitignore @@ -11,5 +11,3 @@ /configure~ *.swo *.swp -/test-reports/ -/.tox/ diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md deleted file mode 100644 index 93093de..0000000 --- a/DEVELOPMENT.md +++ /dev/null @@ -1,122 +0,0 @@ -# Development - -> All changes MUST follow the vendor/tiara-gitflow-spec.git and no work MUST be -> started without a TODO issue. - -## Prerequisites - -- Python 3.9+ -- [Pipenv](https://pipenv.pypa.io/) -- [tox](https://tox.wiki/) (installed via Pipenv dev dependencies) -- Node.js (for the `@byteb4rb1e/mime-todo` issue tracker CLI) - -## Setup - -Iniitialize Git submodules: - -```bash -git submodule update --init --remote --recursive -``` - -Install dependencies (includes the package in editable mode): - -```bash -pipenv install --dev -``` - - -## Tooling - -### Package - -The project is packaged as `byteb4rb1e.utils` under a namespace package -layout (`src/byteb4rb1e/utils/`). It is installed in editable mode via -Pipenv. - -Build a distribution: - -```bash -pipenv run dist -``` - -### Testing - -Tests are managed by tox. Test environments are defined in `tox.ini`: - -```bash -# run all test suites -tox - -# run specific environments -tox -e unit-py313 -tox -e lint -tox -e format -``` - -| Environment | Purpose | -|---|---| -| `unit-py3{9-13}` | Unit tests | -| `smoke-py3{9-13}` | Smoke tests | -| `integration-py3{9-13}` | Integration tests | -| `lint` | Type checking (mypy) | -| `format` | Code style (autopep8) | -| `audit` | Dependency audit (pip-audit) | - -### Issue tracker - -Issues are tracked in the `TODO` file using the -[MIME TODO](https://specs.code.tiararodney.com/mime-todo/) format. Use the -`@byteb4rb1e/mime-todo` CLI to interact with it: - -```bash -# list issues -npx @byteb4rb1e/mime-todo list - -# show a specific issue -npx @byteb4rb1e/mime-todo show 3 - -# create an issue -npx @byteb4rb1e/mime-todo create --type feature --title "Title" --plan "Description" --module homeostat -``` - -See [CONTRIBUTING.md](CONTRIBUTING.md) for the full issue lifecycle. - -### Publishing - -Build wheel and source distributions: - -```sh -pipenv run sdist -``` - -Configure publishing options: - -`~/.pypirc` -``` -[distutils] -index-servers = - tiararodney - -[tiararodney] -repository: https://pypi.code.tiararodney.com/root/byteb4rb1e/ -username: -password: -``` - -Publish to pypi.code.tiararodney.com: - -```sh -pipenv run sdist:publish:tiarardoney -``` - - -## Project layout - -``` -src/byteb4rb1e/utils/ # package source -tests/ # test suites (unit/, smoke/, integration/) -vendor/ # vendored specs -dist/ # sdist and wheel build output -DEVELOPMENT.md # this file -TODO # issue tracker (MIME TODO format) -``` diff --git a/LICENSE b/LICENSE deleted file mode 100644 index e69de29..0000000 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..37439f1 --- /dev/null +++ b/Makefile @@ -0,0 +1,24 @@ +.PHONY: chore configure + +chore: configure Pipfile.lock requirements-dev.txt + +Pipfile.lock: .venv Pipfile + .venv/bin/pipenv lock + +requirements-dev.txt: .venv Pipfile.lock + .venv/bin/pipenv requirements --dev-only > requirements-dev.txt + +configure: configure.ac + autoconf + +.venv: requirements-dev.txt + python3 -m venv .venv + .venv/bin/python3 -m pip install --upgrade pip + .venv/bin/pip install -r requirements-dev.txt + +test-reports: + .venv/bin/python3 -m unittest discover -v + +build: .venv/bin/pipenv + .venv/bin/pipenv run build + diff --git a/Pipfile b/Pipfile index 8671f4d..89a5cd3 100644 --- a/Pipfile +++ b/Pipfile @@ -4,25 +4,17 @@ verify_ssl = true name = "pypi" [dev-packages] +mypy = "~=1.15.0" +autopep8 = "~=2.3.2" setuptools-scm = "~=8.2.0" +pylint = "~=3.3.6" build = "*" pipenv = "*" -tox = "*" -twine = "*" -pypi-attestations = "*" -autopep8 = "*" +byteb4rb1e-utils = { editable = true, path = '.'} [requires] -python_version = "3" +python_version = "3.11" [scripts] -"dist" = "python3 -m build" -"dist:attestations" = "python3 -m pypi_attestations sign dist/*" -"dist:publish:tiararodney" = "python3 -m twine upload --sign --repository tiararodney dist/*" -"test" = "tox" -"test:static" = "tox run -m static" -"test:unit" = "tox run -m unit" -"test:integration" = "tox run -m integration" +"build" = "python3 -m build" -[packages] -"byteb4rb1e.utils" = {file = ".", editable = true} diff --git a/Pipfile.lock b/Pipfile.lock index d715cea..7f78522 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,11 +1,11 @@ { "_meta": { "hash": { - "sha256": "7bf1e5e3285cb7ead9e247720d2abc340a64c17d42127e41745bff3309521b41" + "sha256": "4847baa5a13a96f2c3de2a246a0c088806c308426c79d8105387dff1fe1f1e58" }, "pipfile-spec": 6, "requires": { - "python_version": "3" + "python_version": "3.11" }, "sources": [ { @@ -15,20 +15,15 @@ } ] }, - "default": { - "byteb4rb1e.utils": { - "editable": true, - "file": "." - } - }, + "default": {}, "develop": { - "annotated-types": { + "astroid": { "hashes": [ - "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", - "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89" + "sha256:622cc8e3048684aa42c820d9d218978021c3c3d174fb03a9f0d615921744f550", + "sha256:d05bfd0acba96a7bd43e222828b7d9bc1e138aaeb0649707908d3702a9831248" ], - "markers": "python_version >= '3.8'", - "version": "==0.7.0" + "markers": "python_full_version >= '3.9.0'", + "version": "==3.3.9" }, "autopep8": { "hashes": [ @@ -41,253 +36,24 @@ }, "build": { "hashes": [ - "sha256:6a07c1b8eb6f2b311b96fcbdbce5dab5fe637ffda0fd83c9cac622e927501596", - "sha256:f1b91b925aa322be454f8330c6fb48b465da993d1e7e7e6fa35027ec49f3c936" + "sha256:1d61c0887fa860c01971625baae8bdd338e517b836a2f70dd1f7aa3a6b2fc5b5", + "sha256:b36993e92ca9375a219c99e606a122ff365a760a2d4bba0caa09bd5278b608b7" ], "index": "pypi", - "markers": "python_version >= '3.9'", - "version": "==1.4.0" + "markers": "python_version >= '3.8'", + "version": "==1.2.2.post1" }, - "cachetools": { - "hashes": [ - "sha256:0cd042c24377200c1dcd225f8b7b12b0ca53cc2c961b43757e774ebe190fd990", - "sha256:46bc8ebefbe485407621d0a4264b23c080cedd913921bad7ac3ed2f26c183114" - ], - "markers": "python_version >= '3.10'", - "version": "==7.0.5" + "byteb4rb1e-utils": { + "editable": true, + "path": "." }, "certifi": { "hashes": [ - "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", - "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7" + "sha256:0a816057ea3cdefcef70270d2c515e4506bbc954f417fa5ade2021213bb8f0c6", + "sha256:30350364dfe371162649852c63336a15c70c6510c2ad5015b21c2345311805f3" ], - "markers": "python_version >= '3.7'", - "version": "==2026.2.25" - }, - "cffi": { - "hashes": [ - "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb", - "sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b", - "sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f", - "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9", - "sha256:0cf2d91ecc3fcc0625c2c530fe004f82c110405f101548512cce44322fa8ac44", - "sha256:0f6084a0ea23d05d20c3edcda20c3d006f9b6f3fefeac38f59262e10cef47ee2", - "sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c", - "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75", - "sha256:1cd13c99ce269b3ed80b417dcd591415d3372bcac067009b6e0f59c7d4015e65", - "sha256:1e3a615586f05fc4065a8b22b8152f0c1b00cdbc60596d187c2a74f9e3036e4e", - "sha256:1f72fb8906754ac8a2cc3f9f5aaa298070652a0ffae577e0ea9bd480dc3c931a", - "sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e", - "sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25", - "sha256:2081580ebb843f759b9f617314a24ed5738c51d2aee65d31e02f6f7a2b97707a", - "sha256:21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe", - "sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b", - "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91", - "sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592", - "sha256:2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187", - "sha256:2de9a304e27f7596cd03d16f1b7c72219bd944e99cc52b84d0145aefb07cbd3c", - "sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1", - "sha256:3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94", - "sha256:3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba", - "sha256:3e837e369566884707ddaf85fc1744b47575005c0a229de3327f8f9a20f4efeb", - "sha256:3f4d46d8b35698056ec29bca21546e1551a205058ae1a181d871e278b0b28165", - "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", - "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca", - "sha256:4647afc2f90d1ddd33441e5b0e85b16b12ddec4fca55f0d9671fef036ecca27c", - "sha256:4671d9dd5ec934cb9a73e7ee9676f9362aba54f7f34910956b84d727b0d73fb6", - "sha256:53f77cbe57044e88bbd5ed26ac1d0514d2acf0591dd6bb02a3ae37f76811b80c", - "sha256:5eda85d6d1879e692d546a078b44251cdd08dd1cfb98dfb77b670c97cee49ea0", - "sha256:5fed36fccc0612a53f1d4d9a816b50a36702c28a2aa880cb8a122b3466638743", - "sha256:61d028e90346df14fedc3d1e5441df818d095f3b87d286825dfcbd6459b7ef63", - "sha256:66f011380d0e49ed280c789fbd08ff0d40968ee7b665575489afa95c98196ab5", - "sha256:6824f87845e3396029f3820c206e459ccc91760e8fa24422f8b0c3d1731cbec5", - "sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4", - "sha256:6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d", - "sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b", - "sha256:730cacb21e1bdff3ce90babf007d0a0917cc3e6492f336c2f0134101e0944f93", - "sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205", - "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27", - "sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512", - "sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d", - "sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c", - "sha256:81afed14892743bbe14dacb9e36d9e0e504cd204e0b165062c488942b9718037", - "sha256:8941aaadaf67246224cee8c3803777eed332a19d909b47e29c9842ef1e79ac26", - "sha256:89472c9762729b5ae1ad974b777416bfda4ac5642423fa93bd57a09204712322", - "sha256:8ea985900c5c95ce9db1745f7933eeef5d314f0565b27625d9a10ec9881e1bfb", - "sha256:8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c", - "sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8", - "sha256:9332088d75dc3241c702d852d4671613136d90fa6881da7d770a483fd05248b4", - "sha256:94698a9c5f91f9d138526b48fe26a199609544591f859c870d477351dc7b2414", - "sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9", - "sha256:9de40a7b0323d889cf8d23d1ef214f565ab154443c42737dfe52ff82cf857664", - "sha256:a05d0c237b3349096d3981b727493e22147f934b20f6f125a3eba8f994bec4a9", - "sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775", - "sha256:b18a3ed7d5b3bd8d9ef7a8cb226502c6bf8308df1525e1cc676c3680e7176739", - "sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc", - "sha256:b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062", - "sha256:b4c854ef3adc177950a8dfc81a86f5115d2abd545751a304c5bcf2c2c7283cfe", - "sha256:b882b3df248017dba09d6b16defe9b5c407fe32fc7c65a9c69798e6175601be9", - "sha256:baf5215e0ab74c16e2dd324e8ec067ef59e41125d3eade2b863d294fd5035c92", - "sha256:c649e3a33450ec82378822b3dad03cc228b8f5963c0c12fc3b1e0ab940f768a5", - "sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13", - "sha256:c6638687455baf640e37344fe26d37c404db8b80d037c3d29f58fe8d1c3b194d", - "sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26", - "sha256:cb527a79772e5ef98fb1d700678fe031e353e765d1ca2d409c92263c6d43e09f", - "sha256:cf364028c016c03078a23b503f02058f1814320a56ad535686f90565636a9495", - "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b", - "sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6", - "sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c", - "sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef", - "sha256:da68248800ad6320861f129cd9c1bf96ca849a2771a59e0344e88681905916f5", - "sha256:da902562c3e9c550df360bfa53c035b2f241fed6d9aef119048073680ace4a18", - "sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad", - "sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3", - "sha256:de8dad4425a6ca6e4e5e297b27b5c824ecc7581910bf9aee86cb6835e6812aa7", - "sha256:e11e82b744887154b182fd3e7e8512418446501191994dbf9c9fc1f32cc8efd5", - "sha256:e6e73b9e02893c764e7e8d5bb5ce277f1a009cd5243f8228f75f842bf937c534", - "sha256:f73b96c41e3b2adedc34a7356e64c8eb96e03a3782b535e043a986276ce12a49", - "sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2", - "sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5", - "sha256:fc7de24befaeae77ba923797c7c87834c73648a05a4bde34b3b7e5588973a453", - "sha256:fe562eb1a64e67dd297ccc4f5addea2501664954f2692b69a76449ec7913ecbf" - ], - "markers": "python_version >= '3.9'", - "version": "==2.0.0" - }, - "charset-normalizer": { - "hashes": [ - "sha256:06a7e86163334edfc5d20fe104db92fcd666e5a5df0977cb5680a506fe26cc8e", - "sha256:0c173ce3a681f309f31b87125fecec7a5d1347261ea11ebbb856fa6006b23c8c", - "sha256:0e28d62a8fc7a1fa411c43bd65e346f3bce9716dc51b897fbe930c5987b402d5", - "sha256:0e901eb1049fdb80f5bd11ed5ea1e498ec423102f7a9b9e4645d5b8204ff2815", - "sha256:11afb56037cbc4b1555a34dd69151e8e069bee82e613a73bef6e714ce733585f", - "sha256:150b8ce8e830eb7ccb029ec9ca36022f756986aaaa7956aad6d9ec90089338c0", - "sha256:172985e4ff804a7ad08eebec0a1640ece87ba5041d565fff23c8f99c1f389484", - "sha256:197c1a244a274bb016dd8b79204850144ef77fe81c5b797dc389327adb552407", - "sha256:1ae6b62897110aa7c79ea2f5dd38d1abca6db663687c0b1ad9aed6f6bae3d9d6", - "sha256:1cf0a70018692f85172348fe06d3a4b63f94ecb055e13a00c644d368eb82e5b8", - "sha256:1ed80ff870ca6de33f4d953fda4d55654b9a2b340ff39ab32fa3adbcd718f264", - "sha256:22c6f0c2fbc31e76c3b8a86fba1a56eda6166e238c29cdd3d14befdb4a4e4815", - "sha256:231d4da14bcd9301310faf492051bee27df11f2bc7549bc0bb41fef11b82daa2", - "sha256:259695e2ccc253feb2a016303543d691825e920917e31f894ca1a687982b1de4", - "sha256:2a24157fa36980478dd1770b585c0f30d19e18f4fb0c47c13aa568f871718579", - "sha256:2b1a63e8224e401cafe7739f77efd3f9e7f5f2026bda4aead8e59afab537784f", - "sha256:2bd9d128ef93637a5d7a6af25363cf5dec3fa21cf80e68055aad627f280e8afa", - "sha256:2e1d8ca8611099001949d1cdfaefc510cf0f212484fe7c565f735b68c78c3c95", - "sha256:2ef7fedc7a6ecbe99969cd09632516738a97eeb8bd7258bf8a0f23114c057dab", - "sha256:2f7fdd9b6e6c529d6a2501a2d36b240109e78a8ceaef5687cfcfa2bbe671d297", - "sha256:30f445ae60aad5e1f8bdbb3108e39f6fbc09f4ea16c815c66578878325f8f15a", - "sha256:31215157227939b4fb3d740cd23fe27be0439afef67b785a1eb78a3ae69cba9e", - "sha256:34315ff4fc374b285ad7f4a0bf7dcbfe769e1b104230d40f49f700d4ab6bbd84", - "sha256:3516bbb8d42169de9e61b8520cbeeeb716f12f4ecfe3fd30a9919aa16c806ca8", - "sha256:3778fd7d7cd04ae8f54651f4a7a0bd6e39a0cf20f801720a4c21d80e9b7ad6b0", - "sha256:39f5068d35621da2881271e5c3205125cc456f54e9030d3f723288c873a71bf9", - "sha256:404a1e552cf5b675a87f0651f8b79f5f1e6fd100ee88dc612f89aa16abd4486f", - "sha256:419a9d91bd238052642a51938af8ac05da5b3343becde08d5cdeab9046df9ee1", - "sha256:423fb7e748a08f854a08a222b983f4df1912b1daedce51a72bd24fe8f26a1843", - "sha256:4482481cb0572180b6fd976a4d5c72a30263e98564da68b86ec91f0fe35e8565", - "sha256:461598cd852bfa5a61b09cae2b1c02e2efcd166ee5516e243d540ac24bfa68a7", - "sha256:47955475ac79cc504ef2704b192364e51d0d473ad452caedd0002605f780101c", - "sha256:48696db7f18afb80a068821504296eb0787d9ce239b91ca15059d1d3eaacf13b", - "sha256:4be9f4830ba8741527693848403e2c457c16e499100963ec711b1c6f2049b7c7", - "sha256:4d1d02209e06550bdaef34af58e041ad71b88e624f5d825519da3a3308e22687", - "sha256:4f41da960b196ea355357285ad1316a00099f22d0929fe168343b99b254729c9", - "sha256:517ad0e93394ac532745129ceabdf2696b609ec9f87863d337140317ebce1c14", - "sha256:51fb3c322c81d20567019778cb5a4a6f2dc1c200b886bc0d636238e364848c89", - "sha256:5273b9f0b5835ff0350c0828faea623c68bfa65b792720c453e22b25cc72930f", - "sha256:530d548084c4a9f7a16ed4a294d459b4f229db50df689bfe92027452452943a0", - "sha256:530e8cebeea0d76bdcf93357aa5e41336f48c3dc709ac52da2bb167c5b8271d9", - "sha256:54fae94be3d75f3e573c9a1b5402dc593de19377013c9a0e4285e3d402dd3a2a", - "sha256:572d7c822caf521f0525ba1bce1a622a0b85cf47ffbdae6c9c19e3b5ac3c4389", - "sha256:58c948d0d086229efc484fe2f30c2d382c86720f55cd9bc33591774348ad44e0", - "sha256:5d11595abf8dd942a77883a39d81433739b287b6aa71620f15164f8096221b30", - "sha256:5f8ddd609f9e1af8c7bd6e2aca279c931aefecd148a14402d4e368f3171769fd", - "sha256:5feb91325bbceade6afab43eb3b508c63ee53579fe896c77137ded51c6b6958e", - "sha256:60c74963d8350241a79cb8feea80e54d518f72c26db618862a8f53e5023deaf9", - "sha256:613f19aa6e082cf96e17e3ffd89383343d0d589abda756b7764cf78361fd41dc", - "sha256:659a1e1b500fac8f2779dd9e1570464e012f43e580371470b45277a27baa7532", - "sha256:695f5c2823691a25f17bc5d5ffe79fa90972cc34b002ac6c843bb8a1720e950d", - "sha256:69dd852c2f0ad631b8b60cfbe25a28c0058a894de5abb566619c205ce0550eae", - "sha256:6cceb5473417d28edd20c6c984ab6fee6c6267d38d906823ebfe20b03d607dc2", - "sha256:71be7e0e01753a89cf024abf7ecb6bca2c81738ead80d43004d9b5e3f1244e64", - "sha256:74119174722c4349af9708993118581686f343adc1c8c9c007d59be90d077f3f", - "sha256:74a2e659c7ecbc73562e2a15e05039f1e22c75b7c7618b4b574a3ea9118d1557", - "sha256:7504e9b7dc05f99a9bbb4525c67a2c155073b44d720470a148b34166a69c054e", - "sha256:79090741d842f564b1b2827c0b82d846405b744d31e84f18d7a7b41c20e473ff", - "sha256:7a6967aaf043bceabab5412ed6bd6bd26603dae84d5cb75bf8d9a74a4959d398", - "sha256:7bda6eebafd42133efdca535b04ccb338ab29467b3f7bf79569883676fc628db", - "sha256:7edbed096e4a4798710ed6bc75dcaa2a21b68b6c356553ac4823c3658d53743a", - "sha256:7f9019c9cb613f084481bd6a100b12e1547cf2efe362d873c2e31e4035a6fa43", - "sha256:802168e03fba8bbc5ce0d866d589e4b1ca751d06edee69f7f3a19c5a9fe6b597", - "sha256:80d0a5615143c0b3225e5e3ef22c8d5d51f3f72ce0ea6fb84c943546c7b25b6c", - "sha256:82060f995ab5003a2d6e0f4ad29065b7672b6593c8c63559beefe5b443242c3e", - "sha256:836ab36280f21fc1a03c99cd05c6b7af70d2697e374c7af0b61ed271401a72a2", - "sha256:8761ac29b6c81574724322a554605608a9960769ea83d2c73e396f3df896ad54", - "sha256:87725cfb1a4f1f8c2fc9890ae2f42094120f4b44db9360be5d99a4c6b0e03a9e", - "sha256:899d28f422116b08be5118ef350c292b36fc15ec2daeb9ea987c89281c7bb5c4", - "sha256:8bc5f0687d796c05b1e28ab0d38a50e6309906ee09375dd3aff6a9c09dd6e8f4", - "sha256:8bea55c4eef25b0b19a0337dc4e3f9a15b00d569c77211fa8cde38684f234fb7", - "sha256:8e5a94886bedca0f9b78fecd6afb6629142fd2605aa70a125d49f4edc6037ee6", - "sha256:90ca27cd8da8118b18a52d5f547859cc1f8354a00cd1e8e5120df3e30d6279e5", - "sha256:92734d4d8d187a354a556626c221cd1a892a4e0802ccb2af432a1d85ec012194", - "sha256:947cf925bc916d90adba35a64c82aace04fa39b46b52d4630ece166655905a69", - "sha256:95b52c68d64c1878818687a473a10547b3292e82b6f6fe483808fb1468e2f52f", - "sha256:97d0235baafca5f2b09cf332cc275f021e694e8362c6bb9c96fc9a0eb74fc316", - "sha256:9ca4c0b502ab399ef89248a2c84c54954f77a070f28e546a85e91da627d1301e", - "sha256:9cc4fc6c196d6a8b76629a70ddfcd4635a6898756e2d9cac5565cf0654605d73", - "sha256:9cc6e6d9e571d2f863fa77700701dae73ed5f78881efc8b3f9a4398772ff53e8", - "sha256:a056d1ad2633548ca18ffa2f85c202cfb48b68615129143915b8dc72a806a923", - "sha256:a26611d9987b230566f24a0a125f17fe0de6a6aff9f25c9f564aaa2721a5fb88", - "sha256:a4474d924a47185a06411e0064b803c68be044be2d60e50e8bddcc2649957c1f", - "sha256:a4ea868bc28109052790eb2b52a9ab33f3aa7adc02f96673526ff47419490e21", - "sha256:a9e68c9d88823b274cf1e72f28cb5dc89c990edf430b0bfd3e2fb0785bfeabf4", - "sha256:aa9cccf4a44b9b62d8ba8b4dd06c649ba683e4bf04eea606d2e94cfc2d6ff4d6", - "sha256:ab30e5e3e706e3063bc6de96b118688cb10396b70bb9864a430f67df98c61ecc", - "sha256:ac2393c73378fea4e52aa56285a3d64be50f1a12395afef9cce47772f60334c2", - "sha256:ad8faf8df23f0378c6d527d8b0b15ea4a2e23c89376877c598c4870d1b2c7866", - "sha256:b35b200d6a71b9839a46b9b7fff66b6638bb52fc9658aa58796b0326595d3021", - "sha256:b3694e3f87f8ac7ce279d4355645b3c878d24d1424581b46282f24b92f5a4ae2", - "sha256:b4ff1d35e8c5bd078be89349b6f3a845128e685e751b6ea1169cf2160b344c4d", - "sha256:bbc8c8650c6e51041ad1be191742b8b421d05bbd3410f43fa2a00c8db87678e8", - "sha256:bc72863f4d9aba2e8fd9085e63548a324ba706d2ea2c83b260da08a59b9482de", - "sha256:bf625105bb9eef28a56a943fec8c8a98aeb80e7d7db99bd3c388137e6eb2d237", - "sha256:c2274ca724536f173122f36c98ce188fd24ce3dad886ec2b7af859518ce008a4", - "sha256:c45a03a4c69820a399f1dda9e1d8fbf3562eda46e7720458180302021b08f778", - "sha256:c8ae56368f8cc97c7e40a7ee18e1cedaf8e780cd8bc5ed5ac8b81f238614facb", - "sha256:c907cdc8109f6c619e6254212e794d6548373cc40e1ec75e6e3823d9135d29cc", - "sha256:ca0276464d148c72defa8bb4390cce01b4a0e425f3b50d1435aa6d7a18107602", - "sha256:cd5e2801c89992ed8c0a3f0293ae83c159a60d9a5d685005383ef4caca77f2c4", - "sha256:d08ec48f0a1c48d75d0356cea971921848fb620fdeba805b28f937e90691209f", - "sha256:d1a2ee9c1499fc8f86f4521f27a973c914b211ffa87322f4ee33bb35392da2c5", - "sha256:d5f5d1e9def3405f60e3ca8232d56f35c98fb7bf581efcc60051ebf53cb8b611", - "sha256:d60377dce4511655582e300dc1e5a5f24ba0cb229005a1d5c8d0cb72bb758ab8", - "sha256:d73beaac5e90173ac3deb9928a74763a6d230f494e4bfb422c217a0ad8e629bf", - "sha256:d7de2637729c67d67cf87614b566626057e95c303bc0a55ffe391f5205e7003d", - "sha256:dad6e0f2e481fffdcf776d10ebee25e0ef89f16d691f1e5dee4b586375fdc64b", - "sha256:dda86aba335c902b6149a02a55b38e96287157e609200811837678214ba2b1db", - "sha256:df01808ee470038c3f8dc4f48620df7225c49c2d6639e38f96e6d6ac6e6f7b0e", - "sha256:e1f6e2f00a6b8edb562826e4632e26d063ac10307e80f7461f7de3ad8ef3f077", - "sha256:e25369dc110d58ddf29b949377a93e0716d72a24f62bad72b2b39f155949c1fd", - "sha256:e3c701e954abf6fc03a49f7c579cc80c2c6cc52525340ca3186c41d3f33482ef", - "sha256:e5bcc1a1ae744e0bb59641171ae53743760130600da8db48cbb6e4918e186e4e", - "sha256:e68c14b04827dd76dcbd1aeea9e604e3e4b78322d8faf2f8132c7138efa340a8", - "sha256:e8aeb10fcbe92767f0fa69ad5a72deca50d0dca07fbde97848997d778a50c9fe", - "sha256:e985a16ff513596f217cee86c21371b8cd011c0f6f056d0920aa2d926c544058", - "sha256:ecbbd45615a6885fe3240eb9db73b9e62518b611850fdf8ab08bd56de7ad2b17", - "sha256:ee4ec14bc1680d6b0afab9aea2ef27e26d2024f18b24a2d7155a52b60da7e833", - "sha256:ef5960d965e67165d75b7c7ffc60a83ec5abfc5c11b764ec13ea54fbef8b4421", - "sha256:f0cdaecd4c953bfae0b6bb64910aaaca5a424ad9c72d85cb88417bb9814f7550", - "sha256:f1ce721c8a7dfec21fcbdfe04e8f68174183cf4e8188e0645e92aa23985c57ff", - "sha256:f50498891691e0864dc3da965f340fada0771f6142a378083dc4608f4ea513e2", - "sha256:f5ea69428fa1b49573eef0cc44a1d43bebd45ad0c611eb7d7eac760c7ae771bc", - "sha256:f61aa92e4aad0be58eb6eb4e0c21acf32cf8065f4b2cae5665da756c4ceef982", - "sha256:f6e4333fb15c83f7d1482a76d45a0818897b3d33f00efd215528ff7c51b8e35d", - "sha256:f820f24b09e3e779fe84c3c456cb4108a7aa639b0d1f02c28046e11bfcd088ed", - "sha256:f98059e4fcd3e3e4e2d632b7cf81c2faae96c43c60b569e9c621468082f1d104", - "sha256:fcce033e4021347d80ed9c66dcf1e7b1546319834b74445f561d2e2221de5659" - ], - "markers": "python_version >= '3.7'", - "version": "==3.4.6" + "markers": "python_version >= '3.6'", + "version": "==2025.4.26" }, "colorama": { "hashes": [ @@ -297,448 +63,133 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6'", "version": "==0.4.6" }, - "cryptography": { + "dill": { "hashes": [ - "sha256:02f547fce831f5096c9a567fd41bc12ca8f11df260959ecc7c3202555cc47a72", - "sha256:039917b0dc418bb9f6edce8a906572d69e74bd330b0b3fea4f79dab7f8ddd235", - "sha256:1abfdb89b41c3be0365328a410baa9df3ff8a9110fb75e7b52e66803ddabc9a9", - "sha256:2ae6971afd6246710480e3f15824ed3029a60fc16991db250034efd0b9fb4356", - "sha256:2b7a67c9cd56372f3249b39699f2ad479f6991e62ea15800973b956f4b73e257", - "sha256:351695ada9ea9618b3500b490ad54c739860883df6c1f555e088eaf25b1bbaad", - "sha256:38946c54b16c885c72c4f59846be9743d699eee2b69b6988e0a00a01f46a61a4", - "sha256:3b4995dc971c9fb83c25aa44cf45f02ba86f71ee600d81091c2f0cbae116b06c", - "sha256:3ce58ba46e1bc2aac4f7d9290223cead56743fa6ab94a5d53292ffaac6a91614", - "sha256:3ee190460e2fbe447175cda91b88b84ae8322a104fc27766ad09428754a618ed", - "sha256:4108d4c09fbbf2789d0c926eb4152ae1760d5a2d97612b92d508d96c861e4d31", - "sha256:420d0e909050490d04359e7fdb5ed7e667ca5c3c402b809ae2563d7e66a92229", - "sha256:47fb8a66058b80e509c47118ef8a75d14c455e81ac369050f20ba0d23e77fee0", - "sha256:4c3341037c136030cb46e4b1e17b7418ea4cbd9dd207e4a6f3b2b24e0d4ac731", - "sha256:4d7e3d356b8cd4ea5aff04f129d5f66ebdc7b6f8eae802b93739ed520c47c79b", - "sha256:4d8ae8659ab18c65ced284993c2265910f6c9e650189d4e3f68445ef82a810e4", - "sha256:4e817a8920bfbcff8940ecfd60f23d01836408242b30f1a708d93198393a80b4", - "sha256:50bfb6925eff619c9c023b967d5b77a54e04256c4281b0e21336a130cd7fc263", - "sha256:556e106ee01aa13484ce9b0239bca667be5004efb0aabbed28d353df86445595", - "sha256:582f5fcd2afa31622f317f80426a027f30dc792e9c80ffee87b993200ea115f1", - "sha256:5be7bf2fb40769e05739dd0046e7b26f9d4670badc7b032d6ce4db64dddc0678", - "sha256:60ee7e19e95104d4c03871d7d7dfb3d22ef8a9b9c6778c94e1c8fcc8365afd48", - "sha256:61aa400dce22cb001a98014f647dc21cda08f7915ceb95df0c9eaf84b4b6af76", - "sha256:68f68d13f2e1cb95163fa3b4db4bf9a159a418f5f6e7242564fc75fcae667fd0", - "sha256:7d1f30a86d2757199cb2d56e48cce14deddf1f9c95f1ef1b64ee91ea43fe2e18", - "sha256:7d731d4b107030987fd61a7f8ab512b25b53cef8f233a97379ede116f30eb67d", - "sha256:803812e111e75d1aa73690d2facc295eaefd4439be1023fefc4995eaea2af90d", - "sha256:80a8d7bfdf38f87ca30a5391c0c9ce4ed2926918e017c29ddf643d0ed2778ea1", - "sha256:8293f3dea7fc929ef7240796ba231413afa7b68ce38fd21da2995549f5961981", - "sha256:8456928655f856c6e1533ff59d5be76578a7157224dbd9ce6872f25055ab9ab7", - "sha256:890bcb4abd5a2d3f852196437129eb3667d62630333aacc13dfd470fad3aaa82", - "sha256:94a76daa32eb78d61339aff7952ea819b1734b46f73646a07decb40e5b3448e2", - "sha256:9f16fbdf4da055efb21c22d81b89f155f02ba420558db21288b3d0035bafd5f4", - "sha256:a3d1fae9863299076f05cb8a778c467578262fae09f9dc0ee9b12eb4268ce663", - "sha256:a3d507bb6a513ca96ba84443226af944b0f7f47dcc9a399d110cd6146481d24c", - "sha256:abace499247268e3757271b2f1e244b36b06f8515cf27c4d49468fc9eb16e93d", - "sha256:ba2a27ff02f48193fc4daeadf8ad2590516fa3d0adeeb34336b96f7fa64c1e3a", - "sha256:bc84e875994c3b445871ea7181d424588171efec3e185dced958dad9e001950a", - "sha256:bfd56bb4b37ed4f330b82402f6f435845a5f5648edf1ad497da51a8452d5d62d", - "sha256:c18ff11e86df2e28854939acde2d003f7984f721eba450b56a200ad90eeb0e6b", - "sha256:c3bcce8521d785d510b2aad26ae2c966092b7daa8f45dd8f44734a104dc0bc1a", - "sha256:c4143987a42a2397f2fc3b4d7e3a7d313fbe684f67ff443999e803dd75a76826", - "sha256:c69fd885df7d089548a42d5ec05be26050ebcd2283d89b3d30676eb32ff87dee", - "sha256:ced80795227d70549a411a4ab66e8ce307899fad2220ce5ab2f296e687eacde9", - "sha256:d66e421495fdb797610a08f43b05269e0a5ea7f5e652a89bfd5a7d3c1dee3648", - "sha256:d861ee9e76ace6cf36a6a89b959ec08e7bc2493ee39d07ffe5acb23ef46d27da", - "sha256:e9251e3be159d1020c4030bd2e5f84d6a43fe54b6c19c12f51cde9542a2817b2", - "sha256:f145bba11b878005c496e93e257c1e88f154d278d2638e6450d17e0f31e558d2", - "sha256:fe346b143ff9685e40192a4960938545c699054ba11d4f9029f94751e3f71d87" + "sha256:0633f1d2df477324f53a895b02c901fb961bdbf65a17122586ea7019292cbcf0", + "sha256:44f54bf6412c2c8464c14e8243eb163690a9800dbe2c367330883b19c7561049" ], - "markers": "python_version >= '3.8' and python_full_version not in '3.9.0, 3.9.1'", - "version": "==46.0.5" + "markers": "python_version >= '3.8'", + "version": "==0.4.0" }, "distlib": { "hashes": [ - "sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16", - "sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d" + "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87", + "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403" ], - "version": "==0.4.0" - }, - "dnspython": { - "hashes": [ - "sha256:01d9bbc4a2d76bf0db7c1f729812ded6d912bd318d3b1cf81d30c0f845dbf3af", - "sha256:181d3c6996452cb1189c4046c61599b84a5a86e099562ffde77d26984ff26d0f" - ], - "markers": "python_version >= '3.10'", - "version": "==2.8.0" - }, - "docutils": { - "hashes": [ - "sha256:4db53b1fde9abecbb74d91230d32ab626d94f6badfc575d6db9194a49df29968", - "sha256:d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de" - ], - "markers": "python_version >= '3.9'", - "version": "==0.22.4" - }, - "email-validator": { - "hashes": [ - "sha256:80f13f623413e6b197ae73bb10bf4eb0908faf509ad8362c5edeb0be7fd450b4", - "sha256:9fc05c37f2f6cf439ff414f8fc46d917929974a82244c20eb10231ba60c54426" - ], - "markers": "python_version >= '3.8'", - "version": "==2.3.0" + "version": "==0.3.9" }, "filelock": { "hashes": [ - "sha256:b64ece2b38f4ca29dd3e810287aa8c48182bbecd1ae6e9ae126c9b35f1382694", - "sha256:ca8afb0da15f229774c9ad1b455ed96e85a81373065fb10446672f64444ddf70" - ], - "markers": "python_version >= '3.10'", - "version": "==3.25.2" - }, - "id": { - "hashes": [ - "sha256:d0732d624fb46fd4e7bc4e5152f00214450953b9e772c182c1c22964def1a069", - "sha256:f5ec41ed2629a508f5d0988eda142e190c9c6da971100612c4de9ad9f9b237ca" + "sha256:adbc88eabb99d2fec8c9c1b229b171f18afa655400173ddc653d5d01501fb9f2", + "sha256:c401f4f8377c4464e6db25fff06205fd89bdd83b65eb0488ed1b160f780e21de" ], "markers": "python_version >= '3.9'", - "version": "==1.6.1" + "version": "==3.18.0" }, - "idna": { + "isort": { "hashes": [ - "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", - "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902" + "sha256:1cb5df28dfbc742e490c5e41bad6da41b805b0a8be7bc93cd0fb2a8a890ac450", + "sha256:2dc5d7f65c9678d94c88dfc29161a320eec67328bc97aad576874cb4be1e9615" + ], + "markers": "python_full_version >= '3.9.0'", + "version": "==6.0.1" + }, + "mccabe": { + "hashes": [ + "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", + "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e" + ], + "markers": "python_version >= '3.6'", + "version": "==0.7.0" + }, + "mypy": { + "hashes": [ + "sha256:1124a18bc11a6a62887e3e137f37f53fbae476dc36c185d549d4f837a2a6a14e", + "sha256:171a9ca9a40cd1843abeca0e405bc1940cd9b305eaeea2dda769ba096932bb22", + "sha256:1905f494bfd7d85a23a88c5d97840888a7bd516545fc5aaedff0267e0bb54e2f", + "sha256:1fbb8da62dc352133d7d7ca90ed2fb0e9d42bb1a32724c287d3c76c58cbaa9c2", + "sha256:2922d42e16d6de288022e5ca321cd0618b238cfc5570e0263e5ba0a77dbef56f", + "sha256:2e2c2e6d3593f6451b18588848e66260ff62ccca522dd231cd4dd59b0160668b", + "sha256:2ee2d57e01a7c35de00f4634ba1bbf015185b219e4dc5909e281016df43f5ee5", + "sha256:2f2147ab812b75e5b5499b01ade1f4a81489a147c01585cda36019102538615f", + "sha256:404534629d51d3efea5c800ee7c42b72a6554d6c400e6a79eafe15d11341fd43", + "sha256:5469affef548bd1895d86d3bf10ce2b44e33d86923c29e4d675b3e323437ea3e", + "sha256:5a95fb17c13e29d2d5195869262f8125dfdb5c134dc8d9a9d0aecf7525b10c2c", + "sha256:6983aae8b2f653e098edb77f893f7b6aca69f6cffb19b2cc7443f23cce5f4828", + "sha256:712e962a6357634fef20412699a3655c610110e01cdaa6180acec7fc9f8513ba", + "sha256:8023ff13985661b50a5928fc7a5ca15f3d1affb41e5f0a9952cb68ef090b31ee", + "sha256:811aeccadfb730024c5d3e326b2fbe9249bb7413553f15499a4050f7c30e801d", + "sha256:8f8722560a14cde92fdb1e31597760dc35f9f5524cce17836c0d22841830fd5b", + "sha256:93faf3fdb04768d44bf28693293f3904bbb555d076b781ad2530214ee53e3445", + "sha256:973500e0774b85d9689715feeffcc980193086551110fd678ebe1f4342fb7c5e", + "sha256:979e4e1a006511dacf628e36fadfecbcc0160a8af6ca7dad2f5025529e082c13", + "sha256:98b7b9b9aedb65fe628c62a6dc57f6d5088ef2dfca37903a7d9ee374d03acca5", + "sha256:aea39e0583d05124836ea645f412e88a5c7d0fd77a6d694b60d9b6b2d9f184fd", + "sha256:b9378e2c00146c44793c98b8d5a61039a048e31f429fb0eb546d93f4b000bedf", + "sha256:baefc32840a9f00babd83251560e0ae1573e2f9d1b067719479bfb0e987c6357", + "sha256:be68172e9fd9ad8fb876c6389f16d1c1b5f100ffa779f77b1fb2176fcc9ab95b", + "sha256:c43a7682e24b4f576d93072216bf56eeff70d9140241f9edec0c104d0c515036", + "sha256:c4bb0e1bd29f7d34efcccd71cf733580191e9a264a2202b0239da95984c5b559", + "sha256:c7be1e46525adfa0d97681432ee9fcd61a3964c2446795714699a998d193f1a3", + "sha256:c9817fa23833ff189db061e6d2eff49b2f3b6ed9856b4a0a73046e41932d744f", + "sha256:ce436f4c6d218a070048ed6a44c0bbb10cd2cc5e272b29e7845f6a2f57ee4464", + "sha256:d10d994b41fb3497719bbf866f227b3489048ea4bbbb5015357db306249f7980", + "sha256:e601a7fa172c2131bff456bb3ee08a88360760d0d2f8cbd7a75a65497e2df078", + "sha256:f95579473af29ab73a10bada2f9722856792a36ec5af5399b653aa28360290a5" + ], + "index": "pypi", + "markers": "python_version >= '3.9'", + "version": "==1.15.0" + }, + "mypy-extensions": { + "hashes": [ + "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", + "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558" ], "markers": "python_version >= '3.8'", - "version": "==3.11" - }, - "jaraco.classes": { - "hashes": [ - "sha256:47a024b51d0239c0dd8c8540c6c7f484be3b8fcf0b2d85c13825780d3b3f3acd", - "sha256:f662826b6bed8cace05e7ff873ce0f9283b5c924470fe664fff1c2f00f581790" - ], - "markers": "python_version >= '3.8'", - "version": "==3.4.0" - }, - "jaraco.context": { - "hashes": [ - "sha256:bf8150b79a2d5d91ae48629d8b427a8f7ba0e1097dd6202a9059f29a36379535", - "sha256:f1a6c9d391e661cc5b8d39861ff077a7dc24dc23833ccee564b234b81c82dfe3" - ], - "markers": "python_version >= '3.10'", - "version": "==6.1.2" - }, - "jaraco.functools": { - "hashes": [ - "sha256:9eec1e36f45c818d9bf307c8948eb03b2b56cd44087b3cdc989abca1f20b9176", - "sha256:da21933b0417b89515562656547a77b4931f98176eb173644c0d35032a33d6bb" - ], - "markers": "python_version >= '3.9'", - "version": "==4.4.0" - }, - "jeepney": { - "hashes": [ - "sha256:97e5714520c16fc0a45695e5365a2e11b81ea79bba796e26f9f1d178cb182683", - "sha256:cf0e9e845622b81e4a28df94c40345400256ec608d0e55bb8a3feaa9163f5732" - ], - "markers": "python_version >= '3.7'", - "version": "==0.9.0" - }, - "keyring": { - "hashes": [ - "sha256:be4a0b195f149690c166e850609a477c532ddbfbaed96a404d4e43f8d5e2689f", - "sha256:fe01bd85eb3f8fb3dd0405defdeac9a5b4f6f0439edbb3149577f244a2e8245b" - ], - "markers": "python_version >= '3.9'", - "version": "==25.7.0" - }, - "markdown-it-py": { - "hashes": [ - "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", - "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3" - ], - "markers": "python_version >= '3.10'", - "version": "==4.0.0" - }, - "mdurl": { - "hashes": [ - "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", - "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba" - ], - "markers": "python_version >= '3.7'", - "version": "==0.1.2" - }, - "more-itertools": { - "hashes": [ - "sha256:52d4362373dcf7c52546bc4af9a86ee7c4579df9a8dc268be0a2f949d376cc9b", - "sha256:f638ddf8a1a0d134181275fb5d58b086ead7c6a72429ad725c67503f13ba30bd" - ], - "markers": "python_version >= '3.9'", - "version": "==10.8.0" - }, - "nh3": { - "hashes": [ - "sha256:0d5eb734a78ac364af1797fef718340a373f626a9ff6b4fb0b4badf7927e7b81", - "sha256:185ed41b88c910b9ca8edc89ca3b4be688a12cb9de129d84befa2f74a0039fee", - "sha256:1ef87f8e916321a88b45f2d597f29bd56e560ed4568a50f0f1305afab86b7189", - "sha256:21a63ccb18ddad3f784bb775955839b8b80e347e597726f01e43ca1abcc5c808", - "sha256:21b058cd20d9f0919421a820a2843fdb5e1749c0bf57a6247ab8f4ba6723c9fc", - "sha256:24769a428e9e971e4ccfb24628f83aaa7dc3c8b41b130c8ddc1835fa1c924489", - "sha256:2efd17c0355d04d39e6d79122b42662277ac10a17ea48831d90b46e5ef7e4fc0", - "sha256:3a62b8ae7c235481715055222e54c682422d0495a5c73326807d4e44c5d14691", - "sha256:45fe0d6a607264910daec30360c8a3b5b1500fd832d21b2da608256287bcb92d", - "sha256:4c730617bdc15d7092dcc0469dc2826b914c8f874996d105b4bc3842a41c1cd9", - "sha256:52e973cb742e95b9ae1b35822ce23992428750f4b46b619fe86eba4205255b30", - "sha256:5a4b2c1f3e6f3cbe7048e17f4fefad3f8d3e14cc0fd08fb8599e0d5653f6b181", - "sha256:5bc1d4b30ba1ba896669d944b6003630592665974bd11a3dc2f661bde92798a7", - "sha256:90126a834c18af03bfd6ff9a027bfa6bbf0e238527bc780a24de6bd7cc1041e2", - "sha256:92a958e6f6d0100e025a5686aafd67e3c98eac67495728f8bb64fbeb3e474493", - "sha256:9ed40cf8449a59a03aa465114fedce1ff7ac52561688811d047917cc878b19ca", - "sha256:a446eae598987f49ee97ac2f18eafcce4e62e7574bd1eb23782e4702e54e217d", - "sha256:b50c3770299fb2a7c1113751501e8878d525d15160a4c05194d7fe62b758aad8", - "sha256:b7a18ee057761e455d58b9d31445c3e4b2594cff4ddb84d2e331c011ef46f462", - "sha256:b838e619f483531483d26d889438e53a880510e832d2aafe73f93b7b1ac2bce2", - "sha256:e8ee96156f7dfc6e30ecda650e480c5ae0a7d38f0c6fafc3c1c655e2500421d9", - "sha256:e974850b131fdffa75e7ad8e0d9c7a855b96227b093417fdf1bd61656e530f37", - "sha256:e98fa3dbfd54e25487e36ba500bc29bca3a4cab4ffba18cfb1a35a2d02624297", - "sha256:f433a2dd66545aad4a720ad1b2150edcdca75bfff6f4e6f378ade1ec138d5e77", - "sha256:f4400a73c2a62859e769f9d36d1b5a7a5c65c4179d1dddd2f6f3095b2db0cbfc", - "sha256:f508ddd4e2433fdcb78c790fc2d24e3a349ba775e5fa904af89891321d4844a3", - "sha256:fc305a2264868ec8fa16548296f803d8fd9c1fa66cd28b88b605b1bd06667c0b" - ], - "markers": "python_version >= '3.8'", - "version": "==0.3.3" + "version": "==1.1.0" }, "packaging": { "hashes": [ - "sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4", - "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529" + "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", + "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f" ], "markers": "python_version >= '3.8'", - "version": "==26.0" + "version": "==25.0" }, "pipenv": { "hashes": [ - "sha256:cd2858095181578ec17451f3ff02b8f74eb9038013ddbbc54228c5f0611fa3da", - "sha256:ddba48a3f9a27e6330b391180ba078354d4d8de480bbe49e7432d6c8ead5bbd7" + "sha256:85d42e13da78f27f0213c998dba9a59f3ba6a6fe9e420b75b561acc344f021ad", + "sha256:f26dc0352f3fb167c3897a66a5d8c9ab81dd52a836a48630712e1e5a06840ebf" ], "index": "pypi", - "markers": "python_version >= '3.10'", - "version": "==2026.2.1" + "markers": "python_version >= '3.9'", + "version": "==2025.0.2" }, "platformdirs": { "hashes": [ - "sha256:1ec356301b7dc906d83f371c8f487070e99d3ccf9e501686456394622a01a934", - "sha256:68a9a4619a666ea6439f2ff250c12a853cd1cbd5158d258bd824a7df6be2f868" - ], - "markers": "python_version >= '3.10'", - "version": "==4.9.4" - }, - "pluggy": { - "hashes": [ - "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", - "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746" + "sha256:a03875334331946f13c549dbd8f4bac7a13a50a895a0eb1e8c6a8ace80d40a94", + "sha256:eb437d586b6a0986388f0d6f74aa0cde27b48d0e3d66843640bfb6bdcdb6e351" ], "markers": "python_version >= '3.9'", - "version": "==1.6.0" - }, - "pyasn1": { - "hashes": [ - "sha256:697a8ecd6d98891189184ca1fa05d1bb00e2f84b5977c481452050549c8a72cf", - "sha256:a80184d120f0864a52a073acc6fc642847d0be408e7c7252f31390c0f4eadcde" - ], - "markers": "python_version >= '3.8'", - "version": "==0.6.3" + "version": "==4.3.7" }, "pycodestyle": { "hashes": [ - "sha256:c4b5b517d278089ff9d0abdec919cd97262a3367449ea1c8b49b91529167b783", - "sha256:dd6bf7cb4ee77f8e016f9c8e74a35ddd9f67e1d5fd4184d86c3b98e07099f42d" + "sha256:35863c5974a271c7a726ed228a14a4f6daf49df369d8c50cd9a6f58a5e143ba9", + "sha256:c8415bf09abe81d9c7f872502a6eee881fbe85d8763dd5b9924bb0a01d67efae" ], "markers": "python_version >= '3.9'", - "version": "==2.14.0" + "version": "==2.13.0" }, - "pycparser": { + "pylint": { "hashes": [ - "sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29", - "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992" - ], - "markers": "python_version >= '3.10'", - "version": "==3.0" - }, - "pydantic": { - "extras": [ - "email" - ], - "hashes": [ - "sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49", - "sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d" - ], - "markers": "python_version >= '3.9'", - "version": "==2.12.5" - }, - "pydantic-core": { - "hashes": [ - "sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90", - "sha256:01a3d0ab748ee531f4ea6c3e48ad9dac84ddba4b0d82291f87248f2f9de8d740", - "sha256:0384e2e1021894b1ff5a786dbf94771e2986ebe2869533874d7e43bc79c6f504", - "sha256:03b77d184b9eb40240ae9fd676ca364ce1085f203e1b1256f8ab9984dca80a84", - "sha256:03ca43e12fab6023fc79d28ca6b39b05f794ad08ec2feccc59a339b02f2b3d33", - "sha256:05a2c8852530ad2812cb7914dc61a1125dc4e06252ee98e5638a12da6cc6fb6c", - "sha256:070259a8818988b9a84a449a2a7337c7f430a22acc0859c6b110aa7212a6d9c0", - "sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e", - "sha256:0cbaad15cb0c90aa221d43c00e77bb33c93e8d36e0bf74760cd00e732d10a6a0", - "sha256:100baa204bb412b74fe285fb0f3a385256dad1d1879f0a5cb1499ed2e83d132a", - "sha256:112e305c3314f40c93998e567879e887a3160bb8689ef3d2c04b6cc62c33ac34", - "sha256:16f80f7abe3351f8ea6858914ddc8c77e02578544a0ebc15b4c2e1a0e813b0b2", - "sha256:1746d4a3d9a794cacae06a5eaaccb4b8643a131d45fbc9af23e353dc0a5ba5c3", - "sha256:1962293292865bca8e54702b08a4f26da73adc83dd1fcf26fbc875b35d81c815", - "sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14", - "sha256:1f8d33a7f4d5a7889e60dc39856d76d09333d8a6ed0f5f1190635cbec70ec4ba", - "sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375", - "sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf", - "sha256:242a206cd0318f95cd21bdacff3fcc3aab23e79bba5cac3db5a841c9ef9c6963", - "sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1", - "sha256:266fb4cbf5e3cbd0b53669a6d1b039c45e3ce651fd5442eff4d07c2cc8d66808", - "sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553", - "sha256:287dad91cfb551c363dc62899a80e9e14da1f0e2b6ebde82c806612ca2a13ef1", - "sha256:29452c56df2ed968d18d7e21f4ab0ac55e71dc59524872f6fc57dcf4a3249ed2", - "sha256:299e0a22e7ae2b85c1a57f104538b2656e8ab1873511fd718a1c1c6f149b77b5", - "sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470", - "sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2", - "sha256:2c010c6ded393148374c0f6f0bf89d206bf3217f201faa0635dcd56bd1520f6b", - "sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660", - "sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c", - "sha256:33cb885e759a705b426baada1fe68cbb0a2e68e34c5d0d0289a364cf01709093", - "sha256:346285d28e4c8017da95144c7f3acd42740d637ff41946af5ce6e5e420502dd5", - "sha256:34a64bc3441dc1213096a20fe27e8e128bd3ff89921706e83c0b1ac971276594", - "sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008", - "sha256:378bec5c66998815d224c9ca994f1e14c0c21cb95d2f52b6021cc0b2a58f2a5a", - "sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a", - "sha256:3f84d5c1b4ab906093bdc1ff10484838aca54ef08de4afa9de0f5f14d69639cd", - "sha256:4009935984bd36bd2c774e13f9a09563ce8de4abaa7226f5108262fa3e637284", - "sha256:406bf18d345822d6c21366031003612b9c77b3e29ffdb0f612367352aab7d586", - "sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869", - "sha256:482c982f814460eabe1d3bb0adfdc583387bd4691ef00b90575ca0d2b6fe2294", - "sha256:4bc36bbc0b7584de96561184ad7f012478987882ebf9f9c389b23f432ea3d90f", - "sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66", - "sha256:56121965f7a4dc965bff783d70b907ddf3d57f6eba29b6d2e5dabfaf07799c51", - "sha256:58133647260ea01e4d0500089a8c4f07bd7aa6ce109682b1426394988d8aaacc", - "sha256:5921a4d3ca3aee735d9fd163808f5e8dd6c6972101e4adbda9a4667908849b97", - "sha256:5a4e67afbc95fa5c34cf27d9089bca7fcab4e51e57278d710320a70b956d1b9a", - "sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d", - "sha256:62de39db01b8d593e45871af2af9e497295db8d73b085f6bfd0b18c83c70a8f9", - "sha256:634e8609e89ceecea15e2d61bc9ac3718caaaa71963717bf3c8f38bfde64242c", - "sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07", - "sha256:650ae77860b45cfa6e2cdafc42618ceafab3a2d9a3811fcfbd3bbf8ac3c40d36", - "sha256:6561e94ba9dacc9c61bce40e2d6bdc3bfaa0259d3ff36ace3b1e6901936d2e3e", - "sha256:65840751b72fbfd82c3c640cff9284545342a4f1eb1586ad0636955b261b0b05", - "sha256:6cb58b9c66f7e4179a2d5e0f849c48eff5c1fca560994d6eb6543abf955a149e", - "sha256:6f52298fbd394f9ed112d56f3d11aabd0d5bd27beb3084cc3d8ad069483b8941", - "sha256:707625ef0983fcfb461acfaf14de2067c5942c6bb0f3b4c99158bed6fedd3cf3", - "sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612", - "sha256:753e230374206729bf0a807954bcc6c150d3743928a73faffee51ac6557a03c3", - "sha256:76d0819de158cd855d1cbb8fcafdf6f5cf1eb8e470abe056d5d161106e38062b", - "sha256:76ee27c6e9c7f16f47db7a94157112a2f3a00e958bc626e2f4ee8bec5c328fbe", - "sha256:77b63866ca88d804225eaa4af3e664c5faf3568cea95360d21f4725ab6e07146", - "sha256:79ec52ec461e99e13791ec6508c722742ad745571f234ea6255bed38c6480f11", - "sha256:7b93a4d08587e2b7e7882de461e82b6ed76d9026ce91ca7915e740ecc7855f60", - "sha256:7da7087d756b19037bc2c06edc6c170eeef3c3bafcb8f532ff17d64dc427adfd", - "sha256:7f3bf998340c6d4b0c9a2f02d6a400e51f123b59565d74dc60d252ce888c260b", - "sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c", - "sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a", - "sha256:873e0d5b4fb9b89ef7c2d2a963ea7d02879d9da0da8d9d4933dee8ee86a8b460", - "sha256:88942d3a3dff3afc8288c21e565e476fc278902ae4d6d134f1eeda118cc830b1", - "sha256:8bfeaf8735be79f225f3fefab7f941c712aaca36f1128c9d7e2352ee1aa87bdf", - "sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf", - "sha256:915c3d10f81bec3a74fbd4faebe8391013ba61e5a1a8d48c4455b923bdda7858", - "sha256:93e8740d7503eb008aa2df04d3b9735f845d43ae845e6dcd2be0b55a2da43cd2", - "sha256:941103c9be18ac8daf7b7adca8228f8ed6bb7a1849020f643b3a14d15b1924d9", - "sha256:97aeba56665b4c3235a0e52b2c2f5ae9cd071b8a8310ad27bddb3f7fb30e9aa2", - "sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3", - "sha256:a3a52f6156e73e7ccb0f8cced536adccb7042be67cb45f9562e12b319c119da6", - "sha256:a668ce24de96165bb239160b3d854943128f4334822900534f2fe947930e5770", - "sha256:a75dafbf87d6276ddc5b2bf6fae5254e3d0876b626eb24969a574fff9149ee5d", - "sha256:aabf5777b5c8ca26f7824cb4a120a740c9588ed58df9b2d196ce92fba42ff8dc", - "sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23", - "sha256:b2379fa7ed44ddecb5bfe4e48577d752db9fc10be00a6b7446e9663ba143de26", - "sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa", - "sha256:b5819cd790dbf0c5eb9f82c73c16b39a65dd6dd4d1439dcdea7816ec9adddab8", - "sha256:b74557b16e390ec12dca509bce9264c3bbd128f8a2c376eaa68003d7f327276d", - "sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3", - "sha256:b93590ae81f7010dbe380cdeab6f515902ebcbefe0b9327cc4804d74e93ae69d", - "sha256:b96d5f26b05d03cc60f11a7761a5ded1741da411e7fe0909e27a5e6a0cb7b034", - "sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9", - "sha256:bfea2a5f0b4d8d43adf9d7b8bf019fb46fdd10a2e5cde477fbcb9d1fa08c68e1", - "sha256:c007fe8a43d43b3969e8469004e9845944f1a80e6acd47c150856bb87f230c56", - "sha256:c1df3d34aced70add6f867a8cf413e299177e0c22660cc767218373d0779487b", - "sha256:c23e27686783f60290e36827f9c626e63154b82b116d7fe9adba1fda36da706c", - "sha256:c8d8b4eb992936023be7dee581270af5c6e0697a8559895f527f5b7105ecd36a", - "sha256:c9e19dd6e28fdcaa5a1de679aec4141f691023916427ef9bae8584f9c2fb3b0e", - "sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9", - "sha256:d38548150c39b74aeeb0ce8ee1d8e82696f4a4e16ddc6de7b1d8823f7de4b9b5", - "sha256:d3a978c4f57a597908b7e697229d996d77a6d3c94901e9edee593adada95ce1a", - "sha256:d5160812ea7a8a2ffbe233d8da666880cad0cbaf5d4de74ae15c313213d62556", - "sha256:dc799088c08fa04e43144b164feb0c13f9a0bc40503f8df3e9fde58a3c0c101e", - "sha256:df3959765b553b9440adfd3c795617c352154e497a4eaf3752555cfb5da8fc49", - "sha256:dfa8a0c812ac681395907e71e1274819dec685fec28273a28905df579ef137e2", - "sha256:e25c479382d26a2a41b7ebea1043564a937db462816ea07afa8a44c0866d52f9", - "sha256:e4f4a984405e91527a0d62649ee21138f8e3d0ef103be488c1dc11a80d7f184b", - "sha256:e536c98a7626a98feb2d3eaf75944ef6f3dbee447e1f841eae16f2f0a72d8ddc", - "sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb", - "sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0", - "sha256:e7b576130c69225432866fe2f4a469a85a54ade141d96fd396dffcf607b558f8", - "sha256:e8465ab91a4bd96d36dde3263f06caa6a8a6019e4113f24dc753d79a8b3a3f82", - "sha256:e96cea19e34778f8d59fe40775a7a574d95816eb150850a85a7a4c8f4b94ac69", - "sha256:ece5c59f0ce7d001e017643d8d24da587ea1f74f6993467d85ae8a5ef9d4f42b", - "sha256:eceb81a8d74f9267ef4081e246ffd6d129da5d87e37a77c9bde550cb04870c1c", - "sha256:ed2e99c456e3fadd05c991f8f437ef902e00eedf34320ba2b0842bd1c3ca3a75", - "sha256:f0cd744688278965817fd0839c4a4116add48d23890d468bc436f78beb28abf5", - "sha256:f14f8f046c14563f8eb3f45f499cc658ab8d10072961e07225e507adb700e93f", - "sha256:f15489ba13d61f670dcc96772e733aad1a6f9c429cc27574c6cdaed82d0146ad", - "sha256:f31d95a179f8d64d90f6831d71fa93290893a33148d890ba15de25642c5d075b", - "sha256:f41a7489d32336dbf2199c8c0a215390a751c5b014c2c1c5366e817202e9cdf7", - "sha256:f41eb9797986d6ebac5e8edff36d5cef9de40def462311b3eb3eeded1431e425", - "sha256:f547144f2966e1e16ae626d8ce72b4cfa0caedc7fa28052001c94fb2fcaa1c52" - ], - "markers": "python_version >= '3.9'", - "version": "==2.41.5" - }, - "pygments": { - "hashes": [ - "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", - "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b" - ], - "markers": "python_version >= '3.8'", - "version": "==2.19.2" - }, - "pyjwt": { - "hashes": [ - "sha256:28ca37c070cad8ba8cd9790cd940535d40274d22f80ab87f3ac6a713e6e8454c", - "sha256:c74a7a2adf861c04d002db713dd85f84beb242228e671280bf709d765b03672b" - ], - "markers": "python_version >= '3.9'", - "version": "==2.12.1" - }, - "pyopenssl": { - "hashes": [ - "sha256:df94d28498848b98cc1c0ffb8ef1e71e40210d3b0a8064c9d29571ed2904bf81", - "sha256:f293934e52936f2e3413b89c6ce36df66a0b34ae1ea3a053b8c5020ff2f513fc" - ], - "markers": "python_version >= '3.8'", - "version": "==26.0.0" - }, - "pypi-attestations": { - "hashes": [ - "sha256:278a28d741b57d62973c00d453ec9b9bb30456464d69296c6780474cd0bf098e", - "sha256:2daf3ec46ff4c7123184ec892852b4d4599b78128f01f742a44406a73200c5df" + "sha256:8b7c2d3e86ae3f94fb27703d521dd0b9b6b378775991f504d7c3a6275aa0a6a6", + "sha256:b634a041aac33706d56a0d217e6587228c66427e20ec21a019bc4cdee48c040a" ], "index": "pypi", - "markers": "python_version >= '3.10'", - "version": "==0.0.29" - }, - "pyproject-api": { - "hashes": [ - "sha256:40c6f2d82eebdc4afee61c773ed208c04c19db4c4a60d97f8d7be3ebc0bbb330", - "sha256:8757c41a79c0f4ab71b99abed52b97ecf66bd20b04fa59da43b5840bac105a09" - ], - "markers": "python_version >= '3.10'", - "version": "==1.10.0" + "markers": "python_full_version >= '3.9.0'", + "version": "==3.3.6" }, "pyproject-hooks": { "hashes": [ @@ -748,104 +199,13 @@ "markers": "python_version >= '3.7'", "version": "==1.2.0" }, - "python-discovery": { - "hashes": [ - "sha256:1e108f1bbe2ed0ef089823d28805d5ad32be8e734b86a5f212bf89b71c266e4a", - "sha256:7d33e350704818b09e3da2bd419d37e21e7c30db6e0977bb438916e06b41b5b1" - ], - "markers": "python_version >= '3.8'", - "version": "==1.2.0" - }, - "readme-renderer": { - "hashes": [ - "sha256:2fbca89b81a08526aadf1357a8c2ae889ec05fb03f5da67f9769c9a592166151", - "sha256:8712034eabbfa6805cacf1402b4eeb2a73028f72d1166d6f5cb7f9c047c5d1e1" - ], - "markers": "python_version >= '3.9'", - "version": "==44.0" - }, - "requests": { - "hashes": [ - "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", - "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf" - ], - "markers": "python_version >= '3.9'", - "version": "==2.32.5" - }, - "requests-toolbelt": { - "hashes": [ - "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6", - "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.0.0" - }, - "rfc3161-client": { - "hashes": [ - "sha256:078e4bbf0770ddc472e2ca96cf1e23efd0c313e6682b4c2c9765e1fdf09f55a3", - "sha256:09c47582ecea2ca4a3debf8a1eda775cc3d5ae1379da40272cc065d32e639a7a", - "sha256:3106f3361a5a36789f43d2700e5678c847a9d3460a23f455f4c20cd39314c557", - "sha256:31b6ee79f15b93d90952efd0395bb3f5ebf07941469c5c6eb32f9b64312cda6e", - "sha256:61c04b4953453e5c26a1949c20adac415b65cd062dab0960574d6c36240222d2", - "sha256:8a54fdb2f9e64481272b89137a7b71403cf1d30f5505c2e0c15a47a1cc100264", - "sha256:8fb34470e867a29cc15dc4987ea14f19d3bd25c863e132b6f75dca583e2cc67e", - "sha256:9c53a6711bab0c3f77dc9cf1e2fd750da475ff7abbc40ffe0333d8c518a8a9c8", - "sha256:ae440461a310ae097417afe536d9d22fd71c95fbc9d21db3561b2707bed0aff0", - "sha256:d31d30e354d2349ae8483ce811ef61498a3780daf8622c0b79d8cd44d271b46b", - "sha256:d9ed8e597d0ee7387da1945e1583c4516b26f133770b3956e079606e2d90b69c", - "sha256:e904430e27e75a5a379fc4aac09bd60ba5f4b48054f0481b2fb417297e404047", - "sha256:f1a2e32e2a053455cee1ff9b325b88dbc7c66c8882dde60962add92f572df5c5" - ], - "markers": "python_version >= '3.9'", - "version": "==1.0.5" - }, - "rfc3986": { - "hashes": [ - "sha256:50b1502b60e289cb37883f3dfd34532b8873c7de9f49bb546641ce9cbd256ebd", - "sha256:97aacf9dbd4bfd829baad6e6309fa6573aaf1be3f6fa735c8ab05e46cecb261c" - ], - "markers": "python_version >= '3.7'", - "version": "==2.0.0" - }, - "rfc8785": { - "hashes": [ - "sha256:520d690b448ecf0703691c76e1a34a24ddcd4fc5bc41d589cb7c58ec651bcd48", - "sha256:e545841329fe0eee4f6a3b44e7034343100c12b4ec566dc06ca9735681deb4da" - ], - "markers": "python_version >= '3.8'", - "version": "==0.1.4" - }, - "rich": { - "hashes": [ - "sha256:793431c1f8619afa7d3b52b2cdec859562b950ea0d4b6b505397612db8d5362d", - "sha256:b8daa0b9e4eef54dd8cf7c86c03713f53241884e814f4e2f5fb342fe520f639b" - ], - "markers": "python_full_version >= '3.8.0'", - "version": "==14.3.3" - }, - "secretstorage": { - "hashes": [ - "sha256:0ce65888c0725fcb2c5bc0fdb8e5438eece02c523557ea40ce0703c266248137", - "sha256:f04b8e4689cbce351744d5537bf6b1329c6fc68f91fa666f60a380edddcd11be" - ], - "markers": "python_version >= '3.10'", - "version": "==3.5.0" - }, - "securesystemslib": { - "hashes": [ - "sha256:2e5414bbdde33155a91805b295cbedc4ae3f12b48dccc63e1089093537f43c81", - "sha256:ca915f4b88209bb5450ac05426b859d74b7cd1421cafcf73b8dd3418a0b17486" - ], - "markers": "python_version ~= '3.8'", - "version": "==1.3.1" - }, "setuptools": { "hashes": [ - "sha256:7d872682c5d01cfde07da7bccc7b65469d3dca203318515ada1de5eda35efbf9", - "sha256:a59e362652f08dcd477c78bb6e7bd9d80a7995bc73ce773050228a348ce2e5bb" + "sha256:a65cffc4fb86167e3020b3ef58e08226baad8b29a3b34ce2c9d07e901bac481d", + "sha256:ec8308eb180b2312062b1c5523204acf872cd8b0a9e6c2ae76431b22bc4065d7" ], "markers": "python_version >= '3.9'", - "version": "==82.0.1" + "version": "==80.3.0" }, "setuptools-scm": { "hashes": [ @@ -856,95 +216,29 @@ "markers": "python_version >= '3.8'", "version": "==8.2.0" }, - "sigstore": { + "tomlkit": { "hashes": [ - "sha256:bdbb49a42fd5f0ea6765919adb42ccee7254c482330764d0842eec4e11ad78d7", - "sha256:ed2e0f50aae85148a8aa4fc0f57c298927fce430ad1f988f38611ce90c85829f" - ], - "markers": "python_version >= '3.10'", - "version": "==4.2.0" - }, - "sigstore-models": { - "hashes": [ - "sha256:5201a68f4d7d0f8bec1e2f4378eb646b084c52609a4e31db8c385095fff68b2e", - "sha256:c766c09470c2a7e8a4a333c893f07e2001c56a3ff1757b1a246119f53169a849" - ], - "markers": "python_version >= '3.10'", - "version": "==0.0.6" - }, - "sigstore-rekor-types": { - "hashes": [ - "sha256:19aef25433218ebf9975a1e8b523cc84aaf3cd395ad39a30523b083ea7917ec5", - "sha256:b62bf38c5b1a62bc0d7fe0ee51a0709e49311d137c7880c329882a8f4b2d1d78" + "sha256:7a974427f6e119197f670fbbbeae7bef749a6c14e793db934baefc1b5f03efde", + "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79" ], "markers": "python_version >= '3.8'", - "version": "==0.0.18" - }, - "tomli-w": { - "hashes": [ - "sha256:188306098d013b691fcadc011abd66727d3c414c571bb01b1a174ba8c983cf90", - "sha256:2dd14fac5a47c27be9cd4c976af5a12d87fb1f0b4512f81d69cce3b35ae25021" - ], - "markers": "python_version >= '3.9'", - "version": "==1.2.0" - }, - "tox": { - "hashes": [ - "sha256:5e788a512bfe6f7447e0c8d7c1b666eb2e56e5e676c65717490423bec37d1a07", - "sha256:c745641de6cc4f19d066bd9f98c1c25f7affb005b381b7f3694a1f142ea0946b" - ], - "index": "pypi", - "markers": "python_version >= '3.10'", - "version": "==4.50.3" - }, - "tuf": { - "hashes": [ - "sha256:458f663a233d95cc76dde0e1a3d01796516a05ce2781fefafebe037f7729601a", - "sha256:9eed0f7888c5fff45dc62164ff243a05d47fb8a3208035eb268974287e0aee8d" - ], - "markers": "python_version >= '3.8'", - "version": "==6.0.0" - }, - "twine": { - "hashes": [ - "sha256:418ebf08ccda9a8caaebe414433b0ba5e25eb5e4a927667122fbe8f829f985d8", - "sha256:e5ed0d2fd70c9959770dce51c8f39c8945c574e18173a7b81802dab51b4b75cf" - ], - "index": "pypi", - "markers": "python_version >= '3.9'", - "version": "==6.2.0" + "version": "==0.13.2" }, "typing-extensions": { "hashes": [ - "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", - "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548" + "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c", + "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef" ], - "markers": "python_version >= '3.9'", - "version": "==4.15.0" - }, - "typing-inspection": { - "hashes": [ - "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", - "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464" - ], - "markers": "python_version >= '3.9'", - "version": "==0.4.2" - }, - "urllib3": { - "hashes": [ - "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed", - "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4" - ], - "markers": "python_version >= '3.9'", - "version": "==2.6.3" + "markers": "python_version >= '3.8'", + "version": "==4.13.2" }, "virtualenv": { "hashes": [ - "sha256:1720dc3a62ef5b443092e3f499228599045d7fea4c79199770499df8becf9098", - "sha256:1bd755b504931164a5a496d217c014d098426cddc79363ad66ac78125f9d908f" + "sha256:800863162bcaa5450a6e4d721049730e7f2dae07720e0902b0e4040bd6f9ada8", + "sha256:e34302959180fca3af42d1800df014b35019490b119eba981af27f2fa486e5d6" ], "markers": "python_version >= '3.8'", - "version": "==21.2.0" + "version": "==20.30.0" } } } diff --git a/TODO b/TODO index e747197..dd4cd66 100644 --- a/TODO +++ b/TODO @@ -30,7 +30,7 @@ preserve Git diffing. ID: [ISSUE-NUMBER] Type: [feature/bugfix/hotfix] Title: [Short title] -Status: [open/in-progress/done/hold/cancelled] +Status: [open/in-progress/done] Priority: [low/medium/high] Created: [YYYY-MM-DD] Description: [Detailed explanation] @@ -50,7 +50,7 @@ Description: [Detailed explanation] ID: 1 Type: feature Title: implement KMP algorithm for string searching -Status: hold +Status: in-progress Priority: high Created: 2025-05-03 Description: Implement the Knuth-Morris-Pratt algorithm for string searching. @@ -79,165 +79,3 @@ Description: move the unit test suites to a unit/ subdirectory so that integration tests and benchmarks can be cleanly separated --- - -ID: 4 -Type: feature -Title: implement Rabin-Karp rolling hash algorithm -Status: done -Priority: high -Created: 2025-05-05 -Description: After testing a couple of string search algorithms, I've ditched - the idea of using KMP as my use-case gives no advantage compared to - naive searching. In addition I've came upon the challenge that many - string search algorithms are optimized for search on a linear - buffer, which in my case is not applicable as the implementation - the search algorithm is for uses a circular buffer. Rabin-Karp - seemed promising. I've come up with a different approach though, - which is still based on rolling hashes, therefore, as a base, I - need an implementation of the original Rabin-Karp rolling hash - algorithm - ---- - -ID: 5 -Type: feature -Title: implement chunked rolling hash algorithm -Status: in-progress -Priority: high -Created: 2025-05-05 -Description: Implement my custom algorithm for doing rolling hash string search - against a fixed length ring buffer - ---- - -ID: 6 -Type: feature -Title: implement importlib.resources handler for urllib -Status: done -Priority: high -Created: 2025-06-20 -Description: A handler that can be registered with an urllib.request - OpenerDirector to open importlib.resources package files. - ---- - -ID: 7 -Type: feature -Title: setup advanced testing environment -Status: done -Priority: high -Created: 2025-06-20 -Description: copy the testing environment setup from - byteb4rb1e.sphinxcontrib.ext - ---- - -ID: 8 -Type: bugfix -Title: rename package -Status: done -Priority: high -Created: 2025-06-20 -Description: use dot namespaces to make the package a little more elegant - ---- - -ID: 9 -Type: bugfix -Title: fix LICENSE reference -Status: done -Priority: high -Created: 2025-06-20 -Description: license specification is no longer a trove classifier in - pyproject.toml, hence the reference to LICENSE must be changed - ---- - -ID: 10 -Type: feature -Title: pytest current test context fixtures -Status: done -Priority: high -Created: 2025-06-20 -Description: add fixtures for doing things in relation to the active testing - context - ---- - -ID: 11 -Type: bugfix -Title: move testing utils out of utils -Status: done -Priority: high -Created: 2025-06-20 -Description: to shorten the namespace and also indicate that testing utilities - are different from regular utilities - ---- - -ID: 12 -Type: feature -Title: simplify testing.fixtures.mock_pkg -Status: done -Priority: high -Created: 2025-06-21 -Description: Only bootstrap a package mock with the minimum requirements for a - Python module and let the consumer handle the directory layout. - ---- - -ID: 13 -Type: bugfix -Title: fix unit tests for urllib PkgHandler -Status: done -Priority: high -Created: 2025-06-21 -Description: change of issue 12 wasn't properly reflected in urllib PkgHandler - unit tests - ---- - -ID: 14 -Type: feature -Title: add compression support for urllib PkgHandler -Status: done -Priority: high -Created: 2025-06-21 -Description: with a proper content-type of the PkgHandler addinfourl object, a - consumer can determine whether the file is compressed or not. - ---- - -ID: 15 -Type: bugfix -Title: modularize module containers -Status: open -Priority: high -Created: 2025-06-28 -Description: Even though importlib can find submodules through traversing paths - instead of relying on __init__.py for every ancestor module, this - is not supported by some modules like sphinx.ext.autosummary - ---- - -ID: 16 -Type: feature -Title: SQL-aware dataclass -Status: in-progress -Priority: low -Created: 2025-12-31 -Description: A dataclass that transparently maps onto an SQL datastore, with - command generation for syncing data between data class and store - ---- - -ID: 17 -Type: feature -Title: recursive-descent HTML (DOM) parser -Status: in-progress -Priority: high -Created: 2025-12-31 -Description: Extend the built-in event-driven parser to be modeled after DOM - recursive-descent HTML parser - ---- diff --git a/configure b/configure new file mode 100644 index 0000000..ade147c --- /dev/null +++ b/configure @@ -0,0 +1,2663 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.72. +# +# +# Copyright (C) 1992-1996, 1998-2017, 2020-2023 Free Software Foundation, +# Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 +then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else case e in #( + e) case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac ;; +esac +fi + + + +# Reset variables that may have inherited troublesome values from +# the environment. + +# IFS needs to be set, to space, tab, and newline, in precisely that order. +# (If _AS_PATH_WALK were called with IFS unset, it would have the +# side effect of setting IFS to empty, thus disabling word splitting.) +# Quoting is to prevent editors from complaining about space-tab. +as_nl=' +' +export as_nl +IFS=" "" $as_nl" + +PS1='$ ' +PS2='> ' +PS4='+ ' + +# Ensure predictable behavior from utilities with locale-dependent output. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# We cannot yet rely on "unset" to work, but we need these variables +# to be unset--not just set to an empty or harmless value--now, to +# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct +# also avoids known problems related to "unset" and subshell syntax +# in other old shells (e.g. bash 2.01 and pdksh 5.2.14). +for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH +do eval test \${$as_var+y} \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done + +# Ensure that fds 0, 1, and 2 are open. +if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi +if (exec 3>&2) ; then :; else exec 2>/dev/null; fi + +# The user is always right. +if ${PATH_SEPARATOR+false} :; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + test -r "$as_dir$0" && as_myself=$as_dir$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as 'sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed 'exec'. +printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 +then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else case e in #( + e) case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ) +then : + +else case e in #( + e) exitcode=1; echo positional parameters were not saved. ;; +esac +fi +test x\$exitcode = x0 || exit 1 +blah=\$(echo \$(echo blah)) +test x\"\$blah\" = xblah || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1" + if (eval "$as_required") 2>/dev/null +then : + as_have_required=yes +else case e in #( + e) as_have_required=no ;; +esac +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null +then : + +else case e in #( + e) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + as_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 2>/dev/null +then : + CONFIG_SHELL=$as_shell as_have_required=yes + if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null +then : + break 2 +fi +fi + done;; + esac + as_found=false +done +IFS=$as_save_IFS +if $as_found +then : + +else case e in #( + e) if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null +then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi ;; +esac +fi + + + if test "x$CONFIG_SHELL" != x +then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed 'exec'. +printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno +then : + printf "%s\n" "$0: This script requires a shell more modern than all" + printf "%s\n" "$0: the shells that I found on your system." + if test ${ZSH_VERSION+y} ; then + printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should" + printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later." + else + printf "%s\n" "$0: Please tell bug-autoconf@gnu.org about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi ;; +esac +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null +then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else case e in #( + e) as_fn_append () + { + eval $1=\$$1\$2 + } ;; +esac +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null +then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else case e in #( + e) as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } ;; +esac +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + printf "%s\n" "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + t clear + :clear + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { printf "%s\n" "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +# Determine whether it's possible to make 'echo' print without a newline. +# These variables are no longer used directly by Autoconf, but are AC_SUBSTed +# for compatibility with existing Makefiles. +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +# For backward compatibility with old third-party macros, we provide +# the shell variables $as_echo and $as_echo_n. New code should use +# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. +as_echo='printf %s\n' +as_echo_n='printf %s' + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both 'ln -s file dir' and 'ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; 'ln -s' creates a wrapper executable. + # In both cases, we have to default to 'cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_sed_cpp="y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" +as_tr_cpp="eval sed '$as_sed_cpp'" # deprecated + +# Sed expression to map a string onto a valid variable name. +as_sed_sh="y%*+%pp%;s%[^_$as_cr_alnum]%_%g" +as_tr_sh="eval sed '$as_sed_sh'" # deprecated + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='' +PACKAGE_TARNAME='' +PACKAGE_VERSION='' +PACKAGE_STRING='' +PACKAGE_BUGREPORT='' +PACKAGE_URL='' + +ac_subst_vars='LTLIBOBJS +LIBOBJS +REALPATH +PYTHON3 +GIT +MAKE +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +runstatedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +' + ac_precious_vars='build_alias +host_alias +target_alias' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: '$ac_useropt'" + ac_useropt_orig=$ac_useropt + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: '$ac_useropt'" + ac_useropt_orig=$ac_useropt + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: '$ac_useropt'" + ac_useropt_orig=$ac_useropt + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: '$ac_useropt'" + ac_useropt_orig=$ac_useropt + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: '$ac_option' +Try '$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: '$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + printf "%s\n" "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + printf "%s\n" "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir runstatedir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: '$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but 'cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +'configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print 'checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for '--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or '..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, 'make install' will install all the files in +'$ac_default_prefix/bin', '$ac_default_prefix/lib' etc. You can specify +an installation prefix other than '$ac_default_prefix' using '--prefix', +for instance '--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Report bugs to the package provider. +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for configure.gnu first; this name is used for a wrapper for + # Metaconfig's "Configure" on case-insensitive file systems. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + printf "%s\n" "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +configure +generated by GNU Autoconf 2.72 + +Copyright (C) 2023 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## +ac_configure_args_raw= +for ac_arg +do + case $ac_arg in + *\'*) + ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append ac_configure_args_raw " '$ac_arg'" +done + +case $ac_configure_args_raw in + *$as_nl*) + ac_safe_unquote= ;; + *) + ac_unsafe_z='|&;<>()$`\\"*?[ '' ' # This string ends in space, tab. + ac_unsafe_a="$ac_unsafe_z#~" + ac_safe_unquote="s/ '\\([^$ac_unsafe_a][^$ac_unsafe_z]*\\)'/ \\1/g" + ac_configure_args_raw=` printf "%s\n" "$ac_configure_args_raw" | sed "$ac_safe_unquote"`;; +esac + +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.72. Invocation command line was + + $ $0$ac_configure_args_raw + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + printf "%s\n" "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Sanitize IFS. + IFS=" "" $as_nl" + # Save into config.log some information that might help in debugging. + { + echo + + printf "%s\n" "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + printf "%s\n" "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + printf "%s\n" "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + printf "%s\n" "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + printf "%s\n" "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + printf "%s\n" "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + printf "%s\n" "$as_me: caught signal $ac_signal" + printf "%s\n" "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +printf "%s\n" "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h + +printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h + +printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h + +printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h + +printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h + +printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +if test -n "$CONFIG_SITE"; then + ac_site_files="$CONFIG_SITE" +elif test "x$prefix" != xNONE; then + ac_site_files="$prefix/share/config.site $prefix/etc/config.site" +else + ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" +fi + +for ac_site_file in $ac_site_files +do + case $ac_site_file in #( + */*) : + ;; #( + *) : + ac_site_file=./$ac_site_file ;; +esac + if test -f "$ac_site_file" && test -r "$ac_site_file"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See 'config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +printf "%s\n" "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +printf "%s\n" "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: '$ac_var' was set to '$ac_old_val' in the previous run" >&5 +printf "%s\n" "$as_me: error: '$ac_var' was set to '$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: '$ac_var' was not set in the previous run" >&5 +printf "%s\n" "$as_me: error: '$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: '$ac_var' has changed since the previous run:" >&5 +printf "%s\n" "$as_me: error: '$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in '$ac_var' since the previous run:" >&5 +printf "%s\n" "$as_me: warning: ignoring whitespace changes in '$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: former value: '$ac_old_val'" >&5 +printf "%s\n" "$as_me: former value: '$ac_old_val'" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: current value: '$ac_new_val'" >&5 +printf "%s\n" "$as_me: current value: '$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`printf "%s\n" "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run '${MAKE-make} distclean' and/or 'rm $cache_file' + and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +for ac_prog in make +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_MAKE+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test -n "$MAKE"; then + ac_cv_prog_MAKE="$MAKE" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_MAKE="$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi ;; +esac +fi +MAKE=$ac_cv_prog_MAKE +if test -n "$MAKE"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MAKE" >&5 +printf "%s\n" "$MAKE" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$MAKE" && break +done +test -n "$MAKE" || MAKE="no" + +if test "$MAKE" == "no" +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: without GNU Make, you have to inspect 'Makefile' and deduce build targets yourself." >&5 +printf "%s\n" "$as_me: without GNU Make, you have to inspect 'Makefile' and deduce build targets yourself." >&6;} +fi + +for ac_prog in git +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_GIT+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test -n "$GIT"; then + ac_cv_prog_GIT="$GIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_GIT="$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi ;; +esac +fi +GIT=$ac_cv_prog_GIT +if test -n "$GIT"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $GIT" >&5 +printf "%s\n" "$GIT" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$GIT" && break +done +test -n "$GIT" || GIT="no" + +if test "$GIT" == "no" +then : + as_fn_error $? "install Git, before continuing." "$LINENO" 5 +fi + +for ac_prog in python3 +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_PYTHON3+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test -n "$PYTHON3"; then + ac_cv_prog_PYTHON3="$PYTHON3" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_PYTHON3="$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi ;; +esac +fi +PYTHON3=$ac_cv_prog_PYTHON3 +if test -n "$PYTHON3"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYTHON3" >&5 +printf "%s\n" "$PYTHON3" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$PYTHON3" && break +done +test -n "$PYTHON3" || PYTHON3="no" + +if test "$PYTHON3" == "no" +then : + as_fn_error $? "install Python 3, before continuing." "$LINENO" 5 +fi + +# required in Makefile to ensure proper path resolution during preprocessing +# realpath is not available on macOS +for ac_prog in realpath +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_REALPATH+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test -n "$REALPATH"; then + ac_cv_prog_REALPATH="$REALPATH" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_REALPATH="$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi ;; +esac +fi +REALPATH=$ac_cv_prog_REALPATH +if test -n "$REALPATH"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $REALPATH" >&5 +printf "%s\n" "$REALPATH" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$REALPATH" && break +done +test -n "$REALPATH" || REALPATH="no" + +if test "$REALPATH" == "no" +then : + as_fn_error $? "set a persistent alias for 'realpath', before continuing, e.g. + +alias='python3 -c \"import pathlib,sys;print(pathlib.Path(sys.argv[1]).resolve())\"'\" +" "$LINENO" 5 +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: initializing python3 venv..." >&5 +printf "%s\n" "$as_me: initializing python3 venv..." >&6;} +make .venv + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# 'ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* 'ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # 'set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # 'set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+y} || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +printf "%s\n" "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +printf "%s\n" "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +# +# If the first sed substitution is executed (which looks for macros that +# take arguments), then branch to the quote section. Otherwise, +# look for a macro that doesn't take arguments. +ac_script=' +:mline +/\\$/{ + N + s,\\\n,, + b mline +} +t clear +:clear +s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g +t quote +s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g +t quote +b any +:quote +s/[][ `~#$^&*(){}\\|;'\''"<>?]/\\&/g +s/\$/$$/g +H +:any +${ + g + s/^\n// + s/\n/ /g + p +} +' +DEFS=`sed -n "$ac_script" confdefs.h` + + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`printf "%s\n" "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +printf "%s\n" "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 +then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else case e in #( + e) case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac ;; +esac +fi + + + +# Reset variables that may have inherited troublesome values from +# the environment. + +# IFS needs to be set, to space, tab, and newline, in precisely that order. +# (If _AS_PATH_WALK were called with IFS unset, it would have the +# side effect of setting IFS to empty, thus disabling word splitting.) +# Quoting is to prevent editors from complaining about space-tab. +as_nl=' +' +export as_nl +IFS=" "" $as_nl" + +PS1='$ ' +PS2='> ' +PS4='+ ' + +# Ensure predictable behavior from utilities with locale-dependent output. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# We cannot yet rely on "unset" to work, but we need these variables +# to be unset--not just set to an empty or harmless value--now, to +# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct +# also avoids known problems related to "unset" and subshell syntax +# in other old shells (e.g. bash 2.01 and pdksh 5.2.14). +for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH +do eval test \${$as_var+y} \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done + +# Ensure that fds 0, 1, and 2 are open. +if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi +if (exec 3>&2) ; then :; else exec 2>/dev/null; fi + +# The user is always right. +if ${PATH_SEPARATOR+false} :; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + test -r "$as_dir$0" && as_myself=$as_dir$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as 'sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + printf "%s\n" "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null +then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else case e in #( + e) as_fn_append () + { + eval $1=\$$1\$2 + } ;; +esac +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null +then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else case e in #( + e) as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } ;; +esac +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + +# Determine whether it's possible to make 'echo' print without a newline. +# These variables are no longer used directly by Autoconf, but are AC_SUBSTed +# for compatibility with existing Makefiles. +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +# For backward compatibility with old third-party macros, we provide +# the shell variables $as_echo and $as_echo_n. New code should use +# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. +as_echo='printf %s\n' +as_echo_n='printf %s' + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both 'ln -s file dir' and 'ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; 'ln -s' creates a wrapper executable. + # In both cases, we have to default to 'cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_sed_cpp="y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" +as_tr_cpp="eval sed '$as_sed_cpp'" # deprecated + +# Sed expression to map a string onto a valid variable name. +as_sed_sh="y%*+%pp%;s%[^_$as_cr_alnum]%_%g" +as_tr_sh="eval sed '$as_sed_sh'" # deprecated + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by $as_me, which was +generated by GNU Autoconf 2.72. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + + + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +'$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + +Report bugs to the package provider." + +_ACEOF +ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"` +ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"` +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config='$ac_cs_config_escaped' +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.72, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2023 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + printf "%s\n" "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + printf "%s\n" "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --he | --h | --help | --hel | -h ) + printf "%s\n" "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: '$1' +Try '$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \printf "%s\n" "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + printf "%s\n" "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + + *) as_fn_error $? "invalid argument: '$ac_config_target'" "$LINENO" 5;; + esac +done + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + + diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..e8c53d1 --- /dev/null +++ b/configure.ac @@ -0,0 +1,27 @@ +AC_INIT + +AC_CHECK_PROGS([MAKE], [make], [no]) +AS_IF([test "$MAKE" == "no"], + [AC_MSG_NOTICE([without GNU Make, you have to inspect 'Makefile' and deduce build targets yourself.])]) + +AC_CHECK_PROGS([GIT], [git], [no]) +AS_IF([test "$GIT" == "no"], + [AC_MSG_ERROR([install Git, before continuing.])]) + +AC_CHECK_PROGS([PYTHON3], [python3], [no]) +AS_IF([test "$PYTHON3" == "no"], + [AC_MSG_ERROR([install Python 3, before continuing.])]) + +# required in Makefile to ensure proper path resolution during preprocessing +# realpath is not available on macOS +AC_CHECK_PROGS([REALPATH], [realpath], [no]) +AS_IF([test "$REALPATH" == "no"], + [AC_MSG_ERROR([set a persistent alias for 'realpath', before continuing, e.g. + +alias='python3 -c "import pathlib,sys;print(pathlib.Path(sys.argv[[1]]).resolve())"'" +])]) + +AC_MSG_NOTICE([initializing python3 venv...]) +make .venv + +AC_OUTPUT diff --git a/pyproject.toml b/pyproject.toml index b3c3d30..b5fcdb7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,12 +7,12 @@ requires = [ build-backend = "setuptools.build_meta" [project] -name = "byteb4rb1e.utils" +name = "byteb4rb1e-utils" description = "personal utilities and helpers" authors = [ - { name = "Tiara Rodney", email = "tiara.rodney@byteb4rb1e.me" } + { name = "Tiara Rodney", email = "tiara.rodney@administratrix.de" } ] -license-files = ["LICENSE"] +license = { file = "LICENSE" } readme = "README.md" classifiers = [ "Development Status :: 1 - Planning", @@ -48,6 +48,7 @@ strict = true max_line_length = 80 aggressive = 3 recursive = true +in-place = true [tool.setuptools_scm] diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 0000000..15e7cea --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1,25 @@ +-i https://pypi.org/simple +astroid==3.3.9; python_full_version >= '3.9.0' +autopep8==2.3.2; python_version >= '3.9' +build==1.2.2.post1; python_version >= '3.8' +-e . +certifi==2025.4.26; python_version >= '3.6' +colorama==0.4.6; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6' +dill==0.4.0; python_version >= '3.8' +distlib==0.3.9 +filelock==3.18.0; python_version >= '3.9' +isort==6.0.1; python_full_version >= '3.9.0' +mccabe==0.7.0; python_version >= '3.6' +mypy==1.15.0; python_version >= '3.9' +mypy-extensions==1.1.0; python_version >= '3.8' +packaging==25.0; python_version >= '3.8' +pipenv==2025.0.2; python_version >= '3.9' +platformdirs==4.3.7; python_version >= '3.9' +pycodestyle==2.13.0; python_version >= '3.9' +pylint==3.3.6; python_full_version >= '3.9.0' +pyproject-hooks==1.2.0; python_version >= '3.7' +setuptools==80.3.0; python_version >= '3.9' +setuptools-scm==8.2.0; python_version >= '3.8' +tomlkit==0.13.2; python_version >= '3.8' +typing-extensions==4.13.2; python_version >= '3.8' +virtualenv==20.30.0; python_version >= '3.8' diff --git a/src/byteb4rb1e/testing/pytest/__init__.py b/src/byteb4rb1e/testing/pytest/__init__.py deleted file mode 100644 index 87e7c10..0000000 --- a/src/byteb4rb1e/testing/pytest/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -import os -from pathlib import Path -from typing import Tuple - - -def get_current_test() -> Tuple[Path, str]: - current_test_env = os.getenv("PYTEST_CURRENT_TEST") - if current_test_env is None: - raise RuntimeError("PYTEST_CURRENT_TEST not set. Must be run under pytest.") - - suite_path, case_name = current_test_env.split('::', 1) - case_name = case_name.split(' ', 1)[0] - return Path(suite_path).resolve(), case_name - diff --git a/src/byteb4rb1e/testing/pytest/decorators.py b/src/byteb4rb1e/testing/pytest/decorators.py deleted file mode 100644 index a7d8161..0000000 --- a/src/byteb4rb1e/testing/pytest/decorators.py +++ /dev/null @@ -1,47 +0,0 @@ -from functools import wraps -from pathlib import Path -import os -import subprocess -import sys - -from byteb4rb1e.testing.pytest import get_current_test - - -def run_in_subprocess_once(): - """ - A decorator that reruns th test in a subprocess if not already inside one. - Requires pytest to be installed and test to be run by pytest. - - For what? Anything that can't be done in a thread-safe manner, e.g. modifying PYTHON_PATH - """ - def decorator(test_func): - @wraps(test_func) - def wrapper(*args, **kwargs): - if os.environ.get("XPYTEST_INSIDE_SUBPROCESS") == "1": - return test_func(*args, **kwargs) - - suite_path, case_name = get_current_test() - - cmd = [ - sys.executable, - "-m", "pytest", - f"{suite_path}::{case_name}", - ] - - result = subprocess.run( - cmd, - env={**os.environ, "XPYTEST_INSIDE_SUBPROCESS": "1"}, - capture_output=True, - text=True, - ) - - if result.returncode != 0: - print(' '.join(cmd)) - print("==== Subprocess stdout ====") - print(result.stdout) - print("==== Subprocess stderr ====") - print(result.stderr) - raise AssertionError(f"Subprocess test failed with exit code {result.returncode}") - return wrapper - return decorator - diff --git a/src/byteb4rb1e/testing/pytest/fixtures.py b/src/byteb4rb1e/testing/pytest/fixtures.py deleted file mode 100644 index 7c93041..0000000 --- a/src/byteb4rb1e/testing/pytest/fixtures.py +++ /dev/null @@ -1,44 +0,0 @@ -import os -from pathlib import Path -import sys -from typing import Dict, Tuple, Union - -import pytest - -from byteb4rb1e.testing.pytest import get_current_test - -_SITE_PACKAGE_COUNTER: Dict[str, int] = {} - - -@pytest.fixture -def current_test() -> Tuple[Path, str]: - """ - """ - return get_current_test() - - -@pytest.fixture -def mock_system_site_package_dir(tmp_path): - global _SITE_PACKAGE_COUNTER - - package_id = _SITE_PACKAGE_COUNTER.setdefault(tmp_path, 0) - _SITE_PACKAGE_COUNTER[tmp_path] += 1 - - sys_path = tmp_path / str(package_id) - - def _create(name: str) -> Path: - pkg_path = sys_path / name.replace('.', os.path.sep) - - pkg_path.mkdir(parents=True) - - (pkg_path / "__init__.py").touch() - - sys.path.insert(0, str(sys_path)) - - return pkg_path - - yield _create - - # cleanup sys.path after test - if str(sys_path) in sys.path: - sys.path.remove(str(sys_path)) diff --git a/src/byteb4rb1e/utils/argparse/__init__.py b/src/byteb4rb1e/utils/argparse/__init__.py deleted file mode 100644 index 84ae3ed..0000000 --- a/src/byteb4rb1e/utils/argparse/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -"""Utilities for building composable CLIs from command dataclasses.""" - -from byteb4rb1e.utils.argparse.command import CLICommand -from byteb4rb1e.utils.argparse.dispatcher import CLI - -__all__ = ["CLI", "CLICommand"] diff --git a/src/byteb4rb1e/utils/argparse/command.py b/src/byteb4rb1e/utils/argparse/command.py deleted file mode 100644 index 199e4f1..0000000 --- a/src/byteb4rb1e/utils/argparse/command.py +++ /dev/null @@ -1,54 +0,0 @@ -"""Base command dataclass for composable CLI trees.""" - -from __future__ import annotations - -from argparse import ArgumentParser -from dataclasses import dataclass, fields -from typing import Any, ClassVar, Dict, List, Optional, Type - - -@dataclass -class CLICommand: - """Base class for CLI commands. - - Subclasses define their identity (name, help, description) as - dataclass fields. These are passed as kwargs to - ``subparsers.add_parser()``. - - Override ``add_arguments`` to register flags and positionals. - Override ``execute`` to implement the command's logic. - - Nest subcommands by setting ``_subcommands`` as a class variable. - """ - - name: str = "" - help: str = "" - description: str = "" - - _subcommands: ClassVar[List[Type[Command]]] = [] - - def add_arguments(self, parser: ArgumentParser) -> None: - """Add arguments to the parser. Override in subclasses.""" - - def execute(self, args: Any) -> int: - """Run the command. Override in subclasses. - - Returns an exit code (0 = success). - """ - return 0 - - def parser_kwargs(self) -> Dict[str, Any]: - """Return the dataclass fields as kwargs for add_parser. - - Excludes ``name`` (used as the positional parser name) and - any empty-string fields so argparse defaults apply. - """ - skip = {"name"} - kwargs = {} - for f in fields(self): - if f.name in skip or f.name.startswith("_"): - continue - val = getattr(self, f.name) - if val != "": - kwargs[f.name] = val - return kwargs diff --git a/src/byteb4rb1e/utils/argparse/dispatcher.py b/src/byteb4rb1e/utils/argparse/dispatcher.py deleted file mode 100644 index b579351..0000000 --- a/src/byteb4rb1e/utils/argparse/dispatcher.py +++ /dev/null @@ -1,122 +0,0 @@ -"""CLI dispatcher — builds parser trees from command dataclasses.""" - -from __future__ import annotations - -import logging -from argparse import ArgumentDefaultsHelpFormatter, ArgumentParser -from typing import Any, Dict, List, Optional, Type - -from byteb4rb1e.utils.argparse.command import CLICommand - - -class CLI: - """Composable CLI built from a tree of Command dataclasses. - - Recursively bootstraps an argparse parser hierarchy and tracks - dest names so ``run()`` can dispatch to the correct leaf command - without dest chaining in the caller. - - Usage:: - - cli = CLI(prog="repository", description="...") - cli.bootstrap([MirrorCommand, IndexCommand]) - cli.run() - """ - - def __init__( - self, - prog: Optional[str] = None, - description: str = "", - ) -> None: - kwargs = {} # type: Dict[str, Any] - if prog: - kwargs["prog"] = prog - if description: - kwargs["description"] = description - kwargs.setdefault( - "formatter_class", ArgumentDefaultsHelpFormatter, - ) - self.parser = ArgumentParser(**kwargs) - self._dests = [] # type: List[str] - self._commands = {} # type: Dict[str, Command] - - def add_arguments(self, parser: ArgumentParser) -> None: - """Add global arguments to the root parser.""" - parser.add_argument( - "-v", "--verbose", action="count", default=0, - help="Increase verbosity (-v for INFO, -vv for DEBUG)", - ) - - def bootstrap( - self, - commands: List[Type[Command]], - ) -> None: - """Build the parser tree from a list of top-level commands.""" - self.add_arguments(self.parser) - dest = "command" - self._dests.append(dest) - sub = self.parser.add_subparsers(dest=dest) - for cmd_cls in commands: - self._add(sub, cmd_cls, prefix="") - - def _add( - self, - subparsers: Any, - cmd_cls: Type[Command], - prefix: str, - ) -> None: - """Recursively add a command and its subcommands.""" - cmd = cmd_cls() - parser = subparsers.add_parser( - cmd.name, - formatter_class=ArgumentDefaultsHelpFormatter, - **cmd.parser_kwargs(), - ) - cmd.add_arguments(parser) - - key = "%s.%s" % (prefix, cmd.name) if prefix else cmd.name - self._commands[key] = cmd - - if cmd._subcommands: - dest = "%s_command" % cmd.name - self._dests.append(dest) - child_sub = parser.add_subparsers(dest=dest) - for sc_cls in cmd._subcommands: - self._add(child_sub, sc_cls, prefix=key) - - def _resolve(self, args: Any) -> Optional[Command]: - """Walk dest chain to find the leaf command.""" - parts = [] # type: List[str] - for dest in self._dests: - val = getattr(args, dest, None) - if val is None: - continue - parts.append(val) - if not parts: - return None - key = ".".join(parts) - return self._commands.get(key) - - @staticmethod - def _setup_logging(verbosity: int) -> None: - if verbosity >= 2: - level = logging.DEBUG - elif verbosity >= 1: - level = logging.INFO - else: - level = logging.WARNING - logging.basicConfig( - level=level, - format="%(asctime)s [%(levelname)s] %(message)s", - handlers=[logging.StreamHandler()], - ) - - def run(self) -> None: - """Parse args and dispatch to the leaf command.""" - args = self.parser.parse_args() - self._setup_logging(getattr(args, "verbose", 0)) - cmd = self._resolve(args) - if cmd is None: - self.parser.print_help() - raise SystemExit(1) - raise SystemExit(cmd.execute(args)) diff --git a/src/byteb4rb1e/utils/http/client.py b/src/byteb4rb1e/utils/http/client.py deleted file mode 100644 index 0962445..0000000 --- a/src/byteb4rb1e/utils/http/client.py +++ /dev/null @@ -1,109 +0,0 @@ -#!/usr/bin/env python3 -"""Generic HTTP client. - -Thin urllib wrapper with retry-on-rate-limit. No domain knowledge — -GitHub, Bitbucket, etc. are handled by higher-level modules. -""" - -import json -import time -from typing import Any, Dict, Optional -import urllib.request -import urllib.parse -from warnings import warn - - -class HttpResponse: - def __init__(self, status: int, headers: dict, data: bytes, reason: str): - self.status_code = status - self.headers = headers - self.data = data - self.reason = reason - self.text = data.decode("utf-8", errors="replace") - - def json(self): - return json.loads(self.data.decode("utf-8")) - - -def _request( - url: str, - method: str = "GET", - params: Optional[Dict[str, Any]] = None, - headers: Optional[Dict[str, str]] = None, - data: Optional[bytes] = None, -) -> HttpResponse: - # TODO: do proper exponential backoff - backoff = [1, 2, 4] - - if params: - query = urllib.parse.urlencode(params) - url = f"{url}?{query}" - - req = urllib.request.Request( - url, - headers=headers or {}, - method=method, - data=data, - ) - - for delay in backoff: - try: - with urllib.request.urlopen(req, timeout=30) as resp: - status = resp.getcode() - resp_data = resp.read() - resp_headers = dict(resp.getheaders()) - - if status == 429: - warn(f"Rate-limited on {url} (HTTP {status})." - f" Backing off {delay}s...") - time.sleep(delay) - continue - - return HttpResponse( - status, resp_headers, resp_data, resp.reason, - ) - - except urllib.error.HTTPError as e: - status = e.code - err_data = e.read() - err_headers = dict(e.headers.items()) - if status == 429: - warn(f"Rate-limited on {url} (HTTP {status})." - f" Backing off {delay}s...") - time.sleep(delay) - continue - return HttpResponse( - status, err_headers, err_data, e.reason, - ) - - except urllib.error.URLError as e: - raise Exception( - "Network error on %s: %s", url, e, - ) from e - - # If all retries exhausted, return last error-like response - return HttpResponse(503, {}, b"", "Service unavailable") - - -def get( - url: str, - params: Optional[Dict[str, Any]] = None, - headers: Optional[Dict[str, str]] = None, -) -> HttpResponse: - return _request(url, method="GET", params=params, headers=headers) - - -def post( - url: str, - data: Optional[bytes] = None, - headers: Optional[Dict[str, str]] = None, -) -> HttpResponse: - return _request(url, method="POST", headers=headers, data=data) - - -def put( - url: str, - data: Optional[bytes] = None, - headers: Optional[Dict[str, str]] = None, -) -> HttpResponse: - return _request(url, method="PUT", headers=headers, data=data) diff --git a/src/byteb4rb1e/utils/saas/bitbucket.py b/src/byteb4rb1e/utils/saas/bitbucket.py deleted file mode 100644 index d9b5bad..0000000 --- a/src/byteb4rb1e/utils/saas/bitbucket.py +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/env python3 -"""Bitbucket Cloud REST API v2.0 wrapper. - -Thin layer over http.py for Bitbucket-specific operations: - -- Bearer token authentication -- Repository existence checks -- Repository creation within a workspace/project -""" - -import json -from typing import Any, Dict, Optional - -from byteb4rb1e.utils.http import client as http_client - - -BITBUCKET_API = "https://api.bitbucket.org/2.0" - - -def http_headers(token: str) -> Dict[str, str]: - """Construct Bitbucket API headers with Bearer token auth.""" - return { - "Authorization": f"Bearer {token}", - "Accept": "application/json", - "Content-Type": "application/json", - } - - -def repository_exists( - workspace: str, - repo_slug: str, - token: str, -) -> bool: - """Check whether a repository exists in the workspace.""" - url = f"{BITBUCKET_API}/repositories/{workspace}/{repo_slug}" - resp = http_client.get(url, headers=http_headers(token)) - return resp.status_code == 200 - - -def create_repository( - workspace: str, - repo_slug: str, - token: str, - project: Optional[str] = None, - description: str = "", - is_private: bool = True, -) -> http_client.HttpResponse: - """Create a new repository in the workspace. - - When *project* is given the repository is assigned to that - Bitbucket project (by key). This is required for workspaces - that scope access keys at the project level. - - Returns the API response. Caller should check status_code == 200 - for success. - """ - url = f"{BITBUCKET_API}/repositories/{workspace}/{repo_slug}" - body: Dict[str, Any] = { - "scm": "git", - "is_private": is_private, - "description": description, - "fork_policy": "no_forks", - } - if project: - body["project"] = {"key": project} - return http_client.put( - url, - data=json.dumps(body).encode("utf-8"), - headers=http_headers(token), - ) - - -def clone_url( - workspace: str, - repo_slug: str, -) -> str: - """Return the SSH clone URL for a Bitbucket repository.""" - return f"git@bitbucket.org:{workspace}/{repo_slug}.git" diff --git a/src/byteb4rb1e/utils/saas/github.py b/src/byteb4rb1e/utils/saas/github.py deleted file mode 100644 index d174827..0000000 --- a/src/byteb4rb1e/utils/saas/github.py +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env python3 -import hashlib -from pathlib import Path -from typing import Any, Dict, List, Optional - -from byteb4rb1e.utils.http import client as http_client - - -GITHUB_API = "https://api.github.com" - - -def http_headers(token: Optional[str]) -> Dict[str, str]: - headers = { - "Accept": "application/vnd.github+json", - "User-Agent": "sphinx-h5p-worker1" - } - if token: - # Use standard PAT header; token not logged anywhere. - headers["Authorization"] = f"Bearer {token}" - return headers - - -def blob_sha(path: Path) -> str: - """Calculate Git blob SHA-1 for a file, matching GitHub API 'sha'.""" - data = path.read_bytes() - header = f"blob {len(data)}\0".encode("utf-8") - store = header + data - return hashlib.sha1(store).hexdigest() - - -def list_org_repos(org: str, token: Optional[str]) -> List[Dict[str, Any]]: - repos: List[Dict[str, Any]] = [] - page = 1 - per_page = 100 - while True: - url = f"{GITHUB_API}/orgs/{org}/repos" - resp = http_client.get( - url, - params={"page": page, "per_page": per_page, "type": "public"}, - headers=http_headers(token), - ) - if resp.status_code != 200: - raise RuntimeError(f"Failed to list repos for org {org}: {resp.status_code} {resp.text}") - batch = resp.json() - if not batch: - break - repos.extend(batch) - page += 1 - return repos - - -def fetch_file( - org: str, - repo: str, - path: str, - token: str -) -> http_client.HttpResponse: - """ - """ - url = f"{GITHUB_API}/repos/{org}/{repo}/{path}" - - return http_client.get( - url, - headers=http_headers(token), - ) diff --git a/src/byteb4rb1e/utils/string.py b/src/byteb4rb1e/utils/string.py deleted file mode 100644 index 800a5bc..0000000 --- a/src/byteb4rb1e/utils/string.py +++ /dev/null @@ -1,91 +0,0 @@ -from typing import Optional - - -class RollingHash: - """implementation of Rabin-Karp rolling hash - """ - #: default base - base: int = 31 - #: default modulus - mod: int = 10**9 + 7 - #: current computed hash - _hash: int - #: prime number base (e.g., 31) - _base: int - #: large prime modulus (to prevent overflow) - _mod: int - # Precomputation of ``base^(length-1) % mod`` for removing the old byte when - # rolling over - _hbase_factor: int - - def __init__( - self, - data: bytes, - base: Optional[int] = None, - mod: Optional[int] = None - ): - """Initialize the rolling hash with a given base and modulus. - - base: Prime number base (e.g., 31) - mod: Large prime modulus to prevent overflow - length: Length of the pattern to match - """ - self._base = base if base else RollingHash.base - - self._mod = mod if mod else RollingHash.mod - - self._hash = RollingHash.compute_initial_hash( - data, - self._base, - self._mod - ) - - self._hbase_factor = pow(self._base, len(data) - 1, self._mod) - - @staticmethod - def compute_initial_hash( - data: bytes, - base: int, - mod: int, - ) -> int: - """Compute the hash for the initial window (first `length` bytes). - - rather use this standalone for computing the hash of the search pattern, - to avoid the overhead of instantiating an object. - - :param data: data to build hash for - :param base: - :param: mod: - - :returns: hash of data - """ - hash_ = 0 - for i in range(len(data)): - # computing the modulus at each iteration, as to avoid the summed - # integer to be chunky, as in HUUUUGEE... - hash_ = (hash_ * base + data[i]) % mod - return hash_ - - def roll(self, old_byte: int, new_byte: int) -> int: - """Efficiently update hash by removing ``old_byte`` and adding - ``new_byte`` - - The old_byte removal uses a pre-computed value of the highest base used - in the polynomial calculation. This speeds things up a bit. - - I was thinking about a way on how to store the old_byte efficiently - within the class object, but that would require storing the entire data, - basically doubling the memory consumption as the data must definetly - also live outside of the class object. A memoryview could solve this - problem, but at the cost of making the implementation more complex, so - this will have to do. - - :param old_byte: The ordinal of the first byte in buffer to roll over - :param new_byte: The ordinal of the byte newly appended to the buffer - """ - # Remove old - self._hash = (self._hash - old_byte * self._hbase_factor) % self.mod - # Add new - self._hash = (self._hash * self.base + new_byte) % self.mod - - return self._hash diff --git a/src/byteb4rb1e/utils/urllib/request.py b/src/byteb4rb1e/utils/urllib/request.py deleted file mode 100644 index 2408d94..0000000 --- a/src/byteb4rb1e/utils/urllib/request.py +++ /dev/null @@ -1,41 +0,0 @@ -import email -import importlib.resources -import mimetypes -from urllib.request import URLError -import urllib.request - - -class PkgHandler(urllib.request.BaseHandler): - """ - """ - def pkg_open(self, req) -> urllib.request.addinfourl: - pkg_files = importlib.resources.files(req.host) - - try: - fh = next( - pkg_files.glob(req.selector.lstrip('//')) - ).open('rb') - except Exception as e: - raise URLError(f'{e.__class__.__name__}: {e}') from e - - fh.seek(0, 2); - size = fh.tell(); - fh.seek(0); - - mtype, compression = mimetypes.guess_type(req.selector) - - if compression and mtype: - mtype = f"{mtype}+{compression}" - - headers = email.message_from_string( - 'Content-Type: %s\nContent-Length: %d\n' % - (mtype or 'text/plain', size) - ) - - if not mtype or mtype.startswith('text/'): - fh.close() - fh = next( - pkg_files.glob(req.selector.lstrip('//')) - ).open('r') - - return urllib.request.addinfourl(fh, headers, None) diff --git a/src/byteb4rb1e/utils/vcs/git.py b/src/byteb4rb1e/utils/vcs/git.py deleted file mode 100644 index cd4cd87..0000000 --- a/src/byteb4rb1e/utils/vcs/git.py +++ /dev/null @@ -1,345 +0,0 @@ -#!/usr/bin/env python3 -"""Git subprocess wrapper for repository operations. - -Provides primitives for mirror cloning, syncing, remote management, -file extraction from bare repos, and submodule management. -No pygit2 or gitpython, uses subprocess only. -""" -import logging -import subprocess -from pathlib import Path -from typing import List, Optional - -logger = logging.getLogger(__name__) - - -class GitError(Exception): - """A git subprocess returned a non-zero exit code.""" - - def __init__(self, args: List[str], returncode: int, stderr: str): - self.args_list = args - self.returncode = returncode - self.stderr = stderr - super().__init__( - f"git exited {returncode}: {' '.join(args)}\n{stderr}" - ) - - -def parse_base_url(base_url: str) -> str: - """Extract workspace from an SCP-style Bitbucket base URL. - - The host part must be exactly ``bitbucket.org`` — bootstrapping - requires the Bitbucket API, so other hosts are rejected. - - >>> _parse_base_url("git@bitbucket.org:byteb4rb1e") - 'byteb4rb1e' - """ - # SCP-style: git@bitbucket.org:workspace - if ":" not in base_url or "//" in base_url: - raise ValueError( - f"Expected SCP-style URL (git@bitbucket.org:workspace), " - f"got: {base_url}" - ) - host_part, workspace = base_url.split(":", 1) - # host_part is e.g. "git@bitbucket.org" - host = host_part.split("@", 1)[-1] - if host != "bitbucket.org": - raise ValueError( - f"Mirror base URL must target bitbucket.org, " - f"got host: {host}" - ) - return Path(workspace).parent - - -def parse_repo_name(base_url: str) -> str: - """Extract workspace from an SCP-style Bitbucket base URL. - - The host part must be exactly ``bitbucket.org`` — bootstrapping - requires the Bitbucket API, so other hosts are rejected. - - >>> _parse_base_url("git@bitbucket.org:byteb4rb1e") - 'byteb4rb1e' - """ - # SCP-style: git@bitbucket.org:workspace - if ":" not in base_url or "//" in base_url: - raise ValueError( - f"Expected SCP-style URL (git@bitbucket.org:workspace), " - f"got: {base_url}" - ) - host_part, workspace = base_url.split(":", 1) - # host_part is e.g. "git@bitbucket.org" - host = host_part.split("@", 1)[-1] - if host != "bitbucket.org": - raise ValueError( - f"Mirror base URL must target bitbucket.org, " - f"got host: {host}" - ) - return Path(workspace).name.split('.')[0] - - - -def _run( - args: List[str], - cwd: Optional[Path] = None, - capture_stdout: bool = False, -) -> subprocess.CompletedProcess: # type: ignore[type-arg] - """Run a git command, raising GitError on failure.""" - cmd = ["git"] + args - logger.debug("$ %s", " ".join(cmd)) - result = subprocess.run( - cmd, - cwd=cwd, - capture_output=True, - text=True, - ) - if result.returncode != 0: - raise GitError(cmd, result.returncode, result.stderr.strip()) - return result - - -def mirror_clone(source_url: str, dest: Path) -> None: - """Clone a repository as a bare mirror. - - Equivalent to ``git clone --mirror ``. - The destination directory must not already exist. - """ - _run(["clone", "--mirror", source_url, str(dest)]) - logger.info("Cloned mirror %s → %s", source_url, dest) - - -def add_remote(repo: Path, name: str, url: str) -> None: - """Add a named remote to a bare repository.""" - _run(["remote", "add", name, url], cwd=repo) - logger.debug("Added remote %s → %s in %s", name, url, repo) - - -def has_remote(repo: Path, name: str) -> bool: - """Check whether a named remote exists.""" - result = _run(["remote"], cwd=repo) - return name in result.stdout.splitlines() - - -def mirror_update(repo: Path) -> None: - """Fetch all remotes in a bare mirror repository. - - Equivalent to ``git remote update`` inside the bare repo. - """ - _run(["remote", "update"], cwd=repo) - logger.debug("Updated remotes in %s", repo) - - -def fetch(repo: Path, remote: str = "origin") -> None: - """Fetch from a single remote.""" - _run(["fetch", remote], cwd=repo) - logger.debug("fetched %s in %s", remote, repo) - - -def show_ref(repo: Path) -> str: - """Return the raw output of ``git show-ref`` (all refs + SHAs). - - Returns an empty string if the repo has no refs. - """ - try: - result = _run(["show-ref"], cwd=repo) - return result.stdout - except GitError: - return "" - - -def ls_remote(repo: Path, remote: str) -> str: - """Return the raw output of ``git ls-remote ``. - - Returns an empty string if the remote has no refs or on error. - """ - try: - result = _run(["ls-remote", remote], cwd=repo) - return result.stdout - except GitError: - return "" - - -def mirror_push(repo: Path, remote: str) -> None: - """Push the full mirror to a remote. - - Equivalent to ``git push --mirror ``. - """ - _run(["push", "--mirror", remote], cwd=repo) - logger.info("Pushed mirror to %s from %s", remote, repo) - - -def read_file( - repo: Path, - filepath: str, - ref: str = "HEAD", -) -> Optional[str]: - """Extract a file's contents from a bare repo without checkout. - - Returns the file content as a string, or None if the file does - not exist at the given ref. - """ - try: - result = _run( - ["show", f"{ref}:{filepath}"], - cwd=repo, - capture_stdout=True, - ) - return result.stdout - except GitError: - return None - - -# ------------------------------------------------------------------- -# Ref / tag primitives -# ------------------------------------------------------------------- - -def list_tags(repo: Path) -> List[str]: - """List all tags in a repository.""" - result = _run(["tag", "-l"], cwd=repo) - return [t for t in result.stdout.splitlines() if t] - - -def resolve_ref(repo: Path, ref: str) -> str: - """Resolve a ref to a full SHA. - - Raises GitError if the ref cannot be resolved. - """ - result = _run( - ["rev-parse", ref], cwd=repo, capture_stdout=True, - ) - return result.stdout.strip() - - -def head_ref(repo: Path) -> str: - """Return the full SHA of HEAD.""" - return resolve_ref(repo, "HEAD") - - -# ------------------------------------------------------------------- -# Pull-through bare clone cache -# ------------------------------------------------------------------- - -def bare_path_for_url(url: str, cache_dir: Path) -> Path: - """Derive a cache path from a clone URL. - - Strips scheme/host, keeps the path component, appends ``.git``. - - Examples:: - - https://github.com/h5p/h5p-multi-choice - → cache_dir / h5p / h5p-multi-choice.git - git@github.com:h5p/h5p-multi-choice.git - → cache_dir / h5p / h5p-multi-choice.git - """ - # Handle SCP-style URLs (git@host:path) - if ":" in url and "//" not in url: - path_part = url.split(":", 1)[1] - else: - # Strip scheme + host - from urllib.parse import urlparse - parsed = urlparse(url) - path_part = parsed.path.lstrip("/") - - # Strip trailing .git if present, then re-add it - if path_part.endswith(".git"): - path_part = path_part[:-4] - - return cache_dir / (path_part + ".git") - - -def ensure_bare_clone(url: str, cache_dir: Path) -> Path: - """Ensure a bare mirror clone exists in *cache_dir*. - - If the bare repo already exists, fetches updates via - ``mirror_update``. Otherwise, creates a new mirror clone. - Returns the path to the bare repo. - """ - bare_path = bare_path_for_url(url, cache_dir) - if bare_path.exists(): - mirror_update(bare_path) - logger.debug("Updated existing cache %s", bare_path) - else: - bare_path.parent.mkdir(parents=True, exist_ok=True) - mirror_clone(url, bare_path) - logger.info("Cached new bare clone %s", bare_path) - return bare_path - - -# ------------------------------------------------------------------- -# Submodule operations -# ------------------------------------------------------------------- - -def has_submodule(repo: Path, path: str) -> bool: - """Check whether a submodule is registered at *path*. - - Reads ``.gitmodules`` to determine whether the submodule exists. - *path* is resolved relative to *repo*, then compared against - the repository root so the check works when *repo* is a - subdirectory of the actual git working tree. - Returns False if ``.gitmodules`` does not exist. - """ - try: - toplevel = Path( - _run( - ["rev-parse", "--show-toplevel"], cwd=repo, - ).stdout.strip() - ) - except GitError: - return False - gitmodules = toplevel / ".gitmodules" - if not gitmodules.is_file(): - return False - # Resolve the full path relative to the repo root - full_path = (repo / path).resolve() - try: - rel_path = str(full_path.relative_to(toplevel.resolve())) - except ValueError: - return False - try: - result = _run( - ["config", "--file", str(gitmodules), - "--get-regexp", r"submodule\..*\.path"], - cwd=toplevel, - ) - except GitError: - return False - for line in result.stdout.splitlines(): - parts = line.split(None, 1) - if len(parts) == 2 and parts[1] == rel_path: - return True - return False - - -def submodule_add(repo: Path, url: str, path: str) -> None: - """Add a git submodule at *path* pointing to *url*. - - Equivalent to ``git submodule add `` inside *repo*. - """ - _run(["submodule", "add", url, path], cwd=repo) - logger.info("Added submodule %s → %s", url, path) - - -def submodule_update(repo: Path, path: str) -> None: - """Fetch and update a submodule to the latest remote HEAD. - - Enters the submodule directory, fetches origin, and checks out - the latest commit on the remote default branch. - """ - sub_path = repo / path - _run(["fetch", "origin"], cwd=sub_path) - # Determine default branch from remote HEAD - result = _run( - ["symbolic-ref", "refs/remotes/origin/HEAD", - "--short"], - cwd=sub_path, - ) - default_branch = result.stdout.strip() - _run(["checkout", default_branch], cwd=sub_path) - logger.info("Updated submodule %s to %s", path, default_branch) - - -def submodule_checkout(repo: Path, path: str, ref: str) -> None: - """Fetch and checkout a specific ref in a submodule.""" - sub_path = repo / path - _run(["fetch", "origin"], cwd=sub_path) - _run(["checkout", ref], cwd=sub_path) - logger.info("Checked out submodule %s at %s", path, ref) diff --git a/src/byteb4rb1e/utils/collections.py b/src/byteb4rb1e_utils/collections.py similarity index 100% rename from src/byteb4rb1e/utils/collections.py rename to src/byteb4rb1e_utils/collections.py diff --git a/src/byteb4rb1e/testing/__init__.py b/src/byteb4rb1e_utils/http/__init__.py similarity index 100% rename from src/byteb4rb1e/testing/__init__.py rename to src/byteb4rb1e_utils/http/__init__.py diff --git a/src/byteb4rb1e/utils/http/server/__init__.py b/src/byteb4rb1e_utils/http/server/__init__.py similarity index 99% rename from src/byteb4rb1e/utils/http/server/__init__.py rename to src/byteb4rb1e_utils/http/server/__init__.py index 2486612..c1f6186 100644 --- a/src/byteb4rb1e/utils/http/server/__init__.py +++ b/src/byteb4rb1e_utils/http/server/__init__.py @@ -1,7 +1,7 @@ from dataclasses import dataclass from http.server import SimpleHTTPRequestHandler -from byteb4rb1e.utils.io import ChunksIO +from byteb4rb1e_utils.io import ChunksIO @dataclass diff --git a/src/byteb4rb1e/utils/http/server/__main__.py b/src/byteb4rb1e_utils/http/server/__main__.py similarity index 96% rename from src/byteb4rb1e/utils/http/server/__main__.py rename to src/byteb4rb1e_utils/http/server/__main__.py index b66bc52..7bca378 100644 --- a/src/byteb4rb1e/utils/http/server/__main__.py +++ b/src/byteb4rb1e_utils/http/server/__main__.py @@ -8,12 +8,12 @@ from http.server import HTTPServer from io import BytesIO, IOBase from typing import Optional, Tuple, List -from byteb4rb1e.utils.http.server import ( +from byteb4rb1e_utils.http.server import ( HandlerOptions, MultipartUploadHandler, ServerOptions, ) -from byteb4rb1e.utils.io import ChunksIO +from byteb4rb1e_utils.io import ChunksIO __doc__ = """tsmuds - Tiara's Simple Multipart Upload Debugging Server diff --git a/src/byteb4rb1e/utils/io/__init__.py b/src/byteb4rb1e_utils/io/__init__.py similarity index 100% rename from src/byteb4rb1e/utils/io/__init__.py rename to src/byteb4rb1e_utils/io/__init__.py diff --git a/src/byteb4rb1e_utils/string.py b/src/byteb4rb1e_utils/string.py new file mode 100644 index 0000000..f59babf --- /dev/null +++ b/src/byteb4rb1e_utils/string.py @@ -0,0 +1,68 @@ +from typing import List, Union + +from byteb4rb1e_utils.collections import CircularBuffer + + +class KnuthMorrisPratt: + """Knuth-Morris-Pratt string searching algorithm implemented as a class + + https://gwern.net/doc/cs/algorithm/1977-knuth.pdf + """ + def __init__(self, pattern: bytes): + """ + """ + self._table = KnuthMorrisPratt.build_table(pattern) + self._pattern = pattern + + @staticmethod + def build_table(pattern: bytes) -> List[int]: + """builds the failure table + """ + table = [0] * len(pattern) + j = 0 + for i in range(1, len(pattern)): + while j > 0 and pattern[i] != pattern[j]: + j = table[j - 1] + if pattern[i] == pattern[j]: + j += 1 + table[i] = j + return table + + def match_linear( + self, + data: Union[bytes, bytearray, memoryview], + start: int = 0 + ) -> bool: + """match against a linear fixed-size buffer + + :returns: index of the match or -1 if not found + """ + m, j = len(self.pattern), 0 + + for i in range(start, len(data)): + while j > 0 and data[i] != self.pattern[j]: + j = self._table[j - 1] + + if data[i] == self.pattern[j]: + j += 1 + + if j == m: + return i - m + 1 + return -1 + + def match_circular(self, data: CircularBuffer): + """Finds the boundary using KMP, handling circular wraparound.""" + i, j = data.start, 0 # Start checking from the oldest data in the buffer + + while j < len(boundary) and (data.filled or i != data.end): + if data.buf[i] == self.pattern[j]: + i = (i + 1) % data.size + j += 1 + if j == len(self.pattern): # Full match found + return True + elif j > 0: + j = table[j - 1] + else: + i = (i + 1) % data.size + + return False diff --git a/tests/integration/byteb4rb1e/testing/pytest/test_.py b/tests/integration/byteb4rb1e/testing/pytest/test_.py deleted file mode 100644 index 8141015..0000000 --- a/tests/integration/byteb4rb1e/testing/pytest/test_.py +++ /dev/null @@ -1,33 +0,0 @@ -import os -from pathlib import Path - -import pytest - -pytestmark = pytest.mark.pytest - -from byteb4rb1e.testing.pytest import get_current_test -from byteb4rb1e.testing.pytest.decorators import run_in_subprocess_once - - -class Test_get_current_test: - """ - """ - - def test_default(self): - """ - """ - os.environ['PYTEST_CURRENT_TEST'] = 'foo::bar (something)' - - result = get_current_test() - - assert isinstance(result[0], Path) - assert str(result[0].name) == 'foo' - - assert result[1] == 'bar' - - def test_invalid(self): - """ - """ - del os.environ['PYTEST_CURRENT_TEST'] - with pytest.raises(RuntimeError): - get_current_test() diff --git a/tests/integration/byteb4rb1e/testing/pytest/test_decorators.py b/tests/integration/byteb4rb1e/testing/pytest/test_decorators.py deleted file mode 100644 index c906bef..0000000 --- a/tests/integration/byteb4rb1e/testing/pytest/test_decorators.py +++ /dev/null @@ -1,21 +0,0 @@ -from pathlib import Path - -import pytest - -pytestmark = pytest.mark.pytest - -from byteb4rb1e.testing.pytest.decorators import run_in_subprocess_once - - -@run_in_subprocess_once() -def test_run_in_subprocess_once(tmp_path): - marker = tmp_path / "executed_in_subprocess.txt" - - if marker.exists(): - raise AssertionError("Marker file exists before test logic ran (shouldn't happen in parent process)") - - # Create proof of execution - marker.write_text("Subprocess was here.") - - # Now assert it - assert marker.exists() diff --git a/tests/integration/byteb4rb1e/testing/pytest/test_fixtures.py b/tests/integration/byteb4rb1e/testing/pytest/test_fixtures.py deleted file mode 100644 index a08851d..0000000 --- a/tests/integration/byteb4rb1e/testing/pytest/test_fixtures.py +++ /dev/null @@ -1,38 +0,0 @@ -from pathlib import Path -import importlib.resources - -import pytest - -pytestmark = pytest.mark.pytest - -from byteb4rb1e.testing.pytest.decorators import run_in_subprocess_once -from byteb4rb1e.testing.pytest.fixtures import ( - current_test, - mock_system_site_package_dir -) - - -def test_current_test(current_test): - """ - """ - suite_path, case_name = current_test - - assert str(Path(__file__)) == str(suite_path) - assert case_name == "test_current_test" - - -@run_in_subprocess_once() -def test_mock_system_site_package_dir(mock_system_site_package_dir): - """ - """ - dummy_data = 'Hello' - - pkgdir = mock_system_site_package_dir('foobarpkg') - - (pkgdir / 'data.txt').write_text(dummy_data) - - assert (pkgdir / '__init__.py').exists() - - result = next(importlib.resources.files('foobarpkg').glob('data.txt')).read_text() - - assert result == dummy_data diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py deleted file mode 100644 index 7c7aa51..0000000 --- a/tests/integration/conftest.py +++ /dev/null @@ -1,5 +0,0 @@ -def pytest_configure(config): - # register an additional marker - config.addinivalue_line( - "markers", "pytest: test pytest integration" - ) diff --git a/src/byteb4rb1e/utils/__init__.py b/tests/unit/__init__.py similarity index 100% rename from src/byteb4rb1e/utils/__init__.py rename to tests/unit/__init__.py diff --git a/tests/unit/byteb4rb1e/utils/__init__.py b/tests/unit/byteb4rb1e/utils/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/unit/byteb4rb1e/utils/string/test_rolling_hash.py b/tests/unit/byteb4rb1e/utils/string/test_rolling_hash.py deleted file mode 100644 index 590f527..0000000 --- a/tests/unit/byteb4rb1e/utils/string/test_rolling_hash.py +++ /dev/null @@ -1,61 +0,0 @@ -import unittest - -from byteb4rb1e.utils.string import RollingHash - -class test_compute_initial_hash(unittest.TestCase): - """RollingHash.compute_initial_hash() - - i calculated the hashes by hand, as a basis for this test case. Hopefully - there's no logical flaw... - """ - - def test_default(self): - """computation of hash""" - result = RollingHash.compute_initial_hash( - b'abcdefg', - base = 31, - mod = 10**9 + 7 - ) - - self.assertEqual(result, 988021244) - -class test___init__(unittest.TestCase): - """RollingHash.__init__() - - Make sure the class instance is initialized correctly - - I calculated the hashes by hand, as a basis for this test case. Hopefully - there's no logical flaw... - """ - - def test_default(self): - """computation of initial hash and highest base factor""" - instance = RollingHash(b'abcdefg') - - self.assertEqual(instance._hash, 988021244) - self.assertEqual(instance._hbase_factor, 887503681) - - def test_defaults_override(self): - """override of defaults""" - instance = RollingHash( - b'abcdefg', - base = 9, - mod = 4 - ) - - self.assertEqual(instance._mod, 4) - self.assertEqual(instance._base, 9) - - -class test_roll(unittest.TestCase): - """RollingHash.roll()""" - def test_rolling_hash(self): - base=31 - mod=10**9 + 7 - - rh = RollingHash(b"foobar", base=base, mod=mod) - rolled_hash = rh.roll(ord("f"), ord("n")) - - control_hash = RollingHash.compute_initial_hash(b"oobarn", base, mod) - - self.assertEqual(rolled_hash, control_hash) diff --git a/tests/unit/byteb4rb1e/utils/urllib/test_request.py b/tests/unit/byteb4rb1e/utils/urllib/test_request.py deleted file mode 100644 index 468751d..0000000 --- a/tests/unit/byteb4rb1e/utils/urllib/test_request.py +++ /dev/null @@ -1,93 +0,0 @@ -import os.path -import sys -import urllib.request - -import pytest - -from byteb4rb1e.testing.pytest.decorators import run_in_subprocess_once -from byteb4rb1e.testing.pytest.fixtures import mock_system_site_package_dir -from byteb4rb1e.utils.urllib.request import PkgHandler - - -class TestPkgHandler: - """ - """ - @run_in_subprocess_once() - def test_text(self, mock_system_site_package_dir): - """ - """ - _opener: urllib.request.OpenerDirector = urllib.request.build_opener( - PkgHandler() - ) - - dummy_data = 'Hello' - - pkg_dir = mock_system_site_package_dir('foobarpkg') - (pkg_dir / 'data.txt').write_text(dummy_data) - - result = _opener.open('pkg://foobarpkg/data.txt').readline() - - assert isinstance(result, str) - assert result == dummy_data - - - @run_in_subprocess_once() - def test_bytes(self, mock_system_site_package_dir): - """ - """ - _opener: urllib.request.OpenerDirector = urllib.request.build_opener( - PkgHandler() - ) - - dummy_data = b'foobar123' - - pkg_dir = mock_system_site_package_dir('foobarpkg') - (pkg_dir / 'data.bin').write_bytes(dummy_data) - - result = _opener.open('pkg://foobarpkg/data.bin').readline() - - assert isinstance(result, bytes) - assert result == dummy_data - - - @run_in_subprocess_once() - def test_subdir(self, mock_system_site_package_dir): - """ - """ - _opener: urllib.request.OpenerDirector = urllib.request.build_opener( - PkgHandler() - ) - - dummy_data = 'foobar123' - - pkg_dir = mock_system_site_package_dir('foobarpkg') - - dummy_file = (pkg_dir / 'foo' / 'bar' / 'data.txt') - - dummy_file.parent.mkdir(parents=True) - dummy_file.write_text(dummy_data) - - result = _opener.open('pkg://foobarpkg/foo/bar/data.txt').readline() - - assert result == dummy_data - - - @run_in_subprocess_once() - def test_nested_module(self, mock_system_site_package_dir): - """ - """ - _opener: urllib.request.OpenerDirector = urllib.request.build_opener( - PkgHandler() - ) - - dummy_data = 'foobar123' - - pkg_dir = mock_system_site_package_dir('foo.bar.pkg') - dummy_file = (pkg_dir / 'dummy' / 'data.txt') - - dummy_file.parent.mkdir(parents=True) - dummy_file.write_text(dummy_data) - - result = _opener.open('pkg://foo.bar.pkg/dummy/data.txt').readline() - - assert result == dummy_data diff --git a/src/byteb4rb1e/utils/http/__init__.py b/tests/unit/byteb4rb1e_utils/__init__.py similarity index 100% rename from src/byteb4rb1e/utils/http/__init__.py rename to tests/unit/byteb4rb1e_utils/__init__.py diff --git a/src/byteb4rb1e/utils/urllib/__init__.py b/tests/unit/byteb4rb1e_utils/collections/__init__.py similarity index 100% rename from src/byteb4rb1e/utils/urllib/__init__.py rename to tests/unit/byteb4rb1e_utils/collections/__init__.py diff --git a/tests/unit/byteb4rb1e/utils/collections/test_circular_buffer.py b/tests/unit/byteb4rb1e_utils/collections/test_circular_buffer.py similarity index 98% rename from tests/unit/byteb4rb1e/utils/collections/test_circular_buffer.py rename to tests/unit/byteb4rb1e_utils/collections/test_circular_buffer.py index 1baf601..aeb0934 100644 --- a/tests/unit/byteb4rb1e/utils/collections/test_circular_buffer.py +++ b/tests/unit/byteb4rb1e_utils/collections/test_circular_buffer.py @@ -1,6 +1,6 @@ import unittest -from byteb4rb1e.utils.collections import CircularBuffer +from byteb4rb1e_utils.collections import CircularBuffer class test_init(unittest.TestCase): """CircularBuffer.__init__()""" diff --git a/src/byteb4rb1e/utils/vcs/__init__.py b/tests/unit/byteb4rb1e_utils/io/__init__.py similarity index 100% rename from src/byteb4rb1e/utils/vcs/__init__.py rename to tests/unit/byteb4rb1e_utils/io/__init__.py diff --git a/tests/unit/byteb4rb1e/utils/io/test_chunksio.py b/tests/unit/byteb4rb1e_utils/io/test_chunksio.py similarity index 99% rename from tests/unit/byteb4rb1e/utils/io/test_chunksio.py rename to tests/unit/byteb4rb1e_utils/io/test_chunksio.py index a27f20f..4218d69 100644 --- a/tests/unit/byteb4rb1e/utils/io/test_chunksio.py +++ b/tests/unit/byteb4rb1e_utils/io/test_chunksio.py @@ -1,7 +1,7 @@ from io import BytesIO, IOBase import unittest -from byteb4rb1e.utils.io import ChunksIO +from byteb4rb1e_utils.io import ChunksIO class TestGetChunkSize(unittest.TestCase): diff --git a/tox.ini b/tox.ini deleted file mode 100644 index d4a94e1..0000000 --- a/tox.ini +++ /dev/null @@ -1,54 +0,0 @@ -[tox] -requires = - tox>=4.19 -env_list = - unit-py3{9-13} - integration-py3{9-13}-pytest8 - lint - format - -[testenv] -deps = - . - -[testenv:lint] -description = run type check on code base -labels = static -deps = - mypy -commands = - mypy src tests --junit-xml test-reports/{env_name}.xml - -[testenv:audit] -description = run type check on code base -labels = audit -deps = - pip-audit -commands = - pip-audit . - -[testenv:format] -description = run type check on code base -labels = static -deps = - autopep8 -commands = - autopep8 --diff --exit-code src tests - -[testenv:unit-py3{9-13}] -description = run type check on code base -labels = unit -deps = - {[testenv]deps} - pytest -commands = - pytest tests/unit --junitxml=test-reports/{env_name}.xml - -[testenv:integration-py3{9-13}-pytest8] -description = run pytest integration tests -labels = integration -deps = - {[testenv]deps} - pytest8: pytest>=8.0,<=9.0 -commands = - pytest tests/integration -m pytest --junitxml=test-reports/{env_name}.xml