From 6f267c29e6134c5f3160ab02ed4f59d92d7ecb95 Mon Sep 17 00:00:00 2001 From: "Rodney, Tiara" Date: Sun, 4 May 2025 01:31:37 +0200 Subject: [PATCH 01/74] feat(string): init kmp string search --- src/byteb4rb1e_utils/string.py | 51 ++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 src/byteb4rb1e_utils/string.py diff --git a/src/byteb4rb1e_utils/string.py b/src/byteb4rb1e_utils/string.py new file mode 100644 index 0000000..3261a03 --- /dev/null +++ b/src/byteb4rb1e_utils/string.py @@ -0,0 +1,51 @@ +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 From b9a67eb0a596c85c29621fa18316b07eaf231dea Mon Sep 17 00:00:00 2001 From: "Rodney, Tiara" Date: Sun, 4 May 2025 02:34:05 +0200 Subject: [PATCH 02/74] feat(string): add circular buffer support for KMP search --- src/byteb4rb1e_utils/string.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/byteb4rb1e_utils/string.py b/src/byteb4rb1e_utils/string.py index 3261a03..f59babf 100644 --- a/src/byteb4rb1e_utils/string.py +++ b/src/byteb4rb1e_utils/string.py @@ -49,3 +49,20 @@ class KnuthMorrisPratt: 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 From 358f3a1ea7902cad57834c4236a61e0cfe778373 Mon Sep 17 00:00:00 2001 From: "Rodney, Tiara" Date: Mon, 5 May 2025 00:54:15 +0200 Subject: [PATCH 03/74] todo(4): open --- TODO | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/TODO b/TODO index dd4cd66..5291dea 100644 --- a/TODO +++ b/TODO @@ -79,3 +79,22 @@ 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: open +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 + +--- From c0cfb60f2e7dddbe03b5e76ff84123762c8e29a8 Mon Sep 17 00:00:00 2001 From: "Rodney, Tiara" Date: Mon, 5 May 2025 00:54:44 +0200 Subject: [PATCH 04/74] todo(4): in-progress --- TODO | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO b/TODO index 5291dea..6b5576e 100644 --- a/TODO +++ b/TODO @@ -83,7 +83,7 @@ Description: move the unit test suites to a unit/ subdirectory so that ID: 4 Type: feature Title: implement Rabin-Karp rolling hash algorithm -Status: open +Status: in-progress Priority: high Created: 2025-05-05 Description: After testing a couple of string search algorithms, I've ditched From a8e75c020510c611169651934faafe627d9a0bec Mon Sep 17 00:00:00 2001 From: "Rodney, Tiara" Date: Mon, 5 May 2025 00:55:12 +0200 Subject: [PATCH 05/74] doc(TODO): add additional status for issues I'd like to be able to track when an issue is not being used, in addition to when I'm not actively working on issues. Therefore I introduced `cancelled` and `hold` status. --- TODO | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO b/TODO index 6b5576e..3f9a762 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] +Status: [open/in-progress/done/hold/cancelled] Priority: [low/medium/high] Created: [YYYY-MM-DD] Description: [Detailed explanation] From 7076768586b075e3e39f347e4b23dff921b787e9 Mon Sep 17 00:00:00 2001 From: "Rodney, Tiara" Date: Mon, 5 May 2025 01:31:17 +0200 Subject: [PATCH 06/74] todo(5): open --- TODO | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/TODO b/TODO index 3f9a762..cab98fe 100644 --- a/TODO +++ b/TODO @@ -98,3 +98,14 @@ Description: After testing a couple of string search algorithms, I've ditched algorithm --- + +ID: 5 +Type: feature +Title: implement chunked rolling hash algorithm +Status: open +Priority: high +Created: 2025-05-05 +Description: Implement my custom algorithm for doing rolling hash string search + against a fixed length ring buffer + +--- From ab5a86e07dd1f495adf6a0e0d7175bb6a1f12871 Mon Sep 17 00:00:00 2001 From: "Rodney, Tiara" Date: Mon, 5 May 2025 01:31:35 +0200 Subject: [PATCH 07/74] todo(5): in-progress --- TODO | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO b/TODO index cab98fe..1c1138e 100644 --- a/TODO +++ b/TODO @@ -102,7 +102,7 @@ Description: After testing a couple of string search algorithms, I've ditched ID: 5 Type: feature Title: implement chunked rolling hash algorithm -Status: open +Status: in-progress Priority: high Created: 2025-05-05 Description: Implement my custom algorithm for doing rolling hash string search From e67a95f15a9d91929d9bed8ed8aac0f3f16717ee Mon Sep 17 00:00:00 2001 From: "Rodney, Tiara" Date: Mon, 5 May 2025 00:47:17 +0200 Subject: [PATCH 08/74] feat(string): init Rabin-Karp rolling hash Implemented Rabin-Karp rolling hash class abstraction. After testing muliple algorithms for efficient substring searching in a stream abstracted by a ring buffer, I've dropped the idea of using KMP in favor of implementing my own algorithm based of the Rabin-Karp rolling hash algorithm. --- src/byteb4rb1e_utils/string.py | 91 +++++++++++++++++++ .../unit/byteb4rb1e_utils/string/__init__.py | 0 .../string/test_rolling_hash.py | 61 +++++++++++++ 3 files changed, 152 insertions(+) create mode 100644 src/byteb4rb1e_utils/string.py create mode 100644 tests/unit/byteb4rb1e_utils/string/__init__.py create mode 100644 tests/unit/byteb4rb1e_utils/string/test_rolling_hash.py diff --git a/src/byteb4rb1e_utils/string.py b/src/byteb4rb1e_utils/string.py new file mode 100644 index 0000000..800a5bc --- /dev/null +++ b/src/byteb4rb1e_utils/string.py @@ -0,0 +1,91 @@ +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/tests/unit/byteb4rb1e_utils/string/__init__.py b/tests/unit/byteb4rb1e_utils/string/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/unit/byteb4rb1e_utils/string/test_rolling_hash.py b/tests/unit/byteb4rb1e_utils/string/test_rolling_hash.py new file mode 100644 index 0000000..52c146a --- /dev/null +++ b/tests/unit/byteb4rb1e_utils/string/test_rolling_hash.py @@ -0,0 +1,61 @@ +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) From e22e43c0485b1f92d1489153311d074406b1a6af Mon Sep 17 00:00:00 2001 From: "Rodney, Tiara" Date: Mon, 5 May 2025 01:33:34 +0200 Subject: [PATCH 09/74] todo(4): done --- TODO | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO b/TODO index 1c1138e..947cd5e 100644 --- a/TODO +++ b/TODO @@ -83,7 +83,7 @@ Description: move the unit test suites to a unit/ subdirectory so that ID: 4 Type: feature Title: implement Rabin-Karp rolling hash algorithm -Status: in-progress +Status: done Priority: high Created: 2025-05-05 Description: After testing a couple of string search algorithms, I've ditched From b29ae6087d1aaec1a2229f071e7355585973832e Mon Sep 17 00:00:00 2001 From: "Rodney, Tiara" Date: Mon, 5 May 2025 01:36:58 +0200 Subject: [PATCH 10/74] todo(1): hold I don't have a real use for KMP at the moment. I'm putting it on hold but leaning towards cancelling the feature completely as I'm not trying to create a collection of algorithms... My utilities should only contain what I really need... --- TODO | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO b/TODO index 947cd5e..e4fe7e9 100644 --- a/TODO +++ b/TODO @@ -50,7 +50,7 @@ Description: [Detailed explanation] ID: 1 Type: feature Title: implement KMP algorithm for string searching -Status: in-progress +Status: hold Priority: high Created: 2025-05-03 Description: Implement the Knuth-Morris-Pratt algorithm for string searching. From a384efbe058435b528413426e9d817d28ba38346 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Fri, 20 Jun 2025 19:43:43 +0200 Subject: [PATCH 11/74] todo(6): open --- TODO | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/TODO b/TODO index e4fe7e9..22bafe4 100644 --- a/TODO +++ b/TODO @@ -109,3 +109,14 @@ 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: open +Priority: high +Created: 2025-06-20 +Description: A handler that can be registered with an urllib.request + OpenerDirector to open importlib.resources package files. + +--- From 32d6a7a0dfd408c6de6eba2abb060175030ac9b6 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Fri, 20 Jun 2025 19:44:25 +0200 Subject: [PATCH 12/74] todo(6): in-progress --- TODO | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO b/TODO index 22bafe4..75efac6 100644 --- a/TODO +++ b/TODO @@ -113,7 +113,7 @@ Description: Implement my custom algorithm for doing rolling hash string search ID: 6 Type: feature Title: implement importlib.resources handler for urllib -Status: open +Status: in-progress Priority: high Created: 2025-06-20 Description: A handler that can be registered with an urllib.request From d4068f464ba8f021b165bb30b76c494596a809a0 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Fri, 20 Jun 2025 19:48:05 +0200 Subject: [PATCH 13/74] todo(7): open --- TODO | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/TODO b/TODO index 75efac6..bcbbcbe 100644 --- a/TODO +++ b/TODO @@ -120,3 +120,14 @@ 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: open +Priority: high +Created: 2025-06-20 +Description: copy the testing environment setup from + byteb4rb1e.sphinxcontrib.ext + +--- From c6c6d806acc7f53038544dff09c6c0855038ed32 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Fri, 20 Jun 2025 19:48:22 +0200 Subject: [PATCH 14/74] todo(7): in-progress --- TODO | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO b/TODO index bcbbcbe..0d227ca 100644 --- a/TODO +++ b/TODO @@ -124,7 +124,7 @@ Description: A handler that can be registered with an urllib.request ID: 7 Type: feature Title: setup advanced testing environment -Status: open +Status: in-progress Priority: high Created: 2025-06-20 Description: copy the testing environment setup from From c0adb4cdfbfd13720838b7cdcfdd1c08e1645331 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Fri, 20 Jun 2025 20:19:05 +0200 Subject: [PATCH 15/74] todo(8): open --- TODO | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/TODO b/TODO index 0d227ca..c4d3782 100644 --- a/TODO +++ b/TODO @@ -131,3 +131,13 @@ Description: copy the testing environment setup from byteb4rb1e.sphinxcontrib.ext --- + +ID: 8 +Type: bugfix +Title: rename package +Status: open +Priority: high +Created: 2025-06-20 +Description: use dot namespaces to make the package a little more elegant + +--- From b1a469a351f47b4be2e1c9048794c51b09c2b778 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Fri, 20 Jun 2025 19:52:58 +0200 Subject: [PATCH 16/74] feat(test): init tox config --- tox.ini | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 tox.ini diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..efb3353 --- /dev/null +++ b/tox.ini @@ -0,0 +1,44 @@ +[tox] +requires = + tox>=4.19 +env_list = + py3{8-12}-{unit} + 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 = + black +commands = + black --check src tests + +[testenv:py3{9-13}-unit] +description = run type check on code base +labels = unit +deps = + {[testenv]deps} + pytest +commands = + pytest tests/unit --junitxml=test-reports/{env_name}.xml From 6955b5e33049aeeb4b7bb13cb2a028e50f0de640 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Fri, 20 Jun 2025 19:54:22 +0200 Subject: [PATCH 17/74] feat(test): add entrypoints and runtime dependency --- Pipfile | 4 +- Pipfile.lock | 101 ++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 74 insertions(+), 31 deletions(-) diff --git a/Pipfile b/Pipfile index 89a5cd3..eb452da 100644 --- a/Pipfile +++ b/Pipfile @@ -11,10 +11,12 @@ pylint = "~=3.3.6" build = "*" pipenv = "*" byteb4rb1e-utils = { editable = true, path = '.'} +tox = "*" [requires] python_version = "3.11" [scripts] "build" = "python3 -m build" - +"test-static" = "tox run -m static" +"test-unit" = "tox run -m unit" diff --git a/Pipfile.lock b/Pipfile.lock index 7f78522..75f1b92 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "4847baa5a13a96f2c3de2a246a0c088806c308426c79d8105387dff1fe1f1e58" + "sha256": "9b051b97c212860afb34d1f834104a9bcaefc303b400f6b6828fe6e675b0f170" }, "pipfile-spec": 6, "requires": { @@ -19,11 +19,11 @@ "develop": { "astroid": { "hashes": [ - "sha256:622cc8e3048684aa42c820d9d218978021c3c3d174fb03a9f0d615921744f550", - "sha256:d05bfd0acba96a7bd43e222828b7d9bc1e138aaeb0649707908d3702a9831248" + "sha256:104fb9cb9b27ea95e847a94c003be03a9e039334a8ebca5ee27dafaf5c5711eb", + "sha256:c332157953060c6deb9caa57303ae0d20b0fbdb2e59b4a4f2a6ba49d0a7961ce" ], "markers": "python_full_version >= '3.9.0'", - "version": "==3.3.9" + "version": "==3.3.10" }, "autopep8": { "hashes": [ @@ -47,13 +47,29 @@ "editable": true, "path": "." }, + "cachetools": { + "hashes": [ + "sha256:1c7bb3cf9193deaf3508b7c5f2a79986c13ea38965c5adcff1f84519cf39163e", + "sha256:b4c4f404392848db3ce7aac34950d17be4d864da4b8b66911008e430bc544587" + ], + "markers": "python_version >= '3.9'", + "version": "==6.1.0" + }, "certifi": { "hashes": [ - "sha256:0a816057ea3cdefcef70270d2c515e4506bbc954f417fa5ade2021213bb8f0c6", - "sha256:30350364dfe371162649852c63336a15c70c6510c2ad5015b21c2345311805f3" + "sha256:2e0c7ce7cb5d8f8634ca55d2ba7e6ec2689a2fd6537d8dec1296a477a4910057", + "sha256:d747aa5a8b9bbbb1bb8c22bb13e22bd1f18e9796defa16bab421f7f7a317323b" ], - "markers": "python_version >= '3.6'", - "version": "==2025.4.26" + "markers": "python_version >= '3.7'", + "version": "==2025.6.15" + }, + "chardet": { + "hashes": [ + "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7", + "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970" + ], + "markers": "python_version >= '3.7'", + "version": "==5.2.0" }, "colorama": { "hashes": [ @@ -159,20 +175,28 @@ }, "pipenv": { "hashes": [ - "sha256:85d42e13da78f27f0213c998dba9a59f3ba6a6fe9e420b75b561acc344f021ad", - "sha256:f26dc0352f3fb167c3897a66a5d8c9ab81dd52a836a48630712e1e5a06840ebf" + "sha256:87370bedcf0ff66d226af07ca341ae94afcc08fed90d57ad9fea9ffd44ced4d3", + "sha256:f0a67aa928824e61003d52acea72a94b180800019f03d38a311966f6330bc8d1" ], "index": "pypi", "markers": "python_version >= '3.9'", - "version": "==2025.0.2" + "version": "==2025.0.3" }, "platformdirs": { "hashes": [ - "sha256:a03875334331946f13c549dbd8f4bac7a13a50a895a0eb1e8c6a8ace80d40a94", - "sha256:eb437d586b6a0986388f0d6f74aa0cde27b48d0e3d66843640bfb6bdcdb6e351" + "sha256:3d512d96e16bcb959a814c9f348431070822a6496326a4be0911c40b5a74c2bc", + "sha256:ff7059bb7eb1179e2685604f4aaf157cfd9535242bd23742eadc3c13542139b4" ], "markers": "python_version >= '3.9'", - "version": "==4.3.7" + "version": "==4.3.8" + }, + "pluggy": { + "hashes": [ + "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", + "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746" + ], + "markers": "python_version >= '3.9'", + "version": "==1.6.0" }, "pycodestyle": { "hashes": [ @@ -184,12 +208,20 @@ }, "pylint": { "hashes": [ - "sha256:8b7c2d3e86ae3f94fb27703d521dd0b9b6b378775991f504d7c3a6275aa0a6a6", - "sha256:b634a041aac33706d56a0d217e6587228c66427e20ec21a019bc4cdee48c040a" + "sha256:2b11de8bde49f9c5059452e0c310c079c746a0a8eeaa789e5aa966ecc23e4559", + "sha256:43860aafefce92fca4cf6b61fe199cdc5ae54ea28f9bf4cd49de267b5195803d" ], "index": "pypi", "markers": "python_full_version >= '3.9.0'", - "version": "==3.3.6" + "version": "==3.3.7" + }, + "pyproject-api": { + "hashes": [ + "sha256:43c9918f49daab37e302038fc1aed54a8c7a91a9fa935d00b9a485f37e0f5335", + "sha256:7d6238d92f8962773dd75b5f0c4a6a27cce092a14b623b811dba656f3b628948" + ], + "markers": "python_version >= '3.9'", + "version": "==1.9.1" }, "pyproject-hooks": { "hashes": [ @@ -201,11 +233,11 @@ }, "setuptools": { "hashes": [ - "sha256:a65cffc4fb86167e3020b3ef58e08226baad8b29a3b34ce2c9d07e901bac481d", - "sha256:ec8308eb180b2312062b1c5523204acf872cd8b0a9e6c2ae76431b22bc4065d7" + "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922", + "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c" ], "markers": "python_version >= '3.9'", - "version": "==80.3.0" + "version": "==80.9.0" }, "setuptools-scm": { "hashes": [ @@ -218,27 +250,36 @@ }, "tomlkit": { "hashes": [ - "sha256:7a974427f6e119197f670fbbbeae7bef749a6c14e793db934baefc1b5f03efde", - "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79" + "sha256:430cf247ee57df2b94ee3fbe588e71d362a941ebb545dec29b53961d61add2a1", + "sha256:c89c649d79ee40629a9fda55f8ace8c6a1b42deb912b2a8fd8d942ddadb606b0" ], "markers": "python_version >= '3.8'", - "version": "==0.13.2" + "version": "==0.13.3" + }, + "tox": { + "hashes": [ + "sha256:2b8a7fb986b82aa2c830c0615082a490d134e0626dbc9189986da46a313c4f20", + "sha256:b97d5ecc0c0d5755bcc5348387fef793e1bfa68eb33746412f4c60881d7f5f57" + ], + "index": "pypi", + "markers": "python_version >= '3.9'", + "version": "==4.27.0" }, "typing-extensions": { "hashes": [ - "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c", - "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef" + "sha256:8676b788e32f02ab42d9e7c61324048ae4c6d844a399eebace3d4979d75ceef4", + "sha256:a1514509136dd0b477638fc68d6a91497af5076466ad0fa6c338e44e359944af" ], - "markers": "python_version >= '3.8'", - "version": "==4.13.2" + "markers": "python_version >= '3.9'", + "version": "==4.14.0" }, "virtualenv": { "hashes": [ - "sha256:800863162bcaa5450a6e4d721049730e7f2dae07720e0902b0e4040bd6f9ada8", - "sha256:e34302959180fca3af42d1800df014b35019490b119eba981af27f2fa486e5d6" + "sha256:36efd0d9650ee985f0cad72065001e66d49a6f24eb44d98980f630686243cf11", + "sha256:e10c0a9d02835e592521be48b332b6caee6887f332c111aa79a09b9e79efc2af" ], "markers": "python_version >= '3.8'", - "version": "==20.30.0" + "version": "==20.31.2" } } } From ab626d5c8eb9f60472d1185a7e44012dabd641c1 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Fri, 20 Jun 2025 19:57:57 +0200 Subject: [PATCH 18/74] chore(test): remove redundant dependencies dependencies for test environments are handled by tox and defined in tox.ini --- Pipfile | 3 -- Pipfile.lock | 123 +-------------------------------------------------- 2 files changed, 1 insertion(+), 125 deletions(-) diff --git a/Pipfile b/Pipfile index eb452da..d693e3e 100644 --- a/Pipfile +++ b/Pipfile @@ -4,10 +4,7 @@ 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 = "*" byteb4rb1e-utils = { editable = true, path = '.'} diff --git a/Pipfile.lock b/Pipfile.lock index 75f1b92..aa123f0 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "9b051b97c212860afb34d1f834104a9bcaefc303b400f6b6828fe6e675b0f170" + "sha256": "cb7c8c0a12f574d2bc30ffe38e79ba18ee29424cb1fb1cdce8373f89d56f3e1c" }, "pipfile-spec": 6, "requires": { @@ -17,23 +17,6 @@ }, "default": {}, "develop": { - "astroid": { - "hashes": [ - "sha256:104fb9cb9b27ea95e847a94c003be03a9e039334a8ebca5ee27dafaf5c5711eb", - "sha256:c332157953060c6deb9caa57303ae0d20b0fbdb2e59b4a4f2a6ba49d0a7961ce" - ], - "markers": "python_full_version >= '3.9.0'", - "version": "==3.3.10" - }, - "autopep8": { - "hashes": [ - "sha256:89440a4f969197b69a995e4ce0661b031f455a9f776d2c5ba3dbd83466931758", - "sha256:ce8ad498672c845a0c3de2629c15b635ec2b05ef8177a6e7c91c74f3e9b51128" - ], - "index": "pypi", - "markers": "python_version >= '3.9'", - "version": "==2.3.2" - }, "build": { "hashes": [ "sha256:1d61c0887fa860c01971625baae8bdd338e517b836a2f70dd1f7aa3a6b2fc5b5", @@ -79,14 +62,6 @@ "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" }, - "dill": { - "hashes": [ - "sha256:0633f1d2df477324f53a895b02c901fb961bdbf65a17122586ea7019292cbcf0", - "sha256:44f54bf6412c2c8464c14e8243eb163690a9800dbe2c367330883b19c7561049" - ], - "markers": "python_version >= '3.8'", - "version": "==0.4.0" - }, "distlib": { "hashes": [ "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87", @@ -102,69 +77,6 @@ "markers": "python_version >= '3.9'", "version": "==3.18.0" }, - "isort": { - "hashes": [ - "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": "==1.1.0" - }, "packaging": { "hashes": [ "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", @@ -198,23 +110,6 @@ "markers": "python_version >= '3.9'", "version": "==1.6.0" }, - "pycodestyle": { - "hashes": [ - "sha256:35863c5974a271c7a726ed228a14a4f6daf49df369d8c50cd9a6f58a5e143ba9", - "sha256:c8415bf09abe81d9c7f872502a6eee881fbe85d8763dd5b9924bb0a01d67efae" - ], - "markers": "python_version >= '3.9'", - "version": "==2.13.0" - }, - "pylint": { - "hashes": [ - "sha256:2b11de8bde49f9c5059452e0c310c079c746a0a8eeaa789e5aa966ecc23e4559", - "sha256:43860aafefce92fca4cf6b61fe199cdc5ae54ea28f9bf4cd49de267b5195803d" - ], - "index": "pypi", - "markers": "python_full_version >= '3.9.0'", - "version": "==3.3.7" - }, "pyproject-api": { "hashes": [ "sha256:43c9918f49daab37e302038fc1aed54a8c7a91a9fa935d00b9a485f37e0f5335", @@ -248,14 +143,6 @@ "markers": "python_version >= '3.8'", "version": "==8.2.0" }, - "tomlkit": { - "hashes": [ - "sha256:430cf247ee57df2b94ee3fbe588e71d362a941ebb545dec29b53961d61add2a1", - "sha256:c89c649d79ee40629a9fda55f8ace8c6a1b42deb912b2a8fd8d942ddadb606b0" - ], - "markers": "python_version >= '3.8'", - "version": "==0.13.3" - }, "tox": { "hashes": [ "sha256:2b8a7fb986b82aa2c830c0615082a490d134e0626dbc9189986da46a313c4f20", @@ -265,14 +152,6 @@ "markers": "python_version >= '3.9'", "version": "==4.27.0" }, - "typing-extensions": { - "hashes": [ - "sha256:8676b788e32f02ab42d9e7c61324048ae4c6d844a399eebace3d4979d75ceef4", - "sha256:a1514509136dd0b477638fc68d6a91497af5076466ad0fa6c338e44e359944af" - ], - "markers": "python_version >= '3.9'", - "version": "==4.14.0" - }, "virtualenv": { "hashes": [ "sha256:36efd0d9650ee985f0cad72065001e66d49a6f24eb44d98980f630686243cf11", From dc69eea88af659047451e9d3462fd34a92902066 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Fri, 20 Jun 2025 20:04:15 +0200 Subject: [PATCH 19/74] chore(test): remove redundant module entrypoints pytest compared to built-in unittest does not discover test suites based on a directory being marked as a module, instead matching against the basename of a file to determine whether it is a test suite or not. --- tests/unit/__init__.py | 0 tests/unit/byteb4rb1e_utils/collections/__init__.py | 0 tests/unit/byteb4rb1e_utils/io/__init__.py | 0 tests/unit/byteb4rb1e_utils/string/__init__.py | 0 4 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 tests/unit/__init__.py delete mode 100644 tests/unit/byteb4rb1e_utils/collections/__init__.py delete mode 100644 tests/unit/byteb4rb1e_utils/io/__init__.py delete mode 100644 tests/unit/byteb4rb1e_utils/string/__init__.py diff --git a/tests/unit/__init__.py b/tests/unit/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/unit/byteb4rb1e_utils/collections/__init__.py b/tests/unit/byteb4rb1e_utils/collections/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/unit/byteb4rb1e_utils/io/__init__.py b/tests/unit/byteb4rb1e_utils/io/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/unit/byteb4rb1e_utils/string/__init__.py b/tests/unit/byteb4rb1e_utils/string/__init__.py deleted file mode 100644 index e69de29..0000000 From b6a99d4b2d294a4a85879c4f8f40f5a018508091 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Fri, 20 Jun 2025 20:05:32 +0200 Subject: [PATCH 20/74] chore(test): ignore test-reports --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 5c8bfee..dbfbc60 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ /configure~ *.swo *.swp +/test-reports/ From 6bf67f4a881593648092fd863df4816089cfbef5 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Fri, 20 Jun 2025 20:17:56 +0200 Subject: [PATCH 21/74] chore(test): update Makefile --- Makefile | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 37439f1..f1b82b3 100644 --- a/Makefile +++ b/Makefile @@ -16,8 +16,13 @@ configure: configure.ac .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 +test-reports: test-reports/unit test-reports/static + +test-reports/unit: + python3 -m pipenv run -v test-unit + +test-reports/static: + python3 -m pipenv run -v test-static build: .venv/bin/pipenv .venv/bin/pipenv run build From f0f36542f457727c5bae1d43802ae778c3b32204 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Fri, 20 Jun 2025 20:21:06 +0200 Subject: [PATCH 22/74] todo(7): done --- TODO | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO b/TODO index c4d3782..e748d19 100644 --- a/TODO +++ b/TODO @@ -124,7 +124,7 @@ Description: A handler that can be registered with an urllib.request ID: 7 Type: feature Title: setup advanced testing environment -Status: in-progress +Status: done Priority: high Created: 2025-06-20 Description: copy the testing environment setup from From dd57ecabb937baf268e9f2af35962123146f66b2 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Fri, 20 Jun 2025 20:25:51 +0200 Subject: [PATCH 23/74] todo(8): in-progress --- TODO | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO b/TODO index e748d19..ae2d7f6 100644 --- a/TODO +++ b/TODO @@ -135,7 +135,7 @@ Description: copy the testing environment setup from ID: 8 Type: bugfix Title: rename package -Status: open +Status: in-progress Priority: high Created: 2025-06-20 Description: use dot namespaces to make the package a little more elegant From 1fb1e0d0bf50f61c10746b0c14e6c6922c5de914 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Fri, 20 Jun 2025 20:33:37 +0200 Subject: [PATCH 24/74] chore: rename package --- pyproject.toml | 2 +- src/{byteb4rb1e_utils => byteb4rb1e/utils}/collections.py | 0 src/{byteb4rb1e_utils => byteb4rb1e/utils}/http/__init__.py | 0 .../utils}/http/server/__init__.py | 2 +- .../utils}/http/server/__main__.py | 4 ++-- src/{byteb4rb1e_utils => byteb4rb1e/utils}/io/__init__.py | 0 src/{byteb4rb1e_utils => byteb4rb1e/utils}/string.py | 0 tests/unit/{byteb4rb1e_utils => byteb4rb1e/utils}/__init__.py | 0 .../utils}/collections/test_circular_buffer.py | 2 +- .../utils}/io/test_chunksio.py | 2 +- .../utils}/string/test_rolling_hash.py | 2 +- 11 files changed, 7 insertions(+), 7 deletions(-) rename src/{byteb4rb1e_utils => byteb4rb1e/utils}/collections.py (100%) rename src/{byteb4rb1e_utils => byteb4rb1e/utils}/http/__init__.py (100%) rename src/{byteb4rb1e_utils => byteb4rb1e/utils}/http/server/__init__.py (99%) rename src/{byteb4rb1e_utils => byteb4rb1e/utils}/http/server/__main__.py (96%) rename src/{byteb4rb1e_utils => byteb4rb1e/utils}/io/__init__.py (100%) rename src/{byteb4rb1e_utils => byteb4rb1e/utils}/string.py (100%) rename tests/unit/{byteb4rb1e_utils => byteb4rb1e/utils}/__init__.py (100%) rename tests/unit/{byteb4rb1e_utils => byteb4rb1e/utils}/collections/test_circular_buffer.py (98%) rename tests/unit/{byteb4rb1e_utils => byteb4rb1e/utils}/io/test_chunksio.py (99%) rename tests/unit/{byteb4rb1e_utils => byteb4rb1e/utils}/string/test_rolling_hash.py (97%) diff --git a/pyproject.toml b/pyproject.toml index b5fcdb7..fd23512 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ 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@administratrix.de" } 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_utils/http/__init__.py b/src/byteb4rb1e/utils/http/__init__.py similarity index 100% rename from src/byteb4rb1e_utils/http/__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 c1f6186..2486612 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 7bca378..b66bc52 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 similarity index 100% rename from src/byteb4rb1e_utils/string.py rename to src/byteb4rb1e/utils/string.py diff --git a/tests/unit/byteb4rb1e_utils/__init__.py b/tests/unit/byteb4rb1e/utils/__init__.py similarity index 100% rename from tests/unit/byteb4rb1e_utils/__init__.py rename to tests/unit/byteb4rb1e/utils/__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 aeb0934..1baf601 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/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 4218d69..a27f20f 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/tests/unit/byteb4rb1e_utils/string/test_rolling_hash.py b/tests/unit/byteb4rb1e/utils/string/test_rolling_hash.py similarity index 97% rename from tests/unit/byteb4rb1e_utils/string/test_rolling_hash.py rename to tests/unit/byteb4rb1e/utils/string/test_rolling_hash.py index 52c146a..590f527 100644 --- a/tests/unit/byteb4rb1e_utils/string/test_rolling_hash.py +++ b/tests/unit/byteb4rb1e/utils/string/test_rolling_hash.py @@ -1,6 +1,6 @@ import unittest -from byteb4rb1e_utils.string import RollingHash +from byteb4rb1e.utils.string import RollingHash class test_compute_initial_hash(unittest.TestCase): """RollingHash.compute_initial_hash() From fb0c65c6af2dc29c5f823214b1d36c1e7e5437b6 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Fri, 20 Jun 2025 20:35:11 +0200 Subject: [PATCH 25/74] todo(8): done --- TODO | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO b/TODO index ae2d7f6..d762bd5 100644 --- a/TODO +++ b/TODO @@ -135,7 +135,7 @@ Description: copy the testing environment setup from ID: 8 Type: bugfix Title: rename package -Status: in-progress +Status: done Priority: high Created: 2025-06-20 Description: use dot namespaces to make the package a little more elegant From 576aad9d4c48d636ae286672c2932a76750768bd Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Fri, 20 Jun 2025 20:37:26 +0200 Subject: [PATCH 26/74] todo(9): open --- TODO | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/TODO b/TODO index d762bd5..def7ca6 100644 --- a/TODO +++ b/TODO @@ -141,3 +141,14 @@ 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: open +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 + +--- From e0e99480e36251dcaa6d98439209c8377249ce38 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Fri, 20 Jun 2025 20:38:14 +0200 Subject: [PATCH 27/74] todo(9): in-progress --- TODO | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO b/TODO index def7ca6..e7f9b56 100644 --- a/TODO +++ b/TODO @@ -145,7 +145,7 @@ Description: use dot namespaces to make the package a little more elegant ID: 9 Type: bugfix Title: fix LICENSE reference -Status: open +Status: in-progress Priority: high Created: 2025-06-20 Description: license specification is no longer a trove classifier in From 7e8082bae2d2f7ac98db5e6a3f757b97292ea10f Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Fri, 20 Jun 2025 20:39:01 +0200 Subject: [PATCH 28/74] feat(license): add unlicense license Don't know what to license this under yet --- LICENSE | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e69de29 From d799c62c78feabf922f750b36b8023244842e0c9 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Fri, 20 Jun 2025 20:39:34 +0200 Subject: [PATCH 29/74] chore: change license reference --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index fd23512..5bc3eb4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,7 +12,7 @@ description = "personal utilities and helpers" authors = [ { name = "Tiara Rodney", email = "tiara.rodney@administratrix.de" } ] -license = { file = "LICENSE" } +license-files = ["LICENSE"] readme = "README.md" classifiers = [ "Development Status :: 1 - Planning", From 324df0e6d2d125086fb854696e64abf92af7cefd Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Fri, 20 Jun 2025 20:39:53 +0200 Subject: [PATCH 30/74] todo(9): done --- TODO | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO b/TODO index e7f9b56..be8e36a 100644 --- a/TODO +++ b/TODO @@ -145,7 +145,7 @@ Description: use dot namespaces to make the package a little more elegant ID: 9 Type: bugfix Title: fix LICENSE reference -Status: in-progress +Status: done Priority: high Created: 2025-06-20 Description: license specification is no longer a trove classifier in From 44e35846a50c673221e9b880faaab189415d10ce Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Fri, 20 Jun 2025 21:00:31 +0200 Subject: [PATCH 31/74] todo(10): open --- TODO | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/TODO b/TODO index be8e36a..3b2a0c8 100644 --- a/TODO +++ b/TODO @@ -152,3 +152,14 @@ 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: open +Priority: high +Created: 2025-06-20 +Description: add fixtures for doing things in relation to the active testing + context + +--- From c579ddd0226261f830cbe21101583d8e47a60686 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Fri, 20 Jun 2025 21:00:53 +0200 Subject: [PATCH 32/74] todo(10): in-progress --- TODO | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO b/TODO index 3b2a0c8..0b3b40c 100644 --- a/TODO +++ b/TODO @@ -156,7 +156,7 @@ Description: license specification is no longer a trove classifier in ID: 10 Type: feature Title: pytest current test context fixtures -Status: open +Status: in-progress Priority: high Created: 2025-06-20 Description: add fixtures for doing things in relation to the active testing From 644beb86964fcb29c3f3b664d44a07b73c062b2c Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Fri, 20 Jun 2025 21:47:17 +0200 Subject: [PATCH 33/74] feat(testing): init pytest fixtures current_test fixture allows to retrieve the current test context, that is exposed through the shell environment --- Makefile | 3 +++ Pipfile | 1 + src/byteb4rb1e/utils/testing/pytest/fixtures.py | 14 ++++++++++++++ .../utils/testing/pytest/test_fixtures.py | 16 ++++++++++++++++ tests/integration/conftest.py | 5 +++++ tox.ini | 14 ++++++++++++-- 6 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 src/byteb4rb1e/utils/testing/pytest/fixtures.py create mode 100644 tests/integration/byteb4rb1e/utils/testing/pytest/test_fixtures.py create mode 100644 tests/integration/conftest.py diff --git a/Makefile b/Makefile index f1b82b3..0a1ec21 100644 --- a/Makefile +++ b/Makefile @@ -21,6 +21,9 @@ test-reports: test-reports/unit test-reports/static test-reports/unit: python3 -m pipenv run -v test-unit +test-reports/integration: + python3 -m pipenv run -v test-integration + test-reports/static: python3 -m pipenv run -v test-static diff --git a/Pipfile b/Pipfile index d693e3e..fa10d4e 100644 --- a/Pipfile +++ b/Pipfile @@ -17,3 +17,4 @@ python_version = "3.11" "build" = "python3 -m build" "test-static" = "tox run -m static" "test-unit" = "tox run -m unit" +"test-integration" = "tox run -m integration" diff --git a/src/byteb4rb1e/utils/testing/pytest/fixtures.py b/src/byteb4rb1e/utils/testing/pytest/fixtures.py new file mode 100644 index 0000000..7415a22 --- /dev/null +++ b/src/byteb4rb1e/utils/testing/pytest/fixtures.py @@ -0,0 +1,14 @@ +import os +from pathlib import Path +from typing import Tuple + +import pytest + + +@pytest.fixture +def current_test() -> Tuple[Path, str]: + """ + """ + suite_path, case_name = os.getenv('PYTEST_CURRENT_TEST').split('::', 1) + case_name = case_name.split(' ', 1)[0] + return Path(suite_path).resolve(), case_name diff --git a/tests/integration/byteb4rb1e/utils/testing/pytest/test_fixtures.py b/tests/integration/byteb4rb1e/utils/testing/pytest/test_fixtures.py new file mode 100644 index 0000000..56302e5 --- /dev/null +++ b/tests/integration/byteb4rb1e/utils/testing/pytest/test_fixtures.py @@ -0,0 +1,16 @@ +from pathlib import Path + +import pytest + +pytestmark = pytest.mark.pytest + +from byteb4rb1e.utils.testing.pytest.fixtures import current_test + + +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" diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py new file mode 100644 index 0000000..7c7aa51 --- /dev/null +++ b/tests/integration/conftest.py @@ -0,0 +1,5 @@ +def pytest_configure(config): + # register an additional marker + config.addinivalue_line( + "markers", "pytest: test pytest integration" + ) diff --git a/tox.ini b/tox.ini index efb3353..0f03dd8 100644 --- a/tox.ini +++ b/tox.ini @@ -2,7 +2,8 @@ requires = tox>=4.19 env_list = - py3{8-12}-{unit} + unit-py3{9-13} + integration-py3{9-13}-pytest8 lint format @@ -34,7 +35,7 @@ deps = commands = black --check src tests -[testenv:py3{9-13}-unit] +[testenv:unit-py3{9-13}] description = run type check on code base labels = unit deps = @@ -42,3 +43,12 @@ 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 From 03561be791a2ac8a8b5ac3053d6f933506647f8b Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Fri, 20 Jun 2025 21:48:21 +0200 Subject: [PATCH 34/74] todo(10): done --- TODO | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO b/TODO index 0b3b40c..81b72b8 100644 --- a/TODO +++ b/TODO @@ -156,7 +156,7 @@ Description: license specification is no longer a trove classifier in ID: 10 Type: feature Title: pytest current test context fixtures -Status: in-progress +Status: done Priority: high Created: 2025-06-20 Description: add fixtures for doing things in relation to the active testing From 1ea3b3a24dc757350a07123215169f14fcf8003b Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Fri, 20 Jun 2025 20:54:32 +0200 Subject: [PATCH 35/74] feat(urllib): init PkgHandler --- src/byteb4rb1e/utils/urllib/__init__.py | 0 src/byteb4rb1e/utils/urllib/request.py | 36 +++++++++++++++++++ .../byteb4rb1e/utils/urllib/test_request.py | 9 +++++ 3 files changed, 45 insertions(+) create mode 100644 src/byteb4rb1e/utils/urllib/__init__.py create mode 100644 src/byteb4rb1e/utils/urllib/request.py create mode 100644 tests/unit/byteb4rb1e/utils/urllib/test_request.py diff --git a/src/byteb4rb1e/utils/urllib/__init__.py b/src/byteb4rb1e/utils/urllib/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/byteb4rb1e/utils/urllib/request.py b/src/byteb4rb1e/utils/urllib/request.py new file mode 100644 index 0000000..28e8e8e --- /dev/null +++ b/src/byteb4rb1e/utils/urllib/request.py @@ -0,0 +1,36 @@ +import importlib.resources +from urllib.request import URLError +import urllib.request + + +class PkgHandler(urllib.request.BaseHandler): + """ + """ + def pkg_open(self, req): + pkg_files = importlib.resources.files(req.host) + + raise Exception(sorted(pkg_files.glob('**/*'))) + + try: + fh = list( + pkg_files.glob(req.selector.lstrip('//')) + )[0].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, _ = mimetypes.guess_type(url) + + headers = email.message_from_string( + 'Content-Type: %s\nContent-Length: %d\n' % + (mtype or 'text/plain', size) + ) + + if not mtype or mtype.starts_with('text/'): + fh.close() + fh = importlib.resources.files(req.host).glob(req.selector)[0].open('r') + + return urllib.request.addinfourl(fh, header) diff --git a/tests/unit/byteb4rb1e/utils/urllib/test_request.py b/tests/unit/byteb4rb1e/utils/urllib/test_request.py new file mode 100644 index 0000000..28548ef --- /dev/null +++ b/tests/unit/byteb4rb1e/utils/urllib/test_request.py @@ -0,0 +1,9 @@ +from byteb4rb1e.utils.urllib.request import PkgHandler + +class TestPkgHandler: + """ + """ + def test_default(self): + """ + """ + pass From 43cdf21d4bb2fa7ff7e54abe78c74bc126753a43 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Fri, 20 Jun 2025 23:16:16 +0200 Subject: [PATCH 36/74] feat(testing.pytest): add subprocess decorator --- .../utils/testing/pytest/__init__.py | 14 ++++++ .../utils/testing/pytest/decorators.py | 47 +++++++++++++++++++ .../utils/testing/pytest/fixtures.py | 6 +-- .../byteb4rb1e/utils/testing/pytest/test_.py | 33 +++++++++++++ .../utils/testing/pytest/test_decorators.py | 21 +++++++++ .../byteb4rb1e/utils/urllib/test_request.py | 4 ++ 6 files changed, 122 insertions(+), 3 deletions(-) create mode 100644 src/byteb4rb1e/utils/testing/pytest/__init__.py create mode 100644 src/byteb4rb1e/utils/testing/pytest/decorators.py create mode 100644 tests/integration/byteb4rb1e/utils/testing/pytest/test_.py create mode 100644 tests/integration/byteb4rb1e/utils/testing/pytest/test_decorators.py diff --git a/src/byteb4rb1e/utils/testing/pytest/__init__.py b/src/byteb4rb1e/utils/testing/pytest/__init__.py new file mode 100644 index 0000000..87e7c10 --- /dev/null +++ b/src/byteb4rb1e/utils/testing/pytest/__init__.py @@ -0,0 +1,14 @@ +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/utils/testing/pytest/decorators.py b/src/byteb4rb1e/utils/testing/pytest/decorators.py new file mode 100644 index 0000000..bf1066b --- /dev/null +++ b/src/byteb4rb1e/utils/testing/pytest/decorators.py @@ -0,0 +1,47 @@ +from functools import wraps +from pathlib import Path +import os +import subprocess +import sys + +from byteb4rb1e.utils.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/utils/testing/pytest/fixtures.py b/src/byteb4rb1e/utils/testing/pytest/fixtures.py index 7415a22..dc87091 100644 --- a/src/byteb4rb1e/utils/testing/pytest/fixtures.py +++ b/src/byteb4rb1e/utils/testing/pytest/fixtures.py @@ -4,11 +4,11 @@ from typing import Tuple import pytest +from byteb4rb1e.utils.testing.pytest import get_current_test + @pytest.fixture def current_test() -> Tuple[Path, str]: """ """ - suite_path, case_name = os.getenv('PYTEST_CURRENT_TEST').split('::', 1) - case_name = case_name.split(' ', 1)[0] - return Path(suite_path).resolve(), case_name + return get_current_test() diff --git a/tests/integration/byteb4rb1e/utils/testing/pytest/test_.py b/tests/integration/byteb4rb1e/utils/testing/pytest/test_.py new file mode 100644 index 0000000..57a0410 --- /dev/null +++ b/tests/integration/byteb4rb1e/utils/testing/pytest/test_.py @@ -0,0 +1,33 @@ +import os +from pathlib import Path + +import pytest + +pytestmark = pytest.mark.pytest + +from byteb4rb1e.utils.testing.pytest import get_current_test +from byteb4rb1e.utils.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/utils/testing/pytest/test_decorators.py b/tests/integration/byteb4rb1e/utils/testing/pytest/test_decorators.py new file mode 100644 index 0000000..7dd20fe --- /dev/null +++ b/tests/integration/byteb4rb1e/utils/testing/pytest/test_decorators.py @@ -0,0 +1,21 @@ +from pathlib import Path + +import pytest + +pytestmark = pytest.mark.pytest + +from byteb4rb1e.utils.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/unit/byteb4rb1e/utils/urllib/test_request.py b/tests/unit/byteb4rb1e/utils/urllib/test_request.py index 28548ef..74cf40d 100644 --- a/tests/unit/byteb4rb1e/utils/urllib/test_request.py +++ b/tests/unit/byteb4rb1e/utils/urllib/test_request.py @@ -1,5 +1,8 @@ +import pytest + from byteb4rb1e.utils.urllib.request import PkgHandler + class TestPkgHandler: """ """ @@ -7,3 +10,4 @@ class TestPkgHandler: """ """ pass + From 24806959bbb4cca59240ffa4391def21bced7bf0 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Sat, 21 Jun 2025 00:32:07 +0200 Subject: [PATCH 37/74] feat(testing.pytest): add pkg mock fixture --- .../utils/testing/pytest/fixtures.py | 28 ++++++++++++++++++- .../utils/testing/pytest/test_fixtures.py | 19 ++++++++++++- 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/src/byteb4rb1e/utils/testing/pytest/fixtures.py b/src/byteb4rb1e/utils/testing/pytest/fixtures.py index dc87091..3362010 100644 --- a/src/byteb4rb1e/utils/testing/pytest/fixtures.py +++ b/src/byteb4rb1e/utils/testing/pytest/fixtures.py @@ -1,6 +1,7 @@ import os from pathlib import Path -from typing import Tuple +import sys +from typing import Dict, Tuple, Union import pytest @@ -12,3 +13,28 @@ def current_test() -> Tuple[Path, str]: """ """ return get_current_test() + + +@pytest.fixture +def mock_pkg(tmp_path): + def _create(name: str, files: Dict[str, Union[str, bytes]]): + pkg_path = tmp_path / name.replace('.', os.path.sep) + pkg_path.mkdir(parents=True) + (pkg_path / "__init__.py").touch() + + for fname, content in files.items(): + fpath = (pkg_path / fname) + fpath.parent.mkdir(parents=True, exist_ok=True) + if isinstance(content, str): + fpath.write_text(content) + else: + fpath.write_bytes(content) + + sys.path.insert(0, str(tmp_path)) + return name, pkg_path + + yield _create + + # cleanup sys.path after test + if str(tmp_path) in sys.path: + sys.path.remove(str(tmp_path)) diff --git a/tests/integration/byteb4rb1e/utils/testing/pytest/test_fixtures.py b/tests/integration/byteb4rb1e/utils/testing/pytest/test_fixtures.py index 56302e5..c6b8e1f 100644 --- a/tests/integration/byteb4rb1e/utils/testing/pytest/test_fixtures.py +++ b/tests/integration/byteb4rb1e/utils/testing/pytest/test_fixtures.py @@ -1,10 +1,12 @@ from pathlib import Path +import importlib.resources import pytest pytestmark = pytest.mark.pytest -from byteb4rb1e.utils.testing.pytest.fixtures import current_test +from byteb4rb1e.utils.testing.pytest.decorators import run_in_subprocess_once +from byteb4rb1e.utils.testing.pytest.fixtures import current_test, mock_pkg def test_current_test(current_test): @@ -14,3 +16,18 @@ def test_current_test(current_test): assert str(Path(__file__)) == str(suite_path) assert case_name == "test_current_test" + + +@run_in_subprocess_once() +def test_mock_pkg(mock_pkg): + """ + """ + dummy_data = 'Hello' + + mock_pkg('foobarpkg', { + 'data.txt': dummy_data + }) + + result = next(importlib.resources.files('foobarpkg').glob('data.txt')).read_text() + + assert result == dummy_data From 59713aefb894fe24e81deba795b27d520889a37b Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Sat, 21 Jun 2025 00:32:43 +0200 Subject: [PATCH 38/74] feat(urllib.request): add importlib resource handler --- src/byteb4rb1e/utils/urllib/request.py | 20 ++--- .../byteb4rb1e/utils/urllib/test_request.py | 81 ++++++++++++++++++- 2 files changed, 90 insertions(+), 11 deletions(-) diff --git a/src/byteb4rb1e/utils/urllib/request.py b/src/byteb4rb1e/utils/urllib/request.py index 28e8e8e..3f9ee20 100644 --- a/src/byteb4rb1e/utils/urllib/request.py +++ b/src/byteb4rb1e/utils/urllib/request.py @@ -1,4 +1,6 @@ +import email import importlib.resources +import mimetypes from urllib.request import URLError import urllib.request @@ -6,15 +8,13 @@ import urllib.request class PkgHandler(urllib.request.BaseHandler): """ """ - def pkg_open(self, req): + def pkg_open(self, req) -> urllib.request.addinfourl: pkg_files = importlib.resources.files(req.host) - raise Exception(sorted(pkg_files.glob('**/*'))) - try: - fh = list( + fh = next( pkg_files.glob(req.selector.lstrip('//')) - )[0].open('rb') + ).open('rb') except Exception as e: raise URLError(f'{e.__class__.__name__}: {e}') from e @@ -22,15 +22,17 @@ class PkgHandler(urllib.request.BaseHandler): size = fh.tell(); fh.seek(0); - mtype, _ = mimetypes.guess_type(url) + mtype, _ = mimetypes.guess_type(req.selector) headers = email.message_from_string( 'Content-Type: %s\nContent-Length: %d\n' % (mtype or 'text/plain', size) ) - if not mtype or mtype.starts_with('text/'): + if not mtype or mtype.startswith('text/'): fh.close() - fh = importlib.resources.files(req.host).glob(req.selector)[0].open('r') + fh = next( + pkg_files.glob(req.selector.lstrip('//')) + ).open('r') - return urllib.request.addinfourl(fh, header) + return urllib.request.addinfourl(fh, headers, None) diff --git a/tests/unit/byteb4rb1e/utils/urllib/test_request.py b/tests/unit/byteb4rb1e/utils/urllib/test_request.py index 74cf40d..5fdf7c0 100644 --- a/tests/unit/byteb4rb1e/utils/urllib/test_request.py +++ b/tests/unit/byteb4rb1e/utils/urllib/test_request.py @@ -1,13 +1,90 @@ +import os.path +import sys +import urllib.request + import pytest +from byteb4rb1e.utils.testing.pytest.decorators import run_in_subprocess_once +from byteb4rb1e.utils.testing.pytest.fixtures import mock_pkg from byteb4rb1e.utils.urllib.request import PkgHandler class TestPkgHandler: """ """ - def test_default(self): + @run_in_subprocess_once() + def test_text(self, mock_pkg): """ """ - pass + _opener: urllib.request.OpenerDirector = urllib.request.build_opener( + PkgHandler() + ) + dummy_data = 'Hello' + + mock_pkg('foobarpkg', { + 'data.txt': 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_pkg): + """ + """ + _opener: urllib.request.OpenerDirector = urllib.request.build_opener( + PkgHandler() + ) + + dummy_data = b'foobar123' + + mock_pkg('foobarpkg', { + 'data.bin': 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_pkg): + """ + """ + _opener: urllib.request.OpenerDirector = urllib.request.build_opener( + PkgHandler() + ) + + dummy_data = 'foobar123' + + mock_pkg('foobarpkg', { + 'foo/bar/data.txt': 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_pkg): + """ + """ + _opener: urllib.request.OpenerDirector = urllib.request.build_opener( + PkgHandler() + ) + + dummy_data = 'foobar123' + + mock_pkg('foo.bar.pkg', { + 'dummy/data.txt': dummy_data + }) + + result = _opener.open('pkg://foo.bar.pkg/dummy/data.txt').readline() + + assert result == dummy_data From 3795ff3e38099e2367828e0e5232b98dd6ade48c Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Sat, 21 Jun 2025 00:38:20 +0200 Subject: [PATCH 39/74] chore: add integration test to default tests --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 0a1ec21..5cf7aae 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ configure: configure.ac .venv/bin/python3 -m pip install --upgrade pip .venv/bin/pip install -r requirements-dev.txt -test-reports: test-reports/unit test-reports/static +test-reports: test-reports/unit test-reports/static test-reports/integration test-reports/unit: python3 -m pipenv run -v test-unit From a4fa0839809357573284f2a5e169e909729a4e84 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Sat, 21 Jun 2025 00:39:13 +0200 Subject: [PATCH 40/74] todo(6): done --- TODO | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO b/TODO index 81b72b8..2da03d6 100644 --- a/TODO +++ b/TODO @@ -113,7 +113,7 @@ Description: Implement my custom algorithm for doing rolling hash string search ID: 6 Type: feature Title: implement importlib.resources handler for urllib -Status: in-progress +Status: done Priority: high Created: 2025-06-20 Description: A handler that can be registered with an urllib.request From 0eee6c5771495d7e84946f0830c8496464c5c5ed Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Sat, 21 Jun 2025 01:33:26 +0200 Subject: [PATCH 41/74] todo(11): open --- TODO | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/TODO b/TODO index 2da03d6..8f9d762 100644 --- a/TODO +++ b/TODO @@ -163,3 +163,14 @@ 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: open +Priority: high +Created: 2025-06-20 +Description: to shorten the namespace and also indicate that testing utilities + are different from regular utilities + +--- From 55ec6323bbf33ac0b20c67e5eb713cfed08262d5 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Sat, 21 Jun 2025 01:34:30 +0200 Subject: [PATCH 42/74] todo(11): in-progress --- TODO | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO b/TODO index 8f9d762..30d6506 100644 --- a/TODO +++ b/TODO @@ -167,7 +167,7 @@ Description: add fixtures for doing things in relation to the active testing ID: 11 Type: bugfix Title: move testing utils out of utils -Status: open +Status: in-progres Priority: high Created: 2025-06-20 Description: to shorten the namespace and also indicate that testing utilities From 9abfabde004a7271164c53c9f09336d1d7246fd3 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Sat, 21 Jun 2025 01:41:47 +0200 Subject: [PATCH 43/74] chore: move testing utils out of utils --- src/byteb4rb1e/{utils => }/testing/pytest/__init__.py | 0 src/byteb4rb1e/{utils => }/testing/pytest/decorators.py | 2 +- src/byteb4rb1e/{utils => }/testing/pytest/fixtures.py | 2 +- .../byteb4rb1e/{utils => }/testing/pytest/test_.py | 4 ++-- .../byteb4rb1e/{utils => }/testing/pytest/test_decorators.py | 2 +- .../byteb4rb1e/{utils => }/testing/pytest/test_fixtures.py | 4 ++-- tests/unit/byteb4rb1e/utils/urllib/test_request.py | 4 ++-- 7 files changed, 9 insertions(+), 9 deletions(-) rename src/byteb4rb1e/{utils => }/testing/pytest/__init__.py (100%) rename src/byteb4rb1e/{utils => }/testing/pytest/decorators.py (95%) rename src/byteb4rb1e/{utils => }/testing/pytest/fixtures.py (93%) rename tests/integration/byteb4rb1e/{utils => }/testing/pytest/test_.py (80%) rename tests/integration/byteb4rb1e/{utils => }/testing/pytest/test_decorators.py (85%) rename tests/integration/byteb4rb1e/{utils => }/testing/pytest/test_fixtures.py (78%) diff --git a/src/byteb4rb1e/utils/testing/pytest/__init__.py b/src/byteb4rb1e/testing/pytest/__init__.py similarity index 100% rename from src/byteb4rb1e/utils/testing/pytest/__init__.py rename to src/byteb4rb1e/testing/pytest/__init__.py diff --git a/src/byteb4rb1e/utils/testing/pytest/decorators.py b/src/byteb4rb1e/testing/pytest/decorators.py similarity index 95% rename from src/byteb4rb1e/utils/testing/pytest/decorators.py rename to src/byteb4rb1e/testing/pytest/decorators.py index bf1066b..a7d8161 100644 --- a/src/byteb4rb1e/utils/testing/pytest/decorators.py +++ b/src/byteb4rb1e/testing/pytest/decorators.py @@ -4,7 +4,7 @@ import os import subprocess import sys -from byteb4rb1e.utils.testing.pytest import get_current_test +from byteb4rb1e.testing.pytest import get_current_test def run_in_subprocess_once(): diff --git a/src/byteb4rb1e/utils/testing/pytest/fixtures.py b/src/byteb4rb1e/testing/pytest/fixtures.py similarity index 93% rename from src/byteb4rb1e/utils/testing/pytest/fixtures.py rename to src/byteb4rb1e/testing/pytest/fixtures.py index 3362010..b9ca0cb 100644 --- a/src/byteb4rb1e/utils/testing/pytest/fixtures.py +++ b/src/byteb4rb1e/testing/pytest/fixtures.py @@ -5,7 +5,7 @@ from typing import Dict, Tuple, Union import pytest -from byteb4rb1e.utils.testing.pytest import get_current_test +from byteb4rb1e.testing.pytest import get_current_test @pytest.fixture diff --git a/tests/integration/byteb4rb1e/utils/testing/pytest/test_.py b/tests/integration/byteb4rb1e/testing/pytest/test_.py similarity index 80% rename from tests/integration/byteb4rb1e/utils/testing/pytest/test_.py rename to tests/integration/byteb4rb1e/testing/pytest/test_.py index 57a0410..8141015 100644 --- a/tests/integration/byteb4rb1e/utils/testing/pytest/test_.py +++ b/tests/integration/byteb4rb1e/testing/pytest/test_.py @@ -5,8 +5,8 @@ import pytest pytestmark = pytest.mark.pytest -from byteb4rb1e.utils.testing.pytest import get_current_test -from byteb4rb1e.utils.testing.pytest.decorators import run_in_subprocess_once +from byteb4rb1e.testing.pytest import get_current_test +from byteb4rb1e.testing.pytest.decorators import run_in_subprocess_once class Test_get_current_test: diff --git a/tests/integration/byteb4rb1e/utils/testing/pytest/test_decorators.py b/tests/integration/byteb4rb1e/testing/pytest/test_decorators.py similarity index 85% rename from tests/integration/byteb4rb1e/utils/testing/pytest/test_decorators.py rename to tests/integration/byteb4rb1e/testing/pytest/test_decorators.py index 7dd20fe..c906bef 100644 --- a/tests/integration/byteb4rb1e/utils/testing/pytest/test_decorators.py +++ b/tests/integration/byteb4rb1e/testing/pytest/test_decorators.py @@ -4,7 +4,7 @@ import pytest pytestmark = pytest.mark.pytest -from byteb4rb1e.utils.testing.pytest.decorators import run_in_subprocess_once +from byteb4rb1e.testing.pytest.decorators import run_in_subprocess_once @run_in_subprocess_once() diff --git a/tests/integration/byteb4rb1e/utils/testing/pytest/test_fixtures.py b/tests/integration/byteb4rb1e/testing/pytest/test_fixtures.py similarity index 78% rename from tests/integration/byteb4rb1e/utils/testing/pytest/test_fixtures.py rename to tests/integration/byteb4rb1e/testing/pytest/test_fixtures.py index c6b8e1f..0e0c5d9 100644 --- a/tests/integration/byteb4rb1e/utils/testing/pytest/test_fixtures.py +++ b/tests/integration/byteb4rb1e/testing/pytest/test_fixtures.py @@ -5,8 +5,8 @@ import pytest pytestmark = pytest.mark.pytest -from byteb4rb1e.utils.testing.pytest.decorators import run_in_subprocess_once -from byteb4rb1e.utils.testing.pytest.fixtures import current_test, mock_pkg +from byteb4rb1e.testing.pytest.decorators import run_in_subprocess_once +from byteb4rb1e.testing.pytest.fixtures import current_test, mock_pkg def test_current_test(current_test): diff --git a/tests/unit/byteb4rb1e/utils/urllib/test_request.py b/tests/unit/byteb4rb1e/utils/urllib/test_request.py index 5fdf7c0..787fb29 100644 --- a/tests/unit/byteb4rb1e/utils/urllib/test_request.py +++ b/tests/unit/byteb4rb1e/utils/urllib/test_request.py @@ -4,8 +4,8 @@ import urllib.request import pytest -from byteb4rb1e.utils.testing.pytest.decorators import run_in_subprocess_once -from byteb4rb1e.utils.testing.pytest.fixtures import mock_pkg +from byteb4rb1e.testing.pytest.decorators import run_in_subprocess_once +from byteb4rb1e.testing.pytest.fixtures import mock_pkg from byteb4rb1e.utils.urllib.request import PkgHandler From 53dc780a04d5f1dee47e5a040e69a36f63beff30 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Sat, 21 Jun 2025 01:42:16 +0200 Subject: [PATCH 44/74] todo(11): done --- TODO | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO b/TODO index 30d6506..adbeb8c 100644 --- a/TODO +++ b/TODO @@ -167,7 +167,7 @@ Description: add fixtures for doing things in relation to the active testing ID: 11 Type: bugfix Title: move testing utils out of utils -Status: in-progres +Status: done Priority: high Created: 2025-06-20 Description: to shorten the namespace and also indicate that testing utilities From 6b6fb02f41c03dad1d39e604b8f2d70fc8e2101c Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Sat, 21 Jun 2025 18:13:59 +0200 Subject: [PATCH 45/74] todo(12): open --- TODO | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/TODO b/TODO index adbeb8c..94ae30c 100644 --- a/TODO +++ b/TODO @@ -174,3 +174,14 @@ 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: open +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. + +--- From e6bf6579194753f0823f1892cd92efa2f945a49b Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Sat, 21 Jun 2025 18:14:22 +0200 Subject: [PATCH 46/74] todo(12): in-progress --- TODO | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO b/TODO index 94ae30c..440cd59 100644 --- a/TODO +++ b/TODO @@ -178,7 +178,7 @@ Description: to shorten the namespace and also indicate that testing utilities ID: 12 Type: feature Title: simplify testing.fixtures.mock_pkg -Status: open +Status: in-progress Priority: high Created: 2025-06-21 Description: Only bootstrap a package mock with the minimum requirements for a From aa2540cf3f9a141e045e2e1c3b56ff7aa4a39673 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Sat, 21 Jun 2025 18:14:52 +0200 Subject: [PATCH 47/74] refactor(testing.pytest): change mock_pkg interface being more explicit about what the fixture provides as an output, instead of solely describing the site effects. Also the consumer is now responsible for the module directory layout. --- src/byteb4rb1e/testing/pytest/fixtures.py | 32 +++++++++++-------- .../testing/pytest/test_fixtures.py | 15 ++++++--- 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/src/byteb4rb1e/testing/pytest/fixtures.py b/src/byteb4rb1e/testing/pytest/fixtures.py index b9ca0cb..7c93041 100644 --- a/src/byteb4rb1e/testing/pytest/fixtures.py +++ b/src/byteb4rb1e/testing/pytest/fixtures.py @@ -7,6 +7,8 @@ import pytest from byteb4rb1e.testing.pytest import get_current_test +_SITE_PACKAGE_COUNTER: Dict[str, int] = {} + @pytest.fixture def current_test() -> Tuple[Path, str]: @@ -16,25 +18,27 @@ def current_test() -> Tuple[Path, str]: @pytest.fixture -def mock_pkg(tmp_path): - def _create(name: str, files: Dict[str, Union[str, bytes]]): - pkg_path = tmp_path / name.replace('.', os.path.sep) +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() - for fname, content in files.items(): - fpath = (pkg_path / fname) - fpath.parent.mkdir(parents=True, exist_ok=True) - if isinstance(content, str): - fpath.write_text(content) - else: - fpath.write_bytes(content) + sys.path.insert(0, str(sys_path)) - sys.path.insert(0, str(tmp_path)) - return name, pkg_path + return pkg_path yield _create # cleanup sys.path after test - if str(tmp_path) in sys.path: - sys.path.remove(str(tmp_path)) + if str(sys_path) in sys.path: + sys.path.remove(str(sys_path)) diff --git a/tests/integration/byteb4rb1e/testing/pytest/test_fixtures.py b/tests/integration/byteb4rb1e/testing/pytest/test_fixtures.py index 0e0c5d9..a08851d 100644 --- a/tests/integration/byteb4rb1e/testing/pytest/test_fixtures.py +++ b/tests/integration/byteb4rb1e/testing/pytest/test_fixtures.py @@ -6,7 +6,10 @@ 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_pkg +from byteb4rb1e.testing.pytest.fixtures import ( + current_test, + mock_system_site_package_dir +) def test_current_test(current_test): @@ -19,14 +22,16 @@ def test_current_test(current_test): @run_in_subprocess_once() -def test_mock_pkg(mock_pkg): +def test_mock_system_site_package_dir(mock_system_site_package_dir): """ """ dummy_data = 'Hello' - mock_pkg('foobarpkg', { - 'data.txt': dummy_data - }) + 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() From 16c12b55769ffc0ac66fbf016b63406c20e0b4ea Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Sat, 21 Jun 2025 18:16:18 +0200 Subject: [PATCH 48/74] todo(12): done --- TODO | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO b/TODO index 440cd59..145c66f 100644 --- a/TODO +++ b/TODO @@ -178,7 +178,7 @@ Description: to shorten the namespace and also indicate that testing utilities ID: 12 Type: feature Title: simplify testing.fixtures.mock_pkg -Status: in-progress +Status: done Priority: high Created: 2025-06-21 Description: Only bootstrap a package mock with the minimum requirements for a From 81dc18c506d5890cbc34552bb6337d4cf08c1c71 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Sat, 21 Jun 2025 20:22:19 +0200 Subject: [PATCH 49/74] todo(13): open --- TODO | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/TODO b/TODO index 145c66f..794f881 100644 --- a/TODO +++ b/TODO @@ -185,3 +185,14 @@ 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: open +Priority: high +Created: 2025-06-21 +Description: change of issue 12 wasn't properly reflected in urllib PkgHandler + unit tests + +--- From 3b5097a99c65b7bb0b080045e90ae12c60af996a Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Sat, 21 Jun 2025 20:23:41 +0200 Subject: [PATCH 50/74] todo(14): open --- TODO | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/TODO b/TODO index 794f881..fe7ff1b 100644 --- a/TODO +++ b/TODO @@ -196,3 +196,14 @@ 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: open +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. + +--- From 69d498a20326b597ae8de50f06d1c3a4e3d00e75 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Sat, 21 Jun 2025 20:24:51 +0200 Subject: [PATCH 51/74] todo(13): in-progress --- TODO | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO b/TODO index fe7ff1b..25a59e4 100644 --- a/TODO +++ b/TODO @@ -189,7 +189,7 @@ Description: Only bootstrap a package mock with the minimum requirements for a ID: 13 Type: bugfix Title: fix unit tests for urllib PkgHandler -Status: open +Status: in-progress Priority: high Created: 2025-06-21 Description: change of issue 12 wasn't properly reflected in urllib PkgHandler From f9897a9aa54083c8416de7b959338c836f80b5ad Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Sat, 21 Jun 2025 20:23:59 +0200 Subject: [PATCH 52/74] fix(tests): adapt name of new package mock fixture --- .../byteb4rb1e/utils/urllib/test_request.py | 37 ++++++++++--------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/tests/unit/byteb4rb1e/utils/urllib/test_request.py b/tests/unit/byteb4rb1e/utils/urllib/test_request.py index 787fb29..468751d 100644 --- a/tests/unit/byteb4rb1e/utils/urllib/test_request.py +++ b/tests/unit/byteb4rb1e/utils/urllib/test_request.py @@ -5,7 +5,7 @@ import urllib.request import pytest from byteb4rb1e.testing.pytest.decorators import run_in_subprocess_once -from byteb4rb1e.testing.pytest.fixtures import mock_pkg +from byteb4rb1e.testing.pytest.fixtures import mock_system_site_package_dir from byteb4rb1e.utils.urllib.request import PkgHandler @@ -13,7 +13,7 @@ class TestPkgHandler: """ """ @run_in_subprocess_once() - def test_text(self, mock_pkg): + def test_text(self, mock_system_site_package_dir): """ """ _opener: urllib.request.OpenerDirector = urllib.request.build_opener( @@ -22,9 +22,8 @@ class TestPkgHandler: dummy_data = 'Hello' - mock_pkg('foobarpkg', { - 'data.txt': dummy_data - }) + pkg_dir = mock_system_site_package_dir('foobarpkg') + (pkg_dir / 'data.txt').write_text(dummy_data) result = _opener.open('pkg://foobarpkg/data.txt').readline() @@ -33,7 +32,7 @@ class TestPkgHandler: @run_in_subprocess_once() - def test_bytes(self, mock_pkg): + def test_bytes(self, mock_system_site_package_dir): """ """ _opener: urllib.request.OpenerDirector = urllib.request.build_opener( @@ -42,9 +41,8 @@ class TestPkgHandler: dummy_data = b'foobar123' - mock_pkg('foobarpkg', { - 'data.bin': dummy_data - }) + pkg_dir = mock_system_site_package_dir('foobarpkg') + (pkg_dir / 'data.bin').write_bytes(dummy_data) result = _opener.open('pkg://foobarpkg/data.bin').readline() @@ -53,7 +51,7 @@ class TestPkgHandler: @run_in_subprocess_once() - def test_subdir(self, mock_pkg): + def test_subdir(self, mock_system_site_package_dir): """ """ _opener: urllib.request.OpenerDirector = urllib.request.build_opener( @@ -62,9 +60,12 @@ class TestPkgHandler: dummy_data = 'foobar123' - mock_pkg('foobarpkg', { - 'foo/bar/data.txt': dummy_data - }) + 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() @@ -72,7 +73,7 @@ class TestPkgHandler: @run_in_subprocess_once() - def test_nested_module(self, mock_pkg): + def test_nested_module(self, mock_system_site_package_dir): """ """ _opener: urllib.request.OpenerDirector = urllib.request.build_opener( @@ -81,9 +82,11 @@ class TestPkgHandler: dummy_data = 'foobar123' - mock_pkg('foo.bar.pkg', { - 'dummy/data.txt': dummy_data - }) + 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() From 5beb699ddaaffaa2bc5e63cd8fca417e2a2e2f06 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Sat, 21 Jun 2025 20:25:28 +0200 Subject: [PATCH 53/74] todo(13): done --- TODO | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO b/TODO index 25a59e4..a987c01 100644 --- a/TODO +++ b/TODO @@ -189,7 +189,7 @@ Description: Only bootstrap a package mock with the minimum requirements for a ID: 13 Type: bugfix Title: fix unit tests for urllib PkgHandler -Status: in-progress +Status: done Priority: high Created: 2025-06-21 Description: change of issue 12 wasn't properly reflected in urllib PkgHandler From 981985e51add0dba01dcc44083cbd7f53e9f7821 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Sat, 21 Jun 2025 20:26:15 +0200 Subject: [PATCH 54/74] todo(14): in-progress --- TODO | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO b/TODO index a987c01..20427a8 100644 --- a/TODO +++ b/TODO @@ -200,7 +200,7 @@ Description: change of issue 12 wasn't properly reflected in urllib PkgHandler ID: 14 Type: feature Title: add compression support for urllib PkgHandler -Status: open +Status: in-progress Priority: high Created: 2025-06-21 Description: with a proper content-type of the PkgHandler addinfourl object, a From 2d9fe8b625cda630a302e264c585159bbe1805d9 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Sat, 21 Jun 2025 20:26:36 +0200 Subject: [PATCH 55/74] feat(urllib.request): add compression support for PkgHandler --- src/byteb4rb1e/utils/urllib/request.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/byteb4rb1e/utils/urllib/request.py b/src/byteb4rb1e/utils/urllib/request.py index 3f9ee20..2408d94 100644 --- a/src/byteb4rb1e/utils/urllib/request.py +++ b/src/byteb4rb1e/utils/urllib/request.py @@ -22,7 +22,10 @@ class PkgHandler(urllib.request.BaseHandler): size = fh.tell(); fh.seek(0); - mtype, _ = mimetypes.guess_type(req.selector) + 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' % From 7e18e4795df73db2c50f2e2cd7457d9c9ec25305 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Sat, 21 Jun 2025 20:27:09 +0200 Subject: [PATCH 56/74] todo(14): done --- TODO | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO b/TODO index 20427a8..9b0c012 100644 --- a/TODO +++ b/TODO @@ -200,7 +200,7 @@ Description: change of issue 12 wasn't properly reflected in urllib PkgHandler ID: 14 Type: feature Title: add compression support for urllib PkgHandler -Status: in-progress +Status: done Priority: high Created: 2025-06-21 Description: with a proper content-type of the PkgHandler addinfourl object, a From b9e9e13630e6b7729a7ffe6b5eac38ba7d1e39a6 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Sat, 28 Jun 2025 01:39:37 +0200 Subject: [PATCH 57/74] todo(15): open --- TODO | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/TODO b/TODO index 9b0c012..6cf48ae 100644 --- a/TODO +++ b/TODO @@ -207,3 +207,15 @@ 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 + +--- From 9d09a4abaa3a0ff9e3ba01ba4cd5f3c625b26f75 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Sat, 28 Jun 2025 01:40:17 +0200 Subject: [PATCH 58/74] todo(15): in-progress --- TODO | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO b/TODO index 6cf48ae..f38eda0 100644 --- a/TODO +++ b/TODO @@ -211,7 +211,7 @@ Description: with a proper content-type of the PkgHandler addinfourl object, a ID: 15 Type: bugfix Title: modularize module containers -Status: open +Status: in-progress Priority: high Created: 2025-06-28 Description: Even though importlib can find submodules through traversing paths From 89f7420fae81caadd5cf80d82ab638a74e279092 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Sat, 28 Jun 2025 01:41:32 +0200 Subject: [PATCH 59/74] refactor: modularize submodules --- src/byteb4rb1e/testing/__init__.py | 0 src/byteb4rb1e/utils/__init__.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/byteb4rb1e/testing/__init__.py create mode 100644 src/byteb4rb1e/utils/__init__.py diff --git a/src/byteb4rb1e/testing/__init__.py b/src/byteb4rb1e/testing/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/byteb4rb1e/utils/__init__.py b/src/byteb4rb1e/utils/__init__.py new file mode 100644 index 0000000..e69de29 From 74dac5249bf1a006bf8cdc057c891a2acc87ca05 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Sat, 28 Jun 2025 01:42:13 +0200 Subject: [PATCH 60/74] todo(15): done --- TODO | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO b/TODO index f38eda0..6cf48ae 100644 --- a/TODO +++ b/TODO @@ -211,7 +211,7 @@ Description: with a proper content-type of the PkgHandler addinfourl object, a ID: 15 Type: bugfix Title: modularize module containers -Status: in-progress +Status: open Priority: high Created: 2025-06-28 Description: Even though importlib can find submodules through traversing paths From 6b29a8d525e156c77e1a370849d550c13905a48d Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Wed, 31 Dec 2025 14:22:38 +0100 Subject: [PATCH 61/74] todo(16): open --- TODO | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/TODO b/TODO index 6cf48ae..63dbc1d 100644 --- a/TODO +++ b/TODO @@ -219,3 +219,14 @@ Description: Even though importlib can find submodules through traversing paths is not supported by some modules like sphinx.ext.autosummary --- + +ID: 16 +Type: feature +Title: SQL-aware dataclass +Status: open +Priority: high +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 + +--- From b257fd3d880c3e3fb7dea7bdde935d71b0f7a73d Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Wed, 31 Dec 2025 14:24:09 +0100 Subject: [PATCH 62/74] todo(16): in-progress --- TODO | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO b/TODO index 63dbc1d..f5726f4 100644 --- a/TODO +++ b/TODO @@ -223,7 +223,7 @@ Description: Even though importlib can find submodules through traversing paths ID: 16 Type: feature Title: SQL-aware dataclass -Status: open +Status: in-progress Priority: high Created: 2025-12-31 Description: A dataclass that transparently maps onto an SQL datastore, with From 0a23243b767bac8d4cdd965ad9e24ac58fe19def Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Wed, 31 Dec 2025 14:24:38 +0100 Subject: [PATCH 63/74] todo(16): change priority project that uses it is currently on hold, hence priority is low --- TODO | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO b/TODO index f5726f4..56cf823 100644 --- a/TODO +++ b/TODO @@ -224,7 +224,7 @@ ID: 16 Type: feature Title: SQL-aware dataclass Status: in-progress -Priority: high +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 From 90567899e0fb276473ec48af0ef027662a9acff9 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Wed, 31 Dec 2025 14:27:59 +0100 Subject: [PATCH 64/74] todo(17): open --- TODO | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/TODO b/TODO index 56cf823..47e17df 100644 --- a/TODO +++ b/TODO @@ -230,3 +230,14 @@ 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: open +Priority: high +Created: 2025-12-31 +Description: Extend the built-in event-driven parser to be modeled after DOM + recursive-descent HTML parser + +--- From 22aeecd6302d440462c66136c52dbd922426bee4 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Wed, 31 Dec 2025 14:28:27 +0100 Subject: [PATCH 65/74] todo(17): in-progress --- TODO | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO b/TODO index 47e17df..e747197 100644 --- a/TODO +++ b/TODO @@ -234,7 +234,7 @@ Description: A dataclass that transparently maps onto an SQL datastore, with ID: 17 Type: feature Title: recursive-descent HTML (DOM) parser -Status: open +Status: in-progress Priority: high Created: 2025-12-31 Description: Extend the built-in event-driven parser to be modeled after DOM From cc4b567181068135899af26c239d5d973afd6c02 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Wed, 31 Dec 2025 14:40:39 +0100 Subject: [PATCH 66/74] chore: ignore tox working directory --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index dbfbc60..2351bda 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ *.swo *.swp /test-reports/ +/.tox/ From 5bf4a7eee4386822872423b09539d1517fd4967c Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Wed, 4 Mar 2026 13:11:07 +0100 Subject: [PATCH 67/74] migrate sphinxcontrib.h5p.utils --- src/byteb4rb1e/utils/argparse/__init__.py | 6 + src/byteb4rb1e/utils/argparse/command.py | 54 ++++ src/byteb4rb1e/utils/argparse/dispatcher.py | 122 ++++++++ src/byteb4rb1e/utils/http/client.py | 109 +++++++ src/byteb4rb1e/utils/saas/bitbucket.py | 78 +++++ src/byteb4rb1e/utils/saas/github.py | 65 +++++ src/byteb4rb1e/utils/vcs/__init__.py | 0 src/byteb4rb1e/utils/vcs/git.py | 308 ++++++++++++++++++++ 8 files changed, 742 insertions(+) create mode 100644 src/byteb4rb1e/utils/argparse/__init__.py create mode 100644 src/byteb4rb1e/utils/argparse/command.py create mode 100644 src/byteb4rb1e/utils/argparse/dispatcher.py create mode 100644 src/byteb4rb1e/utils/http/client.py create mode 100644 src/byteb4rb1e/utils/saas/bitbucket.py create mode 100644 src/byteb4rb1e/utils/saas/github.py create mode 100644 src/byteb4rb1e/utils/vcs/__init__.py create mode 100644 src/byteb4rb1e/utils/vcs/git.py diff --git a/src/byteb4rb1e/utils/argparse/__init__.py b/src/byteb4rb1e/utils/argparse/__init__.py new file mode 100644 index 0000000..84ae3ed --- /dev/null +++ b/src/byteb4rb1e/utils/argparse/__init__.py @@ -0,0 +1,6 @@ +"""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 new file mode 100644 index 0000000..199e4f1 --- /dev/null +++ b/src/byteb4rb1e/utils/argparse/command.py @@ -0,0 +1,54 @@ +"""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 new file mode 100644 index 0000000..0c8768b --- /dev/null +++ b/src/byteb4rb1e/utils/argparse/dispatcher.py @@ -0,0 +1,122 @@ +"""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: + break + 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 new file mode 100644 index 0000000..0962445 --- /dev/null +++ b/src/byteb4rb1e/utils/http/client.py @@ -0,0 +1,109 @@ +#!/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 new file mode 100644 index 0000000..d9b5bad --- /dev/null +++ b/src/byteb4rb1e/utils/saas/bitbucket.py @@ -0,0 +1,78 @@ +#!/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 new file mode 100644 index 0000000..d174827 --- /dev/null +++ b/src/byteb4rb1e/utils/saas/github.py @@ -0,0 +1,65 @@ +#!/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/vcs/__init__.py b/src/byteb4rb1e/utils/vcs/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/byteb4rb1e/utils/vcs/git.py b/src/byteb4rb1e/utils/vcs/git.py new file mode 100644 index 0000000..ab7e87f --- /dev/null +++ b/src/byteb4rb1e/utils/vcs/git.py @@ -0,0 +1,308 @@ +#!/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 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. + Returns False if ``.gitmodules`` does not exist. + """ + gitmodules = repo / ".gitmodules" + if not gitmodules.is_file(): + return False + try: + result = _run( + ["config", "--file", ".gitmodules", + "--get-regexp", r"submodule\..*\.path"], + cwd=repo, + ) + except GitError: + return False + for line in result.stdout.splitlines(): + parts = line.split(None, 1) + if len(parts) == 2 and parts[1] == 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) From c4fb29f6945a4030be7b61f52dbb3e8f96ed7c81 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Wed, 4 Mar 2026 18:10:18 +0100 Subject: [PATCH 68/74] feat(git): submodule and remote handling --- src/byteb4rb1e/utils/vcs/git.py | 45 ++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/src/byteb4rb1e/utils/vcs/git.py b/src/byteb4rb1e/utils/vcs/git.py index ab7e87f..cd4cd87 100644 --- a/src/byteb4rb1e/utils/vcs/git.py +++ b/src/byteb4rb1e/utils/vcs/git.py @@ -146,6 +146,18 @@ def show_ref(repo: Path) -> str: 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. @@ -260,22 +272,39 @@ 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. """ - gitmodules = repo / ".gitmodules" + 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", ".gitmodules", + ["config", "--file", str(gitmodules), "--get-regexp", r"submodule\..*\.path"], - cwd=repo, + cwd=toplevel, ) except GitError: return False for line in result.stdout.splitlines(): parts = line.split(None, 1) - if len(parts) == 2 and parts[1] == path: + if len(parts) == 2 and parts[1] == rel_path: return True return False @@ -306,3 +335,11 @@ def submodule_update(repo: Path, path: str) -> None: 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) From 4cdf357022209b57e9507f996aa21578f57a5723 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Mon, 16 Mar 2026 00:09:57 +0100 Subject: [PATCH 69/74] dirty --- src/byteb4rb1e/utils/argparse/dispatcher.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/byteb4rb1e/utils/argparse/dispatcher.py b/src/byteb4rb1e/utils/argparse/dispatcher.py index 0c8768b..b579351 100644 --- a/src/byteb4rb1e/utils/argparse/dispatcher.py +++ b/src/byteb4rb1e/utils/argparse/dispatcher.py @@ -90,7 +90,7 @@ class CLI: for dest in self._dests: val = getattr(args, dest, None) if val is None: - break + continue parts.append(val) if not parts: return None From 4cd79cc6a4252ecd66ec5111ac7a9398ad6ae319 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Mon, 16 Mar 2026 00:16:04 +0100 Subject: [PATCH 70/74] chore: reapply editable --- Pipfile | 7 +- Pipfile.lock | 597 ++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 549 insertions(+), 55 deletions(-) diff --git a/Pipfile b/Pipfile index fa10d4e..673ee77 100644 --- a/Pipfile +++ b/Pipfile @@ -7,14 +7,17 @@ name = "pypi" setuptools-scm = "~=8.2.0" build = "*" pipenv = "*" -byteb4rb1e-utils = { editable = true, path = '.'} tox = "*" +twine = "*" [requires] -python_version = "3.11" +python_version = "3" [scripts] "build" = "python3 -m build" "test-static" = "tox run -m static" "test-unit" = "tox run -m unit" "test-integration" = "tox run -m integration" + +[packages] +"byteb4rb1e.utils" = {file = ".", editable = true} diff --git a/Pipfile.lock b/Pipfile.lock index aa123f0..84ab77b 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,11 +1,11 @@ { "_meta": { "hash": { - "sha256": "cb7c8c0a12f574d2bc30ffe38e79ba18ee29424cb1fb1cdce8373f89d56f3e1c" + "sha256": "b9a6a40fe538c374ded3e0fc84bd0cbe34d236468cb184d613e59e3ccf14f0f1" }, "pipfile-spec": 6, "requires": { - "python_version": "3.11" + "python_version": "3" }, "sources": [ { @@ -15,44 +15,262 @@ } ] }, - "default": {}, + "default": { + "byteb4rb1e.utils": { + "editable": true, + "file": "." + } + }, "develop": { "build": { "hashes": [ - "sha256:1d61c0887fa860c01971625baae8bdd338e517b836a2f70dd1f7aa3a6b2fc5b5", - "sha256:b36993e92ca9375a219c99e606a122ff365a760a2d4bba0caa09bd5278b608b7" + "sha256:6a07c1b8eb6f2b311b96fcbdbce5dab5fe637ffda0fd83c9cac622e927501596", + "sha256:f1b91b925aa322be454f8330c6fb48b465da993d1e7e7e6fa35027ec49f3c936" ], "index": "pypi", - "markers": "python_version >= '3.8'", - "version": "==1.2.2.post1" - }, - "byteb4rb1e-utils": { - "editable": true, - "path": "." + "markers": "python_version >= '3.9'", + "version": "==1.4.0" }, "cachetools": { "hashes": [ - "sha256:1c7bb3cf9193deaf3508b7c5f2a79986c13ea38965c5adcff1f84519cf39163e", - "sha256:b4c4f404392848db3ce7aac34950d17be4d864da4b8b66911008e430bc544587" + "sha256:0cd042c24377200c1dcd225f8b7b12b0ca53cc2c961b43757e774ebe190fd990", + "sha256:46bc8ebefbe485407621d0a4264b23c080cedd913921bad7ac3ed2f26c183114" ], - "markers": "python_version >= '3.9'", - "version": "==6.1.0" + "markers": "python_version >= '3.10'", + "version": "==7.0.5" }, "certifi": { "hashes": [ - "sha256:2e0c7ce7cb5d8f8634ca55d2ba7e6ec2689a2fd6537d8dec1296a477a4910057", - "sha256:d747aa5a8b9bbbb1bb8c22bb13e22bd1f18e9796defa16bab421f7f7a317323b" + "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", + "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7" ], "markers": "python_version >= '3.7'", - "version": "==2025.6.15" + "version": "==2026.2.25" }, - "chardet": { + "cffi": { "hashes": [ - "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7", - "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970" + "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": "==5.2.0" + "version": "==3.4.6" }, "colorama": { "hashes": [ @@ -62,45 +280,221 @@ "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": { + "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" + ], + "markers": "python_version >= '3.8' and python_full_version not in '3.9.0, 3.9.1'", + "version": "==46.0.5" + }, "distlib": { "hashes": [ - "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87", - "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403" + "sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16", + "sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d" ], - "version": "==0.3.9" + "version": "==0.4.0" + }, + "docutils": { + "hashes": [ + "sha256:4db53b1fde9abecbb74d91230d32ab626d94f6badfc575d6db9194a49df29968", + "sha256:d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de" + ], + "markers": "python_version >= '3.9'", + "version": "==0.22.4" }, "filelock": { "hashes": [ - "sha256:adbc88eabb99d2fec8c9c1b229b171f18afa655400173ddc653d5d01501fb9f2", - "sha256:c401f4f8377c4464e6db25fff06205fd89bdd83b65eb0488ed1b160f780e21de" + "sha256:b64ece2b38f4ca29dd3e810287aa8c48182bbecd1ae6e9ae126c9b35f1382694", + "sha256:ca8afb0da15f229774c9ad1b455ed96e85a81373065fb10446672f64444ddf70" + ], + "markers": "python_version >= '3.10'", + "version": "==3.25.2" + }, + "id": { + "hashes": [ + "sha256:d0732d624fb46fd4e7bc4e5152f00214450953b9e772c182c1c22964def1a069", + "sha256:f5ec41ed2629a508f5d0988eda142e190c9c6da971100612c4de9ad9f9b237ca" ], "markers": "python_version >= '3.9'", - "version": "==3.18.0" + "version": "==1.6.1" + }, + "idna": { + "hashes": [ + "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", + "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902" + ], + "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:0df6a0287258f3e364072c3e40d5411b20cafa30cb28c4839d24319cecf9f808", + "sha256:bc046b2dc94f1e5532bd02402684414575cc11f565d929b6563125deb0a6e581" + ], + "markers": "python_version >= '3.9'", + "version": "==6.1.1" + }, + "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" }, "packaging": { "hashes": [ - "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", - "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f" + "sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4", + "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529" ], "markers": "python_version >= '3.8'", - "version": "==25.0" + "version": "==26.0" }, "pipenv": { "hashes": [ - "sha256:87370bedcf0ff66d226af07ca341ae94afcc08fed90d57ad9fea9ffd44ced4d3", - "sha256:f0a67aa928824e61003d52acea72a94b180800019f03d38a311966f6330bc8d1" + "sha256:06fba6b4fa542acf8f551cfedf604a08940bbe3068bd575e5163f7c2e8e51eac", + "sha256:56ca111e9b236f551030eb7422f6aa71edd9b2ccc018e100ad80ebc57eb2b270" ], "index": "pypi", - "markers": "python_version >= '3.9'", - "version": "==2025.0.3" + "markers": "python_version >= '3.10'", + "version": "==2026.1.0" }, "platformdirs": { "hashes": [ - "sha256:3d512d96e16bcb959a814c9f348431070822a6496326a4be0911c40b5a74c2bc", - "sha256:ff7059bb7eb1179e2685604f4aaf157cfd9535242bd23742eadc3c13542139b4" + "sha256:1ec356301b7dc906d83f371c8f487070e99d3ccf9e501686456394622a01a934", + "sha256:68a9a4619a666ea6439f2ff250c12a853cd1cbd5158d258bd824a7df6be2f868" ], - "markers": "python_version >= '3.9'", - "version": "==4.3.8" + "markers": "python_version >= '3.10'", + "version": "==4.9.4" }, "pluggy": { "hashes": [ @@ -110,13 +504,29 @@ "markers": "python_version >= '3.9'", "version": "==1.6.0" }, + "pycparser": { + "hashes": [ + "sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29", + "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992" + ], + "markers": "python_version >= '3.10'", + "version": "==3.0" + }, + "pygments": { + "hashes": [ + "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", + "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b" + ], + "markers": "python_version >= '3.8'", + "version": "==2.19.2" + }, "pyproject-api": { "hashes": [ - "sha256:43c9918f49daab37e302038fc1aed54a8c7a91a9fa935d00b9a485f37e0f5335", - "sha256:7d6238d92f8962773dd75b5f0c4a6a27cce092a14b623b811dba656f3b628948" + "sha256:40c6f2d82eebdc4afee61c773ed208c04c19db4c4a60d97f8d7be3ebc0bbb330", + "sha256:8757c41a79c0f4ab71b99abed52b97ecf66bd20b04fa59da43b5840bac105a09" ], - "markers": "python_version >= '3.9'", - "version": "==1.9.1" + "markers": "python_version >= '3.10'", + "version": "==1.10.0" }, "pyproject-hooks": { "hashes": [ @@ -126,13 +536,69 @@ "markers": "python_version >= '3.7'", "version": "==1.2.0" }, - "setuptools": { + "python-discovery": { "hashes": [ - "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922", - "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c" + "sha256:7acca36e818cd88e9b2ba03e045ad7e93e1713e29c6bbfba5d90202310b7baa5", + "sha256:90e795f0121bc84572e737c9aa9966311b9fde44ffb88a5953b3ec9b31c6945e" + ], + "markers": "python_version >= '3.8'", + "version": "==1.1.3" + }, + "readme-renderer": { + "hashes": [ + "sha256:2fbca89b81a08526aadf1357a8c2ae889ec05fb03f5da67f9769c9a592166151", + "sha256:8712034eabbfa6805cacf1402b4eeb2a73028f72d1166d6f5cb7f9c047c5d1e1" ], "markers": "python_version >= '3.9'", - "version": "==80.9.0" + "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" + }, + "rfc3986": { + "hashes": [ + "sha256:50b1502b60e289cb37883f3dfd34532b8873c7de9f49bb546641ce9cbd256ebd", + "sha256:97aacf9dbd4bfd829baad6e6309fa6573aaf1be3f6fa735c8ab05e46cecb261c" + ], + "markers": "python_version >= '3.7'", + "version": "==2.0.0" + }, + "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" + }, + "setuptools": { + "hashes": [ + "sha256:7d872682c5d01cfde07da7bccc7b65469d3dca203318515ada1de5eda35efbf9", + "sha256:a59e362652f08dcd477c78bb6e7bd9d80a7995bc73ce773050228a348ce2e5bb" + ], + "markers": "python_version >= '3.9'", + "version": "==82.0.1" }, "setuptools-scm": { "hashes": [ @@ -143,22 +609,47 @@ "markers": "python_version >= '3.8'", "version": "==8.2.0" }, + "tomli-w": { + "hashes": [ + "sha256:188306098d013b691fcadc011abd66727d3c414c571bb01b1a174ba8c983cf90", + "sha256:2dd14fac5a47c27be9cd4c976af5a12d87fb1f0b4512f81d69cce3b35ae25021" + ], + "markers": "python_version >= '3.9'", + "version": "==1.2.0" + }, "tox": { "hashes": [ - "sha256:2b8a7fb986b82aa2c830c0615082a490d134e0626dbc9189986da46a313c4f20", - "sha256:b97d5ecc0c0d5755bcc5348387fef793e1bfa68eb33746412f4c60881d7f5f57" + "sha256:4130d02e1d53648d7107d121ed79f69a27b717817c5e9da521d50319dd261212", + "sha256:6dd2d7d4e4fd5895ce4ea20e258fce0d4b81e914b697d116a5ab0365f8303bad" + ], + "index": "pypi", + "markers": "python_version >= '3.10'", + "version": "==4.49.1" + }, + "twine": { + "hashes": [ + "sha256:418ebf08ccda9a8caaebe414433b0ba5e25eb5e4a927667122fbe8f829f985d8", + "sha256:e5ed0d2fd70c9959770dce51c8f39c8945c574e18173a7b81802dab51b4b75cf" ], "index": "pypi", "markers": "python_version >= '3.9'", - "version": "==4.27.0" + "version": "==6.2.0" + }, + "urllib3": { + "hashes": [ + "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed", + "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4" + ], + "markers": "python_version >= '3.9'", + "version": "==2.6.3" }, "virtualenv": { "hashes": [ - "sha256:36efd0d9650ee985f0cad72065001e66d49a6f24eb44d98980f630686243cf11", - "sha256:e10c0a9d02835e592521be48b332b6caee6887f332c111aa79a09b9e79efc2af" + "sha256:1720dc3a62ef5b443092e3f499228599045d7fea4c79199770499df8becf9098", + "sha256:1bd755b504931164a5a496d217c014d098426cddc79363ad66ac78125f9d908f" ], "markers": "python_version >= '3.8'", - "version": "==20.31.2" + "version": "==21.2.0" } } } From bd3d0814c96e717c23807ba12448959a7b15a07a Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Mon, 16 Mar 2026 00:16:04 +0100 Subject: [PATCH 71/74] chore: reapply editable --- Pipfile.lock | 416 +-------------------------------------------------- 1 file changed, 4 insertions(+), 412 deletions(-) diff --git a/Pipfile.lock b/Pipfile.lock index 84ab77b..6702742 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "b9a6a40fe538c374ded3e0fc84bd0cbe34d236468cb184d613e59e3ccf14f0f1" + "sha256": "5341a513f59952743e55c6f51253eecbcec1a2856a69e159f64193f59c081d4c" }, "pipfile-spec": 6, "requires": { @@ -31,6 +31,9 @@ "markers": "python_version >= '3.9'", "version": "==1.4.0" }, + "byteb4rb1e.utils": { + "version": "==0.1.dev92+g4cdf35702.d20260315" + }, "cachetools": { "hashes": [ "sha256:0cd042c24377200c1dcd225f8b7b12b0ca53cc2c961b43757e774ebe190fd990", @@ -47,231 +50,6 @@ "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" - }, "colorama": { "hashes": [ "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", @@ -342,14 +120,6 @@ ], "version": "==0.4.0" }, - "docutils": { - "hashes": [ - "sha256:4db53b1fde9abecbb74d91230d32ab626d94f6badfc575d6db9194a49df29968", - "sha256:d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de" - ], - "markers": "python_version >= '3.9'", - "version": "==0.22.4" - }, "filelock": { "hashes": [ "sha256:b64ece2b38f4ca29dd3e810287aa8c48182bbecd1ae6e9ae126c9b35f1382694", @@ -358,119 +128,6 @@ "markers": "python_version >= '3.10'", "version": "==3.25.2" }, - "id": { - "hashes": [ - "sha256:d0732d624fb46fd4e7bc4e5152f00214450953b9e772c182c1c22964def1a069", - "sha256:f5ec41ed2629a508f5d0988eda142e190c9c6da971100612c4de9ad9f9b237ca" - ], - "markers": "python_version >= '3.9'", - "version": "==1.6.1" - }, - "idna": { - "hashes": [ - "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", - "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902" - ], - "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:0df6a0287258f3e364072c3e40d5411b20cafa30cb28c4839d24319cecf9f808", - "sha256:bc046b2dc94f1e5532bd02402684414575cc11f565d929b6563125deb0a6e581" - ], - "markers": "python_version >= '3.9'", - "version": "==6.1.1" - }, - "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" - }, "packaging": { "hashes": [ "sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4", @@ -544,54 +201,6 @@ "markers": "python_version >= '3.8'", "version": "==1.1.3" }, - "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" - }, - "rfc3986": { - "hashes": [ - "sha256:50b1502b60e289cb37883f3dfd34532b8873c7de9f49bb546641ce9cbd256ebd", - "sha256:97aacf9dbd4bfd829baad6e6309fa6573aaf1be3f6fa735c8ab05e46cecb261c" - ], - "markers": "python_version >= '3.7'", - "version": "==2.0.0" - }, - "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" - }, "setuptools": { "hashes": [ "sha256:7d872682c5d01cfde07da7bccc7b65469d3dca203318515ada1de5eda35efbf9", @@ -626,23 +235,6 @@ "markers": "python_version >= '3.10'", "version": "==4.49.1" }, - "twine": { - "hashes": [ - "sha256:418ebf08ccda9a8caaebe414433b0ba5e25eb5e4a927667122fbe8f829f985d8", - "sha256:e5ed0d2fd70c9959770dce51c8f39c8945c574e18173a7b81802dab51b4b75cf" - ], - "index": "pypi", - "markers": "python_version >= '3.9'", - "version": "==6.2.0" - }, - "urllib3": { - "hashes": [ - "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed", - "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4" - ], - "markers": "python_version >= '3.9'", - "version": "==2.6.3" - }, "virtualenv": { "hashes": [ "sha256:1720dc3a62ef5b443092e3f499228599045d7fea4c79199770499df8becf9098", From 3ee3f1532610fdea091e6c01c0c288c8789f1a32 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Sat, 21 Mar 2026 17:13:02 +0100 Subject: [PATCH 72/74] chore: update build --- Pipfile | 11 +- Pipfile.lock | 712 ++++++++++++++++++++++++++++++++++++++++++++++++- pyproject.toml | 2 +- 3 files changed, 707 insertions(+), 18 deletions(-) diff --git a/Pipfile b/Pipfile index 673ee77..f6b9a8b 100644 --- a/Pipfile +++ b/Pipfile @@ -9,15 +9,18 @@ build = "*" pipenv = "*" tox = "*" twine = "*" +pypi-attestations = "*" [requires] python_version = "3" [scripts] -"build" = "python3 -m build" -"test-static" = "tox run -m static" -"test-unit" = "tox run -m unit" -"test-integration" = "tox run -m integration" +"dist" = "python3 -m build" +"dist:attestations" = "python3 -m pypi_attestations sign dist/*" +"dist:publish" = "python3 -m twine upload --sign --repository tiararodney dist/*" +"test:static" = "tox run -m static" +"test:unit" = "tox run -m unit" +"test:integration" = "tox run -m integration" [packages] "byteb4rb1e.utils" = {file = ".", editable = true} diff --git a/Pipfile.lock b/Pipfile.lock index 6702742..ae31cf6 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "5341a513f59952743e55c6f51253eecbcec1a2856a69e159f64193f59c081d4c" + "sha256": "edaf04f6c9d148cb35296f633912e3b45bfba2ccd30848a824495b4f5ba085ee" }, "pipfile-spec": 6, "requires": { @@ -22,6 +22,14 @@ } }, "develop": { + "annotated-types": { + "hashes": [ + "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", + "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89" + ], + "markers": "python_version >= '3.8'", + "version": "==0.7.0" + }, "build": { "hashes": [ "sha256:6a07c1b8eb6f2b311b96fcbdbce5dab5fe637ffda0fd83c9cac622e927501596", @@ -31,9 +39,6 @@ "markers": "python_version >= '3.9'", "version": "==1.4.0" }, - "byteb4rb1e.utils": { - "version": "==0.1.dev92+g4cdf35702.d20260315" - }, "cachetools": { "hashes": [ "sha256:0cd042c24377200c1dcd225f8b7b12b0ca53cc2c961b43757e774ebe190fd990", @@ -50,6 +55,231 @@ "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" + }, "colorama": { "hashes": [ "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", @@ -120,6 +350,30 @@ ], "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" + }, "filelock": { "hashes": [ "sha256:b64ece2b38f4ca29dd3e810287aa8c48182bbecd1ae6e9ae126c9b35f1382694", @@ -128,6 +382,119 @@ "markers": "python_version >= '3.10'", "version": "==3.25.2" }, + "id": { + "hashes": [ + "sha256:d0732d624fb46fd4e7bc4e5152f00214450953b9e772c182c1c22964def1a069", + "sha256:f5ec41ed2629a508f5d0988eda142e190c9c6da971100612c4de9ad9f9b237ca" + ], + "markers": "python_version >= '3.9'", + "version": "==1.6.1" + }, + "idna": { + "hashes": [ + "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", + "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902" + ], + "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" + }, "packaging": { "hashes": [ "sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4", @@ -138,12 +505,12 @@ }, "pipenv": { "hashes": [ - "sha256:06fba6b4fa542acf8f551cfedf604a08940bbe3068bd575e5163f7c2e8e51eac", - "sha256:56ca111e9b236f551030eb7422f6aa71edd9b2ccc018e100ad80ebc57eb2b270" + "sha256:cd2858095181578ec17451f3ff02b8f74eb9038013ddbbc54228c5f0611fa3da", + "sha256:ddba48a3f9a27e6330b391180ba078354d4d8de480bbe49e7432d6c8ead5bbd7" ], "index": "pypi", "markers": "python_version >= '3.10'", - "version": "==2026.1.0" + "version": "==2026.2.1" }, "platformdirs": { "hashes": [ @@ -161,6 +528,14 @@ "markers": "python_version >= '3.9'", "version": "==1.6.0" }, + "pyasn1": { + "hashes": [ + "sha256:697a8ecd6d98891189184ca1fa05d1bb00e2f84b5977c481452050549c8a72cf", + "sha256:a80184d120f0864a52a073acc6fc642847d0be408e7c7252f31390c0f4eadcde" + ], + "markers": "python_version >= '3.8'", + "version": "==0.6.3" + }, "pycparser": { "hashes": [ "sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29", @@ -169,6 +544,144 @@ "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", @@ -177,6 +690,31 @@ "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" + ], + "index": "pypi", + "markers": "python_version >= '3.10'", + "version": "==0.0.29" + }, "pyproject-api": { "hashes": [ "sha256:40c6f2d82eebdc4afee61c773ed208c04c19db4c4a60d97f8d7be3ebc0bbb330", @@ -195,11 +733,94 @@ }, "python-discovery": { "hashes": [ - "sha256:7acca36e818cd88e9b2ba03e045ad7e93e1713e29c6bbfba5d90202310b7baa5", - "sha256:90e795f0121bc84572e737c9aa9966311b9fde44ffb88a5953b3ec9b31c6945e" + "sha256:1e108f1bbe2ed0ef089823d28805d5ad32be8e734b86a5f212bf89b71c266e4a", + "sha256:7d33e350704818b09e3da2bd419d37e21e7c30db6e0977bb438916e06b41b5b1" ], "markers": "python_version >= '3.8'", - "version": "==1.1.3" + "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": [ @@ -218,6 +839,30 @@ "markers": "python_version >= '3.8'", "version": "==8.2.0" }, + "sigstore": { + "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" + ], + "markers": "python_version >= '3.8'", + "version": "==0.0.18" + }, "tomli-w": { "hashes": [ "sha256:188306098d013b691fcadc011abd66727d3c414c571bb01b1a174ba8c983cf90", @@ -228,12 +873,53 @@ }, "tox": { "hashes": [ - "sha256:4130d02e1d53648d7107d121ed79f69a27b717817c5e9da521d50319dd261212", - "sha256:6dd2d7d4e4fd5895ce4ea20e258fce0d4b81e914b697d116a5ab0365f8303bad" + "sha256:5e788a512bfe6f7447e0c8d7c1b666eb2e56e5e676c65717490423bec37d1a07", + "sha256:c745641de6cc4f19d066bd9f98c1c25f7affb005b381b7f3694a1f142ea0946b" ], "index": "pypi", "markers": "python_version >= '3.10'", - "version": "==4.49.1" + "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" + }, + "typing-extensions": { + "hashes": [ + "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", + "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548" + ], + "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" }, "virtualenv": { "hashes": [ diff --git a/pyproject.toml b/pyproject.toml index 5bc3eb4..423e4e5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,7 +10,7 @@ build-backend = "setuptools.build_meta" name = "byteb4rb1e.utils" description = "personal utilities and helpers" authors = [ - { name = "Tiara Rodney", email = "tiara.rodney@administratrix.de" } + { name = "Tiara Rodney", email = "tiara.rodney@byteb4rb1e.me" } ] license-files = ["LICENSE"] readme = "README.md" From d8d32e1662a63924a116bb65d27fcbcaf77e64f4 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Sat, 21 Mar 2026 18:35:12 +0100 Subject: [PATCH 73/74] docs: add development guidelines --- DEVELOPMENT.md | 122 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 DEVELOPMENT.md diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md new file mode 100644 index 0000000..93093de --- /dev/null +++ b/DEVELOPMENT.md @@ -0,0 +1,122 @@ +# 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) +``` From 9221fdcfe2a925572491314abddd3912d1cb4efe Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Fri, 27 Mar 2026 19:00:09 +0100 Subject: [PATCH 74/74] chore: cleanup --- Makefile | 32 - Pipfile | 4 +- Pipfile.lock | 19 +- configure | 2663 ------------------------------------------ configure.ac | 27 - pyproject.toml | 1 - requirements-dev.txt | 25 - tox.ini | 4 +- 8 files changed, 23 insertions(+), 2752 deletions(-) delete mode 100644 Makefile delete mode 100644 configure delete mode 100644 configure.ac delete mode 100644 requirements-dev.txt diff --git a/Makefile b/Makefile deleted file mode 100644 index 5cf7aae..0000000 --- a/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -.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: test-reports/unit test-reports/static test-reports/integration - -test-reports/unit: - python3 -m pipenv run -v test-unit - -test-reports/integration: - python3 -m pipenv run -v test-integration - -test-reports/static: - python3 -m pipenv run -v test-static - -build: .venv/bin/pipenv - .venv/bin/pipenv run build - diff --git a/Pipfile b/Pipfile index f6b9a8b..8671f4d 100644 --- a/Pipfile +++ b/Pipfile @@ -10,6 +10,7 @@ pipenv = "*" tox = "*" twine = "*" pypi-attestations = "*" +autopep8 = "*" [requires] python_version = "3" @@ -17,7 +18,8 @@ python_version = "3" [scripts] "dist" = "python3 -m build" "dist:attestations" = "python3 -m pypi_attestations sign dist/*" -"dist:publish" = "python3 -m twine upload --sign --repository tiararodney 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" diff --git a/Pipfile.lock b/Pipfile.lock index ae31cf6..d715cea 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "edaf04f6c9d148cb35296f633912e3b45bfba2ccd30848a824495b4f5ba085ee" + "sha256": "7bf1e5e3285cb7ead9e247720d2abc340a64c17d42127e41745bff3309521b41" }, "pipfile-spec": 6, "requires": { @@ -30,6 +30,15 @@ "markers": "python_version >= '3.8'", "version": "==0.7.0" }, + "autopep8": { + "hashes": [ + "sha256:89440a4f969197b69a995e4ce0661b031f455a9f776d2c5ba3dbd83466931758", + "sha256:ce8ad498672c845a0c3de2629c15b635ec2b05ef8177a6e7c91c74f3e9b51128" + ], + "index": "pypi", + "markers": "python_version >= '3.9'", + "version": "==2.3.2" + }, "build": { "hashes": [ "sha256:6a07c1b8eb6f2b311b96fcbdbce5dab5fe637ffda0fd83c9cac622e927501596", @@ -536,6 +545,14 @@ "markers": "python_version >= '3.8'", "version": "==0.6.3" }, + "pycodestyle": { + "hashes": [ + "sha256:c4b5b517d278089ff9d0abdec919cd97262a3367449ea1c8b49b91529167b783", + "sha256:dd6bf7cb4ee77f8e016f9c8e74a35ddd9f67e1d5fd4184d86c3b98e07099f42d" + ], + "markers": "python_version >= '3.9'", + "version": "==2.14.0" + }, "pycparser": { "hashes": [ "sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29", diff --git a/configure b/configure deleted file mode 100644 index ade147c..0000000 --- a/configure +++ /dev/null @@ -1,2663 +0,0 @@ -#! /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 deleted file mode 100644 index e8c53d1..0000000 --- a/configure.ac +++ /dev/null @@ -1,27 +0,0 @@ -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 423e4e5..b3c3d30 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -48,7 +48,6 @@ 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 deleted file mode 100644 index 15e7cea..0000000 --- a/requirements-dev.txt +++ /dev/null @@ -1,25 +0,0 @@ --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/tox.ini b/tox.ini index 0f03dd8..d4a94e1 100644 --- a/tox.ini +++ b/tox.ini @@ -31,9 +31,9 @@ commands = description = run type check on code base labels = static deps = - black + autopep8 commands = - black --check src tests + autopep8 --diff --exit-code src tests [testenv:unit-py3{9-13}] description = run type check on code base