This is an automated email from the ASF dual-hosted git repository.
fokko pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iceberg.git
The following commit(s) were added to refs/heads/master by this push:
new 9d52b54416 Python: Implement Cython based decoding for Avro (#8134)
9d52b54416 is described below
commit 9d52b54416ba50d2f585b37c861a66862e2d7183
Author: Rusty Conover <[email protected]>
AuthorDate: Mon Aug 14 03:50:54 2023 -0400
Python: Implement Cython based decoding for Avro (#8134)
* Python: Improve Avro read performance
Utilize __slots__ for various Avro classes.
Memoize the key/value reader functions in MapReader.
* Python: improve Avro parsing by caching struct types.
Cache the struct types for ManifestEntry and ManifestFile schemas.
Cache the _position_to_field_name lookup in Records if a struct type is
passed.
Improve StructReader to use slots and avoid isinstance() lookups on each
time
the structure is read, by performing the check in __init__().
Improve StructReader to determine the arguments to create_struct() once in
init
and reuse the result each time the structure is read, avoid a try block.
* Python: Improve Avro Parse speed
Cache the hash value of the Struct types so that when new
Record objects are created time is not spent recomputing
the hash value.
Change the implementation of the Record class to cache the
mapping from field name to position. Also utilize an array
rather than a dictionary for these lookups.
* fix some lints
* fix some type casing
* fix: adjust PR comments
* WIP: changes for cython parsing
* fix: address PR feedback.
* Add additional tests for InMemoryBinaryDecoder
* More work on fast Avro decoder
* Work in progress
* Load entire Avro file into memory rather than streaming it
* fix mypy and lint warnings
* fix some more pylint warnings
* Fix lints and build failures
* fix: move lazydict out to its own file.
* fix: disable seeking on input file
* Cleanup expression
* fix: improve integer test case
* fix: rename decoding functions
* fix: remove reader functions that returned native types
* fix: simplify some ReaderClasses via inheritance
Numerous reader classes are simply reading integers, they can all
inherit from IntegerReader rather than having their own implementations
of read() and skip(). Make this change.
* fix: make sqlalchemy optional
* fix: make lazydict generic and move out of avro, add tests
* fix: some lint fixes
* fix: some cleanups and comments
* fix: commit linter changes
---------
Co-authored-by: Fokko Driesprong <[email protected]>
---
python/build-module.py | 81 +++++
python/poetry.lock | 584 ++++++++++++++++++---------------
python/pyiceberg/avro/decoder.py | 116 +------
python/pyiceberg/avro/decoder_basic.c | 61 ++++
python/pyiceberg/avro/decoder_fast.pyi | 56 ++++
python/pyiceberg/avro/decoder_fast.pyx | 186 +++++++++++
python/pyiceberg/avro/file.py | 15 +-
python/pyiceberg/avro/reader.py | 130 +++++---
python/pyiceberg/avro/resolver.py | 6 +-
python/pyiceberg/utils/lazydict.py | 68 ++++
python/pyproject.toml | 20 +-
python/tests/avro/test_decoder.py | 71 +++-
python/tests/avro/test_reader.py | 17 +-
python/tests/utils/test_lazydict.py | 31 ++
14 files changed, 997 insertions(+), 445 deletions(-)
diff --git a/python/build-module.py b/python/build-module.py
new file mode 100644
index 0000000000..c6794ec624
--- /dev/null
+++ b/python/build-module.py
@@ -0,0 +1,81 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+import os
+import shutil
+from pathlib import Path
+
+# Uncommend if your library can still function if extensions fail to compile.
+allowed_to_fail = False
+# allowed_to_fail = os.environ.get("CIBUILDWHEEL", "0") != "1"
+
+
+def build_cython_extensions() -> None:
+ import Cython.Compiler.Options # pyright: ignore [reportMissingImports]
+ from Cython.Build import build_ext, cythonize # pyright: ignore
[reportMissingImports]
+ from setuptools import Extension
+ from setuptools.dist import Distribution
+
+ Cython.Compiler.Options.annotate = True
+
+ if os.name == "nt": # Windows
+ extra_compile_args = [
+ "/O2",
+ ]
+ else: # UNIX-based systems
+ extra_compile_args = [
+ "-O3",
+ ]
+ # Relative to project root directory
+ include_dirs = {
+ "pyiceberg/",
+ }
+
+ extensions = [
+ Extension(
+ # Your .pyx file will be available to cpython at this location.
+ "pyiceberg.avro.decoder_fast",
+ [
+ "pyiceberg/avro/decoder_fast.pyx",
+ ],
+ include_dirs=list(include_dirs),
+ extra_compile_args=extra_compile_args,
+ language="c",
+ ),
+ ]
+
+ for extension in extensions:
+ include_dirs.update(extension.include_dirs)
+
+ ext_modules = cythonize(extensions, include_path=list(include_dirs),
language_level=3, annotate=True)
+ dist = Distribution({"ext_modules": ext_modules})
+ cmd = build_ext(dist)
+ cmd.ensure_finalized()
+
+ cmd.run()
+
+ for output in cmd.get_outputs():
+ output = Path(output)
+ relative_extension = output.relative_to(cmd.build_lib)
+ shutil.copyfile(output, relative_extension)
+
+
+try:
+ build_cython_extensions()
+except Exception:
+ if not allowed_to_fail:
+ raise
diff --git a/python/poetry.lock b/python/poetry.lock
index d6f4178445..b236e578e5 100644
--- a/python/poetry.lock
+++ b/python/poetry.lock
@@ -2,13 +2,13 @@
[[package]]
name = "adlfs"
-version = "2023.4.0"
+version = "2023.8.0"
description = "Access Azure Datalake Gen1 with fsspec and dask"
optional = true
python-versions = ">=3.8"
files = [
- {file = "adlfs-2023.4.0-py3-none-any.whl", hash =
"sha256:43f91a7478a7bb8e1521f4b9369ca6685cdae5392b2b382744f58a40c6d7c877"},
- {file = "adlfs-2023.4.0.tar.gz", hash =
"sha256:84bf8875c57d6cc7e8b3f38034b117b4f43be1c7010aef9947bb5044c7b2fa37"},
+ {file = "adlfs-2023.8.0-py3-none-any.whl", hash =
"sha256:3eb248a3c2a30b419f1147bd7676d156b5219f96ef7f11d47166afd2a3bdb07e"},
+ {file = "adlfs-2023.8.0.tar.gz", hash =
"sha256:07e804f6df4593acfcaf01025b162e30ac13e523d3570279c98b2d91a18026d9"},
]
[package.dependencies]
@@ -24,24 +24,24 @@ docs = ["furo", "myst-parser", "numpydoc", "sphinx"]
[[package]]
name = "aiobotocore"
-version = "2.5.2"
+version = "2.5.4"
description = "Async client for aws services using botocore and aiohttp"
optional = true
python-versions = ">=3.7"
files = [
- {file = "aiobotocore-2.5.2-py3-none-any.whl", hash =
"sha256:337429ffd3cc367532572d40be809a84c7b5335f3f8eca2f23e09dfaa9a9ef90"},
- {file = "aiobotocore-2.5.2.tar.gz", hash =
"sha256:e7399f21570db1c287f1c0c814dd3475dfe1c8166722e2c77ce67f172cbcfa89"},
+ {file = "aiobotocore-2.5.4-py3-none-any.whl", hash =
"sha256:4b32218728ca3d0be83835b604603a0cd6c329066e884bb78149334267f92440"},
+ {file = "aiobotocore-2.5.4.tar.gz", hash =
"sha256:60341f19eda77e41e1ab11eef171b5a98b5dbdb90804f5334b6f90e560e31fae"},
]
[package.dependencies]
aiohttp = ">=3.3.1,<4.0.0"
aioitertools = ">=0.5.1,<1.0.0"
-botocore = ">=1.29.161,<1.29.162"
+botocore = ">=1.31.17,<1.31.18"
wrapt = ">=1.10.10,<2.0.0"
[package.extras]
-awscli = ["awscli (>=1.27.161,<1.27.162)"]
-boto3 = ["boto3 (>=1.26.161,<1.26.162)"]
+awscli = ["awscli (>=1.29.17,<1.29.18)"]
+boto3 = ["boto3 (>=1.28.17,<1.28.18)"]
[[package]]
name = "aiohttp"
@@ -181,13 +181,13 @@ frozenlist = ">=1.1.0"
[[package]]
name = "async-timeout"
-version = "4.0.2"
+version = "4.0.3"
description = "Timeout context manager for asyncio programs"
optional = true
-python-versions = ">=3.6"
+python-versions = ">=3.7"
files = [
- {file = "async-timeout-4.0.2.tar.gz", hash =
"sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15"},
- {file = "async_timeout-4.0.2-py3-none-any.whl", hash =
"sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c"},
+ {file = "async-timeout-4.0.3.tar.gz", hash =
"sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f"},
+ {file = "async_timeout-4.0.3-py3-none-any.whl", hash =
"sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028"},
]
[[package]]
@@ -210,13 +210,13 @@ tests-no-zope = ["cloudpickle", "hypothesis", "mypy
(>=1.1.1)", "pympler", "pyte
[[package]]
name = "azure-core"
-version = "1.28.0"
+version = "1.29.1"
description = "Microsoft Azure Core Library for Python"
optional = true
python-versions = ">=3.7"
files = [
- {file = "azure-core-1.28.0.zip", hash =
"sha256:e9eefc66fc1fde56dab6f04d4e5d12c60754d5a9fa49bdcfd8534fc96ed936bd"},
- {file = "azure_core-1.28.0-py3-none-any.whl", hash =
"sha256:dec36dfc8eb0b052a853f30c07437effec2f9e3e1fc8f703d9bdaa5cfc0043d9"},
+ {file = "azure-core-1.29.1.zip", hash =
"sha256:68e5bb6e3a3230ec202001cc5cb88e57f11c441c8345e921a9ffb8c370abf936"},
+ {file = "azure_core-1.29.1-py3-none-any.whl", hash =
"sha256:6bcefa1f70ff7bf3c39c07c73d8a21df73288eff7e6a1031eb8cfae71cc7bed4"},
]
[package.dependencies]
@@ -245,13 +245,13 @@ requests = ">=2.20.0"
[[package]]
name = "azure-identity"
-version = "1.13.0"
+version = "1.14.0"
description = "Microsoft Azure Identity Library for Python"
optional = true
python-versions = ">=3.7"
files = [
- {file = "azure-identity-1.13.0.zip", hash =
"sha256:c931c27301ffa86b07b4dcf574e29da73e3deba9ab5d1fe4f445bb6a3117e260"},
- {file = "azure_identity-1.13.0-py3-none-any.whl", hash =
"sha256:bd700cebb80cd9862098587c29d8677e819beca33c62568ced6d5a8e5e332b82"},
+ {file = "azure-identity-1.14.0.zip", hash =
"sha256:72441799f8c5c89bfe21026965e266672a7c5d050c2c65119ef899dd5362e2b1"},
+ {file = "azure_identity-1.14.0-py3-none-any.whl", hash =
"sha256:edabf0e010eb85760e1dd19424d5e8f97ba2c9caff73a16e7b30ccbdbcce369b"},
]
[package.dependencies]
@@ -259,7 +259,6 @@ azure-core = ">=1.11.0,<2.0.0"
cryptography = ">=2.5"
msal = ">=1.20.0,<2.0.0"
msal-extensions = ">=0.3.0,<2.0.0"
-six = ">=1.12.0"
[[package]]
name = "azure-storage-blob"
@@ -283,17 +282,17 @@ aio = ["azure-core[aio] (>=1.28.0,<2.0.0)"]
[[package]]
name = "boto3"
-version = "1.26.161"
+version = "1.28.17"
description = "The AWS SDK for Python"
optional = false
python-versions = ">= 3.7"
files = [
- {file = "boto3-1.26.161-py3-none-any.whl", hash =
"sha256:f66e5c9dbe7f34383bcf64fa6070771355c11a44dd75c7f1279f2f37e1c89183"},
- {file = "boto3-1.26.161.tar.gz", hash =
"sha256:662731e464d14af1035f44fc6a46b0e3112ee011ac0a5ed416d205daa3e15f25"},
+ {file = "boto3-1.28.17-py3-none-any.whl", hash =
"sha256:bca0526f819e0f19c0f1e6eba3e2d1d6b6a92a45129f98c0d716e5aab6d9444b"},
+ {file = "boto3-1.28.17.tar.gz", hash =
"sha256:90f7cfb5e1821af95b1fc084bc50e6c47fa3edc99f32de1a2591faa0c546bea7"},
]
[package.dependencies]
-botocore = ">=1.29.161,<1.30.0"
+botocore = ">=1.31.17,<1.32.0"
jmespath = ">=0.7.1,<2.0.0"
s3transfer = ">=0.6.0,<0.7.0"
@@ -302,13 +301,13 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"]
[[package]]
name = "botocore"
-version = "1.29.161"
+version = "1.31.17"
description = "Low-level, data-driven core of boto 3."
optional = false
python-versions = ">= 3.7"
files = [
- {file = "botocore-1.29.161-py3-none-any.whl", hash =
"sha256:b906999dd53dda2ef0ef6f7f55fcc81a4b06b9f1c8a9f65c546e0b981f959f5f"},
- {file = "botocore-1.29.161.tar.gz", hash =
"sha256:a50edd715eb510343e27849f36483804aae4b871590db4d4996aa53368dcac40"},
+ {file = "botocore-1.31.17-py3-none-any.whl", hash =
"sha256:6ac34a1d34aa3750e78b77b8596617e2bab938964694d651939dba2cbde2c12b"},
+ {file = "botocore-1.31.17.tar.gz", hash =
"sha256:396459065dba4339eb4da4ec8b4e6599728eb89b7caaceea199e26f7d824a41c"},
]
[package.dependencies]
@@ -317,7 +316,7 @@ python-dateutil = ">=2.1,<3.0.0"
urllib3 = ">=1.25.4,<1.27"
[package.extras]
-crt = ["awscrt (==0.16.9)"]
+crt = ["awscrt (==0.16.26)"]
[[package]]
name = "build"
@@ -626,34 +625,34 @@ toml = ["tomli"]
[[package]]
name = "cryptography"
-version = "41.0.2"
+version = "41.0.3"
description = "cryptography is a package which provides cryptographic recipes
and primitives to Python developers."
optional = false
python-versions = ">=3.7"
files = [
- {file = "cryptography-41.0.2-cp37-abi3-macosx_10_12_universal2.whl", hash
= "sha256:01f1d9e537f9a15b037d5d9ee442b8c22e3ae11ce65ea1f3316a41c78756b711"},
- {file = "cryptography-41.0.2-cp37-abi3-macosx_10_12_x86_64.whl", hash =
"sha256:079347de771f9282fbfe0e0236c716686950c19dee1b76240ab09ce1624d76d7"},
- {file =
"cryptography-41.0.2-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
hash =
"sha256:439c3cc4c0d42fa999b83ded80a9a1fb54d53c58d6e59234cfe97f241e6c781d"},
- {file =
"cryptography-41.0.2-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
hash =
"sha256:f14ad275364c8b4e525d018f6716537ae7b6d369c094805cae45300847e0894f"},
- {file = "cryptography-41.0.2-cp37-abi3-manylinux_2_28_aarch64.whl", hash =
"sha256:84609ade00a6ec59a89729e87a503c6e36af98ddcd566d5f3be52e29ba993182"},
- {file = "cryptography-41.0.2-cp37-abi3-manylinux_2_28_x86_64.whl", hash =
"sha256:49c3222bb8f8e800aead2e376cbef687bc9e3cb9b58b29a261210456a7783d83"},
- {file = "cryptography-41.0.2-cp37-abi3-musllinux_1_1_aarch64.whl", hash =
"sha256:d73f419a56d74fef257955f51b18d046f3506270a5fd2ac5febbfa259d6c0fa5"},
- {file = "cryptography-41.0.2-cp37-abi3-musllinux_1_1_x86_64.whl", hash =
"sha256:2a034bf7d9ca894720f2ec1d8b7b5832d7e363571828037f9e0c4f18c1b58a58"},
- {file = "cryptography-41.0.2-cp37-abi3-win32.whl", hash =
"sha256:d124682c7a23c9764e54ca9ab5b308b14b18eba02722b8659fb238546de83a76"},
- {file = "cryptography-41.0.2-cp37-abi3-win_amd64.whl", hash =
"sha256:9c3fe6534d59d071ee82081ca3d71eed3210f76ebd0361798c74abc2bcf347d4"},
- {file = "cryptography-41.0.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl",
hash =
"sha256:a719399b99377b218dac6cf547b6ec54e6ef20207b6165126a280b0ce97e0d2a"},
- {file =
"cryptography-41.0.2-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash =
"sha256:182be4171f9332b6741ee818ec27daff9fb00349f706629f5cbf417bd50e66fd"},
- {file =
"cryptography-41.0.2-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash =
"sha256:7a9a3bced53b7f09da251685224d6a260c3cb291768f54954e28f03ef14e3766"},
- {file = "cryptography-41.0.2-pp310-pypy310_pp73-win_amd64.whl", hash =
"sha256:f0dc40e6f7aa37af01aba07277d3d64d5a03dc66d682097541ec4da03cc140ee"},
- {file = "cryptography-41.0.2-pp38-pypy38_pp73-macosx_10_12_x86_64.whl",
hash =
"sha256:674b669d5daa64206c38e507808aae49904c988fa0a71c935e7006a3e1e83831"},
- {file = "cryptography-41.0.2-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl",
hash =
"sha256:7af244b012711a26196450d34f483357e42aeddb04128885d95a69bd8b14b69b"},
- {file = "cryptography-41.0.2-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl",
hash =
"sha256:9b6d717393dbae53d4e52684ef4f022444fc1cce3c48c38cb74fca29e1f08eaa"},
- {file = "cryptography-41.0.2-pp38-pypy38_pp73-win_amd64.whl", hash =
"sha256:192255f539d7a89f2102d07d7375b1e0a81f7478925b3bc2e0549ebf739dae0e"},
- {file = "cryptography-41.0.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl",
hash =
"sha256:f772610fe364372de33d76edcd313636a25684edb94cee53fd790195f5989d14"},
- {file = "cryptography-41.0.2-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl",
hash =
"sha256:b332cba64d99a70c1e0836902720887fb4529ea49ea7f5462cf6640e095e11d2"},
- {file = "cryptography-41.0.2-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl",
hash =
"sha256:9a6673c1828db6270b76b22cc696f40cde9043eb90373da5c2f8f2158957f42f"},
- {file = "cryptography-41.0.2-pp39-pypy39_pp73-win_amd64.whl", hash =
"sha256:342f3767e25876751e14f8459ad85e77e660537ca0a066e10e75df9c9e9099f0"},
- {file = "cryptography-41.0.2.tar.gz", hash =
"sha256:7d230bf856164de164ecb615ccc14c7fc6de6906ddd5b491f3af90d3514c925c"},
+ {file = "cryptography-41.0.3-cp37-abi3-macosx_10_12_universal2.whl", hash
= "sha256:652627a055cb52a84f8c448185922241dd5217443ca194d5739b44612c5e6507"},
+ {file = "cryptography-41.0.3-cp37-abi3-macosx_10_12_x86_64.whl", hash =
"sha256:8f09daa483aedea50d249ef98ed500569841d6498aa9c9f4b0531b9964658922"},
+ {file =
"cryptography-41.0.3-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
hash =
"sha256:4fd871184321100fb400d759ad0cddddf284c4b696568204d281c902fc7b0d81"},
+ {file =
"cryptography-41.0.3-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
hash =
"sha256:84537453d57f55a50a5b6835622ee405816999a7113267739a1b4581f83535bd"},
+ {file = "cryptography-41.0.3-cp37-abi3-manylinux_2_28_aarch64.whl", hash =
"sha256:3fb248989b6363906827284cd20cca63bb1a757e0a2864d4c1682a985e3dca47"},
+ {file = "cryptography-41.0.3-cp37-abi3-manylinux_2_28_x86_64.whl", hash =
"sha256:42cb413e01a5d36da9929baa9d70ca90d90b969269e5a12d39c1e0d475010116"},
+ {file = "cryptography-41.0.3-cp37-abi3-musllinux_1_1_aarch64.whl", hash =
"sha256:aeb57c421b34af8f9fe830e1955bf493a86a7996cc1338fe41b30047d16e962c"},
+ {file = "cryptography-41.0.3-cp37-abi3-musllinux_1_1_x86_64.whl", hash =
"sha256:6af1c6387c531cd364b72c28daa29232162010d952ceb7e5ca8e2827526aceae"},
+ {file = "cryptography-41.0.3-cp37-abi3-win32.whl", hash =
"sha256:0d09fb5356f975974dbcb595ad2d178305e5050656affb7890a1583f5e02a306"},
+ {file = "cryptography-41.0.3-cp37-abi3-win_amd64.whl", hash =
"sha256:a983e441a00a9d57a4d7c91b3116a37ae602907a7618b882c8013b5762e80574"},
+ {file = "cryptography-41.0.3-pp310-pypy310_pp73-macosx_10_12_x86_64.whl",
hash =
"sha256:5259cb659aa43005eb55a0e4ff2c825ca111a0da1814202c64d28a985d33b087"},
+ {file =
"cryptography-41.0.3-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash =
"sha256:67e120e9a577c64fe1f611e53b30b3e69744e5910ff3b6e97e935aeb96005858"},
+ {file =
"cryptography-41.0.3-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash =
"sha256:7efe8041897fe7a50863e51b77789b657a133c75c3b094e51b5e4b5cec7bf906"},
+ {file = "cryptography-41.0.3-pp310-pypy310_pp73-win_amd64.whl", hash =
"sha256:ce785cf81a7bdade534297ef9e490ddff800d956625020ab2ec2780a556c313e"},
+ {file = "cryptography-41.0.3-pp38-pypy38_pp73-macosx_10_12_x86_64.whl",
hash =
"sha256:57a51b89f954f216a81c9d057bf1a24e2f36e764a1ca9a501a6964eb4a6800dd"},
+ {file = "cryptography-41.0.3-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl",
hash =
"sha256:4c2f0d35703d61002a2bbdcf15548ebb701cfdd83cdc12471d2bae80878a4207"},
+ {file = "cryptography-41.0.3-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl",
hash =
"sha256:23c2d778cf829f7d0ae180600b17e9fceea3c2ef8b31a99e3c694cbbf3a24b84"},
+ {file = "cryptography-41.0.3-pp38-pypy38_pp73-win_amd64.whl", hash =
"sha256:95dd7f261bb76948b52a5330ba5202b91a26fbac13ad0e9fc8a3ac04752058c7"},
+ {file = "cryptography-41.0.3-pp39-pypy39_pp73-macosx_10_12_x86_64.whl",
hash =
"sha256:41d7aa7cdfded09b3d73a47f429c298e80796c8e825ddfadc84c8a7f12df212d"},
+ {file = "cryptography-41.0.3-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl",
hash =
"sha256:d0d651aa754ef58d75cec6edfbd21259d93810b73f6ec246436a21b7841908de"},
+ {file = "cryptography-41.0.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl",
hash =
"sha256:ab8de0d091acbf778f74286f4989cf3d1528336af1b59f3e5d2ebca8b5fe49e1"},
+ {file = "cryptography-41.0.3-pp39-pypy39_pp73-win_amd64.whl", hash =
"sha256:a74fbcdb2a0d46fe00504f571a2a540532f4c188e6ccf26f1f178480117b33c4"},
+ {file = "cryptography-41.0.3.tar.gz", hash =
"sha256:6d192741113ef5e30d89dcb5b956ef4e1578f304708701b8b73d38e3e1461f34"},
]
[package.dependencies]
@@ -669,6 +668,73 @@ ssh = ["bcrypt (>=3.1.5)"]
test = ["pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov",
"pytest-xdist"]
test-randomorder = ["pytest-randomly"]
+[[package]]
+name = "cython"
+version = "3.0.0"
+description = "The Cython compiler for writing C extensions in the Python
language."
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+files = [
+ {file = "Cython-3.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash =
"sha256:7c7d728e1a49ad01d41181e3a9ea80b8d14e825f4679e4dd837cbf7bca7998a5"},
+ {file =
"Cython-3.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
hash =
"sha256:626a4a6ef4b7ced87c348ea805488e4bd39dad9d0b39659aa9e1040b62bbfedf"},
+ {file =
"Cython-3.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash
= "sha256:33c900d1ca9f622b969ac7d8fc44bdae140a4a6c7d8819413b51f3ccd0586a09"},
+ {file =
"Cython-3.0.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",
hash =
"sha256:a65bc50dc1bc2faeafd9425defbdef6a468974f5c4192497ff7f14adccfdcd32"},
+ {file = "Cython-3.0.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash =
"sha256:3b71b399b10b038b056ad12dce1e317a8aa7a96e99de7e4fa2fa5d1c9415cfb9"},
+ {file = "Cython-3.0.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash =
"sha256:f42f304c097cc53e9eb5f1a1d150380353d5018a3191f1b77f0de353c762181e"},
+ {file = "Cython-3.0.0-cp310-cp310-win32.whl", hash =
"sha256:3e234e2549e808d9259fdb23ebcfd145be30c638c65118326ec33a8d29248dc2"},
+ {file = "Cython-3.0.0-cp310-cp310-win_amd64.whl", hash =
"sha256:829c8333195100448a23863cf64a07e1334fae6a275aefe871458937911531b6"},
+ {file = "Cython-3.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash =
"sha256:06db81b1a01858fcc406616f8528e686ffb6cf7c3d78fb83767832bfecea8ad8"},
+ {file =
"Cython-3.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
hash =
"sha256:c93634845238645ce7abf63a56b1c5b6248189005c7caff898fd4a0dac1c5e1e"},
+ {file =
"Cython-3.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash
= "sha256:aa606675c6bd23478b1d174e2a84e3c5a2c660968f97dc455afe0fae198f9d3d"},
+ {file =
"Cython-3.0.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",
hash =
"sha256:d3355e6f690184f984eeb108b0f5bbc4bcf8b9444f8168933acf79603abf7baf"},
+ {file = "Cython-3.0.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash =
"sha256:93a34e1ca8afa4b7075b02ed14a7e4969256297029fb1bfd4cbe48f7290dbcff"},
+ {file = "Cython-3.0.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash =
"sha256:bb1165ca9e78823f9ad1efa5b3d83156f868eabd679a615d140a3021bb92cd65"},
+ {file = "Cython-3.0.0-cp311-cp311-win32.whl", hash =
"sha256:2fadde1da055944f5e1e17625055f54ddd11f451889110278ef30e07bd5e1695"},
+ {file = "Cython-3.0.0-cp311-cp311-win_amd64.whl", hash =
"sha256:254ed1f03a6c237fa64f0c6e44862058de65bfa2e6a3b48ca3c205492e0653aa"},
+ {file = "Cython-3.0.0-cp312-cp312-macosx_10_9_x86_64.whl", hash =
"sha256:4e212237b7531759befb92699c452cd65074a78051ae4ee36ff8b237395ecf3d"},
+ {file =
"Cython-3.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
hash =
"sha256:9f29307463eba53747b31f71394ed087e3e3e264dcc433e62de1d51f5c0c966c"},
+ {file =
"Cython-3.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash
= "sha256:53328a8af0806bebbdb48a4191883b11ee9d9dfb084d84f58fa5a8ab58baefc9"},
+ {file =
"Cython-3.0.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",
hash =
"sha256:5962e70b15e863e72bed6910e8c6ffef77d36cc98e2b31c474378f3b9e49b0e3"},
+ {file = "Cython-3.0.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash =
"sha256:9e69139f4e60ab14c50767a568612ea64d6907e9c8e0289590a170eb495e005f"},
+ {file = "Cython-3.0.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash =
"sha256:c40bdbcb2286f0aeeb5df9ce53d45da2d2a9b36a16b331cd0809d212d22a8fc7"},
+ {file = "Cython-3.0.0-cp312-cp312-win32.whl", hash =
"sha256:8abb8915eb2e57fa53d918afe641c05d1bcc6ed1913682ec1f28de71f4e3f398"},
+ {file = "Cython-3.0.0-cp312-cp312-win_amd64.whl", hash =
"sha256:30a4bd2481e59bd7ab2539f835b78edc19fc455811e476916f56026b93afd28b"},
+ {file = "Cython-3.0.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash =
"sha256:0e1e4b7e4bfbf22fecfa5b852f0e499c442d4853b7ebd33ae37cdec9826ed5d8"},
+ {file =
"Cython-3.0.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
hash =
"sha256:6b00df42cdd1a285a64491ba23de08ab14169d3257c840428d40eb7e8e9979af"},
+ {file =
"Cython-3.0.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash
= "sha256:650d03ddddc08b051b4659778733f0f173ca7d327415755c05d265a6c1ba02fb"},
+ {file =
"Cython-3.0.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",
hash =
"sha256:4965f2ebade17166f21a508d66dd60d2a0b3a3b90abe3f72003baa17ae020dd6"},
+ {file = "Cython-3.0.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash =
"sha256:4123c8d03167803df31da6b39de167cb9c04ac0aa4e35d4e5aa9d08ad511b84d"},
+ {file = "Cython-3.0.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash =
"sha256:296c53b6c0030cf82987eef163444e8d7631cc139d995f9d58679d9fd1ddbf31"},
+ {file = "Cython-3.0.0-cp36-cp36m-win32.whl", hash =
"sha256:0d2c1e172f1c81bafcca703093608e10dc16e3e2d24c5644c17606c7fdb1792c"},
+ {file = "Cython-3.0.0-cp36-cp36m-win_amd64.whl", hash =
"sha256:bc816d8eb3686d6f8d165f4156bac18c1147e1035dc28a76742d0b7fb5b7c032"},
+ {file = "Cython-3.0.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash =
"sha256:8d86651347bbdbac1aca1824696c5e4c0a3b162946c422edcca2be12a03744d1"},
+ {file =
"Cython-3.0.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
hash =
"sha256:84176bd04ce9f3cc8799b47ec6d1959fa1ea5e71424507df7bbf0b0915bbedef"},
+ {file =
"Cython-3.0.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash
= "sha256:35abcf07b8277ec95bbe49a07b5c8760a2d941942ccfe759a94c8d2fe5602e9f"},
+ {file =
"Cython-3.0.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",
hash =
"sha256:a44d6b9a29b2bff38bb648577b2fcf6a68cf8b1783eee89c2eb749f69494b98d"},
+ {file = "Cython-3.0.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash =
"sha256:4dc6bbe7cf079db37f1ebb9b0f10d0d7f29e293bb8688e92d50b5ea7a91d82f3"},
+ {file = "Cython-3.0.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash =
"sha256:e28763e75e380b8be62b02266a7995a781997c97c119efbdccb8fb954bcd7574"},
+ {file = "Cython-3.0.0-cp37-cp37m-win32.whl", hash =
"sha256:edae615cb4af51d5173e76ba9aea212424d025c57012e9cdf2f131f774c5ba71"},
+ {file = "Cython-3.0.0-cp37-cp37m-win_amd64.whl", hash =
"sha256:20c604e974832aaf8b7a1f5455ee7274b34df62a35ee095cd7d2ed7e818e6c53"},
+ {file = "Cython-3.0.0-cp38-cp38-macosx_10_9_x86_64.whl", hash =
"sha256:c85fd2b1cbd9400d60ebe074795bb9a9188752f1612be3b35b0831a24879b91f"},
+ {file =
"Cython-3.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash
= "sha256:090256c687106932339f87f888b95f0d69c617bc9b18801555545b695d29d8ab"},
+ {file =
"Cython-3.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash =
"sha256:cec2a67a0a7d9d4399758c0657ca03e5912e37218859cfbf046242cc532bfb3b"},
+ {file =
"Cython-3.0.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",
hash =
"sha256:a1cdd01ce45333bc264a218c6e183700d6b998f029233f586a53c9b13455c2d2"},
+ {file = "Cython-3.0.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash =
"sha256:ecee663d2d50ca939fc5db81f2f8a219c2417b4651ad84254c50a03a9cb1aadd"},
+ {file = "Cython-3.0.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash =
"sha256:30f10e79393b411af7677c270ea69807acb9fc30205c8ff25561f4deef780ec1"},
+ {file = "Cython-3.0.0-cp38-cp38-win32.whl", hash =
"sha256:609777d3a7a0a23b225e84d967af4ad2485c8bdfcacef8037cf197e87d431ca0"},
+ {file = "Cython-3.0.0-cp38-cp38-win_amd64.whl", hash =
"sha256:7f4a6dfd42ae0a45797f50fc4f6add702abf46ab3e7cd61811a6c6a97a40e1a2"},
+ {file = "Cython-3.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash =
"sha256:2d8158277c8942c0b20ff4c074fe6a51c5b89e6ac60cef606818de8c92773596"},
+ {file =
"Cython-3.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash
= "sha256:54e34f99b2a8c1e11478541b2822e6408c132b98b6b8f5ed89411e5e906631ea"},
+ {file =
"Cython-3.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash =
"sha256:877d1c8745df59dd2061a0636c602729e9533ba13f13aa73a498f68662e1cbde"},
+ {file =
"Cython-3.0.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",
hash =
"sha256:204690be60f0ff32eb70b04f28ef0d1e50ffd7b3f77ba06a7dc2389ee3b848e0"},
+ {file = "Cython-3.0.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash =
"sha256:06fcb4628ccce2ba5abc8630adbeaf4016f63a359b4c6c3827b2d80e0673981c"},
+ {file = "Cython-3.0.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash =
"sha256:090e24cfa31c926d0b13d8bb2ef48175acdd061ae1413343c94a2b12a4a4fa6f"},
+ {file = "Cython-3.0.0-cp39-cp39-win32.whl", hash =
"sha256:4cd00f2158dc00f7f93a92444d0f663eda124c9c29bbbd658964f4e89c357fe8"},
+ {file = "Cython-3.0.0-cp39-cp39-win_amd64.whl", hash =
"sha256:5b4cc896d49ce2bae8d6a030f9a4c64965b59c38acfbf4617685e17f7fcf1731"},
+ {file = "Cython-3.0.0-py2.py3-none-any.whl", hash =
"sha256:ff1aef1a03cfe293237c7a86ae9625b0411b2df30c53d1a7f29a8d381f38a1df"},
+ {file = "Cython-3.0.0.tar.gz", hash =
"sha256:350b18f9673e63101dbbfcf774ee2f57c20ac4636d255741d76ca79016b1bd82"},
+]
+
[[package]]
name = "distlib"
version = "0.3.7"
@@ -930,7 +996,7 @@ tqdm = ["tqdm"]
name = "greenlet"
version = "2.0.2"
description = "Lightweight in-process concurrent programming"
-optional = true
+optional = false
python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*"
files = [
{file = "greenlet-2.0.2-cp27-cp27m-macosx_10_14_x86_64.whl", hash =
"sha256:bdfea8c661e80d3c1c99ad7c3ff74e6e87184895bbaca6ee8cc61209f8b9b85d"},
@@ -1001,60 +1067,60 @@ test = ["objgraph", "psutil"]
[[package]]
name = "grpcio"
-version = "1.56.2"
+version = "1.57.0"
description = "HTTP/2-based RPC framework"
optional = true
python-versions = ">=3.7"
files = [
- {file = "grpcio-1.56.2-cp310-cp310-linux_armv7l.whl", hash =
"sha256:bf0b9959e673505ee5869950642428046edb91f99942607c2ecf635f8a4b31c9"},
- {file = "grpcio-1.56.2-cp310-cp310-macosx_12_0_universal2.whl", hash =
"sha256:5144feb20fe76e73e60c7d73ec3bf54f320247d1ebe737d10672480371878b48"},
- {file = "grpcio-1.56.2-cp310-cp310-manylinux_2_17_aarch64.whl", hash =
"sha256:a72797549935c9e0b9bc1def1768c8b5a709538fa6ab0678e671aec47ebfd55e"},
- {file =
"grpcio-1.56.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash =
"sha256:c3f3237a57e42f79f1e560726576aedb3a7ef931f4e3accb84ebf6acc485d316"},
- {file =
"grpcio-1.56.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
hash =
"sha256:900bc0096c2ca2d53f2e5cebf98293a7c32f532c4aeb926345e9747452233950"},
- {file = "grpcio-1.56.2-cp310-cp310-musllinux_1_1_i686.whl", hash =
"sha256:97e0efaebbfd222bcaac2f1735c010c1d3b167112d9d237daebbeedaaccf3d1d"},
- {file = "grpcio-1.56.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash =
"sha256:c0c85c5cbe8b30a32fa6d802588d55ffabf720e985abe9590c7c886919d875d4"},
- {file = "grpcio-1.56.2-cp310-cp310-win32.whl", hash =
"sha256:06e84ad9ae7668a109e970c7411e7992751a116494cba7c4fb877656527f9a57"},
- {file = "grpcio-1.56.2-cp310-cp310-win_amd64.whl", hash =
"sha256:10954662f77dc36c9a1fb5cc4a537f746580d6b5734803be1e587252682cda8d"},
- {file = "grpcio-1.56.2-cp311-cp311-linux_armv7l.whl", hash =
"sha256:c435f5ce1705de48e08fcbcfaf8aee660d199c90536e3e06f2016af7d6a938dd"},
- {file = "grpcio-1.56.2-cp311-cp311-macosx_10_10_universal2.whl", hash =
"sha256:6108e5933eb8c22cd3646e72d5b54772c29f57482fd4c41a0640aab99eb5071d"},
- {file = "grpcio-1.56.2-cp311-cp311-manylinux_2_17_aarch64.whl", hash =
"sha256:8391cea5ce72f4a12368afd17799474015d5d3dc00c936a907eb7c7eaaea98a5"},
- {file =
"grpcio-1.56.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash =
"sha256:750de923b456ca8c0f1354d6befca45d1f3b3a789e76efc16741bd4132752d95"},
- {file =
"grpcio-1.56.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
hash =
"sha256:fda2783c12f553cdca11c08e5af6eecbd717280dc8fbe28a110897af1c15a88c"},
- {file = "grpcio-1.56.2-cp311-cp311-musllinux_1_1_i686.whl", hash =
"sha256:9e04d4e4cfafa7c5264e535b5d28e786f0571bea609c3f0aaab13e891e933e9c"},
- {file = "grpcio-1.56.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash =
"sha256:89a49cc5ad08a38b6141af17e00d1dd482dc927c7605bc77af457b5a0fca807c"},
- {file = "grpcio-1.56.2-cp311-cp311-win32.whl", hash =
"sha256:6a007a541dff984264981fbafeb052bfe361db63578948d857907df9488d8774"},
- {file = "grpcio-1.56.2-cp311-cp311-win_amd64.whl", hash =
"sha256:af4063ef2b11b96d949dccbc5a987272f38d55c23c4c01841ea65a517906397f"},
- {file = "grpcio-1.56.2-cp37-cp37m-linux_armv7l.whl", hash =
"sha256:a6ff459dac39541e6a2763a4439c4ca6bc9ecb4acc05a99b79246751f9894756"},
- {file = "grpcio-1.56.2-cp37-cp37m-macosx_10_10_universal2.whl", hash =
"sha256:f20fd21f7538f8107451156dd1fe203300b79a9ddceba1ee0ac8132521a008ed"},
- {file = "grpcio-1.56.2-cp37-cp37m-manylinux_2_17_aarch64.whl", hash =
"sha256:d1fbad1f9077372b6587ec589c1fc120b417b6c8ad72d3e3cc86bbbd0a3cee93"},
- {file =
"grpcio-1.56.2-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash =
"sha256:6ee26e9dfb3996aff7c870f09dc7ad44a5f6732b8bdb5a5f9905737ac6fd4ef1"},
- {file =
"grpcio-1.56.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash
= "sha256:a4c60abd950d6de3e4f1ddbc318075654d275c29c846ab6a043d6ed2c52e4c8c"},
- {file = "grpcio-1.56.2-cp37-cp37m-musllinux_1_1_i686.whl", hash =
"sha256:1c31e52a04e62c8577a7bf772b3e7bed4df9c9e0dd90f92b6ffa07c16cab63c9"},
- {file = "grpcio-1.56.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash =
"sha256:345356b307cce5d14355e8e055b4ca5f99bc857c33a3dc1ddbc544fca9cd0475"},
- {file = "grpcio-1.56.2-cp37-cp37m-win_amd64.whl", hash =
"sha256:42e63904ee37ae46aa23de50dac8b145b3596f43598fa33fe1098ab2cbda6ff5"},
- {file = "grpcio-1.56.2-cp38-cp38-linux_armv7l.whl", hash =
"sha256:7c5ede2e2558f088c49a1ddda19080e4c23fb5d171de80a726b61b567e3766ed"},
- {file = "grpcio-1.56.2-cp38-cp38-macosx_10_10_universal2.whl", hash =
"sha256:33971197c47965cc1d97d78d842163c283e998223b151bab0499b951fd2c0b12"},
- {file = "grpcio-1.56.2-cp38-cp38-manylinux_2_17_aarch64.whl", hash =
"sha256:d39f5d4af48c138cb146763eda14eb7d8b3ccbbec9fe86fb724cd16e0e914c64"},
- {file =
"grpcio-1.56.2-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash =
"sha256:ded637176addc1d3eef35331c39acc598bac550d213f0a1bedabfceaa2244c87"},
- {file =
"grpcio-1.56.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash
= "sha256:c90da4b124647547a68cf2f197174ada30c7bb9523cb976665dfd26a9963d328"},
- {file = "grpcio-1.56.2-cp38-cp38-musllinux_1_1_i686.whl", hash =
"sha256:3ccb621749a81dc7755243665a70ce45536ec413ef5818e013fe8dfbf5aa497b"},
- {file = "grpcio-1.56.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash =
"sha256:4eb37dd8dd1aa40d601212afa27ca5be255ba792e2e0b24d67b8af5e012cdb7d"},
- {file = "grpcio-1.56.2-cp38-cp38-win32.whl", hash =
"sha256:ddb4a6061933bd9332b74eac0da25f17f32afa7145a33a0f9711ad74f924b1b8"},
- {file = "grpcio-1.56.2-cp38-cp38-win_amd64.whl", hash =
"sha256:8940d6de7068af018dfa9a959a3510e9b7b543f4c405e88463a1cbaa3b2b379a"},
- {file = "grpcio-1.56.2-cp39-cp39-linux_armv7l.whl", hash =
"sha256:51173e8fa6d9a2d85c14426bdee5f5c4a0654fd5fddcc21fe9d09ab0f6eb8b35"},
- {file = "grpcio-1.56.2-cp39-cp39-macosx_10_10_universal2.whl", hash =
"sha256:373b48f210f43327a41e397391715cd11cfce9ded2fe76a5068f9bacf91cc226"},
- {file = "grpcio-1.56.2-cp39-cp39-manylinux_2_17_aarch64.whl", hash =
"sha256:42a3bbb2bc07aef72a7d97e71aabecaf3e4eb616d39e5211e2cfe3689de860ca"},
- {file =
"grpcio-1.56.2-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash =
"sha256:5344be476ac37eb9c9ad09c22f4ea193c1316bf074f1daf85bddb1b31fda5116"},
- {file =
"grpcio-1.56.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash
= "sha256:c3fa3ab0fb200a2c66493828ed06ccd1a94b12eddbfb985e7fd3e5723ff156c6"},
- {file = "grpcio-1.56.2-cp39-cp39-musllinux_1_1_i686.whl", hash =
"sha256:b975b85d1d5efc36cf8b237c5f3849b64d1ba33d6282f5e991f28751317504a1"},
- {file = "grpcio-1.56.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash =
"sha256:cbdf2c498e077282cd427cfd88bdce4668019791deef0be8155385ab2ba7837f"},
- {file = "grpcio-1.56.2-cp39-cp39-win32.whl", hash =
"sha256:139f66656a762572ae718fa0d1f2dce47c05e9fbf7a16acd704c354405b97df9"},
- {file = "grpcio-1.56.2-cp39-cp39-win_amd64.whl", hash =
"sha256:830215173ad45d670140ff99aac3b461f9be9a6b11bee1a17265aaaa746a641a"},
- {file = "grpcio-1.56.2.tar.gz", hash =
"sha256:0ff789ae7d8ddd76d2ac02e7d13bfef6fc4928ac01e1dcaa182be51b6bcc0aaa"},
+ {file = "grpcio-1.57.0-cp310-cp310-linux_armv7l.whl", hash =
"sha256:092fa155b945015754bdf988be47793c377b52b88d546e45c6a9f9579ac7f7b6"},
+ {file = "grpcio-1.57.0-cp310-cp310-macosx_12_0_universal2.whl", hash =
"sha256:2f7349786da979a94690cc5c2b804cab4e8774a3cf59be40d037c4342c906649"},
+ {file = "grpcio-1.57.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash =
"sha256:82640e57fb86ea1d71ea9ab54f7e942502cf98a429a200b2e743d8672171734f"},
+ {file =
"grpcio-1.57.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash =
"sha256:40b72effd4c789de94ce1be2b5f88d7b9b5f7379fe9645f198854112a6567d9a"},
+ {file =
"grpcio-1.57.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
hash =
"sha256:2f708a6a17868ad8bf586598bee69abded4996b18adf26fd2d91191383b79019"},
+ {file = "grpcio-1.57.0-cp310-cp310-musllinux_1_1_i686.whl", hash =
"sha256:60fe15288a0a65d5c1cb5b4a62b1850d07336e3ba728257a810317be14f0c527"},
+ {file = "grpcio-1.57.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash =
"sha256:6907b1cf8bb29b058081d2aad677b15757a44ef2d4d8d9130271d2ad5e33efca"},
+ {file = "grpcio-1.57.0-cp310-cp310-win32.whl", hash =
"sha256:57b183e8b252825c4dd29114d6c13559be95387aafc10a7be645462a0fc98bbb"},
+ {file = "grpcio-1.57.0-cp310-cp310-win_amd64.whl", hash =
"sha256:7b400807fa749a9eb286e2cd893e501b110b4d356a218426cb9c825a0474ca56"},
+ {file = "grpcio-1.57.0-cp311-cp311-linux_armv7l.whl", hash =
"sha256:c6ebecfb7a31385393203eb04ed8b6a08f5002f53df3d59e5e795edb80999652"},
+ {file = "grpcio-1.57.0-cp311-cp311-macosx_10_10_universal2.whl", hash =
"sha256:00258cbe3f5188629828363ae8ff78477ce976a6f63fb2bb5e90088396faa82e"},
+ {file = "grpcio-1.57.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash =
"sha256:23e7d8849a0e58b806253fd206ac105b328171e01b8f18c7d5922274958cc87e"},
+ {file =
"grpcio-1.57.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash =
"sha256:5371bcd861e679d63b8274f73ac281751d34bd54eccdbfcd6aa00e692a82cd7b"},
+ {file =
"grpcio-1.57.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
hash =
"sha256:aed90d93b731929e742967e236f842a4a2174dc5db077c8f9ad2c5996f89f63e"},
+ {file = "grpcio-1.57.0-cp311-cp311-musllinux_1_1_i686.whl", hash =
"sha256:fe752639919aad9ffb0dee0d87f29a6467d1ef764f13c4644d212a9a853a078d"},
+ {file = "grpcio-1.57.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash =
"sha256:fada6b07ec4f0befe05218181f4b85176f11d531911b64c715d1875c4736d73a"},
+ {file = "grpcio-1.57.0-cp311-cp311-win32.whl", hash =
"sha256:bb396952cfa7ad2f01061fbc7dc1ad91dd9d69243bcb8110cf4e36924785a0fe"},
+ {file = "grpcio-1.57.0-cp311-cp311-win_amd64.whl", hash =
"sha256:e503cb45ed12b924b5b988ba9576dc9949b2f5283b8e33b21dcb6be74a7c58d0"},
+ {file = "grpcio-1.57.0-cp37-cp37m-linux_armv7l.whl", hash =
"sha256:fd173b4cf02b20f60860dc2ffe30115c18972d7d6d2d69df97ac38dee03be5bf"},
+ {file = "grpcio-1.57.0-cp37-cp37m-macosx_10_10_universal2.whl", hash =
"sha256:d7f8df114d6b4cf5a916b98389aeaf1e3132035420a88beea4e3d977e5f267a5"},
+ {file = "grpcio-1.57.0-cp37-cp37m-manylinux_2_17_aarch64.whl", hash =
"sha256:76c44efa4ede1f42a9d5b2fed1fe9377e73a109bef8675fb0728eb80b0b8e8f2"},
+ {file =
"grpcio-1.57.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash =
"sha256:4faea2cfdf762a664ab90589b66f416274887641ae17817de510b8178356bf73"},
+ {file =
"grpcio-1.57.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash
= "sha256:c60b83c43faeb6d0a9831f0351d7787a0753f5087cc6fa218d78fdf38e5acef0"},
+ {file = "grpcio-1.57.0-cp37-cp37m-musllinux_1_1_i686.whl", hash =
"sha256:b363bbb5253e5f9c23d8a0a034dfdf1b7c9e7f12e602fc788c435171e96daccc"},
+ {file = "grpcio-1.57.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash =
"sha256:f1fb0fd4a1e9b11ac21c30c169d169ef434c6e9344ee0ab27cfa6f605f6387b2"},
+ {file = "grpcio-1.57.0-cp37-cp37m-win_amd64.whl", hash =
"sha256:34950353539e7d93f61c6796a007c705d663f3be41166358e3d88c45760c7d98"},
+ {file = "grpcio-1.57.0-cp38-cp38-linux_armv7l.whl", hash =
"sha256:871f9999e0211f9551f368612460442a5436d9444606184652117d6a688c9f51"},
+ {file = "grpcio-1.57.0-cp38-cp38-macosx_10_10_universal2.whl", hash =
"sha256:a8a8e560e8dbbdf29288872e91efd22af71e88b0e5736b0daf7773c1fecd99f0"},
+ {file = "grpcio-1.57.0-cp38-cp38-manylinux_2_17_aarch64.whl", hash =
"sha256:2313b124e475aa9017a9844bdc5eafb2d5abdda9d456af16fc4535408c7d6da6"},
+ {file =
"grpcio-1.57.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash =
"sha256:b4098b6b638d9e0ca839a81656a2fd4bc26c9486ea707e8b1437d6f9d61c3941"},
+ {file =
"grpcio-1.57.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash
= "sha256:5e5b58e32ae14658085c16986d11e99abd002ddbf51c8daae8a0671fffb3467f"},
+ {file = "grpcio-1.57.0-cp38-cp38-musllinux_1_1_i686.whl", hash =
"sha256:0f80bf37f09e1caba6a8063e56e2b87fa335add314cf2b78ebf7cb45aa7e3d06"},
+ {file = "grpcio-1.57.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash =
"sha256:5b7a4ce8f862fe32b2a10b57752cf3169f5fe2915acfe7e6a1e155db3da99e79"},
+ {file = "grpcio-1.57.0-cp38-cp38-win32.whl", hash =
"sha256:9338bacf172e942e62e5889b6364e56657fbf8ac68062e8b25c48843e7b202bb"},
+ {file = "grpcio-1.57.0-cp38-cp38-win_amd64.whl", hash =
"sha256:e1cb52fa2d67d7f7fab310b600f22ce1ff04d562d46e9e0ac3e3403c2bb4cc16"},
+ {file = "grpcio-1.57.0-cp39-cp39-linux_armv7l.whl", hash =
"sha256:fee387d2fab144e8a34e0e9c5ca0f45c9376b99de45628265cfa9886b1dbe62b"},
+ {file = "grpcio-1.57.0-cp39-cp39-macosx_10_10_universal2.whl", hash =
"sha256:b53333627283e7241fcc217323f225c37783b5f0472316edcaa4479a213abfa6"},
+ {file = "grpcio-1.57.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash =
"sha256:f19ac6ac0a256cf77d3cc926ef0b4e64a9725cc612f97228cd5dc4bd9dbab03b"},
+ {file =
"grpcio-1.57.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash =
"sha256:e3fdf04e402f12e1de8074458549337febb3b45f21076cc02ef4ff786aff687e"},
+ {file =
"grpcio-1.57.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash
= "sha256:5613a2fecc82f95d6c51d15b9a72705553aa0d7c932fad7aed7afb51dc982ee5"},
+ {file = "grpcio-1.57.0-cp39-cp39-musllinux_1_1_i686.whl", hash =
"sha256:b670c2faa92124b7397b42303e4d8eb64a4cd0b7a77e35a9e865a55d61c57ef9"},
+ {file = "grpcio-1.57.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash =
"sha256:7a635589201b18510ff988161b7b573f50c6a48fae9cb567657920ca82022b37"},
+ {file = "grpcio-1.57.0-cp39-cp39-win32.whl", hash =
"sha256:d78d8b86fcdfa1e4c21f8896614b6cc7ee01a2a758ec0c4382d662f2a62cf766"},
+ {file = "grpcio-1.57.0-cp39-cp39-win_amd64.whl", hash =
"sha256:20ec6fc4ad47d1b6e12deec5045ec3cd5402d9a1597f738263e98f490fe07056"},
+ {file = "grpcio-1.57.0.tar.gz", hash =
"sha256:4b089f7ad1eb00a104078bab8015b0ed0ebcb3b589e527ab009c53893fd4e613"},
]
[package.extras]
-protobuf = ["grpcio-tools (>=1.56.2)"]
+protobuf = ["grpcio-tools (>=1.57.0)"]
[[package]]
name = "identify"
@@ -1102,13 +1168,13 @@ testing = ["flufl.flake8", "importlib-resources
(>=1.3)", "packaging", "pyfakefs
[[package]]
name = "importlib-resources"
-version = "6.0.0"
+version = "6.0.1"
description = "Read resources from Python packages"
optional = true
python-versions = ">=3.8"
files = [
- {file = "importlib_resources-6.0.0-py3-none-any.whl", hash =
"sha256:d952faee11004c045f785bb5636e8f885bed30dc3c940d5d42798a2a4541c185"},
- {file = "importlib_resources-6.0.0.tar.gz", hash =
"sha256:4cf94875a8368bd89531a756df9a9ebe1f150e0f885030b461237bc7f2d905f2"},
+ {file = "importlib_resources-6.0.1-py3-none-any.whl", hash =
"sha256:134832a506243891221b88b4ae1213327eea96ceb4e407a00d790bb0626f45cf"},
+ {file = "importlib_resources-6.0.1.tar.gz", hash =
"sha256:4359457e42708462b9626a04657c6208ad799ceb41e5c58c57ffa0e6a098a5d4"},
]
[package.dependencies]
@@ -1173,13 +1239,13 @@ files = [
[[package]]
name = "jsonschema"
-version = "4.18.4"
+version = "4.19.0"
description = "An implementation of JSON Schema validation for Python"
optional = true
python-versions = ">=3.8"
files = [
- {file = "jsonschema-4.18.4-py3-none-any.whl", hash =
"sha256:971be834317c22daaa9132340a51c01b50910724082c2c1a2ac87eeec153a3fe"},
- {file = "jsonschema-4.18.4.tar.gz", hash =
"sha256:fb3642735399fa958c0d2aad7057901554596c63349f4f6b283c493cf692a25d"},
+ {file = "jsonschema-4.19.0-py3-none-any.whl", hash =
"sha256:043dc26a3845ff09d20e4420d6012a9c91c9aa8999fa184e7efcfeccb41e32cb"},
+ {file = "jsonschema-4.19.0.tar.gz", hash =
"sha256:6e1e7569ac13be8139b2dd2c21a55d350066ee3f80df06c608b398cdc6f30e8f"},
]
[package.dependencies]
@@ -1348,13 +1414,13 @@ files = [
[[package]]
name = "moto"
-version = "4.1.13"
+version = "4.1.14"
description = ""
optional = false
python-versions = ">=3.7"
files = [
- {file = "moto-4.1.13-py2.py3-none-any.whl", hash =
"sha256:9650d05d89b6f97043695548fbc0d8fb293f4177daaebbcee00bb0d171367f1a"},
- {file = "moto-4.1.13.tar.gz", hash =
"sha256:dd3e2ad920ab8b058c4f62fa7c195b788bd1f018cc701a1868ff5d5c4de6ed47"},
+ {file = "moto-4.1.14-py2.py3-none-any.whl", hash =
"sha256:7d3bd748a34641715ba469c761f72fb8ec18f349987c98f5a0f9be85a07a9911"},
+ {file = "moto-4.1.14.tar.gz", hash =
"sha256:545afeb4df94dfa730e2d7e87366dc26b4a33c2891f462cbb049f040c80ed1ec"},
]
[package.dependencies]
@@ -1369,17 +1435,17 @@ werkzeug = ">=0.5,<2.2.0 || >2.2.0,<2.2.1 || >2.2.1"
xmltodict = "*"
[package.extras]
-all = ["PyYAML (>=5.1)", "aws-xray-sdk (>=0.93,!=0.96)", "cfn-lint
(>=0.40.0)", "docker (>=3.0.0)", "ecdsa (!=0.15)", "graphql-core", "jsondiff
(>=1.1.2)", "openapi-spec-validator (>=0.2.8)", "py-partiql-parser (==0.3.3)",
"pyparsing (>=3.0.7)", "python-jose[cryptography] (>=3.1.0,<4.0.0)",
"setuptools", "sshpubkeys (>=3.1.0)"]
+all = ["PyYAML (>=5.1)", "aws-xray-sdk (>=0.93,!=0.96)", "cfn-lint
(>=0.40.0)", "docker (>=3.0.0)", "ecdsa (!=0.15)", "graphql-core", "jsondiff
(>=1.1.2)", "openapi-spec-validator (>=0.2.8)", "py-partiql-parser (==0.3.6)",
"pyparsing (>=3.0.7)", "python-jose[cryptography] (>=3.1.0,<4.0.0)",
"setuptools", "sshpubkeys (>=3.1.0)"]
apigateway = ["PyYAML (>=5.1)", "ecdsa (!=0.15)", "openapi-spec-validator
(>=0.2.8)", "python-jose[cryptography] (>=3.1.0,<4.0.0)"]
apigatewayv2 = ["PyYAML (>=5.1)"]
appsync = ["graphql-core"]
awslambda = ["docker (>=3.0.0)"]
batch = ["docker (>=3.0.0)"]
-cloudformation = ["PyYAML (>=5.1)", "aws-xray-sdk (>=0.93,!=0.96)", "cfn-lint
(>=0.40.0)", "docker (>=3.0.0)", "ecdsa (!=0.15)", "graphql-core", "jsondiff
(>=1.1.2)", "openapi-spec-validator (>=0.2.8)", "py-partiql-parser (==0.3.3)",
"pyparsing (>=3.0.7)", "python-jose[cryptography] (>=3.1.0,<4.0.0)",
"setuptools", "sshpubkeys (>=3.1.0)"]
+cloudformation = ["PyYAML (>=5.1)", "aws-xray-sdk (>=0.93,!=0.96)", "cfn-lint
(>=0.40.0)", "docker (>=3.0.0)", "ecdsa (!=0.15)", "graphql-core", "jsondiff
(>=1.1.2)", "openapi-spec-validator (>=0.2.8)", "py-partiql-parser (==0.3.6)",
"pyparsing (>=3.0.7)", "python-jose[cryptography] (>=3.1.0,<4.0.0)",
"setuptools", "sshpubkeys (>=3.1.0)"]
cognitoidp = ["ecdsa (!=0.15)", "python-jose[cryptography] (>=3.1.0,<4.0.0)"]
ds = ["sshpubkeys (>=3.1.0)"]
-dynamodb = ["docker (>=3.0.0)", "py-partiql-parser (==0.3.3)"]
-dynamodbstreams = ["docker (>=3.0.0)", "py-partiql-parser (==0.3.3)"]
+dynamodb = ["docker (>=3.0.0)", "py-partiql-parser (==0.3.6)"]
+dynamodbstreams = ["docker (>=3.0.0)", "py-partiql-parser (==0.3.6)"]
ebs = ["sshpubkeys (>=3.1.0)"]
ec2 = ["sshpubkeys (>=3.1.0)"]
efs = ["sshpubkeys (>=3.1.0)"]
@@ -1387,8 +1453,9 @@ eks = ["sshpubkeys (>=3.1.0)"]
glue = ["pyparsing (>=3.0.7)"]
iotdata = ["jsondiff (>=1.1.2)"]
route53resolver = ["sshpubkeys (>=3.1.0)"]
-s3 = ["PyYAML (>=5.1)", "py-partiql-parser (==0.3.3)"]
-server = ["PyYAML (>=5.1)", "aws-xray-sdk (>=0.93,!=0.96)", "cfn-lint
(>=0.40.0)", "docker (>=3.0.0)", "ecdsa (!=0.15)", "flask (!=2.2.0,!=2.2.1)",
"flask-cors", "graphql-core", "jsondiff (>=1.1.2)", "openapi-spec-validator
(>=0.2.8)", "py-partiql-parser (==0.3.3)", "pyparsing (>=3.0.7)",
"python-jose[cryptography] (>=3.1.0,<4.0.0)", "setuptools", "sshpubkeys
(>=3.1.0)"]
+s3 = ["PyYAML (>=5.1)", "py-partiql-parser (==0.3.6)"]
+s3crc32c = ["PyYAML (>=5.1)", "crc32c", "py-partiql-parser (==0.3.6)"]
+server = ["PyYAML (>=5.1)", "aws-xray-sdk (>=0.93,!=0.96)", "cfn-lint
(>=0.40.0)", "docker (>=3.0.0)", "ecdsa (!=0.15)", "flask (!=2.2.0,!=2.2.1)",
"flask-cors", "graphql-core", "jsondiff (>=1.1.2)", "openapi-spec-validator
(>=0.2.8)", "py-partiql-parser (==0.3.6)", "pyparsing (>=3.0.7)",
"python-jose[cryptography] (>=3.1.0,<4.0.0)", "setuptools", "sshpubkeys
(>=3.1.0)"]
ssm = ["PyYAML (>=5.1)"]
xray = ["aws-xray-sdk (>=0.93,!=0.96)", "setuptools"]
@@ -1726,18 +1793,18 @@ files = [
[[package]]
name = "platformdirs"
-version = "3.9.1"
+version = "3.10.0"
description = "A small Python package for determining appropriate
platform-specific dirs, e.g. a \"user data dir\"."
optional = false
python-versions = ">=3.7"
files = [
- {file = "platformdirs-3.9.1-py3-none-any.whl", hash =
"sha256:ad8291ae0ae5072f66c16945166cb11c63394c7a3ad1b1bc9828ca3162da8c2f"},
- {file = "platformdirs-3.9.1.tar.gz", hash =
"sha256:1b42b450ad933e981d56e59f1b97495428c9bd60698baab9f3eb3d00d5822421"},
+ {file = "platformdirs-3.10.0-py3-none-any.whl", hash =
"sha256:d7c24979f292f916dc9cbf8648319032f551ea8c49a4c9bf2fb556a02070ec1d"},
+ {file = "platformdirs-3.10.0.tar.gz", hash =
"sha256:b45696dab2d7cc691a3226759c0d3b00c47c8b6e293d96f6436f733303f77f6d"},
]
[package.extras]
-docs = ["furo (>=2023.5.20)", "proselint (>=0.13)", "sphinx (>=7.0.1)",
"sphinx-autodoc-typehints (>=1.23,!=1.23.4)"]
-test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)",
"pytest-cov (>=4.1)", "pytest-mock (>=3.10)"]
+docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.1)",
"sphinx-autodoc-typehints (>=1.24)"]
+test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)",
"pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)"]
[[package]]
name = "pluggy"
@@ -1793,95 +1860,93 @@ virtualenv = ">=20.10.0"
[[package]]
name = "protobuf"
-version = "4.23.4"
+version = "4.24.0"
description = ""
optional = true
python-versions = ">=3.7"
files = [
- {file = "protobuf-4.23.4-cp310-abi3-win32.whl", hash =
"sha256:5fea3c64d41ea5ecf5697b83e41d09b9589e6f20b677ab3c48e5f242d9b7897b"},
- {file = "protobuf-4.23.4-cp310-abi3-win_amd64.whl", hash =
"sha256:7b19b6266d92ca6a2a87effa88ecc4af73ebc5cfde194dc737cf8ef23a9a3b12"},
- {file = "protobuf-4.23.4-cp37-abi3-macosx_10_9_universal2.whl", hash =
"sha256:8547bf44fe8cec3c69e3042f5c4fb3e36eb2a7a013bb0a44c018fc1e427aafbd"},
- {file = "protobuf-4.23.4-cp37-abi3-manylinux2014_aarch64.whl", hash =
"sha256:fee88269a090ada09ca63551bf2f573eb2424035bcf2cb1b121895b01a46594a"},
- {file = "protobuf-4.23.4-cp37-abi3-manylinux2014_x86_64.whl", hash =
"sha256:effeac51ab79332d44fba74660d40ae79985901ac21bca408f8dc335a81aa597"},
- {file = "protobuf-4.23.4-cp37-cp37m-win32.whl", hash =
"sha256:c3e0939433c40796ca4cfc0fac08af50b00eb66a40bbbc5dee711998fb0bbc1e"},
- {file = "protobuf-4.23.4-cp37-cp37m-win_amd64.whl", hash =
"sha256:9053df6df8e5a76c84339ee4a9f5a2661ceee4a0dab019e8663c50ba324208b0"},
- {file = "protobuf-4.23.4-cp38-cp38-win32.whl", hash =
"sha256:e1c915778d8ced71e26fcf43c0866d7499891bca14c4368448a82edc61fdbc70"},
- {file = "protobuf-4.23.4-cp38-cp38-win_amd64.whl", hash =
"sha256:351cc90f7d10839c480aeb9b870a211e322bf05f6ab3f55fcb2f51331f80a7d2"},
- {file = "protobuf-4.23.4-cp39-cp39-win32.whl", hash =
"sha256:6dd9b9940e3f17077e820b75851126615ee38643c2c5332aa7a359988820c720"},
- {file = "protobuf-4.23.4-cp39-cp39-win_amd64.whl", hash =
"sha256:0a5759f5696895de8cc913f084e27fd4125e8fb0914bb729a17816a33819f474"},
- {file = "protobuf-4.23.4-py3-none-any.whl", hash =
"sha256:e9d0be5bf34b275b9f87ba7407796556abeeba635455d036c7351f7c183ef8ff"},
- {file = "protobuf-4.23.4.tar.gz", hash =
"sha256:ccd9430c0719dce806b93f89c91de7977304729e55377f872a92465d548329a9"},
+ {file = "protobuf-4.24.0-cp310-abi3-win32.whl", hash =
"sha256:81cb9c4621d2abfe181154354f63af1c41b00a4882fb230b4425cbaed65e8f52"},
+ {file = "protobuf-4.24.0-cp310-abi3-win_amd64.whl", hash =
"sha256:6c817cf4a26334625a1904b38523d1b343ff8b637d75d2c8790189a4064e51c3"},
+ {file = "protobuf-4.24.0-cp37-abi3-macosx_10_9_universal2.whl", hash =
"sha256:ae97b5de10f25b7a443b40427033e545a32b0e9dda17bcd8330d70033379b3e5"},
+ {file = "protobuf-4.24.0-cp37-abi3-manylinux2014_aarch64.whl", hash =
"sha256:567fe6b0647494845d0849e3d5b260bfdd75692bf452cdc9cb660d12457c055d"},
+ {file = "protobuf-4.24.0-cp37-abi3-manylinux2014_x86_64.whl", hash =
"sha256:a6b1ca92ccabfd9903c0c7dde8876221dc7d8d87ad5c42e095cc11b15d3569c7"},
+ {file = "protobuf-4.24.0-cp37-cp37m-win32.whl", hash =
"sha256:a38400a692fd0c6944c3c58837d112f135eb1ed6cdad5ca6c5763336e74f1a04"},
+ {file = "protobuf-4.24.0-cp37-cp37m-win_amd64.whl", hash =
"sha256:5ab19ee50037d4b663c02218a811a5e1e7bb30940c79aac385b96e7a4f9daa61"},
+ {file = "protobuf-4.24.0-cp38-cp38-win32.whl", hash =
"sha256:e8834ef0b4c88666ebb7c7ec18045aa0f4325481d724daa624a4cf9f28134653"},
+ {file = "protobuf-4.24.0-cp38-cp38-win_amd64.whl", hash =
"sha256:8bb52a2be32db82ddc623aefcedfe1e0eb51da60e18fcc908fb8885c81d72109"},
+ {file = "protobuf-4.24.0-cp39-cp39-win32.whl", hash =
"sha256:ae7a1835721086013de193311df858bc12cd247abe4ef9710b715d930b95b33e"},
+ {file = "protobuf-4.24.0-cp39-cp39-win_amd64.whl", hash =
"sha256:44825e963008f8ea0d26c51911c30d3e82e122997c3c4568fd0385dd7bacaedf"},
+ {file = "protobuf-4.24.0-py3-none-any.whl", hash =
"sha256:82e6e9ebdd15b8200e8423676eab38b774624d6a1ad696a60d86a2ac93f18201"},
+ {file = "protobuf-4.24.0.tar.gz", hash =
"sha256:5d0ceb9de6e08311832169e601d1fc71bd8e8c779f3ee38a97a78554945ecb85"},
]
[[package]]
name = "psycopg2-binary"
-version = "2.9.6"
+version = "2.9.7"
description = "psycopg2 - Python-PostgreSQL Database Adapter"
optional = true
python-versions = ">=3.6"
files = [
- {file = "psycopg2-binary-2.9.6.tar.gz", hash =
"sha256:1f64dcfb8f6e0c014c7f55e51c9759f024f70ea572fbdef123f85318c297947c"},
- {file = "psycopg2_binary-2.9.6-cp310-cp310-macosx_10_9_x86_64.whl", hash =
"sha256:d26e0342183c762de3276cca7a530d574d4e25121ca7d6e4a98e4f05cb8e4df7"},
- {file = "psycopg2_binary-2.9.6-cp310-cp310-macosx_11_0_arm64.whl", hash =
"sha256:c48d8f2db17f27d41fb0e2ecd703ea41984ee19362cbce52c097963b3a1b4365"},
- {file =
"psycopg2_binary-2.9.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
hash =
"sha256:ffe9dc0a884a8848075e576c1de0290d85a533a9f6e9c4e564f19adf8f6e54a7"},
- {file =
"psycopg2_binary-2.9.6-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl",
hash =
"sha256:8a76e027f87753f9bd1ab5f7c9cb8c7628d1077ef927f5e2446477153a602f2c"},
- {file =
"psycopg2_binary-2.9.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",
hash =
"sha256:6460c7a99fc939b849431f1e73e013d54aa54293f30f1109019c56a0b2b2ec2f"},
- {file =
"psycopg2_binary-2.9.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
hash =
"sha256:ae102a98c547ee2288637af07393dd33f440c25e5cd79556b04e3fca13325e5f"},
- {file = "psycopg2_binary-2.9.6-cp310-cp310-musllinux_1_1_aarch64.whl",
hash =
"sha256:9972aad21f965599ed0106f65334230ce826e5ae69fda7cbd688d24fa922415e"},
- {file = "psycopg2_binary-2.9.6-cp310-cp310-musllinux_1_1_i686.whl", hash =
"sha256:7a40c00dbe17c0af5bdd55aafd6ff6679f94a9be9513a4c7e071baf3d7d22a70"},
- {file = "psycopg2_binary-2.9.6-cp310-cp310-musllinux_1_1_ppc64le.whl",
hash =
"sha256:cacbdc5839bdff804dfebc058fe25684cae322987f7a38b0168bc1b2df703fb1"},
- {file = "psycopg2_binary-2.9.6-cp310-cp310-musllinux_1_1_x86_64.whl", hash
= "sha256:7f0438fa20fb6c7e202863e0d5ab02c246d35efb1d164e052f2f3bfe2b152bd0"},
- {file = "psycopg2_binary-2.9.6-cp310-cp310-win32.whl", hash =
"sha256:b6c8288bb8a84b47e07013bb4850f50538aa913d487579e1921724631d02ea1b"},
- {file = "psycopg2_binary-2.9.6-cp310-cp310-win_amd64.whl", hash =
"sha256:61b047a0537bbc3afae10f134dc6393823882eb263088c271331602b672e52e9"},
- {file = "psycopg2_binary-2.9.6-cp311-cp311-macosx_10_9_x86_64.whl", hash =
"sha256:964b4dfb7c1c1965ac4c1978b0f755cc4bd698e8aa2b7667c575fb5f04ebe06b"},
- {file = "psycopg2_binary-2.9.6-cp311-cp311-macosx_11_0_arm64.whl", hash =
"sha256:afe64e9b8ea66866a771996f6ff14447e8082ea26e675a295ad3bdbffdd72afb"},
- {file =
"psycopg2_binary-2.9.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
hash =
"sha256:15e2ee79e7cf29582ef770de7dab3d286431b01c3bb598f8e05e09601b890081"},
- {file =
"psycopg2_binary-2.9.6-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl",
hash =
"sha256:dfa74c903a3c1f0d9b1c7e7b53ed2d929a4910e272add6700c38f365a6002820"},
- {file =
"psycopg2_binary-2.9.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",
hash =
"sha256:b83456c2d4979e08ff56180a76429263ea254c3f6552cd14ada95cff1dec9bb8"},
- {file =
"psycopg2_binary-2.9.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
hash =
"sha256:0645376d399bfd64da57148694d78e1f431b1e1ee1054872a5713125681cf1be"},
- {file = "psycopg2_binary-2.9.6-cp311-cp311-musllinux_1_1_aarch64.whl",
hash =
"sha256:e99e34c82309dd78959ba3c1590975b5d3c862d6f279f843d47d26ff89d7d7e1"},
- {file = "psycopg2_binary-2.9.6-cp311-cp311-musllinux_1_1_i686.whl", hash =
"sha256:4ea29fc3ad9d91162c52b578f211ff1c931d8a38e1f58e684c45aa470adf19e2"},
- {file = "psycopg2_binary-2.9.6-cp311-cp311-musllinux_1_1_ppc64le.whl",
hash =
"sha256:4ac30da8b4f57187dbf449294d23b808f8f53cad6b1fc3623fa8a6c11d176dd0"},
- {file = "psycopg2_binary-2.9.6-cp311-cp311-musllinux_1_1_x86_64.whl", hash
= "sha256:e78e6e2a00c223e164c417628572a90093c031ed724492c763721c2e0bc2a8df"},
- {file = "psycopg2_binary-2.9.6-cp311-cp311-win32.whl", hash =
"sha256:1876843d8e31c89c399e31b97d4b9725a3575bb9c2af92038464231ec40f9edb"},
- {file = "psycopg2_binary-2.9.6-cp311-cp311-win_amd64.whl", hash =
"sha256:b4b24f75d16a89cc6b4cdff0eb6a910a966ecd476d1e73f7ce5985ff1328e9a6"},
- {file = "psycopg2_binary-2.9.6-cp36-cp36m-win32.whl", hash =
"sha256:498807b927ca2510baea1b05cc91d7da4718a0f53cb766c154c417a39f1820a0"},
- {file = "psycopg2_binary-2.9.6-cp36-cp36m-win_amd64.whl", hash =
"sha256:0d236c2825fa656a2d98bbb0e52370a2e852e5a0ec45fc4f402977313329174d"},
- {file = "psycopg2_binary-2.9.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash =
"sha256:34b9ccdf210cbbb1303c7c4db2905fa0319391bd5904d32689e6dd5c963d2ea8"},
- {file =
"psycopg2_binary-2.9.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
hash =
"sha256:84d2222e61f313c4848ff05353653bf5f5cf6ce34df540e4274516880d9c3763"},
- {file =
"psycopg2_binary-2.9.6-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl",
hash =
"sha256:30637a20623e2a2eacc420059be11527f4458ef54352d870b8181a4c3020ae6b"},
- {file =
"psycopg2_binary-2.9.6-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",
hash =
"sha256:8122cfc7cae0da9a3077216528b8bb3629c43b25053284cc868744bfe71eb141"},
- {file =
"psycopg2_binary-2.9.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
hash =
"sha256:38601cbbfe600362c43714482f43b7c110b20cb0f8172422c616b09b85a750c5"},
- {file = "psycopg2_binary-2.9.6-cp37-cp37m-musllinux_1_1_aarch64.whl", hash
= "sha256:c7e62ab8b332147a7593a385d4f368874d5fe4ad4e341770d4983442d89603e3"},
- {file = "psycopg2_binary-2.9.6-cp37-cp37m-musllinux_1_1_i686.whl", hash =
"sha256:2ab652e729ff4ad76d400df2624d223d6e265ef81bb8aa17fbd63607878ecbee"},
- {file = "psycopg2_binary-2.9.6-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash
= "sha256:c83a74b68270028dc8ee74d38ecfaf9c90eed23c8959fca95bd703d25b82c88e"},
- {file = "psycopg2_binary-2.9.6-cp37-cp37m-musllinux_1_1_x86_64.whl", hash
= "sha256:d4e6036decf4b72d6425d5b29bbd3e8f0ff1059cda7ac7b96d6ac5ed34ffbacd"},
- {file = "psycopg2_binary-2.9.6-cp37-cp37m-win32.whl", hash =
"sha256:a8c28fd40a4226b4a84bdf2d2b5b37d2c7bd49486b5adcc200e8c7ec991dfa7e"},
- {file = "psycopg2_binary-2.9.6-cp37-cp37m-win_amd64.whl", hash =
"sha256:51537e3d299be0db9137b321dfb6a5022caaab275775680e0c3d281feefaca6b"},
- {file = "psycopg2_binary-2.9.6-cp38-cp38-macosx_10_9_x86_64.whl", hash =
"sha256:cf4499e0a83b7b7edcb8dabecbd8501d0d3a5ef66457200f77bde3d210d5debb"},
- {file = "psycopg2_binary-2.9.6-cp38-cp38-macosx_11_0_arm64.whl", hash =
"sha256:7e13a5a2c01151f1208d5207e42f33ba86d561b7a89fca67c700b9486a06d0e2"},
- {file =
"psycopg2_binary-2.9.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
hash =
"sha256:0e0f754d27fddcfd74006455b6e04e6705d6c31a612ec69ddc040a5468e44b4e"},
- {file =
"psycopg2_binary-2.9.6-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl",
hash =
"sha256:d57c3fd55d9058645d26ae37d76e61156a27722097229d32a9e73ed54819982a"},
- {file =
"psycopg2_binary-2.9.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",
hash =
"sha256:71f14375d6f73b62800530b581aed3ada394039877818b2d5f7fc77e3bb6894d"},
- {file =
"psycopg2_binary-2.9.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
hash =
"sha256:441cc2f8869a4f0f4bb408475e5ae0ee1f3b55b33f350406150277f7f35384fc"},
- {file = "psycopg2_binary-2.9.6-cp38-cp38-musllinux_1_1_aarch64.whl", hash
= "sha256:65bee1e49fa6f9cf327ce0e01c4c10f39165ee76d35c846ade7cb0ec6683e303"},
- {file = "psycopg2_binary-2.9.6-cp38-cp38-musllinux_1_1_i686.whl", hash =
"sha256:af335bac6b666cc6aea16f11d486c3b794029d9df029967f9938a4bed59b6a19"},
- {file = "psycopg2_binary-2.9.6-cp38-cp38-musllinux_1_1_ppc64le.whl", hash
= "sha256:cfec476887aa231b8548ece2e06d28edc87c1397ebd83922299af2e051cf2827"},
- {file = "psycopg2_binary-2.9.6-cp38-cp38-musllinux_1_1_x86_64.whl", hash =
"sha256:65c07febd1936d63bfde78948b76cd4c2a411572a44ac50719ead41947d0f26b"},
- {file = "psycopg2_binary-2.9.6-cp38-cp38-win32.whl", hash =
"sha256:4dfb4be774c4436a4526d0c554af0cc2e02082c38303852a36f6456ece7b3503"},
- {file = "psycopg2_binary-2.9.6-cp38-cp38-win_amd64.whl", hash =
"sha256:02c6e3cf3439e213e4ee930308dc122d6fb4d4bea9aef4a12535fbd605d1a2fe"},
- {file = "psycopg2_binary-2.9.6-cp39-cp39-macosx_10_9_x86_64.whl", hash =
"sha256:e9182eb20f41417ea1dd8e8f7888c4d7c6e805f8a7c98c1081778a3da2bee3e4"},
- {file = "psycopg2_binary-2.9.6-cp39-cp39-macosx_11_0_arm64.whl", hash =
"sha256:8a6979cf527e2603d349a91060f428bcb135aea2be3201dff794813256c274f1"},
- {file =
"psycopg2_binary-2.9.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
hash =
"sha256:8338a271cb71d8da40b023a35d9c1e919eba6cbd8fa20a54b748a332c355d896"},
- {file =
"psycopg2_binary-2.9.6-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl",
hash =
"sha256:e3ed340d2b858d6e6fb5083f87c09996506af483227735de6964a6100b4e6a54"},
- {file =
"psycopg2_binary-2.9.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",
hash =
"sha256:f81e65376e52f03422e1fb475c9514185669943798ed019ac50410fb4c4df232"},
- {file =
"psycopg2_binary-2.9.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
hash =
"sha256:bfb13af3c5dd3a9588000910178de17010ebcccd37b4f9794b00595e3a8ddad3"},
- {file = "psycopg2_binary-2.9.6-cp39-cp39-musllinux_1_1_aarch64.whl", hash
= "sha256:4c727b597c6444a16e9119386b59388f8a424223302d0c06c676ec8b4bc1f963"},
- {file = "psycopg2_binary-2.9.6-cp39-cp39-musllinux_1_1_i686.whl", hash =
"sha256:4d67fbdaf177da06374473ef6f7ed8cc0a9dc640b01abfe9e8a2ccb1b1402c1f"},
- {file = "psycopg2_binary-2.9.6-cp39-cp39-musllinux_1_1_ppc64le.whl", hash
= "sha256:0892ef645c2fabb0c75ec32d79f4252542d0caec1d5d949630e7d242ca4681a3"},
- {file = "psycopg2_binary-2.9.6-cp39-cp39-musllinux_1_1_x86_64.whl", hash =
"sha256:02c0f3757a4300cf379eb49f543fb7ac527fb00144d39246ee40e1df684ab514"},
- {file = "psycopg2_binary-2.9.6-cp39-cp39-win32.whl", hash =
"sha256:c3dba7dab16709a33a847e5cd756767271697041fbe3fe97c215b1fc1f5c9848"},
- {file = "psycopg2_binary-2.9.6-cp39-cp39-win_amd64.whl", hash =
"sha256:f6a88f384335bb27812293fdb11ac6aee2ca3f51d3c7820fe03de0a304ab6249"},
+ {file = "psycopg2-binary-2.9.7.tar.gz", hash =
"sha256:1b918f64a51ffe19cd2e230b3240ba481330ce1d4b7875ae67305bd1d37b041c"},
+ {file = "psycopg2_binary-2.9.7-cp310-cp310-macosx_10_9_x86_64.whl", hash =
"sha256:ea5f8ee87f1eddc818fc04649d952c526db4426d26bab16efbe5a0c52b27d6ab"},
+ {file = "psycopg2_binary-2.9.7-cp310-cp310-macosx_11_0_arm64.whl", hash =
"sha256:2993ccb2b7e80844d534e55e0f12534c2871952f78e0da33c35e648bf002bbff"},
+ {file =
"psycopg2_binary-2.9.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
hash =
"sha256:dbbc3c5d15ed76b0d9db7753c0db40899136ecfe97d50cbde918f630c5eb857a"},
+ {file =
"psycopg2_binary-2.9.7-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl",
hash =
"sha256:692df8763b71d42eb8343f54091368f6f6c9cfc56dc391858cdb3c3ef1e3e584"},
+ {file =
"psycopg2_binary-2.9.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",
hash =
"sha256:9dcfd5d37e027ec393a303cc0a216be564b96c80ba532f3d1e0d2b5e5e4b1e6e"},
+ {file =
"psycopg2_binary-2.9.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
hash =
"sha256:17cc17a70dfb295a240db7f65b6d8153c3d81efb145d76da1e4a096e9c5c0e63"},
+ {file = "psycopg2_binary-2.9.7-cp310-cp310-musllinux_1_1_aarch64.whl",
hash =
"sha256:e5666632ba2b0d9757b38fc17337d84bdf932d38563c5234f5f8c54fd01349c9"},
+ {file = "psycopg2_binary-2.9.7-cp310-cp310-musllinux_1_1_i686.whl", hash =
"sha256:7db7b9b701974c96a88997d458b38ccb110eba8f805d4b4f74944aac48639b42"},
+ {file = "psycopg2_binary-2.9.7-cp310-cp310-musllinux_1_1_ppc64le.whl",
hash =
"sha256:c82986635a16fb1fa15cd5436035c88bc65c3d5ced1cfaac7f357ee9e9deddd4"},
+ {file = "psycopg2_binary-2.9.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash
= "sha256:4fe13712357d802080cfccbf8c6266a3121dc0e27e2144819029095ccf708372"},
+ {file = "psycopg2_binary-2.9.7-cp310-cp310-win32.whl", hash =
"sha256:122641b7fab18ef76b18860dd0c772290566b6fb30cc08e923ad73d17461dc63"},
+ {file = "psycopg2_binary-2.9.7-cp310-cp310-win_amd64.whl", hash =
"sha256:f8651cf1f144f9ee0fa7d1a1df61a9184ab72962531ca99f077bbdcba3947c58"},
+ {file = "psycopg2_binary-2.9.7-cp311-cp311-macosx_10_9_x86_64.whl", hash =
"sha256:4ecc15666f16f97709106d87284c136cdc82647e1c3f8392a672616aed3c7151"},
+ {file = "psycopg2_binary-2.9.7-cp311-cp311-macosx_11_0_arm64.whl", hash =
"sha256:3fbb1184c7e9d28d67671992970718c05af5f77fc88e26fd7136613c4ece1f89"},
+ {file =
"psycopg2_binary-2.9.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
hash =
"sha256:8a7968fd20bd550431837656872c19575b687f3f6f98120046228e451e4064df"},
+ {file =
"psycopg2_binary-2.9.7-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl",
hash =
"sha256:094af2e77a1976efd4956a031028774b827029729725e136514aae3cdf49b87b"},
+ {file =
"psycopg2_binary-2.9.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",
hash =
"sha256:26484e913d472ecb6b45937ea55ce29c57c662066d222fb0fbdc1fab457f18c5"},
+ {file =
"psycopg2_binary-2.9.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
hash =
"sha256:8f309b77a7c716e6ed9891b9b42953c3ff7d533dc548c1e33fddc73d2f5e21f9"},
+ {file = "psycopg2_binary-2.9.7-cp311-cp311-musllinux_1_1_aarch64.whl",
hash =
"sha256:6d92e139ca388ccfe8c04aacc163756e55ba4c623c6ba13d5d1595ed97523e4b"},
+ {file = "psycopg2_binary-2.9.7-cp311-cp311-musllinux_1_1_i686.whl", hash =
"sha256:2df562bb2e4e00ee064779902d721223cfa9f8f58e7e52318c97d139cf7f012d"},
+ {file = "psycopg2_binary-2.9.7-cp311-cp311-musllinux_1_1_ppc64le.whl",
hash =
"sha256:4eec5d36dbcfc076caab61a2114c12094c0b7027d57e9e4387b634e8ab36fd44"},
+ {file = "psycopg2_binary-2.9.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash
= "sha256:1011eeb0c51e5b9ea1016f0f45fa23aca63966a4c0afcf0340ccabe85a9f65bd"},
+ {file = "psycopg2_binary-2.9.7-cp311-cp311-win32.whl", hash =
"sha256:ded8e15f7550db9e75c60b3d9fcbc7737fea258a0f10032cdb7edc26c2a671fd"},
+ {file = "psycopg2_binary-2.9.7-cp311-cp311-win_amd64.whl", hash =
"sha256:8a136c8aaf6615653450817a7abe0fc01e4ea720ae41dfb2823eccae4b9062a3"},
+ {file = "psycopg2_binary-2.9.7-cp37-cp37m-macosx_10_9_x86_64.whl", hash =
"sha256:2dec5a75a3a5d42b120e88e6ed3e3b37b46459202bb8e36cd67591b6e5feebc1"},
+ {file =
"psycopg2_binary-2.9.7-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
hash =
"sha256:fc10da7e7df3380426521e8c1ed975d22df678639da2ed0ec3244c3dc2ab54c8"},
+ {file =
"psycopg2_binary-2.9.7-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl",
hash =
"sha256:ee919b676da28f78f91b464fb3e12238bd7474483352a59c8a16c39dfc59f0c5"},
+ {file =
"psycopg2_binary-2.9.7-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",
hash =
"sha256:eb1c0e682138f9067a58fc3c9a9bf1c83d8e08cfbee380d858e63196466d5c86"},
+ {file =
"psycopg2_binary-2.9.7-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
hash =
"sha256:00d8db270afb76f48a499f7bb8fa70297e66da67288471ca873db88382850bf4"},
+ {file = "psycopg2_binary-2.9.7-cp37-cp37m-musllinux_1_1_aarch64.whl", hash
= "sha256:9b0c2b466b2f4d89ccc33784c4ebb1627989bd84a39b79092e560e937a11d4ac"},
+ {file = "psycopg2_binary-2.9.7-cp37-cp37m-musllinux_1_1_i686.whl", hash =
"sha256:51d1b42d44f4ffb93188f9b39e6d1c82aa758fdb8d9de65e1ddfe7a7d250d7ad"},
+ {file = "psycopg2_binary-2.9.7-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash
= "sha256:11abdbfc6f7f7dea4a524b5f4117369b0d757725798f1593796be6ece20266cb"},
+ {file = "psycopg2_binary-2.9.7-cp37-cp37m-musllinux_1_1_x86_64.whl", hash
= "sha256:f02f4a72cc3ab2565c6d9720f0343cb840fb2dc01a2e9ecb8bc58ccf95dc5c06"},
+ {file = "psycopg2_binary-2.9.7-cp37-cp37m-win32.whl", hash =
"sha256:81d5dd2dd9ab78d31a451e357315f201d976c131ca7d43870a0e8063b6b7a1ec"},
+ {file = "psycopg2_binary-2.9.7-cp37-cp37m-win_amd64.whl", hash =
"sha256:62cb6de84d7767164a87ca97e22e5e0a134856ebcb08f21b621c6125baf61f16"},
+ {file = "psycopg2_binary-2.9.7-cp38-cp38-macosx_10_9_x86_64.whl", hash =
"sha256:59f7e9109a59dfa31efa022e94a244736ae401526682de504e87bd11ce870c22"},
+ {file = "psycopg2_binary-2.9.7-cp38-cp38-macosx_11_0_arm64.whl", hash =
"sha256:95a7a747bdc3b010bb6a980f053233e7610276d55f3ca506afff4ad7749ab58a"},
+ {file =
"psycopg2_binary-2.9.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
hash =
"sha256:8c721ee464e45ecf609ff8c0a555018764974114f671815a0a7152aedb9f3343"},
+ {file =
"psycopg2_binary-2.9.7-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl",
hash =
"sha256:f4f37bbc6588d402980ffbd1f3338c871368fb4b1cfa091debe13c68bb3852b3"},
+ {file =
"psycopg2_binary-2.9.7-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",
hash =
"sha256:ac83ab05e25354dad798401babaa6daa9577462136ba215694865394840e31f8"},
+ {file =
"psycopg2_binary-2.9.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
hash =
"sha256:024eaeb2a08c9a65cd5f94b31ace1ee3bb3f978cd4d079406aef85169ba01f08"},
+ {file = "psycopg2_binary-2.9.7-cp38-cp38-musllinux_1_1_aarch64.whl", hash
= "sha256:1c31c2606ac500dbd26381145684d87730a2fac9a62ebcfbaa2b119f8d6c19f4"},
+ {file = "psycopg2_binary-2.9.7-cp38-cp38-musllinux_1_1_i686.whl", hash =
"sha256:42a62ef0e5abb55bf6ffb050eb2b0fcd767261fa3faf943a4267539168807522"},
+ {file = "psycopg2_binary-2.9.7-cp38-cp38-musllinux_1_1_ppc64le.whl", hash
= "sha256:7952807f95c8eba6a8ccb14e00bf170bb700cafcec3924d565235dffc7dc4ae8"},
+ {file = "psycopg2_binary-2.9.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash =
"sha256:e02bc4f2966475a7393bd0f098e1165d470d3fa816264054359ed4f10f6914ea"},
+ {file = "psycopg2_binary-2.9.7-cp38-cp38-win32.whl", hash =
"sha256:fdca0511458d26cf39b827a663d7d87db6f32b93efc22442a742035728603d5f"},
+ {file = "psycopg2_binary-2.9.7-cp38-cp38-win_amd64.whl", hash =
"sha256:d0b16e5bb0ab78583f0ed7ab16378a0f8a89a27256bb5560402749dbe8a164d7"},
+ {file = "psycopg2_binary-2.9.7-cp39-cp39-macosx_10_9_x86_64.whl", hash =
"sha256:6822c9c63308d650db201ba22fe6648bd6786ca6d14fdaf273b17e15608d0852"},
+ {file = "psycopg2_binary-2.9.7-cp39-cp39-macosx_11_0_arm64.whl", hash =
"sha256:8f94cb12150d57ea433e3e02aabd072205648e86f1d5a0a692d60242f7809b15"},
+ {file =
"psycopg2_binary-2.9.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
hash =
"sha256:a5ee89587696d808c9a00876065d725d4ae606f5f7853b961cdbc348b0f7c9a1"},
+ {file =
"psycopg2_binary-2.9.7-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl",
hash =
"sha256:ad5ec10b53cbb57e9a2e77b67e4e4368df56b54d6b00cc86398578f1c635f329"},
+ {file =
"psycopg2_binary-2.9.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",
hash =
"sha256:642df77484b2dcaf87d4237792246d8068653f9e0f5c025e2c692fc56b0dda70"},
+ {file =
"psycopg2_binary-2.9.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
hash =
"sha256:a6a8b575ac45af1eaccbbcdcf710ab984fd50af048fe130672377f78aaff6fc1"},
+ {file = "psycopg2_binary-2.9.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash
= "sha256:f955aa50d7d5220fcb6e38f69ea126eafecd812d96aeed5d5f3597f33fad43bb"},
+ {file = "psycopg2_binary-2.9.7-cp39-cp39-musllinux_1_1_i686.whl", hash =
"sha256:ad26d4eeaa0d722b25814cce97335ecf1b707630258f14ac4d2ed3d1d8415265"},
+ {file = "psycopg2_binary-2.9.7-cp39-cp39-musllinux_1_1_ppc64le.whl", hash
= "sha256:ced63c054bdaf0298f62681d5dcae3afe60cbae332390bfb1acf0e23dcd25fc8"},
+ {file = "psycopg2_binary-2.9.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash =
"sha256:2b04da24cbde33292ad34a40db9832a80ad12de26486ffeda883413c9e1b1d5e"},
+ {file = "psycopg2_binary-2.9.7-cp39-cp39-win32.whl", hash =
"sha256:18f12632ab516c47c1ac4841a78fddea6508a8284c7cf0f292cb1a523f2e2379"},
+ {file = "psycopg2_binary-2.9.7-cp39-cp39-win_amd64.whl", hash =
"sha256:eb3b8d55924a6058a26db69fb1d3e7e32695ff8b491835ba9f479537e14dcf9f"},
]
[[package]]
@@ -1934,47 +1999,47 @@ files = [
[[package]]
name = "pydantic"
-version = "1.10.11"
+version = "1.10.12"
description = "Data validation and settings management using python type hints"
optional = false
python-versions = ">=3.7"
files = [
- {file = "pydantic-1.10.11-cp310-cp310-macosx_10_9_x86_64.whl", hash =
"sha256:ff44c5e89315b15ff1f7fdaf9853770b810936d6b01a7bcecaa227d2f8fe444f"},
- {file = "pydantic-1.10.11-cp310-cp310-macosx_11_0_arm64.whl", hash =
"sha256:a6c098d4ab5e2d5b3984d3cb2527e2d6099d3de85630c8934efcfdc348a9760e"},
- {file =
"pydantic-1.10.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
hash =
"sha256:16928fdc9cb273c6af00d9d5045434c39afba5f42325fb990add2c241402d151"},
- {file =
"pydantic-1.10.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",
hash =
"sha256:0588788a9a85f3e5e9ebca14211a496409cb3deca5b6971ff37c556d581854e7"},
- {file = "pydantic-1.10.11-cp310-cp310-musllinux_1_1_i686.whl", hash =
"sha256:e9baf78b31da2dc3d3f346ef18e58ec5f12f5aaa17ac517e2ffd026a92a87588"},
- {file = "pydantic-1.10.11-cp310-cp310-musllinux_1_1_x86_64.whl", hash =
"sha256:373c0840f5c2b5b1ccadd9286782852b901055998136287828731868027a724f"},
- {file = "pydantic-1.10.11-cp310-cp310-win_amd64.whl", hash =
"sha256:c3339a46bbe6013ef7bdd2844679bfe500347ac5742cd4019a88312aa58a9847"},
- {file = "pydantic-1.10.11-cp311-cp311-macosx_10_9_x86_64.whl", hash =
"sha256:08a6c32e1c3809fbc49debb96bf833164f3438b3696abf0fbeceb417d123e6eb"},
- {file = "pydantic-1.10.11-cp311-cp311-macosx_11_0_arm64.whl", hash =
"sha256:a451ccab49971af043ec4e0d207cbc8cbe53dbf148ef9f19599024076fe9c25b"},
- {file =
"pydantic-1.10.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
hash =
"sha256:5b02d24f7b2b365fed586ed73582c20f353a4c50e4be9ba2c57ab96f8091ddae"},
- {file =
"pydantic-1.10.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",
hash =
"sha256:3f34739a89260dfa420aa3cbd069fbcc794b25bbe5c0a214f8fb29e363484b66"},
- {file = "pydantic-1.10.11-cp311-cp311-musllinux_1_1_i686.whl", hash =
"sha256:e297897eb4bebde985f72a46a7552a7556a3dd11e7f76acda0c1093e3dbcf216"},
- {file = "pydantic-1.10.11-cp311-cp311-musllinux_1_1_x86_64.whl", hash =
"sha256:d185819a7a059550ecb85d5134e7d40f2565f3dd94cfd870132c5f91a89cf58c"},
- {file = "pydantic-1.10.11-cp311-cp311-win_amd64.whl", hash =
"sha256:4400015f15c9b464c9db2d5d951b6a780102cfa5870f2c036d37c23b56f7fc1b"},
- {file = "pydantic-1.10.11-cp37-cp37m-macosx_10_9_x86_64.whl", hash =
"sha256:2417de68290434461a266271fc57274a138510dca19982336639484c73a07af6"},
- {file =
"pydantic-1.10.11-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
hash =
"sha256:331c031ba1554b974c98679bd0780d89670d6fd6f53f5d70b10bdc9addee1713"},
- {file =
"pydantic-1.10.11-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",
hash =
"sha256:8268a735a14c308923e8958363e3a3404f6834bb98c11f5ab43251a4e410170c"},
- {file = "pydantic-1.10.11-cp37-cp37m-musllinux_1_1_i686.whl", hash =
"sha256:44e51ba599c3ef227e168424e220cd3e544288c57829520dc90ea9cb190c3248"},
- {file = "pydantic-1.10.11-cp37-cp37m-musllinux_1_1_x86_64.whl", hash =
"sha256:d7781f1d13b19700b7949c5a639c764a077cbbdd4322ed505b449d3ca8edcb36"},
- {file = "pydantic-1.10.11-cp37-cp37m-win_amd64.whl", hash =
"sha256:7522a7666157aa22b812ce14c827574ddccc94f361237ca6ea8bb0d5c38f1629"},
- {file = "pydantic-1.10.11-cp38-cp38-macosx_10_9_x86_64.whl", hash =
"sha256:bc64eab9b19cd794a380179ac0e6752335e9555d214cfcb755820333c0784cb3"},
- {file = "pydantic-1.10.11-cp38-cp38-macosx_11_0_arm64.whl", hash =
"sha256:8dc77064471780262b6a68fe67e013298d130414d5aaf9b562c33987dbd2cf4f"},
- {file =
"pydantic-1.10.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
hash =
"sha256:fe429898f2c9dd209bd0632a606bddc06f8bce081bbd03d1c775a45886e2c1cb"},
- {file =
"pydantic-1.10.11-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",
hash =
"sha256:192c608ad002a748e4a0bed2ddbcd98f9b56df50a7c24d9a931a8c5dd053bd3d"},
- {file = "pydantic-1.10.11-cp38-cp38-musllinux_1_1_i686.whl", hash =
"sha256:ef55392ec4bb5721f4ded1096241e4b7151ba6d50a50a80a2526c854f42e6a2f"},
- {file = "pydantic-1.10.11-cp38-cp38-musllinux_1_1_x86_64.whl", hash =
"sha256:41e0bb6efe86281623abbeeb0be64eab740c865388ee934cd3e6a358784aca6e"},
- {file = "pydantic-1.10.11-cp38-cp38-win_amd64.whl", hash =
"sha256:265a60da42f9f27e0b1014eab8acd3e53bd0bad5c5b4884e98a55f8f596b2c19"},
- {file = "pydantic-1.10.11-cp39-cp39-macosx_10_9_x86_64.whl", hash =
"sha256:469adf96c8e2c2bbfa655fc7735a2a82f4c543d9fee97bd113a7fb509bf5e622"},
- {file = "pydantic-1.10.11-cp39-cp39-macosx_11_0_arm64.whl", hash =
"sha256:e6cbfbd010b14c8a905a7b10f9fe090068d1744d46f9e0c021db28daeb8b6de1"},
- {file =
"pydantic-1.10.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
hash =
"sha256:abade85268cc92dff86d6effcd917893130f0ff516f3d637f50dadc22ae93999"},
- {file =
"pydantic-1.10.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",
hash =
"sha256:e9738b0f2e6c70f44ee0de53f2089d6002b10c33264abee07bdb5c7f03038303"},
- {file = "pydantic-1.10.11-cp39-cp39-musllinux_1_1_i686.whl", hash =
"sha256:787cf23e5a0cde753f2eabac1b2e73ae3844eb873fd1f5bdbff3048d8dbb7604"},
- {file = "pydantic-1.10.11-cp39-cp39-musllinux_1_1_x86_64.whl", hash =
"sha256:174899023337b9fc685ac8adaa7b047050616136ccd30e9070627c1aaab53a13"},
- {file = "pydantic-1.10.11-cp39-cp39-win_amd64.whl", hash =
"sha256:1954f8778489a04b245a1e7b8b22a9d3ea8ef49337285693cf6959e4b757535e"},
- {file = "pydantic-1.10.11-py3-none-any.whl", hash =
"sha256:008c5e266c8aada206d0627a011504e14268a62091450210eda7c07fabe6963e"},
- {file = "pydantic-1.10.11.tar.gz", hash =
"sha256:f66d479cf7eb331372c470614be6511eae96f1f120344c25f3f9bb59fb1b5528"},
+ {file = "pydantic-1.10.12-cp310-cp310-macosx_10_9_x86_64.whl", hash =
"sha256:a1fcb59f2f355ec350073af41d927bf83a63b50e640f4dbaa01053a28b7a7718"},
+ {file = "pydantic-1.10.12-cp310-cp310-macosx_11_0_arm64.whl", hash =
"sha256:b7ccf02d7eb340b216ec33e53a3a629856afe1c6e0ef91d84a4e6f2fb2ca70fe"},
+ {file =
"pydantic-1.10.12-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
hash =
"sha256:8fb2aa3ab3728d950bcc885a2e9eff6c8fc40bc0b7bb434e555c215491bcf48b"},
+ {file =
"pydantic-1.10.12-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",
hash =
"sha256:771735dc43cf8383959dc9b90aa281f0b6092321ca98677c5fb6125a6f56d58d"},
+ {file = "pydantic-1.10.12-cp310-cp310-musllinux_1_1_i686.whl", hash =
"sha256:ca48477862372ac3770969b9d75f1bf66131d386dba79506c46d75e6b48c1e09"},
+ {file = "pydantic-1.10.12-cp310-cp310-musllinux_1_1_x86_64.whl", hash =
"sha256:a5e7add47a5b5a40c49b3036d464e3c7802f8ae0d1e66035ea16aa5b7a3923ed"},
+ {file = "pydantic-1.10.12-cp310-cp310-win_amd64.whl", hash =
"sha256:e4129b528c6baa99a429f97ce733fff478ec955513630e61b49804b6cf9b224a"},
+ {file = "pydantic-1.10.12-cp311-cp311-macosx_10_9_x86_64.whl", hash =
"sha256:b0d191db0f92dfcb1dec210ca244fdae5cbe918c6050b342d619c09d31eea0cc"},
+ {file = "pydantic-1.10.12-cp311-cp311-macosx_11_0_arm64.whl", hash =
"sha256:795e34e6cc065f8f498c89b894a3c6da294a936ee71e644e4bd44de048af1405"},
+ {file =
"pydantic-1.10.12-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
hash =
"sha256:69328e15cfda2c392da4e713443c7dbffa1505bc9d566e71e55abe14c97ddc62"},
+ {file =
"pydantic-1.10.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",
hash =
"sha256:2031de0967c279df0d8a1c72b4ffc411ecd06bac607a212892757db7462fc494"},
+ {file = "pydantic-1.10.12-cp311-cp311-musllinux_1_1_i686.whl", hash =
"sha256:ba5b2e6fe6ca2b7e013398bc7d7b170e21cce322d266ffcd57cca313e54fb246"},
+ {file = "pydantic-1.10.12-cp311-cp311-musllinux_1_1_x86_64.whl", hash =
"sha256:2a7bac939fa326db1ab741c9d7f44c565a1d1e80908b3797f7f81a4f86bc8d33"},
+ {file = "pydantic-1.10.12-cp311-cp311-win_amd64.whl", hash =
"sha256:87afda5539d5140cb8ba9e8b8c8865cb5b1463924d38490d73d3ccfd80896b3f"},
+ {file = "pydantic-1.10.12-cp37-cp37m-macosx_10_9_x86_64.whl", hash =
"sha256:549a8e3d81df0a85226963611950b12d2d334f214436a19537b2efed61b7639a"},
+ {file =
"pydantic-1.10.12-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
hash =
"sha256:598da88dfa127b666852bef6d0d796573a8cf5009ffd62104094a4fe39599565"},
+ {file =
"pydantic-1.10.12-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",
hash =
"sha256:ba5c4a8552bff16c61882db58544116d021d0b31ee7c66958d14cf386a5b5350"},
+ {file = "pydantic-1.10.12-cp37-cp37m-musllinux_1_1_i686.whl", hash =
"sha256:c79e6a11a07da7374f46970410b41d5e266f7f38f6a17a9c4823db80dadf4303"},
+ {file = "pydantic-1.10.12-cp37-cp37m-musllinux_1_1_x86_64.whl", hash =
"sha256:ab26038b8375581dc832a63c948f261ae0aa21f1d34c1293469f135fa92972a5"},
+ {file = "pydantic-1.10.12-cp37-cp37m-win_amd64.whl", hash =
"sha256:e0a16d274b588767602b7646fa05af2782576a6cf1022f4ba74cbb4db66f6ca8"},
+ {file = "pydantic-1.10.12-cp38-cp38-macosx_10_9_x86_64.whl", hash =
"sha256:6a9dfa722316f4acf4460afdf5d41d5246a80e249c7ff475c43a3a1e9d75cf62"},
+ {file = "pydantic-1.10.12-cp38-cp38-macosx_11_0_arm64.whl", hash =
"sha256:a73f489aebd0c2121ed974054cb2759af8a9f747de120acd2c3394cf84176ccb"},
+ {file =
"pydantic-1.10.12-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
hash =
"sha256:6b30bcb8cbfccfcf02acb8f1a261143fab622831d9c0989707e0e659f77a18e0"},
+ {file =
"pydantic-1.10.12-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",
hash =
"sha256:2fcfb5296d7877af406ba1547dfde9943b1256d8928732267e2653c26938cd9c"},
+ {file = "pydantic-1.10.12-cp38-cp38-musllinux_1_1_i686.whl", hash =
"sha256:2f9a6fab5f82ada41d56b0602606a5506aab165ca54e52bc4545028382ef1c5d"},
+ {file = "pydantic-1.10.12-cp38-cp38-musllinux_1_1_x86_64.whl", hash =
"sha256:dea7adcc33d5d105896401a1f37d56b47d443a2b2605ff8a969a0ed5543f7e33"},
+ {file = "pydantic-1.10.12-cp38-cp38-win_amd64.whl", hash =
"sha256:1eb2085c13bce1612da8537b2d90f549c8cbb05c67e8f22854e201bde5d98a47"},
+ {file = "pydantic-1.10.12-cp39-cp39-macosx_10_9_x86_64.whl", hash =
"sha256:ef6c96b2baa2100ec91a4b428f80d8f28a3c9e53568219b6c298c1125572ebc6"},
+ {file = "pydantic-1.10.12-cp39-cp39-macosx_11_0_arm64.whl", hash =
"sha256:6c076be61cd0177a8433c0adcb03475baf4ee91edf5a4e550161ad57fc90f523"},
+ {file =
"pydantic-1.10.12-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
hash =
"sha256:2d5a58feb9a39f481eda4d5ca220aa8b9d4f21a41274760b9bc66bfd72595b86"},
+ {file =
"pydantic-1.10.12-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl",
hash =
"sha256:e5f805d2d5d0a41633651a73fa4ecdd0b3d7a49de4ec3fadf062fe16501ddbf1"},
+ {file = "pydantic-1.10.12-cp39-cp39-musllinux_1_1_i686.whl", hash =
"sha256:1289c180abd4bd4555bb927c42ee42abc3aee02b0fb2d1223fb7c6e5bef87dbe"},
+ {file = "pydantic-1.10.12-cp39-cp39-musllinux_1_1_x86_64.whl", hash =
"sha256:5d1197e462e0364906cbc19681605cb7c036f2475c899b6f296104ad42b9f5fb"},
+ {file = "pydantic-1.10.12-cp39-cp39-win_amd64.whl", hash =
"sha256:fdbdd1d630195689f325c9ef1a12900524dceb503b00a987663ff4f58669b93d"},
+ {file = "pydantic-1.10.12-py3-none-any.whl", hash =
"sha256:b749a43aa51e32839c9d71dc67eb1e4221bb04af1033a32e3923d46f9effa942"},
+ {file = "pydantic-1.10.12.tar.gz", hash =
"sha256:0fe8a415cea8f340e7a9af9c54fc71a649b43e8ca3cc732986116b3cb135d303"},
]
[package.dependencies]
@@ -1986,13 +2051,13 @@ email = ["email-validator (>=1.0.3)"]
[[package]]
name = "pygments"
-version = "2.15.1"
+version = "2.16.1"
description = "Pygments is a syntax highlighting package written in Python."
optional = false
python-versions = ">=3.7"
files = [
- {file = "Pygments-2.15.1-py3-none-any.whl", hash =
"sha256:db2db3deb4b4179f399a09054b023b6a586b76499d36965813c71aa8ed7b5fd1"},
- {file = "Pygments-2.15.1.tar.gz", hash =
"sha256:8ace4d3c1dd481894b2005f560ead0f9f19ee64fe983366be1a21e171d12775c"},
+ {file = "Pygments-2.16.1-py3-none-any.whl", hash =
"sha256:13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692"},
+ {file = "Pygments-2.16.1.tar.gz", hash =
"sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29"},
]
[package.extras]
@@ -2020,13 +2085,13 @@ tests = ["coverage[toml] (==5.0.4)", "pytest
(>=6.0.0,<7.0.0)"]
[[package]]
name = "pyparsing"
-version = "3.1.0"
+version = "3.1.1"
description = "pyparsing module - Classes and methods to define and execute
parsing grammars"
optional = false
python-versions = ">=3.6.8"
files = [
- {file = "pyparsing-3.1.0-py3-none-any.whl", hash =
"sha256:d554a96d1a7d3ddaf7183104485bc19fd80543ad6ac5bdb6426719d766fb06c1"},
- {file = "pyparsing-3.1.0.tar.gz", hash =
"sha256:edb662d6fe322d6e990b1594b5feaeadf806803359e3d4d42f11e295e588f0ea"},
+ {file = "pyparsing-3.1.1-py3-none-any.whl", hash =
"sha256:32c7c0b711493c72ff18a981d24f28aaf9c1fb7ed5e9667c9e84e3db623bdbfb"},
+ {file = "pyparsing-3.1.1.tar.gz", hash =
"sha256:ede28a1a32462f5a9705e07aea48001a08f7cf81a021585011deba701581a0db"},
]
[package.extras]
@@ -2270,21 +2335,26 @@ files = [
{file = "ray-2.6.2-cp310-cp310-macosx_11_0_arm64.whl", hash =
"sha256:120631ce1e6206ceb0395aeca5c1dcef4b0b65dd0a0cd53053e131254da96f0a"},
{file = "ray-2.6.2-cp310-cp310-manylinux2014_aarch64.whl", hash =
"sha256:8aeef75db0d9922f69a6ab31ffd3df3f40fff404c30bfb4ca76e480c53df98ce"},
{file = "ray-2.6.2-cp310-cp310-manylinux2014_x86_64.whl", hash =
"sha256:050d3c2ac71a8ca7779c7b590a91400f45e071b298b67727949ffdcc096406e0"},
+ {file = "ray-2.6.2-cp310-cp310-win_amd64.whl", hash =
"sha256:38a23c417b5e96532eee9480ccaebdde1af7fb2f9d884155c5aef894aa7dda25"},
{file = "ray-2.6.2-cp311-cp311-macosx_10_15_x86_64.whl", hash =
"sha256:2356454ec63135b6dee3e46b091c76b7daec09bae05aa943a767f884377acda8"},
{file = "ray-2.6.2-cp311-cp311-macosx_11_0_arm64.whl", hash =
"sha256:e924173198e2d37e29baa7b7893221594139442e9a0b0334fa80f1c8a7b5a6ed"},
{file = "ray-2.6.2-cp311-cp311-manylinux2014_aarch64.whl", hash =
"sha256:7ee8afffa1c971a71570b6a98de0c69d83c99423a97d29000aeabb706cc1baab"},
{file = "ray-2.6.2-cp311-cp311-manylinux2014_x86_64.whl", hash =
"sha256:2fa25cf5071082c386dbc086f917f6a4a9f29980eff2cb94d939fd23dd16735a"},
+ {file = "ray-2.6.2-cp311-cp311-win_amd64.whl", hash =
"sha256:58e632c7cc69b560b46826c454777cf44518a09fa5e3cf275e0aba167bf49cca"},
{file = "ray-2.6.2-cp37-cp37m-macosx_10_15_x86_64.whl", hash =
"sha256:8ecac78203045ef33236ec913775fe9f30d5f3ebe7ee090276c05a3a1fc1ba31"},
{file = "ray-2.6.2-cp37-cp37m-manylinux2014_aarch64.whl", hash =
"sha256:267b52ed13422f9bc57a7ae89289d2cdb6174fd27c1ea842a2618b2d054cf795"},
{file = "ray-2.6.2-cp37-cp37m-manylinux2014_x86_64.whl", hash =
"sha256:a0507f49113d98eea24903b5ef384e631997ebfd4934b94ce13c15fbb0adb0c4"},
+ {file = "ray-2.6.2-cp37-cp37m-win_amd64.whl", hash =
"sha256:4c919861433cb70d1e8b8605eda8319780b8f3c07c1abe73afba15aad5aea54f"},
{file = "ray-2.6.2-cp38-cp38-macosx_10_15_x86_64.whl", hash =
"sha256:ff3d5ea1057c4d57bae9b921df0bdd98263c91d0fe7a4221a179bb9034005795"},
{file = "ray-2.6.2-cp38-cp38-macosx_11_0_arm64.whl", hash =
"sha256:302213def2b0d9fd2039d14b992a2dffa5b4db36ac8d154a219d8bd8e580d694"},
{file = "ray-2.6.2-cp38-cp38-manylinux2014_aarch64.whl", hash =
"sha256:8f34ddd7012b5908d19a12e452138e941d83e38a1fbce2db4545c281957bbda5"},
{file = "ray-2.6.2-cp38-cp38-manylinux2014_x86_64.whl", hash =
"sha256:9a4cdabff16caaed76e9b7f2a9d94cfbae30073b6dc8956f55d70b99e218d1dc"},
+ {file = "ray-2.6.2-cp38-cp38-win_amd64.whl", hash =
"sha256:a4b405e3595993db91703e9847fe51e41fb98c3181ee904d673da82e25fe7e86"},
{file = "ray-2.6.2-cp39-cp39-macosx_10_15_x86_64.whl", hash =
"sha256:86b57fb864a9328971d7e554e0c55608735e94434f13948a58bb07423c783a39"},
{file = "ray-2.6.2-cp39-cp39-macosx_11_0_arm64.whl", hash =
"sha256:21608b9dbc19175fbb1832ec9296e7c93cf416d28b0e21ee7e2667da7af952b7"},
{file = "ray-2.6.2-cp39-cp39-manylinux2014_aarch64.whl", hash =
"sha256:4ab10849705f41923ec1ccf597f3881c9f3f304c43da3e6f5b794c2072694f77"},
{file = "ray-2.6.2-cp39-cp39-manylinux2014_x86_64.whl", hash =
"sha256:3f359fdb88406528c564e66dbe848ab98679ddb046d44465ebd3933fa1ecdd62"},
+ {file = "ray-2.6.2-cp39-cp39-win_amd64.whl", hash =
"sha256:d23a9059d84b416df135512d224cfbe4ed45de8fc727eb6c616468ab9dbdd7bd"},
]
[package.dependencies]
@@ -2322,13 +2392,13 @@ tune = ["pandas", "pyarrow (>=6.0.1)", "requests",
"tensorboardX (>=1.9)"]
[[package]]
name = "referencing"
-version = "0.30.0"
+version = "0.30.2"
description = "JSON Referencing + Python"
optional = true
python-versions = ">=3.8"
files = [
- {file = "referencing-0.30.0-py3-none-any.whl", hash =
"sha256:c257b08a399b6c2f5a3510a50d28ab5dbc7bbde049bcaf954d43c446f83ab548"},
- {file = "referencing-0.30.0.tar.gz", hash =
"sha256:47237742e990457f7512c7d27486394a9aadaf876cbfaa4be65b27b4f4d47c6b"},
+ {file = "referencing-0.30.2-py3-none-any.whl", hash =
"sha256:449b6669b6121a9e96a7f9e410b245d471e8d48964c67113ce9afe50c8dd7bdf"},
+ {file = "referencing-0.30.2.tar.gz", hash =
"sha256:794ad8003c65938edcdbc027f1933215e0d0ccc0291e3ce20a4d87432b59efc0"},
]
[package.dependencies]
@@ -2377,20 +2447,20 @@ test = ["fixtures", "mock", "purl", "pytest",
"requests-futures", "sphinx", "tes
[[package]]
name = "responses"
-version = "0.23.1"
+version = "0.23.3"
description = "A utility library for mocking out the `requests` Python
library."
optional = false
python-versions = ">=3.7"
files = [
- {file = "responses-0.23.1-py3-none-any.whl", hash =
"sha256:8a3a5915713483bf353b6f4079ba8b2a29029d1d1090a503c70b0dc5d9d0c7bd"},
- {file = "responses-0.23.1.tar.gz", hash =
"sha256:c4d9aa9fc888188f0c673eff79a8dadbe2e75b7fe879dc80a221a06e0a68138f"},
+ {file = "responses-0.23.3-py3-none-any.whl", hash =
"sha256:e6fbcf5d82172fecc0aa1860fd91e58cbfd96cee5e96da5b63fa6eb3caa10dd3"},
+ {file = "responses-0.23.3.tar.gz", hash =
"sha256:205029e1cb334c21cb4ec64fc7599be48b859a0fd381a42443cdd600bfe8b16a"},
]
[package.dependencies]
pyyaml = "*"
-requests = ">=2.22.0,<3.0"
+requests = ">=2.30.0,<3.0"
types-PyYAML = "*"
-urllib3 = ">=1.25.10"
+urllib3 = ">=1.25.10,<3.0"
[package.extras]
tests = ["coverage (>=6.0.0)", "flake8", "mypy", "pytest (>=7.0.0)",
"pytest-asyncio", "pytest-cov", "pytest-httpserver", "tomli", "tomli-w",
"types-requests"]
@@ -2599,7 +2669,7 @@ files = [
name = "sqlalchemy"
version = "2.0.19"
description = "Database Abstraction Library"
-optional = true
+optional = false
python-versions = ">=3.7"
files = [
{file = "SQLAlchemy-2.0.19-cp310-cp310-macosx_10_9_x86_64.whl", hash =
"sha256:9deaae357edc2091a9ed5d25e9ee8bba98bcfae454b3911adeaf159c2e9ca9e3"},
@@ -2767,23 +2837,23 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
[[package]]
name = "virtualenv"
-version = "20.24.1"
+version = "20.24.2"
description = "Virtual Python Environment builder"
optional = false
python-versions = ">=3.7"
files = [
- {file = "virtualenv-20.24.1-py3-none-any.whl", hash =
"sha256:01aacf8decd346cf9a865ae85c0cdc7f64c8caa07ff0d8b1dfc1733d10677442"},
- {file = "virtualenv-20.24.1.tar.gz", hash =
"sha256:2ef6a237c31629da6442b0bcaa3999748108c7166318d1f55cc9f8d7294e97bd"},
+ {file = "virtualenv-20.24.2-py3-none-any.whl", hash =
"sha256:43a3052be36080548bdee0b42919c88072037d50d56c28bd3f853cbe92b953ff"},
+ {file = "virtualenv-20.24.2.tar.gz", hash =
"sha256:fd8a78f46f6b99a67b7ec5cf73f92357891a7b3a40fd97637c27f854aae3b9e0"},
]
[package.dependencies]
-distlib = ">=0.3.6,<1"
-filelock = ">=3.12,<4"
-platformdirs = ">=3.5.1,<4"
+distlib = ">=0.3.7,<1"
+filelock = ">=3.12.2,<4"
+platformdirs = ">=3.9.1,<4"
[package.extras]
docs = ["furo (>=2023.5.20)", "proselint (>=0.13)", "sphinx (>=7.0.1)",
"sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier
(>=23.6)"]
-test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)",
"coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)",
"pytest (>=7.3.1)", "pytest-env (>=0.8.1)", "pytest-freezer (>=0.4.6)",
"pytest-mock (>=3.10)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)",
"setuptools (>=67.8)", "time-machine (>=2.9)"]
+test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)",
"coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)",
"pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)",
"pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)",
"setuptools (>=68)", "time-machine (>=2.10)"]
[[package]]
name = "werkzeug"
@@ -3074,4 +3144,4 @@ zstandard = ["zstandard"]
[metadata]
lock-version = "2.0"
python-versions = "^3.8"
-content-hash =
"3bc57dab7b6f6c9e86a978bf58ca83a60e0e85a4d672880dd73b8825bd3a654f"
+content-hash =
"d0ec7a103ebb44f96382fd5d3c58fea9b01db3f7927975a89b1c0e0b5f1a866f"
diff --git a/python/pyiceberg/avro/decoder.py b/python/pyiceberg/avro/decoder.py
index 0b39340b0e..8603319c53 100644
--- a/python/pyiceberg/avro/decoder.py
+++ b/python/pyiceberg/avro/decoder.py
@@ -16,7 +16,12 @@
# under the License.
from abc import ABC, abstractmethod
from io import SEEK_CUR
-from typing import Dict, List
+from typing import (
+ Dict,
+ List,
+ Tuple,
+ cast,
+)
from pyiceberg.avro import STRUCT_DOUBLE, STRUCT_FLOAT
from pyiceberg.io import InputStream
@@ -64,17 +69,9 @@ class BinaryDecoder(ABC):
datum = (n >> 1) ^ -(n & 1)
return datum
- def read_ints(self, n: int, dest: List[int]) -> None:
+ def read_ints(self, n: int) -> Tuple[int, ...]:
"""Reads a list of integers."""
- for _ in range(n):
- dest.append(self.read_int())
-
- def read_int_int_dict(self, n: int, dest: Dict[int, int]) -> None:
- """Reads a dictionary of integers for keys and values into a
destination dictionary."""
- for _ in range(n):
- k = self.read_int()
- v = self.read_int()
- dest[k] = v
+ return tuple(self.read_int() for _ in range(n))
def read_int_bytes_dict(self, n: int, dest: Dict[int, bytes]) -> None:
"""Reads a dictionary of integers for keys and bytes for values into a
destination dictionary."""
@@ -90,7 +87,7 @@ class BinaryDecoder(ABC):
The float is converted into a 32-bit integer using a method equivalent
to
Java's floatToIntBits and then encoded in little-endian format.
"""
- return float(STRUCT_FLOAT.unpack(self.read(4))[0])
+ return float(cast(Tuple[float, ...],
STRUCT_FLOAT.unpack(self.read(4)))[0])
def read_double(self) -> float:
"""Reads a value from the stream as a double.
@@ -99,7 +96,7 @@ class BinaryDecoder(ABC):
The double is converted into a 64-bit integer using a method
equivalent to
Java's doubleToLongBits and then encoded in little-endian format.
"""
- return float(STRUCT_DOUBLE.unpack(self.read(8))[0])
+ return float(cast(Tuple[float, ...],
STRUCT_DOUBLE.unpack(self.read(8)))[0])
def read_bytes(self) -> bytes:
"""Bytes are encoded as a long followed by that many bytes of data."""
@@ -173,96 +170,3 @@ class StreamingBinaryDecoder(BinaryDecoder):
def skip(self, n: int) -> None:
self._input_stream.seek(n, SEEK_CUR)
-
-
-class InMemoryBinaryDecoder(BinaryDecoder):
- """Implement a BinaryDecoder that reads from an in-memory buffer.
-
- This may be more efficient if the entire block is already in memory
- as it does not need to interact with the I/O subsystem.
- """
-
- __slots__ = ["_contents", "_position", "_size"]
- _contents: bytes
- _position: int
- _size: int
-
- def __init__(self, input_stream: InputStream) -> None:
- """Reader is a Python object on which we can call read, seek, and
tell."""
- super().__init__(input_stream)
- self._contents = input_stream.read()
- self._size = len(self._contents)
- self._position = 0
-
- def tell(self) -> int:
- """Return the current stream position."""
- return self._position
-
- def read(self, n: int) -> bytes:
- """Read n bytes."""
- if n < 0:
- raise ValueError(f"Requested {n} bytes to read, expected positive
integer.")
- if self._position + n > self._size:
- raise EOFError(f"EOF: read {n} bytes")
- r = self._contents[self._position : self._position + n]
- self._position += n
- return r
-
- def skip(self, n: int) -> None:
- self._position += n
-
- def read_boolean(self) -> bool:
- """Reads a value from the stream as a boolean.
-
- A boolean is written as a single byte
- whose value is either 0 (false) or 1 (true).
- """
- r = self._contents[self._position]
- self._position += 1
- return r != 0
-
- def read_int(self) -> int:
- """Reads a value from the stream as an integer.
-
- int/long values are written using variable-length, zigzag coding.
- """
- if self._position == self._size:
- raise EOFError("EOF: read 1 byte")
- b = self._contents[self._position]
- self._position += 1
- n = b & 0x7F
- shift = 7
- while b & 0x80:
- b = self._contents[self._position]
- self._position += 1
- n |= (b & 0x7F) << shift
- shift += 7
- return (n >> 1) ^ -(n & 1)
-
- def read_int_bytes_dict(self, n: int, dest: Dict[int, bytes]) -> None:
- """Reads a dictionary of integers for keys and bytes for values into a
destination dict."""
- for _ in range(n):
- k = self.read_int()
-
- byte_length = self.read_int()
- if byte_length <= 0:
- dest[k] = b""
- else:
- dest[k] = self._contents[self._position : self._position +
byte_length]
- self._position += byte_length
-
- def read_bytes(self) -> bytes:
- """Bytes are encoded as a long followed by that many bytes of data."""
- num_bytes = self.read_int()
- if num_bytes <= 0:
- return b""
- r = self._contents[self._position : self._position + num_bytes]
- self._position += num_bytes
- return r
-
- def skip_int(self) -> None:
- b = self._contents[self._position]
- self._position += 1
- while b & 0x80:
- b = self._contents[self._position]
- self._position += 1
diff --git a/python/pyiceberg/avro/decoder_basic.c
b/python/pyiceberg/avro/decoder_basic.c
new file mode 100644
index 0000000000..e75e2d2e1b
--- /dev/null
+++ b/python/pyiceberg/avro/decoder_basic.c
@@ -0,0 +1,61 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+*/
+
+/*
+ Decode an an array of zig-zag encoded longs from a buffer.
+
+ The buffer is advanced to the end of the integers.
+ `count` is the number of integers to decode.
+ `result` is where the decoded integers are stored.
+
+*/
+static inline void decode_longs(const unsigned char **buffer, unsigned int
count, unsigned long *result) {
+ unsigned int current_index;
+ const unsigned char *current_position = *buffer;
+ unsigned long temp;
+ // The largest shift will always be < 64
+ unsigned char shift;
+
+ for (current_index = 0; current_index < count; current_index++) {
+ shift = 7;
+ temp = *current_position & 0x7F;
+ while(*current_position & 0x80) {
+ current_position += 1;
+ temp |= (unsigned long)(*current_position & 0x7F) << shift;
+ shift += 7;
+ }
+ result[current_index] = (temp >> 1) ^ (~(temp & 1) + 1);
+ current_position += 1;
+ }
+ *buffer = current_position;
+}
+
+
+
+/*
+ Skip a zig-zag encoded integer in a buffer.
+
+ The buffer is advanced to the end of the integer.
+*/
+static inline void skip_int(const unsigned char **buffer) {
+ while(**buffer & 0x80) {
+ *buffer += 1;
+ }
+ *buffer += 1;
+}
diff --git a/python/pyiceberg/avro/decoder_fast.pyi
b/python/pyiceberg/avro/decoder_fast.pyi
new file mode 100644
index 0000000000..5d68fa2628
--- /dev/null
+++ b/python/pyiceberg/avro/decoder_fast.pyi
@@ -0,0 +1,56 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+from typing import Tuple, Dict
+
+class CythonBinaryDecoder:
+ def __init__(self, input_contents: bytes) -> None:
+ pass
+ def tell(self) -> int:
+ pass
+ def read(self, n: int) -> bytes:
+ pass
+ def read_boolean(self) -> bool:
+ pass
+ def read_int(self) -> int:
+ pass
+ def read_ints(self, count: int) -> Tuple[int, ...]:
+ pass
+ def read_int_bytes_dict(self, count: int, dest: Dict[int, bytes]) -> None:
+ pass
+ def read_bytes(self) -> bytes:
+ pass
+ def read_float(self) -> float:
+ pass
+ def read_double(self) -> float:
+ pass
+ def read_utf8(self) -> str:
+ pass
+ def skip(self, n: int) -> None:
+ pass
+ def skip_int(self) -> None:
+ pass
+ def skip_boolean(self) -> None:
+ pass
+ def skip_float(self) -> None:
+ pass
+ def skip_double(self) -> None:
+ pass
+ def skip_bytes(self) -> None:
+ pass
+ def skip_utf8(self) -> None:
+ pass
diff --git a/python/pyiceberg/avro/decoder_fast.pyx
b/python/pyiceberg/avro/decoder_fast.pyx
new file mode 100644
index 0000000000..c48e098bb9
--- /dev/null
+++ b/python/pyiceberg/avro/decoder_fast.pyx
@@ -0,0 +1,186 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+import cython
+from cython.cimports.cpython import array
+from datetime import datetime, time
+from uuid import UUID
+from pyiceberg.avro import STRUCT_DOUBLE, STRUCT_FLOAT
+from pyiceberg.utils.datetime import micros_to_time, micros_to_timestamp,
micros_to_timestamptz
+from pyiceberg.utils.decimal import unscaled_to_decimal
+from pyiceberg.io import InputStream
+from cpython.mem cimport PyMem_Malloc, PyMem_Realloc, PyMem_Free
+from libc.string cimport memcpy
+import decimal
+
+import array
+
+cdef extern from "decoder_basic.c":
+ void decode_longs(const unsigned char **buffer, unsigned int count, unsigned
long *result);
+ void skip_int(const unsigned char **buffer);
+
+unsigned_long_array_template = cython.declare(array.array, array.array('L',
[]))
+
[email protected]
+cdef class CythonBinaryDecoder:
+ """Implement a BinaryDecoder that reads from an in-memory buffer.
+
+ """
+
+ # This the data that is duplicated when the decoder is created.
+ cdef unsigned char *_data
+
+ # This is the current pointer to the buffer.
+ cdef const unsigned char *_current
+
+ # This is the address after the data buffer
+ cdef const unsigned char *_end
+
+ # This is the size of the buffer of the data being parsed.
+ cdef unsigned int _size
+
+ def __cinit__(self, input_contents: bytes) -> None:
+ self._size = len(input_contents)
+
+ # Make a copy of the data so the data can be iterated.
+ self._data = <unsigned char *> PyMem_Malloc(self._size * sizeof(char))
+ if not self._data:
+ raise MemoryError()
+ cdef const unsigned char *input_as_array = input_contents
+ memcpy(self._data, input_as_array, self._size)
+ self._end = self._data + self._size
+ self._current = self._data
+
+ def __dealloc__(self):
+ PyMem_Free(self._data)
+
+ cpdef unsigned int tell(self):
+ """Return the current stream position."""
+ return self._current - self._data
+
+ cpdef bytes read(self, n: int):
+ """Read n bytes."""
+ if n < 0:
+ raise ValueError(f"Requested {n} bytes to read, expected positive
integer.")
+ cdef const unsigned char *r = self._current
+ self._current += n
+ return r[0:n]
+
+ def read_boolean(self) -> bool:
+ """Reads a value from the stream as a boolean.
+
+ A boolean is written as a single byte
+ whose value is either 0 (false) or 1 (true).
+ """
+ self._current += 1;
+ return self._current[-1] != 0
+
+ cpdef inline long read_int(self):
+ """Reads a value from the stream as an integer.
+
+ int/long values are written using variable-length, zigzag coding.
+ """
+ cdef unsigned long result;
+ if self._current >= self._end:
+ raise EOFError(f"EOF: read 1 bytes")
+ decode_longs(&self._current, 1, <unsigned long *>&result)
+ return result
+
+ def read_ints(self, count: int) -> Tuple[int, ...]:
+ """Reads a list of integers."""
+ newarray = array.clone(unsigned_long_array_template, count, zero=False)
+ if self._current >= self._end:
+ raise EOFError(f"EOF: read 1 bytes")
+ decode_longs(&self._current, count, newarray.data.as_ulongs)
+ return newarray
+
+ cpdef void read_int_bytes_dict(self, count: int, dest: Dict[int, bytes]):
+ """Reads a dictionary of integers for keys and bytes for values into a
destination dict."""
+ cdef unsigned long result[2];
+ if self._current >= self._end:
+ raise EOFError(f"EOF: read 1 bytes")
+
+ for _ in range(count):
+ decode_longs(&self._current, 2, <unsigned long *>&result)
+ if result[1] <= 0:
+ dest[result[0]] = b""
+ else:
+ dest[result[0]] = self._current[0:result[1]]
+ self._current += result[1]
+
+ cpdef inline bytes read_bytes(self):
+ """Bytes are encoded as a long followed by that many bytes of data."""
+ cdef unsigned long length;
+ if self._current >= self._end:
+ raise EOFError(f"EOF: read 1 bytes")
+
+ decode_longs(&self._current, 1, <unsigned long *>&length)
+
+ if length <= 0:
+ return b""
+ cdef const unsigned char *r = self._current
+ self._current += length
+ return r[0:length]
+
+ cpdef float read_float(self):
+ """Reads a value from the stream as a float.
+
+ A float is written as 4 bytes.
+ The float is converted into a 32-bit integer using a method equivalent
to
+ Java's floatToIntBits and then encoded in little-endian format.
+ """
+ return float(STRUCT_FLOAT.unpack(self.read(4))[0])
+
+ cpdef float read_double(self):
+ """Reads a value from the stream as a double.
+
+ A double is written as 8 bytes.
+ The double is converted into a 64-bit integer using a method
equivalent to
+ Java's doubleToLongBits and then encoded in little-endian format.
+ """
+ return float(STRUCT_DOUBLE.unpack(self.read(8))[0])
+
+ cpdef str read_utf8(self):
+ """Reads a utf-8 encoded string from the stream.
+
+ A string is encoded as a long followed by
+ that many bytes of UTF-8 encoded character data.
+ """
+ return self.read_bytes().decode("utf-8")
+
+ def skip_int(self) -> None:
+ skip_int(&self._current)
+ return
+
+ def skip(self, n: int) -> None:
+ self._current += n
+
+ def skip_boolean(self) -> None:
+ self._current += 1
+
+ def skip_float(self) -> None:
+ self._current += 4
+
+ def skip_double(self) -> None:
+ self._current += 8
+
+ def skip_bytes(self) -> None:
+ cdef long result;
+ decode_longs(&self._current, 1, <unsigned long *>&result)
+ self._current += result
+
+ def skip_utf8(self) -> None:
+ self.skip_bytes()
diff --git a/python/pyiceberg/avro/file.py b/python/pyiceberg/avro/file.py
index 3b2f62045e..de71206919 100644
--- a/python/pyiceberg/avro/file.py
+++ b/python/pyiceberg/avro/file.py
@@ -35,9 +35,9 @@ from typing import (
)
from pyiceberg.avro.codecs import KNOWN_CODECS, Codec
-from pyiceberg.avro.decoder import BinaryDecoder, InMemoryBinaryDecoder
+from pyiceberg.avro.decoder_fast import CythonBinaryDecoder
from pyiceberg.avro.encoder import BinaryEncoder
-from pyiceberg.avro.reader import Reader
+from pyiceberg.avro.reader import ReadableDecoder, Reader
from pyiceberg.avro.resolver import construct_reader, construct_writer, resolve
from pyiceberg.avro.writer import Writer
from pyiceberg.io import InputFile, OutputFile, OutputStream
@@ -105,7 +105,7 @@ D = TypeVar("D", bound=StructProtocol)
class Block(Generic[D]):
reader: Reader
block_records: int
- block_decoder: BinaryDecoder
+ block_decoder: ReadableDecoder
position: int = 0
def __iter__(self) -> Block[D]:
@@ -143,7 +143,7 @@ class AvroFile(Generic[D]):
schema: Schema
reader: Reader
- decoder: BinaryDecoder
+ decoder: ReadableDecoder
block: Optional[Block[D]]
def __init__(
@@ -165,8 +165,7 @@ class AvroFile(Generic[D]):
Returns:
A generator returning the AvroStructs.
"""
- with self.input_file.open() as f:
- self.decoder = InMemoryBinaryDecoder(io.BytesIO(f.read()))
+ self.decoder = CythonBinaryDecoder(self.input_file.open().read())
self.header = self._read_header()
self.schema = self.header.get_schema()
if not self.read_schema:
@@ -198,9 +197,7 @@ class AvroFile(Generic[D]):
if codec := self.header.compression_codec():
block_bytes = codec.decompress(block_bytes)
- self.block = Block(
- reader=self.reader, block_records=block_records,
block_decoder=InMemoryBinaryDecoder(io.BytesIO(block_bytes))
- )
+ self.block = Block(reader=self.reader, block_records=block_records,
block_decoder=CythonBinaryDecoder(block_bytes))
return block_records
def __next__(self) -> D:
diff --git a/python/pyiceberg/avro/reader.py b/python/pyiceberg/avro/reader.py
index 8236deb56a..4bb066874f 100644
--- a/python/pyiceberg/avro/reader.py
+++ b/python/pyiceberg/avro/reader.py
@@ -32,21 +32,26 @@ from decimal import Decimal
from typing import (
Any,
Callable,
- Dict,
List,
+ Mapping,
Optional,
Tuple,
+ Union,
)
from uuid import UUID
from pyiceberg.avro.decoder import BinaryDecoder
+from pyiceberg.avro.decoder_fast import CythonBinaryDecoder
from pyiceberg.typedef import StructProtocol
from pyiceberg.types import StructType
from pyiceberg.utils.decimal import bytes_to_decimal, decimal_required_bytes
+from pyiceberg.utils.lazydict import LazyDict
from pyiceberg.utils.singleton import Singleton
+ReadableDecoder = Union[BinaryDecoder, CythonBinaryDecoder]
-def _skip_map_array(decoder: BinaryDecoder, skip_entry: Callable[[], None]) ->
None:
+
+def _skip_map_array(decoder: ReadableDecoder, skip_entry: Callable[[], None])
-> None:
"""Skips over an array or map.
Both the array and map are encoded similar, and we can re-use
@@ -84,11 +89,11 @@ def _skip_map_array(decoder: BinaryDecoder, skip_entry:
Callable[[], None]) -> N
class Reader(Singleton):
@abstractmethod
- def read(self, decoder: BinaryDecoder) -> Any:
+ def read(self, decoder: ReadableDecoder) -> Any:
...
@abstractmethod
- def skip(self, decoder: BinaryDecoder) -> None:
+ def skip(self, decoder: ReadableDecoder) -> None:
...
def __repr__(self) -> str:
@@ -97,10 +102,10 @@ class Reader(Singleton):
class NoneReader(Reader):
- def read(self, _: BinaryDecoder) -> None:
+ def read(self, _: ReadableDecoder) -> None:
return None
- def skip(self, decoder: BinaryDecoder) -> None:
+ def skip(self, decoder: ReadableDecoder) -> None:
return None
@@ -111,44 +116,44 @@ class DefaultReader(Reader):
def __init__(self, default_value: Any) -> None:
self.default_value = default_value
- def read(self, _: BinaryDecoder) -> Any:
+ def read(self, _: ReadableDecoder) -> Any:
return self.default_value
- def skip(self, decoder: BinaryDecoder) -> None:
+ def skip(self, decoder: ReadableDecoder) -> None:
pass
class BooleanReader(Reader):
- def read(self, decoder: BinaryDecoder) -> bool:
+ def read(self, decoder: ReadableDecoder) -> bool:
return decoder.read_boolean()
- def skip(self, decoder: BinaryDecoder) -> None:
+ def skip(self, decoder: ReadableDecoder) -> None:
decoder.skip_boolean()
class IntegerReader(Reader):
"""Longs and ints are encoded the same way, and there is no long in
Python."""
- def read(self, decoder: BinaryDecoder) -> int:
+ def read(self, decoder: ReadableDecoder) -> int:
return decoder.read_int()
- def skip(self, decoder: BinaryDecoder) -> None:
+ def skip(self, decoder: ReadableDecoder) -> None:
decoder.skip_int()
class FloatReader(Reader):
- def read(self, decoder: BinaryDecoder) -> float:
+ def read(self, decoder: ReadableDecoder) -> float:
return decoder.read_float()
- def skip(self, decoder: BinaryDecoder) -> None:
+ def skip(self, decoder: ReadableDecoder) -> None:
decoder.skip_float()
class DoubleReader(Reader):
- def read(self, decoder: BinaryDecoder) -> float:
+ def read(self, decoder: ReadableDecoder) -> float:
return decoder.read_double()
- def skip(self, decoder: BinaryDecoder) -> None:
+ def skip(self, decoder: ReadableDecoder) -> None:
decoder.skip_double()
@@ -186,18 +191,18 @@ class TimestamptzReader(IntegerReader):
class StringReader(Reader):
- def read(self, decoder: BinaryDecoder) -> str:
+ def read(self, decoder: ReadableDecoder) -> str:
return decoder.read_utf8()
- def skip(self, decoder: BinaryDecoder) -> None:
+ def skip(self, decoder: ReadableDecoder) -> None:
decoder.skip_utf8()
class UUIDReader(Reader):
- def read(self, decoder: BinaryDecoder) -> UUID:
+ def read(self, decoder: ReadableDecoder) -> UUID:
return UUID(bytes=decoder.read(16))
- def skip(self, decoder: BinaryDecoder) -> None:
+ def skip(self, decoder: ReadableDecoder) -> None:
decoder.skip(16)
@@ -205,10 +210,10 @@ class UUIDReader(Reader):
class FixedReader(Reader):
_len: int = dataclassfield()
- def read(self, decoder: BinaryDecoder) -> bytes:
+ def read(self, decoder: ReadableDecoder) -> bytes:
return decoder.read(len(self))
- def skip(self, decoder: BinaryDecoder) -> None:
+ def skip(self, decoder: ReadableDecoder) -> None:
decoder.skip(len(self))
def __len__(self) -> int:
@@ -227,10 +232,10 @@ class BinaryReader(Reader):
then reads the binary field itself.
"""
- def read(self, decoder: BinaryDecoder) -> bytes:
+ def read(self, decoder: ReadableDecoder) -> bytes:
return decoder.read_bytes()
- def skip(self, decoder: BinaryDecoder) -> None:
+ def skip(self, decoder: ReadableDecoder) -> None:
decoder.skip_bytes()
@@ -251,10 +256,10 @@ class DecimalReader(Reader):
object.__setattr__(self, "scale", scale)
object.__setattr__(self, "_length", decimal_required_bytes(precision))
- def read(self, decoder: BinaryDecoder) -> Decimal:
+ def read(self, decoder: ReadableDecoder) -> Decimal:
return bytes_to_decimal(decoder.read(self._length), self.scale)
- def skip(self, decoder: BinaryDecoder) -> None:
+ def skip(self, decoder: ReadableDecoder) -> None:
decoder.skip_bytes()
def __repr__(self) -> str:
@@ -266,7 +271,7 @@ class DecimalReader(Reader):
class OptionReader(Reader):
option: Reader = dataclassfield()
- def read(self, decoder: BinaryDecoder) -> Optional[Any]:
+ def read(self, decoder: ReadableDecoder) -> Optional[Any]:
# For the Iceberg spec it is required to set the default value to null
# From https://iceberg.apache.org/spec/#avro
# Optional fields must always set the Avro field default value to null.
@@ -280,7 +285,7 @@ class OptionReader(Reader):
return self.option.read(decoder)
return None
- def skip(self, decoder: BinaryDecoder) -> None:
+ def skip(self, decoder: ReadableDecoder) -> None:
if decoder.read_int() > 0:
return self.option.skip(decoder)
@@ -290,7 +295,7 @@ class StructReader(Reader):
field_readers: Tuple[Tuple[Optional[int], Reader], ...]
create_struct: Callable[..., StructProtocol]
struct: StructType
- field_reader_functions = Tuple[Tuple[Optional[str], int,
Optional[Callable[[BinaryDecoder], Any]]], ...]
+ field_reader_functions = Tuple[Tuple[Optional[str], int,
Optional[Callable[[ReadableDecoder], Any]]], ...]
def __init__(
self,
@@ -316,7 +321,7 @@ class StructReader(Reader):
if not isinstance(created_struct, StructProtocol):
raise ValueError(f"Incompatible with StructProtocol:
{self.create_struct}")
- reading_callbacks: List[Tuple[Optional[int], Callable[[BinaryDecoder],
Any]]] = []
+ reading_callbacks: List[Tuple[Optional[int],
Callable[[ReadableDecoder], Any]]] = []
for pos, field in field_readers:
if pos is not None:
reading_callbacks.append((pos, field.read))
@@ -326,9 +331,8 @@ class StructReader(Reader):
self._field_reader_functions = tuple(reading_callbacks)
self._hash = hash(self._field_reader_functions)
- def read(self, decoder: BinaryDecoder) -> StructProtocol:
+ def read(self, decoder: ReadableDecoder) -> StructProtocol:
struct = self.create_struct(struct=self.struct) if
self._create_with_keyword else self.create_struct()
-
for pos, field_reader in self._field_reader_functions:
if pos is not None:
struct[pos] = field_reader(decoder) # later: pass reuse in
here
@@ -337,7 +341,7 @@ class StructReader(Reader):
return struct
- def skip(self, decoder: BinaryDecoder) -> None:
+ def skip(self, decoder: ReadableDecoder) -> None:
for _, field in self.field_readers:
field.skip(decoder)
@@ -369,7 +373,7 @@ class ListReader(Reader):
self._hash = hash(self.element)
self._is_int_list = isinstance(self.element, IntegerReader)
- def read(self, decoder: BinaryDecoder) -> List[Any]:
+ def read(self, decoder: ReadableDecoder) -> List[Any]:
read_items: List[Any] = []
block_count = decoder.read_int()
while block_count != 0:
@@ -377,14 +381,14 @@ class ListReader(Reader):
block_count = -block_count
_ = decoder.read_int()
if self._is_int_list:
- decoder.read_ints(block_count, read_items)
+ read_items.extend(decoder.read_ints(block_count))
else:
for _ in range(block_count):
read_items.append(self.element.read(decoder))
block_count = decoder.read_int()
return read_items
- def skip(self, decoder: BinaryDecoder) -> None:
+ def skip(self, decoder: ReadableDecoder) -> None:
_skip_map_array(decoder, lambda: self.element.skip(decoder))
def __hash__(self) -> int:
@@ -392,6 +396,10 @@ class ListReader(Reader):
return self._hash
+# Represent an empty dict as a singleton
+EMPTY_DICT: dict[Any, Any] = {}
+
+
@dataclass(frozen=False, init=False)
class MapReader(Reader):
__slots__ = ("key", "value", "_is_int_int", "_is_int_bytes",
"_key_reader", "_value_reader", "_hash")
@@ -412,22 +420,58 @@ class MapReader(Reader):
self._value_reader = self.value.read
self._hash = hash((self.key, self.value))
- def read(self, decoder: BinaryDecoder) -> Dict[Any, Any]:
- read_items: dict[Any, Any] = {}
+ def _read_int_int(self, decoder: ReadableDecoder) -> Mapping[int, int]:
+ """Read a mapping from int to int from the decoder.
+
+ Read a map of ints to ints from the decoder, since this is such a
common
+ data type, it is optimized to be faster than the generic map reader, by
+ using a lazy dict.
+ The time it takes to create the python dictionary is much larger than
+ the time it takes to read the data from the decoder as an array, so the
+ lazy dict defers creating the python dictionary until it is actually
+ accessed.
+
+ """
block_count = decoder.read_int()
+
+ # Often times the map is empty, so we can just return an empty dict
without
+ # instancing the LazyDict
+ if block_count == 0:
+ return EMPTY_DICT
+
+ contents_array: List[Tuple[int, ...]] = []
+
+ while block_count != 0:
+ if block_count < 0:
+ block_count = -block_count
+ # We ignore the block size for now
+ decoder.skip_int()
+
+ # Since the integers are encoding right next to each other
+ # just read them all at once.
+ contents_array.append(decoder.read_ints(block_count * 2))
+ block_count = decoder.read_int()
+
+ return LazyDict(contents_array)
+
+ def read(self, decoder: ReadableDecoder) -> Mapping[Any, Any]:
+ read_items: dict[Any, Any] = {}
+
if self._is_int_int or self._is_int_bytes:
+ if self._is_int_int:
+ return self._read_int_int(decoder)
+
+ block_count = decoder.read_int()
while block_count != 0:
if block_count < 0:
block_count = -block_count
# We ignore the block size for now
_ = decoder.read_int()
- if self._is_int_int:
- decoder.read_int_int_dict(block_count, read_items)
- else:
- decoder.read_int_bytes_dict(block_count, read_items)
+ decoder.read_int_bytes_dict(block_count, read_items)
block_count = decoder.read_int()
else:
+ block_count = decoder.read_int()
while block_count != 0:
if block_count < 0:
block_count = -block_count
@@ -440,7 +484,7 @@ class MapReader(Reader):
return read_items
- def skip(self, decoder: BinaryDecoder) -> None:
+ def skip(self, decoder: ReadableDecoder) -> None:
def skip() -> None:
self.key.skip(decoder)
self.value.skip(decoder)
diff --git a/python/pyiceberg/avro/resolver.py
b/python/pyiceberg/avro/resolver.py
index efd99936c5..9b34a106aa 100644
--- a/python/pyiceberg/avro/resolver.py
+++ b/python/pyiceberg/avro/resolver.py
@@ -25,7 +25,6 @@ from typing import (
Union,
)
-from pyiceberg.avro.decoder import BinaryDecoder
from pyiceberg.avro.reader import (
BinaryReader,
BooleanReader,
@@ -40,6 +39,7 @@ from pyiceberg.avro.reader import (
MapReader,
NoneReader,
OptionReader,
+ ReadableDecoder,
Reader,
StringReader,
StructReader,
@@ -226,10 +226,10 @@ class EnumReader(Reader):
self.enum = enum
self.reader = reader
- def read(self, decoder: BinaryDecoder) -> Enum:
+ def read(self, decoder: ReadableDecoder) -> Enum:
return self.enum(self.reader.read(decoder))
- def skip(self, decoder: BinaryDecoder) -> None:
+ def skip(self, decoder: ReadableDecoder) -> None:
pass
diff --git a/python/pyiceberg/utils/lazydict.py
b/python/pyiceberg/utils/lazydict.py
new file mode 100644
index 0000000000..90159ce30b
--- /dev/null
+++ b/python/pyiceberg/utils/lazydict.py
@@ -0,0 +1,68 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+from typing import (
+ Dict,
+ Iterator,
+ Mapping,
+ Optional,
+ Sequence,
+ TypeVar,
+ Union,
+ cast,
+)
+
+K = TypeVar("K")
+V = TypeVar("V")
+
+
+class LazyDict(Mapping[K, V]):
+ """Lazily build a dictionary from an array of items."""
+
+ __slots__ = ("_contents", "_dict")
+
+ # Since Python's type system is not powerful enough to express the type of
the
+ # contents of the dictionary, we use specify the type as a sequence of
either K or V
+ # values.
+ #
+ # Rather than spending the runtime cost of checking the type of each item,
we presume
+ # that the developer has correctly used the class and that the contents
are valid.
+ def __init__(self, contents: Sequence[Sequence[Union[K, V]]]):
+ self._contents = contents
+ self._dict: Optional[Dict[K, V]] = None
+
+ def _build_dict(self) -> Dict[K, V]:
+ self._dict = {}
+ for item in self._contents:
+ self._dict.update(dict(zip(cast(Sequence[K], item[::2]),
cast(Sequence[V], item[1::2]))))
+
+ return self._dict
+
+ def __getitem__(self, key: K, /) -> V:
+ """Returns the value for the given key."""
+ source = self._dict or self._build_dict()
+ return source[key]
+
+ def __iter__(self) -> Iterator[K]:
+ """Returns an iterator over the keys of the dictionary."""
+ source = self._dict or self._build_dict()
+ return iter(source)
+
+ def __len__(self) -> int:
+ """Returns the number of items in the dictionary."""
+ source = self._dict or self._build_dict()
+ return len(source)
diff --git a/python/pyproject.toml b/python/pyproject.toml
index 7eea9f4271..ec5257535a 100644
--- a/python/pyproject.toml
+++ b/python/pyproject.toml
@@ -39,7 +39,10 @@ packages = [
{ include = "Makefile", format = "sdist" },
{ include = "NOTICE", format = ["sdist", "wheel"] }
]
-include = [{ path = "dev", format = "sdist" }]
+include = [
+ { path = "dev", format = "sdist" },
+ { path = "pyiceberg/**/*.so", format = "wheel" }
+]
[tool.poetry.dependencies]
python = "^3.8"
@@ -75,6 +78,7 @@ requests-mock = "1.11.0"
moto = "^4.1.13"
typing-extensions = "4.7.1"
pytest-mock = "3.11.1"
+cython = "3.0.0"
[[tool.mypy.overrides]]
module = "pytest_mock.*"
@@ -84,9 +88,13 @@ ignore_missing_imports = true
pyiceberg = "pyiceberg.cli.console:run"
[build-system]
-requires = ["poetry-core>=1.0.0"]
+requires = ["poetry-core>=1.0.0", "wheel", "Cython>=3.0.0", "setuptools"]
build-backend = "poetry.core.masonry.api"
+[tool.poetry.build]
+generate-setup-file = false
+script = "build-module.py"
+
[tool.poetry.extras]
pyarrow = ["pyarrow"]
pandas = ["pandas", "pyarrow"]
@@ -259,5 +267,13 @@ ignore_missing_imports = true
module = "sqlalchemy.*"
ignore_missing_imports = true
+[[tool.mypy.overrides]]
+module = "Cython.*"
+ignore_missing_imports = true
+
+[[tool.mypy.overrides]]
+module = "setuptools.*"
+ignore_missing_imports = true
+
[tool.coverage.run]
source = ['pyiceberg/']
diff --git a/python/tests/avro/test_decoder.py
b/python/tests/avro/test_decoder.py
index c51f1090fc..0b35dcff0c 100644
--- a/python/tests/avro/test_decoder.py
+++ b/python/tests/avro/test_decoder.py
@@ -17,36 +17,42 @@
from __future__ import annotations
import io
+import itertools
+import struct
from io import SEEK_SET
from types import TracebackType
-from typing import Optional, Type
+from typing import Callable, Optional, Type
import pytest
-from pyiceberg.avro.decoder import BinaryDecoder, InMemoryBinaryDecoder,
StreamingBinaryDecoder
+from pyiceberg.avro.decoder import StreamingBinaryDecoder
+from pyiceberg.avro.decoder_fast import CythonBinaryDecoder
+from pyiceberg.avro.reader import ReadableDecoder
from pyiceberg.avro.resolver import resolve
from pyiceberg.io import InputStream
from pyiceberg.types import DoubleType, FloatType
-AVAILABLE_DECODERS = [StreamingBinaryDecoder, InMemoryBinaryDecoder]
+AVAILABLE_DECODERS = [StreamingBinaryDecoder, lambda stream:
CythonBinaryDecoder(stream.read())]
+
+CALLABLE_DECODER = Callable[[InputStream], ReadableDecoder]
@pytest.mark.parametrize("decoder_class", AVAILABLE_DECODERS)
-def test_read_boolean_true(decoder_class: Type[BinaryDecoder]) -> None:
+def test_read_boolean_true(decoder_class: CALLABLE_DECODER) -> None:
mis = io.BytesIO(b"\x01")
decoder = decoder_class(mis)
assert decoder.read_boolean() is True
@pytest.mark.parametrize("decoder_class", AVAILABLE_DECODERS)
-def test_read_boolean_false(decoder_class: Type[BinaryDecoder]) -> None:
+def test_read_boolean_false(decoder_class: CALLABLE_DECODER) -> None:
mis = io.BytesIO(b"\x00")
decoder = decoder_class(mis)
assert decoder.read_boolean() is False
@pytest.mark.parametrize("decoder_class", AVAILABLE_DECODERS)
-def test_skip_boolean(decoder_class: Type[BinaryDecoder]) -> None:
+def test_skip_boolean(decoder_class: CALLABLE_DECODER) -> None:
mis = io.BytesIO(b"\x00")
decoder = decoder_class(mis)
assert decoder.tell() == 0
@@ -55,14 +61,43 @@ def test_skip_boolean(decoder_class: Type[BinaryDecoder])
-> None:
@pytest.mark.parametrize("decoder_class", AVAILABLE_DECODERS)
-def test_read_int(decoder_class: Type[BinaryDecoder]) -> None:
+def test_read_int(decoder_class: CALLABLE_DECODER) -> None:
mis = io.BytesIO(b"\x18")
decoder = decoder_class(mis)
assert decoder.read_int() == 12
@pytest.mark.parametrize("decoder_class", AVAILABLE_DECODERS)
-def test_skip_int(decoder_class: Type[BinaryDecoder]) -> None:
+def test_read_int_longer(decoder_class: CALLABLE_DECODER) -> None:
+ mis = io.BytesIO(b"\x8e\xd1\x87\x01")
+ decoder = decoder_class(mis)
+ assert decoder.read_int() == 1111111
+
+
+def zigzag_encode(datum: int) -> bytes:
+ result = []
+ datum = (datum << 1) ^ (datum >> 63)
+ while (datum & ~0x7F) != 0:
+ result.append(struct.pack("B", (datum & 0x7F) | 0x80))
+ datum >>= 7
+ result.append(struct.pack("B", datum))
+ return b"".join(result)
+
+
[email protected](
+ "decoder_class, expected_value",
+ list(itertools.product(AVAILABLE_DECODERS, [0, -1, 2**32, -(2**32), (2**63
- 1), -(2**63)])),
+)
+def test_read_int_custom_encode(decoder_class: CALLABLE_DECODER,
expected_value: int) -> None:
+ encoded = zigzag_encode(expected_value)
+ mis = io.BytesIO(encoded)
+ decoder = decoder_class(mis)
+ decoded = decoder.read_int()
+ assert decoded == expected_value, f"Decoded value does not match
decoded={decoded} expected={expected_value}"
+
+
[email protected]("decoder_class", AVAILABLE_DECODERS)
+def test_skip_int(decoder_class: CALLABLE_DECODER) -> None:
mis = io.BytesIO(b"\x18")
decoder = decoder_class(mis)
assert decoder.tell() == 0
@@ -71,7 +106,7 @@ def test_skip_int(decoder_class: Type[BinaryDecoder]) ->
None:
@pytest.mark.parametrize("decoder_class", AVAILABLE_DECODERS)
-def test_read_negative_bytes(decoder_class: Type[BinaryDecoder]) -> None:
+def test_read_negative_bytes(decoder_class: CALLABLE_DECODER) -> None:
mis = io.BytesIO(b"")
decoder = decoder_class(mis)
@@ -113,20 +148,20 @@ class OneByteAtATimeInputStream(InputStream):
# InMemoryBinaryDecoder doesn't work for a byte at a time reading
@pytest.mark.parametrize("decoder_class", [StreamingBinaryDecoder])
-def test_read_single_byte_at_the_time(decoder_class: Type[BinaryDecoder]) ->
None:
+def test_read_single_byte_at_the_time(decoder_class: CALLABLE_DECODER) -> None:
decoder = decoder_class(OneByteAtATimeInputStream())
assert decoder.read(2) == b"\x01\x02"
@pytest.mark.parametrize("decoder_class", AVAILABLE_DECODERS)
-def test_read_float(decoder_class: Type[BinaryDecoder]) -> None:
+def test_read_float(decoder_class: CALLABLE_DECODER) -> None:
mis = io.BytesIO(b"\x00\x00\x9A\x41")
decoder = decoder_class(mis)
assert decoder.read_float() == 19.25
@pytest.mark.parametrize("decoder_class", AVAILABLE_DECODERS)
-def test_skip_float(decoder_class: Type[BinaryDecoder]) -> None:
+def test_skip_float(decoder_class: CALLABLE_DECODER) -> None:
mis = io.BytesIO(b"\x00\x00\x9A\x41")
decoder = decoder_class(mis)
assert decoder.tell() == 0
@@ -135,14 +170,14 @@ def test_skip_float(decoder_class: Type[BinaryDecoder])
-> None:
@pytest.mark.parametrize("decoder_class", AVAILABLE_DECODERS)
-def test_read_double(decoder_class: Type[BinaryDecoder]) -> None:
+def test_read_double(decoder_class: CALLABLE_DECODER) -> None:
mis = io.BytesIO(b"\x00\x00\x00\x00\x00\x40\x33\x40")
decoder = decoder_class(mis)
assert decoder.read_double() == 19.25
@pytest.mark.parametrize("decoder_class", AVAILABLE_DECODERS)
-def test_skip_double(decoder_class: Type[BinaryDecoder]) -> None:
+def test_skip_double(decoder_class: CALLABLE_DECODER) -> None:
mis = io.BytesIO(b"\x00\x00\x00\x00\x00\x40\x33\x40")
decoder = decoder_class(mis)
assert decoder.tell() == 0
@@ -151,7 +186,7 @@ def test_skip_double(decoder_class: Type[BinaryDecoder]) ->
None:
@pytest.mark.parametrize("decoder_class", AVAILABLE_DECODERS)
-def test_read_bytes(decoder_class: Type[BinaryDecoder]) -> None:
+def test_read_bytes(decoder_class: CALLABLE_DECODER) -> None:
mis = io.BytesIO(b"\x08\x01\x02\x03\x04")
decoder = decoder_class(mis)
actual = decoder.read_bytes()
@@ -159,14 +194,14 @@ def test_read_bytes(decoder_class: Type[BinaryDecoder])
-> None:
@pytest.mark.parametrize("decoder_class", AVAILABLE_DECODERS)
-def test_read_utf8(decoder_class: Type[BinaryDecoder]) -> None:
+def test_read_utf8(decoder_class: CALLABLE_DECODER) -> None:
mis = io.BytesIO(b"\x04\x76\x6F")
decoder = decoder_class(mis)
assert decoder.read_utf8() == "vo"
@pytest.mark.parametrize("decoder_class", AVAILABLE_DECODERS)
-def test_skip_utf8(decoder_class: Type[BinaryDecoder]) -> None:
+def test_skip_utf8(decoder_class: CALLABLE_DECODER) -> None:
mis = io.BytesIO(b"\x04\x76\x6F")
decoder = decoder_class(mis)
assert decoder.tell() == 0
@@ -175,7 +210,7 @@ def test_skip_utf8(decoder_class: Type[BinaryDecoder]) ->
None:
@pytest.mark.parametrize("decoder_class", AVAILABLE_DECODERS)
-def test_read_int_as_float(decoder_class: Type[BinaryDecoder]) -> None:
+def test_read_int_as_float(decoder_class: CALLABLE_DECODER) -> None:
mis = io.BytesIO(b"\x00\x00\x9A\x41")
decoder = decoder_class(mis)
reader = resolve(FloatType(), DoubleType())
diff --git a/python/tests/avro/test_reader.py b/python/tests/avro/test_reader.py
index 416a11abb2..36d148e8b3 100644
--- a/python/tests/avro/test_reader.py
+++ b/python/tests/avro/test_reader.py
@@ -17,11 +17,12 @@
# pylint:disable=protected-access
import io
import json
-from typing import Type
+from typing import Callable
import pytest
-from pyiceberg.avro.decoder import BinaryDecoder, InMemoryBinaryDecoder,
StreamingBinaryDecoder
+from pyiceberg.avro.decoder import StreamingBinaryDecoder
+from pyiceberg.avro.decoder_fast import CythonBinaryDecoder
from pyiceberg.avro.file import AvroFile
from pyiceberg.avro.reader import (
BinaryReader,
@@ -32,6 +33,7 @@ from pyiceberg.avro.reader import (
FixedReader,
FloatReader,
IntegerReader,
+ ReadableDecoder,
StringReader,
StructReader,
TimeReader,
@@ -40,6 +42,7 @@ from pyiceberg.avro.reader import (
UUIDReader,
)
from pyiceberg.avro.resolver import construct_reader
+from pyiceberg.io import InputStream
from pyiceberg.io.pyarrow import PyArrowFileIO
from pyiceberg.manifest import MANIFEST_ENTRY_SCHEMA, DataFile, ManifestEntry
from pyiceberg.schema import Schema
@@ -64,7 +67,7 @@ from pyiceberg.types import (
UUIDType,
)
-AVAILABLE_DECODERS = [StreamingBinaryDecoder, InMemoryBinaryDecoder]
+AVAILABLE_DECODERS = [StreamingBinaryDecoder, lambda stream:
CythonBinaryDecoder(stream.read())]
def test_read_header(generated_manifest_entry_file: str,
iceberg_manifest_entry_schema: Schema) -> None:
@@ -339,7 +342,7 @@ def test_uuid_reader() -> None:
@pytest.mark.parametrize("decoder_class", AVAILABLE_DECODERS)
-def test_read_struct(decoder_class: Type[BinaryDecoder]) -> None:
+def test_read_struct(decoder_class: Callable[[InputStream], ReadableDecoder])
-> None:
mis = io.BytesIO(b"\x18")
decoder = decoder_class(mis)
struct = StructType(NestedField(1, "id", IntegerType(), required=True))
@@ -348,7 +351,7 @@ def test_read_struct(decoder_class: Type[BinaryDecoder]) ->
None:
@pytest.mark.parametrize("decoder_class", AVAILABLE_DECODERS)
-def test_read_struct_lambda(decoder_class: Type[BinaryDecoder]) -> None:
+def test_read_struct_lambda(decoder_class: Callable[[InputStream],
ReadableDecoder]) -> None:
mis = io.BytesIO(b"\x18")
decoder = decoder_class(mis)
@@ -361,7 +364,7 @@ def test_read_struct_lambda(decoder_class:
Type[BinaryDecoder]) -> None:
@pytest.mark.parametrize("decoder_class", AVAILABLE_DECODERS)
-def test_read_not_struct_type(decoder_class: Type[BinaryDecoder]) -> None:
+def test_read_not_struct_type(decoder_class: Callable[[InputStream],
ReadableDecoder]) -> None:
mis = io.BytesIO(b"\x18")
decoder = decoder_class(mis)
@@ -373,7 +376,7 @@ def test_read_not_struct_type(decoder_class:
Type[BinaryDecoder]) -> None:
@pytest.mark.parametrize("decoder_class", AVAILABLE_DECODERS)
-def test_read_struct_exception_handling(decoder_class: Type[BinaryDecoder]) ->
None:
+def test_read_struct_exception_handling(decoder_class: Callable[[InputStream],
ReadableDecoder]) -> None:
mis = io.BytesIO(b"\x18")
decoder = decoder_class(mis)
diff --git a/python/tests/utils/test_lazydict.py
b/python/tests/utils/test_lazydict.py
new file mode 100644
index 0000000000..a95b015a99
--- /dev/null
+++ b/python/tests/utils/test_lazydict.py
@@ -0,0 +1,31 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+from pyiceberg.utils.lazydict import LazyDict
+
+
+def test_lazy_dict_ints() -> None:
+ lazy_dict = LazyDict[int, int]([[1, 2], [3, 4]])
+ assert lazy_dict[1] == 2
+ assert lazy_dict[3] == 4
+
+
+def test_lazy_dict_strings() -> None:
+ lazy_dict = LazyDict[int, str]([[1, "red", 5, "banana"], [3, "blue"]])
+ assert lazy_dict[1] == "red"
+ assert lazy_dict[3] == "blue"
+ assert lazy_dict[5] == "banana"